diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2d4a6db25f0c..4af594604e9d 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -22,6 +22,13 @@ ip_no_pmtu_disc - BOOLEAN min_pmtu - INTEGER default 552 - minimum discovered Path MTU +fwmark_reflect - BOOLEAN + Controls the fwmark of kernel-generated IPv4 reply packets that are not + associated with a socket for example, TCP RSTs or ICMP echo replies). + If unset, these packets have a fwmark of zero. If set, they have the + fwmark of the packet they are replying to. + Default: 0 + route/max_size - INTEGER Maximum number of routes allowed in the kernel. Increase this when using large numbers of interfaces and/or routes. @@ -1048,6 +1055,13 @@ proxy_ndp - INTEGER 2 NDP packets are sent to userspace, where a userspace proxy can be implemented +fwmark_reflect - BOOLEAN + Controls the fwmark of kernel-generated IPv6 reply packets that are not + associated with a socket for example, TCP RSTs or ICMPv6 echo replies). + If unset, these packets have a fwmark of zero. If set, they have the + fwmark of the packet they are replying to. + Default: 0 + conf/interface/*: Change special settings per interface. diff --git a/arch/arm/configs/w3ds_global_com_defconfig b/arch/arm/configs/w3ds_global_com_defconfig index d2ecfa20748d..794a164443f8 100755 --- a/arch/arm/configs/w3ds_global_com_defconfig +++ b/arch/arm/configs/w3ds_global_com_defconfig @@ -1,5 +1,7 @@ # CONFIG_ARM_PATCH_PHYS_VIRT is not set CONFIG_EXPERIMENTAL=y +CONFIG_LZ4_COMPRESS=y +CONFIG_LZ4_DECOMPRESS=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_AUDIT=y @@ -467,6 +469,7 @@ CONFIG_UIO=y CONFIG_UIO_MSM_SHAREDMEM=y CONFIG_STAGING=y CONFIG_ZRAM=y +CONFIG_ZRAM_LZ4_COMPRESS=y CONFIG_ZSMALLOC=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y diff --git a/arch/arm/configs/w5_global_com_defconfig b/arch/arm/configs/w5_global_com_defconfig index 2920ddc55b38..0c7e5a250b7e 100644 --- a/arch/arm/configs/w5_global_com_defconfig +++ b/arch/arm/configs/w5_global_com_defconfig @@ -253,9 +253,11 @@ CONFIG_BT_HIDP=y CONFIG_BT_HCISMD=y CONFIG_CFG80211=y CONFIG_NL80211_TESTMODE=y -#CONFIG_LGE_NFC=y -#CONFIG_LGE_NFC_PN547=y -#CONFIG_LGE_NFC_SET_IRQ_WAKEUP=y + +CONFIG_LGE_NFC=y +CONFIG_LGE_NFC_PN547=y +CONFIG_LGE_NFC_SET_IRQ_WAKEUP=y + CONFIG_CMA=y CONFIG_CMA_SIZE_MBYTES=4 CONFIG_BLK_DEV_LOOP=y diff --git a/arch/arm/configs/w5ds_global_com_defconfig b/arch/arm/configs/w5ds_global_com_defconfig index 8483407bd8be..6bfa59238c60 100644 --- a/arch/arm/configs/w5ds_global_com_defconfig +++ b/arch/arm/configs/w5ds_global_com_defconfig @@ -1,5 +1,7 @@ # CONFIG_ARM_PATCH_PHYS_VIRT is not set CONFIG_EXPERIMENTAL=y +CONFIG_LZ4_COMPRESS=y +CONFIG_LZ4_DECOMPRESS=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_AUDIT=y @@ -463,6 +465,7 @@ CONFIG_UIO=y CONFIG_UIO_MSM_SHAREDMEM=y CONFIG_STAGING=y CONFIG_ZRAM=y +CONFIG_ZRAM_LZ4_COMPRESS=y CONFIG_ZSMALLOC=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y diff --git a/arch/arm/configs/w5n_global_com_defconfig b/arch/arm/configs/w5n_global_com_defconfig index 7118ad22178e..173c675aa35b 100644 --- a/arch/arm/configs/w5n_global_com_defconfig +++ b/arch/arm/configs/w5n_global_com_defconfig @@ -469,6 +469,7 @@ CONFIG_UIO=y CONFIG_UIO_MSM_SHAREDMEM=y CONFIG_STAGING=y CONFIG_ZRAM=y + CONFIG_ZSMALLOC=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y diff --git a/drivers/input/sensor/bma2x2_driver.c b/drivers/input/sensor/bma2x2_driver.c index 15322f49f068..511f91513469 100644 --- a/drivers/input/sensor/bma2x2_driver.c +++ b/drivers/input/sensor/bma2x2_driver.c @@ -1486,7 +1486,7 @@ static int bma2x2_set_int1_pad_sel(struct i2c_client *client, unsigned char int1sel) { int comres = 0; - unsigned char data; + unsigned char data = '0'; unsigned char state; state = 0x01; @@ -1569,7 +1569,7 @@ static int bma2x2_set_int2_pad_sel(struct i2c_client *client, unsigned char int2sel) { int comres = 0; - unsigned char data; + unsigned char data = '0'; unsigned char state; state = 0x01; @@ -1651,7 +1651,7 @@ static int bma2x2_set_Int_Enable(struct i2c_client *client, unsigned char InterruptType , unsigned char value) { int comres = 0; - unsigned char data1, data2; + unsigned char data1 = '0', data2 = '0'; if ((11 < InterruptType) && (InterruptType < 16)) { switch (InterruptType) { @@ -1786,7 +1786,7 @@ static int bma2x2_get_interruptstatus1(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS1_REG, &data); *intstatus = data; @@ -1799,7 +1799,7 @@ static int bma2x2_get_HIGH_first(struct i2c_client *client, unsigned char param, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; switch (param) { case 0: @@ -1831,7 +1831,7 @@ static int bma2x2_get_HIGH_sign(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); @@ -1846,7 +1846,7 @@ static int bma2x2_get_slope_first(struct i2c_client *client, unsigned char param, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; switch (param) { case 0: @@ -1878,7 +1878,7 @@ static int bma2x2_get_slope_sign(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_TAP_SLOPE_REG, &data); @@ -1893,7 +1893,7 @@ static int bma2x2_get_orient_status(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); @@ -1907,7 +1907,7 @@ static int bma2x2_get_orient_flat_status(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); @@ -1921,7 +1921,7 @@ static int bma2x2_get_orient_flat_status(struct i2c_client *client, unsigned static int bma2x2_set_slope_source(struct i2c_client *client, unsigned char value) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_UNFILT_INT_SRC_SLOPE__REG, &data); @@ -1936,7 +1936,7 @@ static int bma2x2_set_slope_source(struct i2c_client *client, unsigned char valu static int bma2x2_get_slope_source(struct i2c_client *client, unsigned char *value) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_UNFILT_INT_SRC_SLOPE__REG, &data); @@ -1950,7 +1950,7 @@ static int bma2x2_get_slope_source(struct i2c_client *client, unsigned char *val static int bma2x2_set_high_g_source(struct i2c_client *client, unsigned char value) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_UNFILT_INT_SRC_HIGHG__REG, &data); @@ -1964,7 +1964,7 @@ static int bma2x2_set_high_g_source(struct i2c_client *client, unsigned char val static int bma2x2_get_high_g_source(struct i2c_client *client, unsigned char *value) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_UNFILT_INT_SRC_HIGHG__REG, &data); @@ -1977,7 +1977,7 @@ static int bma2x2_get_high_g_source(struct i2c_client *client, unsigned char *va static int bma2x2_set_high_g_hyst(struct i2c_client *client, unsigned char value) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGHG_HYST__REG, &data); @@ -1991,7 +1991,7 @@ static int bma2x2_set_high_g_hyst(struct i2c_client *client, unsigned char value static int bma2x2_get_high_g_hyst(struct i2c_client *client, unsigned char *value) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGHG_HYST__REG, &data); @@ -2005,7 +2005,7 @@ static int bma2x2_get_high_g_hyst(struct i2c_client *client, unsigned char *valu static int bma2x2_set_Int_Mode(struct i2c_client *client, unsigned char Mode) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2022,7 +2022,7 @@ static int bma2x2_set_Int_Mode(struct i2c_client *client, unsigned char Mode) static int bma2x2_get_Int_Mode(struct i2c_client *client, unsigned char *Mode) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2037,7 +2037,7 @@ static int bma2x2_set_slope_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2054,7 +2054,7 @@ static int bma2x2_get_slope_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2070,7 +2070,7 @@ static int bma2x2_set_slope_no_mot_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2087,7 +2087,7 @@ static int bma2x2_get_slope_no_mot_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2103,7 +2103,7 @@ static int bma2x2_set_slope_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; - unsigned char data; + unsigned char data = '0'; data = threshold; comres = bma2x2_smbus_write_byte(client, @@ -2116,7 +2116,7 @@ static int bma2x2_get_slope_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2130,7 +2130,7 @@ static int bma2x2_set_slope_no_mot_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; - unsigned char data; + unsigned char data = '0'; data = threshold; comres = bma2x2_smbus_write_byte(client, @@ -2143,7 +2143,7 @@ static int bma2x2_get_slope_no_mot_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, @@ -2158,7 +2158,7 @@ static int bma2x2_set_low_g_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOWG_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_LOWG_DUR, duration); @@ -2171,7 +2171,7 @@ static int bma2x2_get_low_g_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_DURN_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_LOWG_DUR); @@ -2184,7 +2184,7 @@ static int bma2x2_set_low_g_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOWG_THRES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_LOWG_THRES, threshold); @@ -2197,7 +2197,7 @@ static int bma2x2_get_low_g_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_LOWG_THRES); @@ -2210,7 +2210,7 @@ static int bma2x2_set_high_g_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGHG_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_HIGHG_DUR, duration); @@ -2223,7 +2223,7 @@ static int bma2x2_get_high_g_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGH_DURN_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_DUR); @@ -2236,7 +2236,7 @@ static int bma2x2_set_high_g_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGHG_THRES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_HIGHG_THRES, threshold); @@ -2250,7 +2250,7 @@ static int bma2x2_get_high_g_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGH_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_THRES); @@ -2264,7 +2264,7 @@ static int bma2x2_set_tap_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_DUR, duration); @@ -2277,7 +2277,7 @@ static int bma2x2_get_tap_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_DUR); @@ -2289,7 +2289,7 @@ static int bma2x2_get_tap_duration(struct i2c_client *client, unsigned char static int bma2x2_set_tap_shock(struct i2c_client *client, unsigned char setval) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_SHOCK_DURN__REG, &data); @@ -2304,7 +2304,7 @@ static int bma2x2_get_tap_shock(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_SHOCK_DURN); @@ -2317,7 +2317,7 @@ static int bma2x2_set_tap_quiet(struct i2c_client *client, unsigned char duration) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_QUIET_DURN__REG, &data); @@ -2332,7 +2332,7 @@ static int bma2x2_get_tap_quiet(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_QUIET_DURN); @@ -2345,7 +2345,7 @@ static int bma2x2_set_tap_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_THRES, threshold); @@ -2358,7 +2358,7 @@ static int bma2x2_get_tap_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_THRES); @@ -2370,7 +2370,7 @@ static int bma2x2_get_tap_threshold(struct i2c_client *client, unsigned char static int bma2x2_set_tap_samp(struct i2c_client *client, unsigned char samp) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_SAMPLES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_SAMPLES, samp); @@ -2383,7 +2383,7 @@ static int bma2x2_set_tap_samp(struct i2c_client *client, unsigned char samp) static int bma2x2_get_tap_samp(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_SAMPLES); @@ -2395,7 +2395,7 @@ static int bma2x2_get_tap_samp(struct i2c_client *client, unsigned char *status) static int bma2x2_set_orient_mode(struct i2c_client *client, unsigned char mode) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_MODE__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_ORIENT_MODE, mode); @@ -2409,7 +2409,7 @@ static int bma2x2_get_orient_mode(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_MODE); @@ -2422,7 +2422,7 @@ static int bma2x2_set_orient_blocking(struct i2c_client *client, unsigned char samp) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_BLOCK__REG, &data); @@ -2437,7 +2437,7 @@ static int bma2x2_get_orient_blocking(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_BLOCK); @@ -2450,7 +2450,7 @@ static int bma2x2_set_orient_hyst(struct i2c_client *client, unsigned char orienthyst) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_HYST__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_ORIENT_HYST, orienthyst); @@ -2464,7 +2464,7 @@ static int bma2x2_get_orient_hyst(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_HYST); @@ -2476,7 +2476,7 @@ static int bma2x2_set_theta_blocking(struct i2c_client *client, unsigned char thetablk) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_BLOCK__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_THETA_BLOCK, thetablk); @@ -2490,7 +2490,7 @@ static int bma2x2_get_theta_blocking(struct i2c_client *client, unsigned char *status) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_BLOCK_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_THETA_BLOCK); @@ -2503,7 +2503,7 @@ static int bma2x2_set_theta_flat(struct i2c_client *client, unsigned char thetaflat) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_FLAT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_THETA_FLAT, thetaflat); @@ -2516,7 +2516,7 @@ static int bma2x2_get_theta_flat(struct i2c_client *client, unsigned char *status) { int comres = 0 ; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_FLAT_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_THETA_FLAT); @@ -2529,7 +2529,7 @@ static int bma2x2_set_flat_hold_time(struct i2c_client *client, unsigned char holdtime) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FLAT_HOLD_TIME__REG, &data); @@ -2544,7 +2544,7 @@ static int bma2x2_get_flat_hold_time(struct i2c_client *client, unsigned char *holdtime) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FLAT_HOLD_TIME_REG, &data); @@ -2557,7 +2557,7 @@ static int bma2x2_get_flat_hold_time(struct i2c_client *client, unsigned char static int bma2x2_set_mode(struct i2c_client *client, unsigned char Mode) { int comres = 0; - unsigned char data1, data2; + unsigned char data1 = '0', data2 = '0'; if (Mode < 6) { comres = bma2x2_smbus_read_byte(client, BMA2X2_MODE_CTRL_REG, @@ -2645,7 +2645,7 @@ static int bma2x2_set_mode(struct i2c_client *client, unsigned char Mode) static int bma2x2_get_mode(struct i2c_client *client, unsigned char *Mode) { int comres = 0; - unsigned char data1, data2; + unsigned char data1 = '0', data2 ='0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_MODE_CTRL_REG, &data1); comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, @@ -2692,7 +2692,7 @@ static int bma2x2_get_mode(struct i2c_client *client, unsigned char *Mode) static int bma2x2_set_range(struct i2c_client *client, unsigned char Range) { int comres = 0 ; - unsigned char data1; + unsigned char data1 = '0'; if ((Range == 3) || (Range == 5) || (Range == 8) || (Range == 12)) { comres = bma2x2_smbus_read_byte(client, BMA2X2_RANGE_SEL_REG, @@ -2729,7 +2729,7 @@ static int bma2x2_set_range(struct i2c_client *client, unsigned char Range) static int bma2x2_get_range(struct i2c_client *client, unsigned char *Range) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_RANGE_SEL__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_RANGE_SEL); @@ -2742,7 +2742,7 @@ static int bma2x2_get_range(struct i2c_client *client, unsigned char *Range) static int bma2x2_set_bandwidth(struct i2c_client *client, unsigned char BW) { int comres = 0; - unsigned char data; + unsigned char data = '0'; int Bandwidth = 0; if (BW > 7 && BW < 16) { @@ -2805,7 +2805,7 @@ static int bma2x2_set_bandwidth(struct i2c_client *client, unsigned char BW) static int bma2x2_get_bandwidth(struct i2c_client *client, unsigned char *BW) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_BANDWIDTH__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_BANDWIDTH); @@ -2818,7 +2818,7 @@ int bma2x2_get_sleep_duration(struct i2c_client *client, unsigned char *sleep_dur) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_SLEEP_DUR__REG, &data); @@ -2832,7 +2832,7 @@ int bma2x2_set_sleep_duration(struct i2c_client *client, unsigned char sleep_dur) { int comres = 0; - unsigned char data; + unsigned char data = '0'; int sleep_duration = 0; if (sleep_dur > 4 && sleep_dur < 16) { @@ -2913,7 +2913,7 @@ static int bma2x2_get_fifo_mode(struct i2c_client *client, unsigned char *fifo_mode) { int comres; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_MODE__REG, &data); *fifo_mode = BMA2X2_GET_BITSLICE(data, BMA2X2_FIFO_MODE); @@ -2924,7 +2924,7 @@ static int bma2x2_get_fifo_mode(struct i2c_client *client, unsigned char static int bma2x2_set_fifo_mode(struct i2c_client *client, unsigned char fifo_mode) { - unsigned char data; + unsigned char data = '0'; int comres = 0; if (fifo_mode < 4) { @@ -2945,7 +2945,7 @@ static int bma2x2_get_fifo_trig(struct i2c_client *client, unsigned char *fifo_trig) { int comres; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_TRIGGER_ACTION__REG, &data); @@ -2957,7 +2957,7 @@ static int bma2x2_get_fifo_trig(struct i2c_client *client, unsigned char static int bma2x2_set_fifo_trig(struct i2c_client *client, unsigned char fifo_trig) { - unsigned char data; + unsigned char data = '0'; int comres = 0; if (fifo_trig < 4) { @@ -2978,7 +2978,7 @@ static int bma2x2_get_fifo_trig_src(struct i2c_client *client, unsigned char *trig_src) { int comres; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_TRIGGER_SOURCE__REG, &data); @@ -2991,7 +2991,7 @@ static int bma2x2_get_fifo_trig_src(struct i2c_client *client, unsigned char static int bma2x2_set_fifo_trig_src(struct i2c_client *client, unsigned char trig_src) { - unsigned char data; + unsigned char data = '0'; int comres = 0; if (trig_src < 4) { @@ -3012,7 +3012,7 @@ static int bma2x2_get_fifo_framecount(struct i2c_client *client, unsigned char *framecount) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_FRAME_COUNTER_S__REG, &data); @@ -3025,7 +3025,7 @@ static int bma2x2_get_fifo_data_sel(struct i2c_client *client, unsigned char *data_sel) { int comres; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_DATA_SELECT__REG, &data); @@ -3037,7 +3037,7 @@ static int bma2x2_get_fifo_data_sel(struct i2c_client *client, unsigned char static int bma2x2_set_fifo_data_sel(struct i2c_client *client, unsigned char data_sel) { - unsigned char data; + unsigned char data = '0'; int comres = 0; if (data_sel < 4) { @@ -3059,7 +3059,7 @@ static int bma2x2_set_fifo_data_sel(struct i2c_client *client, unsigned char static int bma2x2_get_fifo_data_out_reg(struct i2c_client *client, unsigned char *out_reg) { - unsigned char data; + unsigned char data = '0'; int comres = 0; comres = bma2x2_smbus_read_byte(client, @@ -3073,7 +3073,7 @@ static int bma2x2_get_fifo_data_out_reg(struct i2c_client *client, unsigned char static int bma2x2_get_offset_target(struct i2c_client *client, unsigned char channel, unsigned char *offset) { - unsigned char data; + unsigned char data = '0'; int comres = 0; switch (channel) { @@ -3112,7 +3112,7 @@ static int bma2x2_get_offset_target(struct i2c_client *client, unsigned char static int bma2x2_set_offset_target(struct i2c_client *client, unsigned char channel, unsigned char offset) { - unsigned char data; + unsigned char data = '0'; int comres = 0; switch (channel) { @@ -3169,7 +3169,7 @@ static int bma2x2_get_cal_ready(struct i2c_client *client, unsigned char *calrdy ) { int comres = 0 ; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_FAST_CAL_RDY_S__REG, &data); @@ -3183,7 +3183,7 @@ static int bma2x2_set_cal_trigger(struct i2c_client *client, unsigned char caltrigger) { int comres = 0; - unsigned char data; + unsigned char data = '0'; #ifdef BMA2X2_ACCEL_CALIBRATION struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); @@ -3216,7 +3216,7 @@ static int bma2x2_set_offset_x(struct i2c_client *client, unsigned char offsetfilt) { int comres = 0; - unsigned char data; + unsigned char data = '0'; data = offsetfilt; comres = bma2x2_smbus_write_byte(client, BMA2X2_OFFSET_X_AXIS_REG, @@ -3230,7 +3230,7 @@ static int bma2x2_get_offset_x(struct i2c_client *client, unsigned char *offsetfilt) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_OFFSET_X_AXIS_REG, &data); @@ -3243,7 +3243,7 @@ static int bma2x2_set_offset_y(struct i2c_client *client, unsigned char offsetfilt) { int comres = 0; - unsigned char data; + unsigned char data = '0'; data = offsetfilt; comres = bma2x2_smbus_write_byte(client, BMA2X2_OFFSET_Y_AXIS_REG, @@ -3256,7 +3256,7 @@ static int bma2x2_get_offset_y(struct i2c_client *client, unsigned char *offsetfilt) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_OFFSET_Y_AXIS_REG, &data); @@ -3269,7 +3269,7 @@ static int bma2x2_set_offset_z(struct i2c_client *client, unsigned char offsetfilt) { int comres = 0; - unsigned char data; + unsigned char data = '0'; data = offsetfilt; comres = bma2x2_smbus_write_byte(client, BMA2X2_OFFSET_Z_AXIS_REG, @@ -3282,7 +3282,7 @@ static int bma2x2_get_offset_z(struct i2c_client *client, unsigned char *offsetfilt) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_OFFSET_Z_AXIS_REG, &data); @@ -3296,7 +3296,7 @@ static int bma2x2_set_selftest_st(struct i2c_client *client, unsigned char selftest) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_SELF_TEST__REG, &data); @@ -3310,7 +3310,7 @@ static int bma2x2_set_selftest_st(struct i2c_client *client, unsigned char static int bma2x2_set_selftest_stn(struct i2c_client *client, unsigned char stn) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_NEG_SELF_TEST__REG, &data); @@ -3324,7 +3324,7 @@ static int bma2x2_set_selftest_stn(struct i2c_client *client, unsigned char stn) static int bma2x2_set_selftest_amp(struct i2c_client *client, unsigned char amp) { int comres = 0; - unsigned char data; + unsigned char data = '0'; comres = bma2x2_smbus_read_byte(client, BMA2X2_SELF_TEST_AMP__REG, &data); @@ -3539,7 +3539,7 @@ static int bma2x2_read_accel_z(struct i2c_client *client, static int bma2x2_read_temperature(struct i2c_client *client, signed char *temperature) { - unsigned char data; + unsigned char data = '0'; int comres = 0; comres = bma2x2_smbus_read_byte(client, BMA2X2_TEMPERATURE_REG, &data); @@ -3623,7 +3623,7 @@ static ssize_t bma2x2_enable_int_store(struct device *dev, static ssize_t bma2x2_int_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_Int_Mode(bma2x2->bma2x2_client, &data) < 0) @@ -3652,7 +3652,7 @@ static ssize_t bma2x2_int_mode_store(struct device *dev, static ssize_t bma2x2_slope_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_slope_duration(bma2x2->bma2x2_client, &data) < 0) @@ -3684,7 +3684,7 @@ static ssize_t bma2x2_slope_duration_store(struct device *dev, static ssize_t bma2x2_slope_no_mot_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_slope_no_mot_duration(bma2x2->bma2x2_client, &data) < 0) @@ -3717,7 +3717,7 @@ static ssize_t bma2x2_slope_no_mot_duration_store(struct device *dev, static ssize_t bma2x2_slope_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_slope_threshold(bma2x2->bma2x2_client, &data) < 0) @@ -3748,7 +3748,7 @@ static ssize_t bma2x2_slope_threshold_store(struct device *dev, static ssize_t bma2x2_slope_no_mot_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_slope_no_mot_threshold(bma2x2->bma2x2_client, &data) < 0) @@ -3779,7 +3779,7 @@ static ssize_t bma2x2_slope_no_mot_threshold_store(struct device *dev, static ssize_t bma2x2_high_g_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_high_g_duration(bma2x2->bma2x2_client, &data) < 0) @@ -3811,7 +3811,7 @@ static ssize_t bma2x2_high_g_duration_store(struct device *dev, static ssize_t bma2x2_high_g_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_high_g_threshold(bma2x2->bma2x2_client, &data) < 0) @@ -3842,7 +3842,7 @@ static ssize_t bma2x2_high_g_threshold_store(struct device *dev, static ssize_t bma2x2_low_g_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_low_g_duration(bma2x2->bma2x2_client, &data) < 0) @@ -3874,7 +3874,7 @@ static ssize_t bma2x2_low_g_duration_store(struct device *dev, static ssize_t bma2x2_low_g_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_low_g_threshold(bma2x2->bma2x2_client, &data) < 0) @@ -3904,7 +3904,7 @@ static ssize_t bma2x2_low_g_threshold_store(struct device *dev, static ssize_t bma2x2_tap_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_tap_threshold(bma2x2->bma2x2_client, &data) < 0) @@ -3934,7 +3934,7 @@ static ssize_t bma2x2_tap_threshold_store(struct device *dev, static ssize_t bma2x2_tap_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_tap_duration(bma2x2->bma2x2_client, &data) < 0) @@ -3965,7 +3965,7 @@ static ssize_t bma2x2_tap_duration_store(struct device *dev, static ssize_t bma2x2_tap_quiet_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_tap_quiet(bma2x2->bma2x2_client, &data) < 0) @@ -3997,7 +3997,7 @@ static ssize_t bma2x2_tap_quiet_store(struct device *dev, static ssize_t bma2x2_tap_shock_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_tap_shock(bma2x2->bma2x2_client, &data) < 0) @@ -4029,7 +4029,7 @@ static ssize_t bma2x2_tap_shock_store(struct device *dev, static ssize_t bma2x2_tap_samp_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_tap_samp(bma2x2->bma2x2_client, &data) < 0) @@ -4060,7 +4060,7 @@ static ssize_t bma2x2_tap_samp_store(struct device *dev, static ssize_t bma2x2_orient_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_orient_mode(bma2x2->bma2x2_client, &data) < 0) @@ -4092,7 +4092,7 @@ static ssize_t bma2x2_orient_mode_store(struct device *dev, static ssize_t bma2x2_orient_blocking_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_orient_blocking(bma2x2->bma2x2_client, &data) < 0) @@ -4123,7 +4123,7 @@ static ssize_t bma2x2_orient_blocking_store(struct device *dev, static ssize_t bma2x2_orient_hyst_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_orient_hyst(bma2x2->bma2x2_client, &data) < 0) @@ -4155,7 +4155,7 @@ static ssize_t bma2x2_orient_hyst_store(struct device *dev, static ssize_t bma2x2_orient_theta_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_theta_blocking(bma2x2->bma2x2_client, &data) < 0) @@ -4187,7 +4187,7 @@ static ssize_t bma2x2_orient_theta_store(struct device *dev, static ssize_t bma2x2_flat_theta_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_theta_flat(bma2x2->bma2x2_client, &data) < 0) @@ -4218,7 +4218,7 @@ static ssize_t bma2x2_flat_theta_store(struct device *dev, static ssize_t bma2x2_flat_hold_time_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_flat_hold_time(bma2x2->bma2x2_client, &data) < 0) @@ -4688,7 +4688,7 @@ static ssize_t bma2x2_register_show(struct device *dev, static ssize_t bma2x2_range_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_range(bma2x2->bma2x2_client, &data) < 0) @@ -4717,7 +4717,7 @@ static ssize_t bma2x2_range_store(struct device *dev, static ssize_t bma2x2_bandwidth_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_bandwidth(bma2x2->bma2x2_client, &data) < 0) @@ -4764,7 +4764,7 @@ static ssize_t bma2x2_bandwidth_store(struct device *dev, static ssize_t bma2x2_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_mode(bma2x2->bma2x2_client, &data) < 0) @@ -5199,7 +5199,7 @@ static ssize_t bma2x2_fast_calibration_x_show(struct device *dev, #ifdef BMA2X2_ACCEL_CALIBRATION return sprintf(buf, "%d\n", atomic_read(&bma2x2->fast_calib_x_rslt)); #else - unsigned char data; + unsigned char data = '0'; if (bma2x2_get_offset_target(bma2x2->bma2x2_client, 1, &data) < 0) return sprintf(buf, "Read error\n"); @@ -5298,7 +5298,7 @@ static ssize_t bma2x2_fast_calibration_y_show(struct device *dev, #ifdef BMA2X2_ACCEL_CALIBRATION return sprintf(buf, "%d\n", atomic_read(&bma2x2->fast_calib_y_rslt)); #else - unsigned char data; + unsigned char data = '0'; if (bma2x2_get_offset_target(bma2x2->bma2x2_client, 2, &data) < 0) return sprintf(buf, "Read error\n"); @@ -5399,7 +5399,7 @@ static ssize_t bma2x2_fast_calibration_z_show(struct device *dev, #ifdef BMA2X2_ACCEL_CALIBRATION return sprintf(buf, "%d\n", atomic_read(&bma2x2->fast_calib_z_rslt)); #else - unsigned char data; + unsigned char data = '0'; if (bma2x2_get_offset_target(bma2x2->bma2x2_client, 3, &data) < 0) return sprintf(buf, "Read error\n"); @@ -5494,7 +5494,7 @@ static ssize_t bma2x2_fast_calibration_z_store(struct device *dev, static ssize_t bma2x2_SleepDur_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_sleep_duration(bma2x2->bma2x2_client, &data) < 0) @@ -5525,7 +5525,7 @@ static ssize_t bma2x2_SleepDur_store(struct device *dev, static ssize_t bma2x2_fifo_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_fifo_mode(bma2x2->bma2x2_client, &data) < 0) @@ -5558,7 +5558,7 @@ static ssize_t bma2x2_fifo_mode_store(struct device *dev, static ssize_t bma2x2_fifo_trig_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_fifo_trig(bma2x2->bma2x2_client, &data) < 0) @@ -5591,7 +5591,7 @@ static ssize_t bma2x2_fifo_trig_store(struct device *dev, static ssize_t bma2x2_fifo_trig_src_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_fifo_trig_src(bma2x2->bma2x2_client, &data) < 0) @@ -5624,7 +5624,7 @@ static ssize_t bma2x2_fifo_trig_src_store(struct device *dev, static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_fifo_data_sel(bma2x2->bma2x2_client, &data) < 0) @@ -5637,7 +5637,7 @@ static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, static ssize_t bma2x2_fifo_framecount_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_fifo_framecount(bma2x2->bma2x2_client, &data) < 0) @@ -5650,7 +5650,7 @@ static ssize_t bma2x2_fifo_framecount_show(struct device *dev, static ssize_t bma2x2_temperature_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_read_temperature(bma2x2->bma2x2_client, &data) < 0) @@ -5683,7 +5683,7 @@ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, static ssize_t bma2x2_fifo_data_out_frame_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; int err, i, len; signed char fifo_data_out[MAX_FIFO_F_LEVEL * MAX_FIFO_F_BYTES] = {0}; unsigned char f_count, f_len = 0; @@ -5742,7 +5742,7 @@ static ssize_t bma2x2_fifo_data_out_frame_show(struct device *dev, static ssize_t bma2x2_offset_x_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_offset_x(bma2x2->bma2x2_client, &data) < 0) @@ -5774,7 +5774,7 @@ static ssize_t bma2x2_offset_x_store(struct device *dev, static ssize_t bma2x2_offset_y_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_offset_y(bma2x2->bma2x2_client, &data) < 0) @@ -5806,7 +5806,7 @@ static ssize_t bma2x2_offset_y_store(struct device *dev, static ssize_t bma2x2_offset_z_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_offset_z(bma2x2->bma2x2_client, &data) < 0) @@ -5838,7 +5838,7 @@ static ssize_t bma2x2_offset_z_store(struct device *dev, static ssize_t bma2x2_high_g_source_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_high_g_source(bma2x2->bma2x2_client, &data) < 0) return sprintf(buf, "Read error\n"); @@ -5869,7 +5869,7 @@ static ssize_t bma2x2_high_g_source_store(struct device *dev, static ssize_t bma2x2_slope_source_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_slope_source(bma2x2->bma2x2_client, &data) < 0) return sprintf(buf, "Read error\n"); @@ -5882,13 +5882,13 @@ static ssize_t bma2x2_slope_source_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long data; - int error; + unsigned char data = '0'; +// int error; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); - error = strict_strtoul(buf, 10, &data); - if (error) - return error; +// error = strict_strtoul(buf, 10, &data); +// if (error) +// return error; if (bma2x2_set_slope_source(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; @@ -5899,7 +5899,7 @@ static ssize_t bma2x2_slope_source_store(struct device *dev, static ssize_t bma2x2_high_g_hyst_show(struct device *dev, struct device_attribute *attr, char *buf) { - unsigned char data; + unsigned char data = '0'; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); if (bma2x2_get_high_g_hyst(bma2x2->bma2x2_client, &data) < 0) return sprintf(buf, "Read error\n"); @@ -5912,15 +5912,16 @@ static ssize_t bma2x2_high_g_hyst_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long data; + unsigned long data = 1; + unsigned char data1 = '0'; int error; struct bma2x2_data *bma2x2 = dev_get_drvdata(dev); error = strict_strtoul(buf, 10, &data); if (error) return error; - - if (bma2x2_set_high_g_hyst(bma2x2->bma2x2_client, (unsigned char)data) < 0) + data1 = (unsigned char)data; + if (bma2x2_set_high_g_hyst(bma2x2->bma2x2_client, data1) < 0) return -EINVAL; return count; @@ -6052,7 +6053,7 @@ static int bma2x2_read_Calibration_data(struct i2c_client *client) static int bma2x2_set_offset_target_fast_cal(struct i2c_client *client, unsigned char offset) { - unsigned char data; + unsigned char data = '0'; int comres = 0; @@ -6079,7 +6080,7 @@ static int bma2x2_set_offset_target_fast_cal(struct i2c_client *client, unsigned static int bma2x2_set_cal_trigger_fast_cal(struct i2c_client *client) { int comres = 0; - unsigned char data; + unsigned char data = '0'; signed char tmp; unsigned char timeout = 0; diff --git a/drivers/input/touchscreen/ist30xx_factory.c b/drivers/input/touchscreen/ist30xx_factory.c index 1c36fc989a7e..edd0e05aec65 100644 --- a/drivers/input/touchscreen/ist30xx_factory.c +++ b/drivers/input/touchscreen/ist30xx_factory.c @@ -361,7 +361,7 @@ ssize_t factory_back_key_state_show(struct device *dev, DMSG("[TSP] back tkey state: %d\n", key_state); - return snprintf(buf, sizeof(buf), "%d\n", key_state); + return snprintf(buf, sizeof(*buf), "%d\n", key_state); } /* /sys/class/factory/tkey/tkey_menu */ diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index 4b7a3bead7a9..a563f68917d6 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -342,12 +342,6 @@ static int get_hfi_extradata_index(enum hal_extradata_id index) case HAL_EXTRADATA_RECOVERY_POINT_SEI: ret = HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA; break; - case HAL_EXTRADATA_CLOSED_CAPTION_UD: - ret = HFI_PROPERTY_PARAM_VDEC_CLOSED_CAPTION_EXTRADATA; - break; - case HAL_EXTRADATA_AFD_UD: - ret = HFI_PROPERTY_PARAM_VDEC_AFD_EXTRADATA; - break; case HAL_EXTRADATA_MULTISLICE_INFO: ret = HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO; break; @@ -372,6 +366,9 @@ static int get_hfi_extradata_index(enum hal_extradata_id index) case HAL_EXTRADATA_METADATA_MBI: ret = HFI_PROPERTY_PARAM_VENC_MBI_DUMPING; break; + case HAL_EXTRADATA_STREAM_USERDATA: + ret = HFI_PROPERTY_PARAM_VDEC_STREAM_USERDATA_EXTRADATA; + break; default: dprintk(VIDC_WARN, "Extradata index not found: %d\n", index); break; @@ -1479,14 +1476,36 @@ int create_pkt_cmd_session_set_property( pr_err("MARK LTR\n"); break; } - case HAL_PARAM_VENC_HIER_P_NUM_FRAMES: + case HAL_PARAM_VENC_HIER_P_MAX_ENH_LAYERS: { pkt->rg_property_data[0] = - HFI_PROPERTY_PARAM_VENC_HIER_P_NUM_ENH_LAYER; + HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER; pkt->rg_property_data[1] = *(u32 *)pdata; pkt->size += sizeof(u32) * 2; break; } + case HAL_CONFIG_VENC_HIER_P_NUM_FRAMES: + { + pkt->rg_property_data[0] = + HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER; + pkt->rg_property_data[1] = *(u32 *)pdata; + pkt->size += sizeof(u32) * 2; + break; + } + case HAL_PARAM_VENC_ENABLE_INITIAL_QP: + { + struct hfi_initial_quantization *hfi; + struct hal_initial_quantization *quant = pdata; + pkt->rg_property_data[0] = + HFI_PROPERTY_PARAM_VENC_INITIAL_QP; + hfi = (struct hfi_initial_quantization *) &pkt->rg_property_data[1]; + hfi->init_qp_enable = quant->initqp_enable; + hfi->qp_i = quant->qpi; + hfi->qp_p = quant->qpp; + hfi->qp_b = quant->qpb; + pkt->size += sizeof(u32) + sizeof(struct hfi_initial_quantization); + break; + } /* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */ case HAL_CONFIG_BUFFER_REQUIREMENTS: case HAL_CONFIG_PRIORITY: diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index 3d632050f8fd..0eee5308cf13 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -49,7 +49,7 @@ static enum vidc_status hfi_map_err_status(int hfi_err) vidc_err = VIDC_ERR_NOT_SUPPORTED; break; case HFI_ERR_SYS_MAX_SESSIONS_REACHED: - vidc_err = VIDC_ERR_MAX_CLIENT; + vidc_err = VIDC_ERR_MAX_CLIENTS; break; case HFI_ERR_SYS_SESSION_IN_USE: vidc_err = VIDC_ERR_CLIENT_PRESENT; @@ -75,6 +75,8 @@ static enum vidc_status hfi_map_err_status(int hfi_err) vidc_err = VIDC_ERR_FAIL; break; } + if (vidc_err != HFI_ERR_NONE) + dprintk(VIDC_ERR, "HFI Error: %d\n", vidc_err); return vidc_err; } @@ -108,7 +110,8 @@ static void hfi_process_sess_evt_seq_changed( struct hfi_frame_size frame_sz; u8 *data_ptr; int prop_id; - dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY"); + dprintk(VIDC_DBG, "RECEIVED: EVENT_NOTIFY[%u]: %d, 0x%x\n", + pkt->session_id, pkt->event_data1, pkt->event_data2); if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) { dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size"); @@ -249,27 +252,33 @@ static void hfi_process_event_notify( hfi_process_sys_error(callback, device_id); break; case HFI_EVENT_SESSION_ERROR: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR"); + dprintk(VIDC_INFO, + "HFI_EVENT_SESSION_ERROR[%u]\n", pkt->session_id); if (!validate_session_pkt(sessions, sess, session_lock)) hfi_process_session_error(callback, device_id, pkt); break; case HFI_EVENT_SESSION_SEQUENCE_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED"); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%u]\n", + pkt->session_id); if (!validate_session_pkt(sessions, sess, session_lock)) hfi_process_sess_evt_seq_changed(callback, device_id, pkt); break; case HFI_EVENT_SESSION_PROPERTY_CHANGED: - dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED"); + dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%u]\n", + pkt->session_id); break; case HFI_EVENT_RELEASE_BUFFER_REFERENCE: - dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n"); + dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%u]\n", + pkt->session_id); if (!validate_session_pkt(sessions, sess, session_lock)) hfi_process_evt_release_buffer_ref(callback, device_id, pkt); break; default: - dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id"); + dprintk(VIDC_WARN, + "hal_process_event_notify: unknown_event_id[%u]\n", + pkt->session_id); break; } } @@ -759,7 +768,8 @@ static void hfi_process_session_prop_info( struct msm_vidc_cb_cmd_done cmd_done; struct buffer_requirements buff_req; - dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO"); + dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%u]\n", + pkt->session_id); if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) { dprintk(VIDC_ERR, "hal_process_session_prop_info:bad_pkt_size"); @@ -801,7 +811,8 @@ static void hfi_process_session_init_done( struct msm_vidc_cb_cmd_done cmd_done; struct vidc_hal_session_init_done session_init_done; struct hal_session *sess_close = NULL; - dprintk(VIDC_DBG, "RECEIVED:SESSION_INIT_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%u]\n", + pkt->session_id); if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) { dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size"); @@ -840,7 +851,8 @@ static void hfi_process_session_load_res_done( struct hfi_msg_session_load_resources_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_LOAD_RESOURCES_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%u]\n", + pkt->session_id); if (sizeof(struct hfi_msg_session_load_resources_done_packet) != pkt->size) { @@ -866,7 +878,8 @@ static void hfi_process_session_flush_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_FLUSH_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%u]\n", + pkt->session_id); if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) { dprintk(VIDC_ERR, "hal_process_session_flush_done: " @@ -890,7 +903,8 @@ static void hfi_process_session_etb_done( { struct msm_vidc_cb_data_done data_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_ETB_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size < sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { @@ -931,7 +945,8 @@ static void hfi_process_session_ftb_done( session = (struct hal_session *) ((struct hal_session *) pack->session_id)->session_id; - dprintk(VIDC_DBG, "RECEIVED:SESSION_FTB_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%u]\n", + pack->session_id); memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done)); @@ -1029,7 +1044,8 @@ static void hfi_process_session_start_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_START_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_start_done_packet)) { @@ -1054,7 +1070,8 @@ static void hfi_process_session_stop_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_STOP_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_stop_done_packet)) { @@ -1079,7 +1096,8 @@ static void hfi_process_session_rel_res_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_RESOURCES_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_release_resources_done_packet)) { @@ -1103,6 +1121,8 @@ static void hfi_process_session_rel_buf_done( struct hfi_msg_session_release_buffers_done_packet *pkt) { struct msm_vidc_cb_cmd_done cmd_done; + dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_session_release_buffers_done_packet)) { @@ -1130,7 +1150,8 @@ static void hfi_process_session_end_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_END_DONE"); + dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_end_done_packet)) { @@ -1155,8 +1176,8 @@ static void hfi_process_session_abort_done( { struct msm_vidc_cb_cmd_done cmd_done; - dprintk(VIDC_DBG, "RECEIVED:SESSION_ABORT_DONE"); - + dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%u]\n", + pkt->session_id); if (!pkt || pkt->size != sizeof(struct hfi_msg_sys_session_abort_done_packet)) { dprintk(VIDC_ERR, "%s: bad packet/packet size: %d", @@ -1185,6 +1206,8 @@ static void hfi_process_session_get_seq_hdr_done( dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size); return; } + dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%u]\n", + pkt->session_id); memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done)); data_done.device_id = device_id; data_done.size = sizeof(struct msm_vidc_cb_data_done); diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 3e5e6d783d24..4b84d908f201 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -22,7 +22,8 @@ #define MSM_VDEC_DVC_NAME "msm_vdec_8974" #define MIN_NUM_OUTPUT_BUFFERS 4 #define MAX_NUM_OUTPUT_BUFFERS VIDEO_MAX_FRAME -#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8080 +#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8010 +#define MB_SIZE_IN_PIXEL (16 * 16) #define TZ_DYNAMIC_BUFFER_FEATURE_ID 12 #define TZ_FEATURE_VERSION(major, minor, patch) \ @@ -220,7 +221,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .name = "Extradata Type", .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE, - .maximum = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO, + .maximum = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA, .default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE, .menu_skip_mask = ~( (1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) | @@ -233,8 +234,6 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE) | (1 << V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW) | (1 << V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_AFD_UD) | (1 << V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO) | (1 << V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB) | (1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER) | @@ -243,7 +242,8 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { (1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO) | (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP) | (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) + (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO) | + (1 << V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA) ), .qmenu = mpeg_video_vidc_extradata, .step = 0, @@ -331,6 +331,17 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .step = 1, .cluster = 0, }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT, + .name = "Buffer size limit", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 0, + .maximum = 0x7fffffff, + .default_value = 0, + .step = 1, + .menu_skip_mask = 0, + .qmenu = NULL, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls) @@ -342,9 +353,39 @@ static u32 get_frame_size_nv12(int plane, } static u32 get_frame_size_compressed(int plane, - u32 height, u32 width) + u32 max_mbs_per_frame, u32 size_per_mb) { - return (width * height * 3/2)/4; + return (max_mbs_per_frame * size_per_mb * 3/2)/2; +} + +static u32 get_frame_size(struct msm_vidc_inst *inst, + const struct msm_vidc_format *fmt, + int fmt_type, int plane) +{ + u32 frame_size = 0; + if (fmt_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + frame_size = fmt->get_frame_size(plane, + inst->capability.mbs_per_frame.max, + MB_SIZE_IN_PIXEL); + if (inst->capability.buffer_size_limit && + (inst->capability.buffer_size_limit < frame_size)) { + frame_size = inst->capability.buffer_size_limit; + dprintk(VIDC_DBG, "input buffer size limited to %d\n", + frame_size); + } else { + dprintk(VIDC_DBG, "set input buffer size to %d\n", + frame_size); + } + } else if (fmt_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + frame_size = fmt->get_frame_size(plane, + inst->capability.height.max, + inst->capability.width.max); + dprintk(VIDC_DBG, "set output buffer size to %d\n", + frame_size); + } else { + dprintk(VIDC_WARN, "Wrong format type\n"); + } + return frame_size; } struct msm_vidc_format vdec_formats[] = { @@ -756,11 +797,11 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) for (i = 0; i < fmt->num_planes; ++i) { if (plane_sizes[i] == 0) { f->fmt.pix_mp.plane_fmt[i].sizeimage = - fmt->get_frame_size(i, - inst->capability.height.max, - inst->capability.width.max); + get_frame_size(inst, fmt, + f->type, i); plane_sizes[i] = - f->fmt.pix_mp.plane_fmt[i].sizeimage; + f->fmt.pix_mp.plane_fmt[i]. + sizeimage; } else f->fmt.pix_mp.plane_fmt[i].sizeimage = plane_sizes[i]; @@ -924,9 +965,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (ret) { for (i = 0; i < fmt->num_planes; ++i) { f->fmt.pix_mp.plane_fmt[i].sizeimage = - fmt->get_frame_size(i, - inst->capability.height.max, - inst->capability.width.max); + get_frame_size(inst, fmt, f->type, i); } } else { buff_req_buffer = @@ -1008,11 +1047,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) frame_sz.buffer_type, frame_sz.width, frame_sz.height); msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz); - - max_input_size = fmt->get_frame_size(0, - inst->capability.height.max, - inst->capability.width.max); - + max_input_size = get_frame_size(inst, fmt, f->type, 0); if (f->fmt.pix_mp.plane_fmt[0].sizeimage > max_input_size || f->fmt.pix_mp.plane_fmt[0].sizeimage == 0) { f->fmt.pix_mp.plane_fmt[0].sizeimage = max_input_size; @@ -1111,9 +1146,8 @@ static int msm_vdec_queue_setup(struct vb2_queue *q, *num_buffers > MAX_NUM_OUTPUT_BUFFERS) *num_buffers = MIN_NUM_OUTPUT_BUFFERS; for (i = 0; i < *num_planes; i++) { - sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size( - i, inst->capability.height.max, - inst->capability.width.max); + sizes[i] = get_frame_size(inst, + inst->fmts[OUTPUT_PORT], q->type, i); } property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL; new_buf_count.buffer_type = HAL_BUFFER_INPUT; @@ -1700,6 +1734,13 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) property_val = ctrl->val; pdata = &property_val; break; + case V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT: + { + inst->capability.buffer_size_limit = ctrl->val; + dprintk(VIDC_DBG, + "Limiting input buffer size to :%u\n", ctrl->val); + break; + } default: break; } diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index d67929569043..d7f33d7bc4b3 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -689,8 +689,6 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE) | (1 << V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW) | (1 << V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD) | - (1 << V4L2_MPEG_VIDC_EXTRADATA_AFD_UD) | (1 << V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO) | (1 << V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB) | (1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER) | @@ -811,6 +809,45 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .step = 1, .qmenu = NULL, .cluster = 0, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP, + .name = "Enable setting initial QP", + .type = V4L2_CTRL_TYPE_BUTTON, + .minimum = 0, + .maximum = 0, + .default_value = 0, + .step = 0, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP, + .name = "Iframe initial QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 1, + .maximum = 51, + .default_value = 1, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP, + .name = "Pframe initial QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 1, + .maximum = 51, + .default_value = 1, + .step = 1, + .qmenu = NULL, + }, + { + .id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP, + .name = "Bframe initial QP", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = 1, + .maximum = 51, + .default_value = 1, + .step = 1, + .qmenu = NULL, } }; @@ -992,11 +1029,53 @@ static int msm_venc_queue_setup(struct vb2_queue *q, return rc; } +static int msm_venc_enable_hier_p(struct msm_vidc_inst *inst) +{ + int num_enh_layers = 0; + u32 property_id = 0; + struct hfi_device *hdev = NULL; + int rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_VP8) + return 0; + + num_enh_layers = inst->capability.hier_p.max - 1; + if (!num_enh_layers) + return 0; + + hdev = inst->core->device; + property_id = HAL_PARAM_VENC_HIER_P_MAX_ENH_LAYERS; + + rc = call_hfi_op(hdev, session_set_property, + (void *)inst->session, property_id, + (void *)&num_enh_layers); + if (rc) { + dprintk(VIDC_ERR, + "%s: failed with error = %d\n", __func__, rc); + } + return rc; +} + static inline int start_streaming(struct msm_vidc_inst *inst) { int rc = 0; struct vb2_buf_entry *temp; struct list_head *ptr, *next; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + rc = msm_venc_enable_hier_p(inst); + if (rc) + return rc; + if (inst->capability.pixelprocess_capabilities & HAL_VIDEO_ENCODER_SCALING_CAPABILITY) rc = msm_comm_check_scaling_supported(inst); @@ -2093,7 +2172,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &markltr; break; case V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS: - property_id = HAL_PARAM_VENC_HIER_P_NUM_FRAMES; + property_id = HAL_CONFIG_VENC_HIER_P_NUM_FRAMES; hier_p_layers = ctrl->val; if (hier_p_layers > (inst->capability.hier_p.max - 1)) { dprintk(VIDC_ERR, @@ -2143,6 +2222,7 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst, u32 property_id = 0; void *pdata = NULL; struct msm_vidc_core_capability *cap = NULL; + struct hal_initial_quantization quant; if (!inst || !inst->core || !inst->core->device || !ctrl) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); @@ -2187,6 +2267,26 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst, property_id = HAL_PARAM_VENC_LTRMODE; pdata = <rmode; break; + case V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP: + property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; + quant.initqp_enable = control[i].value; + pdata = &quant; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP: + quant.qpi = control[i].value; + property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; + pdata = &quant; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP: + quant.qpp = control[i].value; + property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; + pdata = &quant; + break; + case V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP: + quant.qpb = control[i].value; + property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; + pdata = &quant; + break; default: dprintk(VIDC_ERR, "Invalid id set: %d\n", control[i].id); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index b40997fda1c9..a5b612e5aacb 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -390,8 +390,9 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, &inst->completions[SESSION_MSG_INDEX(cmd)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", - SESSION_MSG_INDEX(cmd)); + dprintk(VIDC_ERR, + "%s: Wait interrupted or timeout[%u]: %d\n", + __func__, (u32)inst->session, SESSION_MSG_INDEX(cmd)); msm_comm_recover_from_session_error(inst); rc = -EIO; } else { @@ -439,6 +440,21 @@ static void msm_comm_generate_session_error(struct msm_vidc_inst *inst) mutex_unlock(&inst->lock); } +static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst) +{ + if (!inst) { + dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__); + return; + } + mutex_lock(&inst->sync_lock); + inst->session = NULL; + inst->state = MSM_VIDC_CORE_INVALID; + msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_MAX_CLIENTS); + dprintk(VIDC_WARN, + "%s: Too many clients\n", __func__); + mutex_unlock(&inst->sync_lock); +} + static void handle_session_init_done(enum command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; @@ -469,6 +485,8 @@ static void handle_session_init_done(enum command_response cmd, void *data) inst->capability.hier_p = session_init_done->hier_p; inst->capability.pixelprocess_capabilities = call_hfi_op(hdev, get_core_capabilities); + inst->capability.mbs_per_frame = + session_init_done->mbs_per_frame; inst->capability.capability_set = true; inst->capability.buffer_mode[CAPTURE_PORT] = session_init_done->alloc_mode_out; @@ -476,7 +494,10 @@ static void handle_session_init_done(enum command_response cmd, void *data) dprintk(VIDC_ERR, "Session init response from FW : 0x%x", response->status); - msm_comm_generate_session_error(inst); + if (response->status == VIDC_ERR_MAX_CLIENTS) + msm_comm_generate_max_clients_error(inst); + else + msm_comm_generate_session_error(inst); } signal_session_msg_receipt(cmd, inst); } else { @@ -1534,8 +1555,8 @@ static int msm_comm_unset_ocmem(struct msm_vidc_core *core) &core->completions[SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", - SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)); + dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n", + __func__, SYS_MSG_INDEX(RELEASE_RESOURCE_DONE)); rc = -EIO; } release_ocmem_failed: @@ -1557,8 +1578,8 @@ static int msm_comm_init_core_done(struct msm_vidc_inst *inst) &core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", - SYS_MSG_INDEX(SYS_INIT_DONE)); + dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n", + __func__, SYS_MSG_INDEX(SYS_INIT_DONE)); rc = -EIO; goto exit; } else { @@ -2670,7 +2691,8 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "Wait interrupted or timeout: %d\n", + "%s: Wait interrupted or timeout[%u]: %d\n", + __func__, (u32)inst->session, SESSION_MSG_INDEX(SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; msm_comm_recover_from_session_error(inst); @@ -3217,12 +3239,6 @@ enum hal_extradata_id msm_comm_get_hal_extradata_index( case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI: ret = HAL_EXTRADATA_RECOVERY_POINT_SEI; break; - case V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD: - ret = HAL_EXTRADATA_CLOSED_CAPTION_UD; - break; - case V4L2_MPEG_VIDC_EXTRADATA_AFD_UD: - ret = HAL_EXTRADATA_AFD_UD; - break; case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO: ret = HAL_EXTRADATA_MULTISLICE_INFO; break; @@ -3250,6 +3266,9 @@ enum hal_extradata_id msm_comm_get_hal_extradata_index( case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI: ret = HAL_EXTRADATA_METADATA_MBI; break; + case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA: + ret = HAL_EXTRADATA_STREAM_USERDATA; + break; default: dprintk(VIDC_WARN, "Extradata not found: %d\n", index); break; @@ -3447,7 +3466,11 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) mutex_lock(&inst->sync_lock); inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->sync_lock); - msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); + msm_vidc_queue_v4l2_event(inst, + V4L2_EVENT_MSM_VIDC_HW_OVERLOAD); + dprintk(VIDC_WARN, + "%s: Hardware is overloaded\n", __func__); + wake_up(&inst->kernel_event_queue); } return rc; } @@ -3497,8 +3520,9 @@ int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst) &inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)], msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { - dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n", - __func__, SESSION_MSG_INDEX(SESSION_ABORT_DONE)); + dprintk(VIDC_ERR, "%s: Wait interrupted or timeout[%u]: %d\n", + __func__, (u32)inst->session, + SESSION_MSG_INDEX(SESSION_ABORT_DONE)); msm_comm_generate_sys_error(inst); } else change_inst_state(inst, MSM_VIDC_CLOSE_DONE); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h index 06181dd9844e..a1cec43058fa 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h @@ -192,8 +192,10 @@ struct msm_vidc_core_capability { struct hal_capability_supported scale_y; struct hal_capability_supported ltr_count; struct hal_capability_supported hier_p; + struct hal_capability_supported mbs_per_frame; u32 capability_set; enum buffer_mode_type buffer_mode[MAX_PORT_NUM]; + u32 buffer_size_limit; }; struct msm_vidc_core { diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index 75f583ff0dc7..55663381d156 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -79,9 +79,8 @@ #define HFI_EXTRADATA_FRAME_RATE 0x00000007 #define HFI_EXTRADATA_PANSCAN_WINDOW 0x00000008 #define HFI_EXTRADATA_RECOVERY_POINT_SEI 0x00000009 -#define HFI_EXTRADATA_CLOSED_CAPTION_UD 0x0000000A -#define HFI_EXTRADATA_AFD_UD 0x0000000B #define HFI_EXTRADATA_MPEG2_SEQDISP 0x0000000D +#define HFI_EXTRADATA_STREAM_USERDATA 0x0000000E #define HFI_EXTRADATA_FRAME_QP 0x0000000F #define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010 #define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000 @@ -190,10 +189,6 @@ struct hfi_extradata_header { #define HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00E) -#define HFI_PROPERTY_PARAM_VDEC_CLOSED_CAPTION_EXTRADATA \ - (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00F) -#define HFI_PROPERTY_PARAM_VDEC_AFD_EXTRADATA \ - (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x010) #define HFI_PROPERTY_PARAM_VDEC_VC1_FRAMEDISP_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x011) #define HFI_PROPERTY_PARAM_VDEC_VC1_SEQDISP_EXTRADATA \ @@ -206,6 +201,8 @@ struct hfi_extradata_header { (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015) #define HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x016) +#define HFI_PROPERTY_PARAM_VDEC_STREAM_USERDATA_EXTRADATA \ + (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x017) #define HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA \ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x018) #define HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA \ diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index 563714d051f4..8884c454a03d 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -63,7 +63,7 @@ enum vidc_status { VIDC_ERR_BAD_HANDLE, VIDC_ERR_NOT_SUPPORTED, VIDC_ERR_BAD_STATE, - VIDC_ERR_MAX_CLIENT, + VIDC_ERR_MAX_CLIENTS, VIDC_ERR_IFRAME_EXPECTED, VIDC_ERR_HW_FATAL, VIDC_ERR_BITSTREAM_ERR, @@ -91,8 +91,6 @@ enum hal_extradata_id { HAL_EXTRADATA_FRAME_RATE, HAL_EXTRADATA_PANSCAN_WINDOW, HAL_EXTRADATA_RECOVERY_POINT_SEI, - HAL_EXTRADATA_CLOSED_CAPTION_UD, - HAL_EXTRADATA_AFD_UD, HAL_EXTRADATA_MULTISLICE_INFO, HAL_EXTRADATA_INDEX, HAL_EXTRADATA_NUM_CONCEALED_MB, @@ -103,6 +101,7 @@ enum hal_extradata_id { HAL_EXTRADATA_FRAME_BITS_INFO, HAL_EXTRADATA_LTR_INFO, HAL_EXTRADATA_METADATA_MBI, + HAL_EXTRADATA_STREAM_USERDATA, }; enum hal_property { @@ -186,7 +185,9 @@ enum hal_property { HAL_CONFIG_VENC_MARKLTRFRAME, HAL_CONFIG_VENC_USELTRFRAME, HAL_CONFIG_VENC_LTRPERIOD, - HAL_PARAM_VENC_HIER_P_NUM_FRAMES, + HAL_CONFIG_VENC_HIER_P_NUM_FRAMES, + HAL_PARAM_VENC_HIER_P_MAX_ENH_LAYERS, + HAL_PARAM_VENC_ENABLE_INITIAL_QP, }; enum hal_domain { @@ -632,6 +633,13 @@ struct hal_quantization { u32 layer_id; }; +struct hal_initial_quantization { + u32 qpi; + u32 qpp; + u32 qpb; + u32 initqp_enable; +}; + struct hal_quantization_range { u32 min_qp; u32 max_qp; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index f5c8888feb76..b3c20b657ccc 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -306,8 +306,6 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x018) #define HFI_PROPERTY_PARAM_VENC_MULTIREF_P \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x019) -#define HFI_PROPERTY_PARAM_VENC_HIER_P_NUM_ENH_LAYER \ - (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01A) #define HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B) #define HFI_PROPERTY_PARAM_VENC_LTRMODE \ @@ -320,6 +318,10 @@ struct hfi_buffer_info { (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01F) #define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES \ (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x020) +#define HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x026) +#define HFI_PROPERTY_PARAM_VENC_INITIAL_QP \ + (HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x028) #define HFI_PROPERTY_CONFIG_VENC_COMMON_START \ (HFI_DOMAIN_BASE_VENC + HFI_ARCH_COMMON_OFFSET + 0x6000) #define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE \ @@ -343,6 +345,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x009) #define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME \ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00A) +#define HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00B) #define HFI_PROPERTY_CONFIG_VENC_LTRPERIOD \ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00C) #define HFI_PROPERTY_CONFIG_VPE_COMMON_START \ @@ -532,6 +536,13 @@ struct hfi_quantization { u32 layer_id; }; +struct hfi_initial_quantization { + u32 qp_i; + u32 qp_p; + u32 qp_b; + u32 init_qp_enable; +}; + struct hfi_quantization_range { u32 min_qp; u32 max_qp; diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index 983314c41349..a5eacd618a9c 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -16,6 +16,19 @@ config ZRAM See zram.txt for more information. Project home: +config ZRAM_LZ4_COMPRESS + bool "Enable LZ4 algorithm support" + depends on ZRAM + select LZ4_COMPRESS + select LZ4_DECOMPRESS + default n + help + This option enables LZ4 compression algorithm support, instead + of the default LZO. LZ4 may be faster on some architectures + compared to LZO compression. + + See https://code.google.com/p/lz4/ for more information about LZ4. + config ZRAM_DEBUG bool "Compressed RAM block device debug support" depends on ZRAM diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 83fa65773a5c..a98fb3318ee9 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -30,12 +30,42 @@ #include #include #include +#include #include #include #include #include "zram_drv.h" +static inline int z_decompress_safe(const unsigned char *src, size_t src_len, + unsigned char *dest, size_t *dest_len) +{ +#ifdef CONFIG_ZRAM_LZ4_COMPRESS + return lz4_decompress_unknownoutputsize(src, src_len, dest, dest_len); +#else + return lzo1x_decompress_safe(src, src_len, dest, dest_len); +#endif +} + +static inline int z_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem) +{ +#ifdef CONFIG_ZRAM_LZ4_COMPRESS + return lz4_compress(src, src_len, dst, dst_len, wrkmem); +#else + return lzo1x_1_compress(src, src_len, dst, dst_len, wrkmem); +#endif +} + +static inline size_t z_scratch_size(void) +{ +#ifdef CONFIG_ZRAM_LZ4_COMPRESS + return LZ4_MEM_COMPRESS; +#else + return LZO1X_MEM_COMPRESS; +#endif +} + /* Globals */ static int zram_major; static struct zram *zram_devices; @@ -210,7 +240,7 @@ static struct zram_meta *zram_meta_alloc(u64 disksize) if (!meta) goto out; - meta->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + meta->compress_workmem = kzalloc(z_scratch_size(), GFP_KERNEL); if (!meta->compress_workmem) goto free_meta; @@ -337,7 +367,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) if (meta->table[index].size == PAGE_SIZE) copy_page(mem, cmem); else - ret = lzo1x_decompress_safe(cmem, meta->table[index].size, + ret = z_decompress_safe(cmem, meta->table[index].size, mem, &clen); zs_unmap_object(meta->mem_pool, handle); @@ -457,7 +487,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, zram_test_flag(meta, index, ZRAM_ZERO))) zram_free_page(zram, index); - ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, + ret = z_compress(uncmem, PAGE_SIZE, src, &clen, meta->compress_workmem); if (!is_partial_io(bvec)) { diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index 82956e88551e..e432a178660a 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -49,7 +49,7 @@ static inline u32 mdss_mdp_pipe_read(struct mdss_mdp_pipe *pipe, u32 reg) } static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map, - size_t n) + size_t n, bool force_alloc) { u32 i, mmb; u32 fixed_cnt = bitmap_weight(smp_map->fixed, SMP_MB_CNT); @@ -67,7 +67,7 @@ static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map, * that calls for change in smp configuration (addition/removal * of smp blocks), so that fallback solution happens. */ - if (i != 0 && n != i) { + if (i != 0 && n != i && !force_alloc) { pr_debug("Can't change mmb config, num_blks: %d alloc: %d\n", n, i); return 0; @@ -190,6 +190,7 @@ int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe) struct mdss_mdp_plane_sizes ps; int i; int rc = 0, rot_mode = 0, wb_mixer = 0; + bool force_alloc = 0; u32 nlines, format, seg_w; u16 width; @@ -273,6 +274,8 @@ int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe) if (pipe->mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK) wb_mixer = 1; + force_alloc = pipe->flags & MDP_SMP_FORCE_ALLOC; + mutex_lock(&mdss_mdp_smp_lock); for (i = (MAX_PLANES - 1); i >= ps.num_planes; i--) { @@ -303,7 +306,7 @@ int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe) pr_debug("reserving %d mmb for pnum=%d plane=%d\n", num_blks, pipe->num, i); reserved = mdss_mdp_smp_mmb_reserve(&pipe->smp_map[i], - num_blks); + num_blks, force_alloc); if (reserved < num_blks) break; } diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 4640d3bd7d04..59fc7bfb851e 100755 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -17,6 +17,7 @@ header-y += netfilter_arp/ header-y += netfilter_bridge/ header-y += netfilter_ipv4/ header-y += netfilter_ipv6/ +header-y += nfc/ header-y += usb/ header-y += wimax/ header-y += mfd/ @@ -443,6 +444,7 @@ header-y += msm_audio_sbc.h header-y += msm_ipc.h header-y += msm_charm.h header-y += msm_rmnet.h +header-y += rmnet_data.h header-y += qseecom.h header-y += qcedev.h header-y += idle_stats_device.h diff --git a/include/linux/decompress/unlz4.h b/include/linux/decompress/unlz4.h new file mode 100644 index 000000000000..d5b68bf3ec92 --- /dev/null +++ b/include/linux/decompress/unlz4.h @@ -0,0 +1,10 @@ +#ifndef DECOMPRESS_UNLZ4_H +#define DECOMPRESS_UNLZ4_H + +int unlz4(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error)(char *x)); +#endif diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h index 51da65b68b85..9dcdb6251cb8 100644 --- a/include/linux/fib_rules.h +++ b/include/linux/fib_rules.h @@ -49,6 +49,8 @@ enum { FRA_TABLE, /* Extended table id */ FRA_FWMASK, /* mask for netfilter mark */ FRA_OIFNAME, + FRA_UID_START, /* UID range */ + FRA_UID_END, __FRA_MAX }; diff --git a/include/linux/lz4.h b/include/linux/lz4.h new file mode 100644 index 000000000000..4356686b0a39 --- /dev/null +++ b/include/linux/lz4.h @@ -0,0 +1,87 @@ +#ifndef __LZ4_H__ +#define __LZ4_H__ +/* + * LZ4 Kernel Interface + * + * Copyright (C) 2013, LG Electronics, Kyungsik Lee + * + * 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 LZ4_MEM_COMPRESS (4096 * sizeof(unsigned char *)) +#define LZ4HC_MEM_COMPRESS (65538 * sizeof(unsigned char *)) + +/* + * lz4_compressbound() + * Provides the maximum size that LZ4 may output in a "worst case" scenario + * (input data not compressible) + */ +static inline size_t lz4_compressbound(size_t isize) +{ + return isize + (isize / 255) + 16; +} + +/* + * lz4_compress() + * src : source address of the original data + * src_len : size of the original data + * dst : output buffer address of the compressed data + * This requires 'dst' of size LZ4_COMPRESSBOUND. + * dst_len : is the output size, which is returned after compress done + * workmem : address of the working memory. + * This requires 'workmem' of size LZ4_MEM_COMPRESS. + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer and workmem must be already allocated with + * the defined size. + */ +int lz4_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + + /* + * lz4hc_compress() + * src : source address of the original data + * src_len : size of the original data + * dst : output buffer address of the compressed data + * This requires 'dst' of size LZ4_COMPRESSBOUND. + * dst_len : is the output size, which is returned after compress done + * workmem : address of the working memory. + * This requires 'workmem' of size LZ4HC_MEM_COMPRESS. + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer and workmem must be already allocated with + * the defined size. + */ +int lz4hc_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + +/* + * lz4_decompress() + * src : source address of the compressed data + * src_len : is the input size, whcih is returned after decompress done + * dest : output buffer address of the decompressed data + * actual_dest_len: is the size of uncompressed data, supposing it's known + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer must be already allocated. + * slightly faster than lz4_decompress_unknownoutputsize() + */ +int lz4_decompress(const unsigned char *src, size_t *src_len, + unsigned char *dest, size_t actual_dest_len); + +/* + * lz4_decompress_unknownoutputsize() + * src : source address of the compressed data + * src_len : is the input size, therefore the compressed size + * dest : output buffer address of the decompressed data + * dest_len: is the max size of the destination buffer, which is + * returned with actual size of decompressed data after + * decompress done + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer must be already allocated. + */ +int lz4_decompress_unknownoutputsize(const unsigned char *src, size_t src_len, + unsigned char *dest, size_t *dest_len); +#endif diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h index a7430d9806fb..02523d03802e 100644 --- a/include/linux/msm_mdp.h +++ b/include/linux/msm_mdp.h @@ -197,6 +197,7 @@ enum { #define MDP_MEMORY_ID_TYPE_FB 0x00001000 #define MDP_BWC_EN 0x00000400 #define MDP_DECIMATION_EN 0x00000800 +#define MDP_SMP_FORCE_ALLOC 0x00200000 #define MDP_TRANSP_NOP 0xffffffff #define MDP_ALPHA_NOP 0xff diff --git a/include/linux/msm_rmnet.h b/include/linux/msm_rmnet.h index d41b55c98afd..08cd3b67ece2 100644 --- a/include/linux/msm_rmnet.h +++ b/include/linux/msm_rmnet.h @@ -29,9 +29,114 @@ enum rmnet_ioctl_cmds_e { RMNET_IOCTL_CLOSE = 0x000089F9, /* Close transport port */ RMNET_IOCTL_FLOW_ENABLE = 0x000089FA, /* Flow enable */ RMNET_IOCTL_FLOW_DISABLE = 0x000089FB, /* Flow disable */ + RMNET_IOCTL_FLOW_SET_HNDL = 0x000089FC, /* Set flow handle */ + RMNET_IOCTL_EXTENDED = 0x000089FD, /* Extended IOCTLs */ RMNET_IOCTL_MAX }; +enum rmnet_ioctl_extended_cmds_e { +/* RmNet Data Required IOCTLs */ + RMNET_IOCTL_GET_SUPPORTED_FEATURES = 0x0000, /* Get features */ + RMNET_IOCTL_SET_MRU = 0x0001, /* Set MRU */ + RMNET_IOCTL_GET_MRU = 0x0002, /* Get MRU */ + RMNET_IOCTL_GET_EPID = 0x0003, /* Get endpoint ID */ + RMNET_IOCTL_GET_DRIVER_NAME = 0x0004, /* Get driver name */ + RMNET_IOCTL_ADD_MUX_CHANNEL = 0x0005, /* Add MUX ID */ + RMNET_IOCTL_SET_EGRESS_DATA_FORMAT = 0x0006, /* Set EDF */ + RMNET_IOCTL_SET_INGRESS_DATA_FORMAT = 0x0007, /* Set IDF */ + RMNET_IOCTL_SET_AGGREGATION_COUNT = 0x0008, /* Set agg count */ + RMNET_IOCTL_GET_AGGREGATION_COUNT = 0x0009, /* Get agg count */ + RMNET_IOCTL_SET_AGGREGATION_SIZE = 0x000A, /* Set agg size */ + RMNET_IOCTL_GET_AGGREGATION_SIZE = 0x000B, /* Get agg size */ + RMNET_IOCTL_FLOW_CONTROL = 0x000C, /* Do flow control */ + RMNET_IOCTL_GET_DFLT_CONTROL_CHANNEL = 0x000D, /* For legacy use */ + RMNET_IOCTL_GET_HWSW_MAP = 0x000E, /* Get HW/SW map */ + RMNET_IOCTL_SET_RX_HEADROOM = 0x000F, /* RX Headroom */ + RMNET_IOCTL_GET_EP_PAIR = 0x0010, /* Endpoint pair */ + RMNET_IOCTL_SET_QOS_VERSION = 0x0011, /* 8/6 byte QoS hdr*/ + RMNET_IOCTL_GET_QOS_VERSION = 0x0012, /* 8/6 byte QoS hdr*/ + RMNET_IOCTL_GET_SUPPORTED_QOS_MODES = 0x0013, /* Get QoS modes */ + RMNET_IOCTL_SET_SLEEP_STATE = 0x0014, /* Set sleep state */ + RMNET_IOCTL_SET_XLAT_DEV_INFO = 0x0015, /* xlat dev name */ + RMNET_IOCTL_EXTENDED_MAX = 0x0016 +}; + +/* Return values for the RMNET_IOCTL_GET_SUPPORTED_FEATURES IOCTL */ +#define RMNET_IOCTL_FEAT_NOTIFY_MUX_CHANNEL (1<<0) +#define RMNET_IOCTL_FEAT_SET_EGRESS_DATA_FORMAT (1<<1) +#define RMNET_IOCTL_FEAT_SET_INGRESS_DATA_FORMAT (1<<2) +#define RMNET_IOCTL_FEAT_SET_AGGREGATION_COUNT (1<<3) +#define RMNET_IOCTL_FEAT_GET_AGGREGATION_COUNT (1<<4) +#define RMNET_IOCTL_FEAT_SET_AGGREGATION_SIZE (1<<5) +#define RMNET_IOCTL_FEAT_GET_AGGREGATION_SIZE (1<<6) +#define RMNET_IOCTL_FEAT_FLOW_CONTROL (1<<7) +#define RMNET_IOCTL_FEAT_GET_DFLT_CONTROL_CHANNEL (1<<8) +#define RMNET_IOCTL_FEAT_GET_HWSW_MAP (1<<9) + +/* Input values for the RMNET_IOCTL_SET_EGRESS_DATA_FORMAT IOCTL */ +#define RMNET_IOCTL_EGRESS_FORMAT_MAP (1<<1) +#define RMNET_IOCTL_EGRESS_FORMAT_AGGREGATION (1<<2) +#define RMNET_IOCTL_EGRESS_FORMAT_MUXING (1<<3) +#define RMNET_IOCTL_EGRESS_FORMAT_CHECKSUM (1<<4) + +/* Input values for the RMNET_IOCTL_SET_INGRESS_DATA_FORMAT IOCTL */ +#define RMNET_IOCTL_INGRESS_FORMAT_MAP (1<<1) +#define RMNET_IOCTL_INGRESS_FORMAT_DEAGGREGATION (1<<2) +#define RMNET_IOCTL_INGRESS_FORMAT_DEMUXING (1<<3) +#define RMNET_IOCTL_INGRESS_FORMAT_CHECKSUM (1<<4) +#define RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA (1<<5) + +/* User space may not have this defined. */ +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +struct rmnet_ioctl_extended_s { + uint32_t extended_ioctl; + union { + uint32_t data; /* Generic data field for most extended IOCTLs */ + + /* Return values for + * RMNET_IOCTL_GET_DRIVER_NAME + * RMNET_IOCTL_GET_DFLT_CONTROL_CHANNEL */ + int8_t if_name[IFNAMSIZ]; + + /* Input values for the RMNET_IOCTL_ADD_MUX_CHANNEL IOCTL */ + struct { + uint32_t mux_id; + int8_t vchannel_name[IFNAMSIZ]; + } rmnet_mux_val; + + /* Input values for the RMNET_IOCTL_FLOW_CONTROL IOCTL */ + struct { + uint8_t flow_mode; + uint8_t mux_id; + } flow_control_prop; + + /* Return values for RMNET_IOCTL_GET_EP_PAIR */ + struct { + uint32_t consumer_pipe_num; + uint32_t producer_pipe_num; + } ipa_ep_pair; + + struct { + uint32_t __data; /* Placeholder for legacy data*/ + uint32_t agg_size; + uint32_t agg_count; + } ingress_format; + } u; +}; + +struct rmnet_ioctl_data_s { + union { + uint32_t operation_mode; + uint32_t tcm_handle; + } u; +}; + +#define RMNET_IOCTL_QOS_MODE_6 (1<<0) +#define RMNET_IOCTL_QOS_MODE_8 (1<<1) + /* QMI QoS header definition */ #define QMI_QOS_HDR_S __attribute((__packed__)) qmi_qos_hdr_s struct QMI_QOS_HDR_S { @@ -40,4 +145,10 @@ struct QMI_QOS_HDR_S { unsigned long flow_id; }; +/* QMI QoS 8-byte header. */ +struct qmi_qos_hdr8_s { + struct QMI_QOS_HDR_S hdr; + uint8_t reserved[2]; +} __attribute((__packed__)); + #endif /* _MSM_RMNET_H_ */ diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h index 9301006eb40a..1c3337cb2f8e 100644 --- a/include/linux/msm_vidc_dec.h +++ b/include/linux/msm_vidc_dec.h @@ -58,6 +58,8 @@ #define VDEC_MSG_EVT_HW_ERROR (VDEC_MSG_BASE + 14) #define VDEC_MSG_EVT_INFO_CONFIG_CHANGED (VDEC_MSG_BASE + 15) #define VDEC_MSG_EVT_INFO_FIELD_DROPPED (VDEC_MSG_BASE + 16) +#define VDEC_MSG_EVT_HW_OVERLOAD (VDEC_MSG_BASE + 17) +#define VDEC_MSG_EVT_MAX_CLIENTS (VDEC_MSG_BASE + 18) /*Buffer flags bits masks.*/ #define VDEC_BUFFERFLAG_EOS 0x00000001 diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h index 4ce3db188399..36625a70cb1c 100644 --- a/include/linux/msm_vidc_enc.h +++ b/include/linux/msm_vidc_enc.h @@ -45,7 +45,8 @@ #define VEN_MSG_RESUME 9 #define VEN_MSG_STOP_READING_MSG 10 #define VEN_MSG_LTRUSE_FAILED 11 - +#define VEN_MSG_HW_OVERLOAD 12 +#define VEN_MSG_MAX_CLIENTS 13 /*Buffer flags bits masks*/ #define VEN_BUFFLAG_EOS 0x00000001 diff --git a/include/linux/nfc/Kbuild b/include/linux/nfc/Kbuild new file mode 100644 index 000000000000..9781cfb191fc --- /dev/null +++ b/include/linux/nfc/Kbuild @@ -0,0 +1,2 @@ +header-y += pn544.h + diff --git a/include/linux/nfc/pn544.h b/include/linux/nfc/pn544.h index 7ab8521f2347..785b3fafa43c 100644 --- a/include/linux/nfc/pn544.h +++ b/include/linux/nfc/pn544.h @@ -25,6 +25,18 @@ #include +#define PN544_MAGIC 0xE9 + +/* + * PN544 power control via ioctl + * PN544_SET_PWR(0): power off + * PN544_SET_PWR(1): power on + * PN544_SET_PWR(2): reset and power on with firmware download enabled + */ +#define PN544_SET_PWR _IOW(PN544_MAGIC, 0x01, unsigned int) + +#define PN544_HW_REVISION _IOR(PN544_MAGIC, 0x02, unsigned int) + #define PN544_DRIVER_NAME "pn544" #define PN544_MAXWINDOW_SIZE 7 #define PN544_WINDOW_SIZE 4 diff --git a/include/linux/rmnet_data.h b/include/linux/rmnet_data.h new file mode 100644 index 000000000000..92c04b3ad6c3 --- /dev/null +++ b/include/linux/rmnet_data.h @@ -0,0 +1,238 @@ +#ifndef _RMNET_DATA_H_ +#define _RMNET_DATA_H_ + +/* ***************** Constants ********************************************** */ +#define RMNET_LOCAL_LOGICAL_ENDPOINT -1 + +#define RMNET_EGRESS_FORMAT__RESERVED__ (1<<0) +#define RMNET_EGRESS_FORMAT_MAP (1<<1) +#define RMNET_EGRESS_FORMAT_AGGREGATION (1<<2) +#define RMNET_EGRESS_FORMAT_MUXING (1<<3) +#define RMNET_EGRESS_FORMAT_MAP_CKSUMV3 (1<<4) +#define RMNET_EGRESS_FORMAT_MAP_CKSUMV4 (1<<5) + +#define RMNET_INGRESS_FIX_ETHERNET (1<<0) +#define RMNET_INGRESS_FORMAT_MAP (1<<1) +#define RMNET_INGRESS_FORMAT_DEAGGREGATION (1<<2) +#define RMNET_INGRESS_FORMAT_DEMUXING (1<<3) +#define RMNET_INGRESS_FORMAT_MAP_COMMANDS (1<<4) +#define RMNET_INGRESS_FORMAT_MAP_CKSUMV3 (1<<5) +#define RMNET_INGRESS_FORMAT_MAP_CKSUMV4 (1<<6) + +/* ***************** Netlink API ******************************************** */ +#define RMNET_NETLINK_PROTO 31 +#define RMNET_MAX_STR_LEN 16 +#define RMNET_NL_DATA_MAX_LEN 64 + +#define RMNET_NETLINK_MSG_COMMAND 0 +#define RMNET_NETLINK_MSG_RETURNCODE 1 +#define RMNET_NETLINK_MSG_RETURNDATA 2 + +struct rmnet_nl_msg_s { + uint16_t reserved; + uint16_t message_type; + uint16_t reserved2:14; + uint16_t crd:2; + union { + uint16_t arg_length; + uint16_t return_code; + }; + union { + uint8_t data[RMNET_NL_DATA_MAX_LEN]; + struct { + uint8_t dev[RMNET_MAX_STR_LEN]; + uint32_t flags; + uint16_t agg_size; + uint16_t agg_count; + uint8_t tail_spacing; + } data_format; + struct { + uint8_t dev[RMNET_MAX_STR_LEN]; + int32_t ep_id; + uint8_t operating_mode; + uint8_t next_dev[RMNET_MAX_STR_LEN]; + } local_ep_config; + struct { + uint32_t id; + uint8_t vnd_name[RMNET_MAX_STR_LEN]; + } vnd; + struct { + uint32_t id; + uint32_t map_flow_id; + uint32_t tc_flow_id; + } flow_control; + }; +}; + +enum rmnet_netlink_message_types_e { + /* + * RMNET_NETLINK_ASSOCIATE_NETWORK_DEVICE - Register RMNET data driver + * on a particular device. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: status code + */ + RMNET_NETLINK_ASSOCIATE_NETWORK_DEVICE, + + /* + * RMNET_NETLINK_UNASSOCIATE_NETWORK_DEVICE - Unregister RMNET data + * driver on a particular + * device. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: status code + */ + RMNET_NETLINK_UNASSOCIATE_NETWORK_DEVICE, + + /* + * RMNET_NETLINK_GET_NETWORK_DEVICE_ASSOCIATED - Get if RMNET data + * driver is registered on a + * particular device. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: 1 if registered, 0 if not + */ + RMNET_NETLINK_GET_NETWORK_DEVICE_ASSOCIATED, + + /* + * RMNET_NETLINK_SET_LINK_EGRESS_DATA_FORMAT - Sets the egress data + * format for a particular + * link. + * Args: uint32_t egress_flags + * char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: status code + */ + RMNET_NETLINK_SET_LINK_EGRESS_DATA_FORMAT, + + /* + * RMNET_NETLINK_GET_LINK_EGRESS_DATA_FORMAT - Gets the egress data + * format for a particular + * link. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: 4-bytes data: uint32_t egress_flags + */ + RMNET_NETLINK_GET_LINK_EGRESS_DATA_FORMAT, + + /* + * RMNET_NETLINK_SET_LINK_INGRESS_DATA_FORMAT - Sets the ingress data + * format for a particular + * link. + * Args: uint32_t ingress_flags + * char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: status code + */ + RMNET_NETLINK_SET_LINK_INGRESS_DATA_FORMAT, + + /* + * RMNET_NETLINK_GET_LINK_INGRESS_DATA_FORMAT - Gets the ingress data + * format for a particular + * link. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * Returns: 4-bytes data: uint32_t ingress_flags + */ + RMNET_NETLINK_GET_LINK_INGRESS_DATA_FORMAT, + + /* + * RMNET_NETLINK_SET_LOGICAL_EP_CONFIG - Sets the logical endpoint + * configuration for a particular + * link. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * int32_t logical_ep_id, valid values are -1 through 31 + * uint8_t rmnet_mode: one of none, vnd, bridged + * char[] egress_dev_name: Egress device if operating in bridge mode + * Returns: status code + */ + RMNET_NETLINK_SET_LOGICAL_EP_CONFIG, + + /* + * RMNET_NETLINK_UNSET_LOGICAL_EP_CONFIG - Un-sets the logical endpoint + * configuration for a particular + * link. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * int32_t logical_ep_id, valid values are -1 through 31 + * Returns: status code + */ + RMNET_NETLINK_UNSET_LOGICAL_EP_CONFIG, + + /* + * RMNET_NETLINK_GET_LOGICAL_EP_CONFIG - Gets the logical endpoint + * configuration for a particular + * link. + * Args: char[] dev_name: Null terminated ASCII string, max length: 15 + * int32_t logical_ep_id, valid values are -1 through 31 + * Returns: uint8_t rmnet_mode: one of none, vnd, bridged + * char[] egress_dev_name: Egress device + */ + RMNET_NETLINK_GET_LOGICAL_EP_CONFIG, + + /* + * RMNET_NETLINK_NEW_VND - Creates a new virtual network device node + * Args: int32_t node number + * Returns: status code + */ + RMNET_NETLINK_NEW_VND, + + /* + * RMNET_NETLINK_NEW_VND_WITH_PREFIX - Creates a new virtual network + * device node with the specified + * prefix for the device name + * Args: int32_t node number + * char[] vnd_name - Use as prefix + * Returns: status code + */ + RMNET_NETLINK_NEW_VND_WITH_PREFIX, + + /* + * RMNET_NETLINK_GET_VND_NAME - Gets the string name of a VND from ID + * Args: int32_t node number + * Returns: char[] vnd_name + */ + RMNET_NETLINK_GET_VND_NAME, + + /* + * RMNET_NETLINK_FREE_VND - Removes virtual network device node + * Args: int32_t node number + * Returns: status code + */ + RMNET_NETLINK_FREE_VND, + + /* + * RMNET_NETLINK_ADD_VND_TC_FLOW - Add flow control handle on VND + * Args: int32_t node number + * uint32_t MAP Flow Handle + * uint32_t TC Flow Handle + * Returns: status code + */ + RMNET_NETLINK_ADD_VND_TC_FLOW, + + /* + * RMNET_NETLINK_DEL_VND_TC_FLOW - Removes flow control handle on VND + * Args: int32_t node number + * uint32_t MAP Flow Handle + * Returns: status code + */ + RMNET_NETLINK_DEL_VND_TC_FLOW +}; + +enum rmnet_config_endpoint_modes_e { + /* Pass the frame up the stack with no modifications to skb->dev */ + RMNET_EPMODE_NONE, + /* Replace skb->dev to a virtual rmnet device and pass up the stack */ + RMNET_EPMODE_VND, + /* Pass the frame directly to another device with dev_queue_xmit(). */ + RMNET_EPMODE_BRIDGE, + /* Must be the last item in the list */ + RMNET_EPMODE_LENGTH +}; + +enum rmnet_config_return_codes_e { + RMNET_CONFIG_OK, + RMNET_CONFIG_UNKNOWN_MESSAGE, + RMNET_CONFIG_UNKNOWN_ERROR, + RMNET_CONFIG_NOMEM, + RMNET_CONFIG_DEVICE_IN_USE, + RMNET_CONFIG_INVALID_REQUEST, + RMNET_CONFIG_NO_SUCH_DEVICE, + RMNET_CONFIG_BAD_ARGUMENTS, + RMNET_CONFIG_BAD_EGRESS_DEVICE, + RMNET_CONFIG_TC_HANDLE_FULL +}; + +#endif /* _RMNET_DATA_H_ */ diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 577592ea0ea0..5529245a4a10 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -283,6 +283,8 @@ enum rtattr_type_t { RTA_MP_ALGO, /* no longer used */ RTA_TABLE, RTA_MARK, + RTA_MFC_STATS, /* not used - backported from the future */ + RTA_UID, __RTA_MAX }; diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index f446f5168141..91c5f8106001 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1824,29 +1824,30 @@ enum v4l2_mpeg_vidc_video_sync_frame_decode { #define V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 25) enum v4l2_mpeg_vidc_extradata { - V4L2_MPEG_VIDC_EXTRADATA_NONE, - V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION, - V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO, - V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP, - V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP, - V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP, - V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING, - V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE, - V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW, - V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI, - V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD, - V4L2_MPEG_VIDC_EXTRADATA_AFD_UD, - V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO, - V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB, - V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER, - V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP, - V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM, - V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO, - V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP, - V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP, - V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO, - V4L2_MPEG_VIDC_EXTRADATA_LTR, - V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI, + V4L2_MPEG_VIDC_EXTRADATA_NONE = 0, + V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION = 1, + V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO = 2, + V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP = 3, + V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP = 4, + V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP = 5, + V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING = 6, + V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE = 7, + V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW = 8, + V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI = 9, + V4L2_MPEG_VIDC_EXTRADATA_CLOSED_CAPTION_UD = 10, + V4L2_MPEG_VIDC_EXTRADATA_AFD_UD = 11, + V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO = 12, + V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB = 13, + V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER = 14, + V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP = 15, + V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM = 16, + V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO = 17, + V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP = 18, + V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP = 19, + V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO = 20, + V4L2_MPEG_VIDC_EXTRADATA_LTR = 21, + V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI = 22, + V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA = 23, }; #define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26) @@ -1935,6 +1936,21 @@ enum v4l2_mpeg_vidc_video_ltrmode { #define V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 43) +#define V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 44) + +#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 45) + +#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 46) + +#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 47) + +#define V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 48) + /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) #define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) @@ -2500,6 +2516,8 @@ struct v4l2_streamparm { (V4L2_EVENT_MSM_VIDC_START + 6) #define V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER \ (V4L2_EVENT_MSM_VIDC_START + 7) +#define V4L2_EVENT_MSM_VIDC_HW_OVERLOAD (V4L2_EVENT_MSM_VIDC_START + 8) +#define V4L2_EVENT_MSM_VIDC_MAX_CLIENTS (V4L2_EVENT_MSM_VIDC_START + 9) /* Payload for V4L2_EVENT_VSYNC */ struct v4l2_event_vsync { diff --git a/include/media/msm_media_info.h b/include/media/msm_media_info.h index ddf9c8eb17e7..d46b5051e469 100644 --- a/include/media/msm_media_info.h +++ b/include/media/msm_media_info.h @@ -79,6 +79,18 @@ enum color_fmts { COLOR_FMT_NV21, }; +static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height) +{ + (void)height; + (void)width; + + /* + * In the future, calculate the size based on the w/h but just + * hardcode it for now since 8K satisfies all current usecases. + */ + return 8 * 1024; +} + static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width) { unsigned int alignment, stride = 0; @@ -158,8 +170,8 @@ static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) static inline unsigned int VENUS_BUFFER_SIZE( int color_fmt, int width, int height) { - unsigned int uv_alignment; - unsigned int size = 0; + const unsigned int extra_size = VENUS_EXTRADATA_SIZE(width, height); + unsigned int uv_alignment = 0, size = 0; unsigned int y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines; if (!width || !height) @@ -175,7 +187,7 @@ static inline unsigned int VENUS_BUFFER_SIZE( uv_alignment = 4096; y_plane = y_stride * y_sclines; uv_plane = uv_stride * uv_sclines + uv_alignment; - size = y_plane + uv_plane; + size = y_plane + uv_plane + extra_size; size = MSM_MEDIA_ALIGN(size, 4096); break; default: diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h index 657f5828ea79..e48c7dac1021 100644 --- a/include/media/msm_vidc.h +++ b/include/media/msm_vidc.h @@ -180,6 +180,11 @@ struct msm_vidc_frame_bits_info_payload { unsigned int header_bits; }; +struct msm_vidc_stream_userdata_payload { + unsigned int type; + unsigned int data[1]; +}; + enum msm_vidc_extradata_type { EXTRADATA_NONE = 0x00000000, EXTRADATA_MB_QUANTIZATION = 0x00000001, @@ -192,6 +197,7 @@ enum msm_vidc_extradata_type { EXTRADATA_PANSCAN_WINDOW = 0x00000008, EXTRADATA_RECOVERY_POINT_SEI = 0x00000009, EXTRADATA_MPEG2_SEQDISP = 0x0000000D, + EXTRADATA_STREAM_USERDATA = 0x0000000E, EXTRADATA_FRAME_QP = 0x0000000F, EXTRADATA_FRAME_BITS_INFO = 0x00000010, EXTRADATA_MULTISLICE_INFO = 0x7F100000, @@ -215,4 +221,9 @@ enum msm_vidc_recovery_sei { FRAME_RECONSTRUCTION_APPROXIMATELY_CORRECT = 0x02, }; +enum msm_vidc_userdata_type { + MSM_VIDC_USERDATA_TYPE_FRAME = 0x1, + MSM_VIDC_USERDATA_TYPE_TOP_FIELD = 0x2, + MSM_VIDC_USERDATA_TYPE_BOTTOM_FIELD = 0x3, +}; #endif diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 075f1e3a0fed..52e77a366bfc 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -23,6 +23,8 @@ struct fib_rule { struct fib_rule __rcu *ctarget; char iifname[IFNAMSIZ]; char oifname[IFNAMSIZ]; + uid_t uid_start; + uid_t uid_end; struct rcu_head rcu; struct net * fr_net; }; @@ -79,7 +81,9 @@ struct fib_rules_ops { [FRA_FWMARK] = { .type = NLA_U32 }, \ [FRA_FWMASK] = { .type = NLA_U32 }, \ [FRA_TABLE] = { .type = NLA_U32 }, \ - [FRA_GOTO] = { .type = NLA_U32 } + [FRA_GOTO] = { .type = NLA_U32 }, \ + [FRA_UID_START] = { .type = NLA_U32 }, \ + [FRA_UID_END] = { .type = NLA_U32 } static inline void fib_rule_get(struct fib_rule *rule) { diff --git a/include/net/flow.h b/include/net/flow.h index 6c469dbdb917..3fe9261baacf 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -23,6 +23,7 @@ struct flowi_common { #define FLOWI_FLAG_PRECOW_METRICS 0x02 #define FLOWI_FLAG_CAN_SLEEP 0x04 __u32 flowic_secid; + uid_t flowic_uid; }; union flowi_uli { @@ -59,6 +60,7 @@ struct flowi4 { #define flowi4_proto __fl_common.flowic_proto #define flowi4_flags __fl_common.flowic_flags #define flowi4_secid __fl_common.flowic_secid +#define flowi4_uid __fl_common.flowic_uid /* (saddr,daddr) must be grouped, same order as in IP header */ __be32 saddr; @@ -78,7 +80,8 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif, __u32 mark, __u8 tos, __u8 scope, __u8 proto, __u8 flags, __be32 daddr, __be32 saddr, - __be16 dport, __be16 sport) + __be16 dport, __be16 sport, + uid_t uid) { fl4->flowi4_oif = oif; fl4->flowi4_iif = 0; @@ -88,6 +91,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif, fl4->flowi4_proto = proto; fl4->flowi4_flags = flags; fl4->flowi4_secid = 0; + fl4->flowi4_uid = uid; fl4->daddr = daddr; fl4->saddr = saddr; fl4->fl4_dport = dport; @@ -115,6 +119,7 @@ struct flowi6 { #define flowi6_proto __fl_common.flowic_proto #define flowi6_flags __fl_common.flowic_flags #define flowi6_secid __fl_common.flowic_secid +#define flowi6_uid __fl_common.flowic_uid struct in6_addr daddr; struct in6_addr saddr; __be32 flowlabel; @@ -158,6 +163,7 @@ struct flowi { #define flowi_proto u.__fl_common.flowic_proto #define flowi_flags u.__fl_common.flowic_flags #define flowi_secid u.__fl_common.flowic_secid +#define flowi_uid u.__fl_common.flowic_uid } __attribute__((__aligned__(BITS_PER_LONG/8))); static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4) diff --git a/include/net/ip.h b/include/net/ip.h index eb7a7d264bb1..76f0c09cd01c 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -167,6 +167,7 @@ struct ip_reply_arg { /* -1 if not needed */ int bound_dev_if; u8 tos; + uid_t uid; }; #define IP_REPLY_ARG_NOSRCCHECK 1 @@ -238,6 +239,9 @@ extern void ipfrag_init(void); extern void ip_static_sysctl_init(void); +#define IP4_REPLY_MARK(net, mark) \ + ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0) + static inline bool ip_is_fragment(const struct iphdr *iph) { return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; diff --git a/include/net/ipv6.h b/include/net/ipv6.h index e4170a22fc6f..f55c78ec8520 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -109,6 +109,9 @@ struct frag_hdr { #define IP6_MF 0x0001 +#define IP6_REPLY_MARK(net, mark) \ + ((net)->ipv6.sysctl.fwmark_reflect ? (mark) : 0) + #include /* sysctls */ diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index bbd023a1c9b9..446db341c5b2 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -56,6 +56,7 @@ struct netns_ipv4 { unsigned int sysctl_ping_group_range[2]; long sysctl_tcp_mem[3]; + int sysctl_fwmark_reflect; atomic_t rt_genid; atomic_t dev_addr_genid; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 81abfcb2eb4e..20b76abcb15e 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -25,6 +25,7 @@ struct netns_sysctl_ipv6 { int ip6_rt_mtu_expires; int ip6_rt_min_advmss; int icmpv6_time; + int fwmark_reflect; }; struct netns_ipv6 { diff --git a/include/net/route.h b/include/net/route.h index b1c0d5b564c2..7488c9ed1033 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -60,6 +60,7 @@ struct rtable { int rt_iif; int rt_oif; __u32 rt_mark; + uid_t rt_uid; /* Info on neighbour */ __be32 rt_gateway; @@ -146,7 +147,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos, RT_SCOPE_UNIVERSE, proto, sk ? inet_sk_flowi_flags(sk) : 0, - daddr, saddr, dport, sport); + daddr, saddr, dport, sport, sk ? sock_i_uid(sk) : 0); if (sk) security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); return ip_route_output_flow(net, fl4, sk); @@ -250,7 +251,8 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 flow_flags |= FLOWI_FLAG_CAN_SLEEP; flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, - protocol, flow_flags, dst, src, dport, sport); + protocol, flow_flags, dst, src, dport, sport, + sock_i_uid(sk)); } static inline struct rtable *ip_route_connect(struct flowi4 *fl4, diff --git a/init/Kconfig b/init/Kconfig index e4b67a1dddf0..11a5a227daa7 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -130,10 +130,13 @@ config HAVE_KERNEL_XZ config HAVE_KERNEL_LZO bool +config HAVE_KERNEL_LZ4 + bool + choice prompt "Kernel compression mode" default KERNEL_GZIP - depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO + depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4 help The linux kernel is a kind of self-extracting executable. Several compression algorithms are available, which differ @@ -201,6 +204,18 @@ config KERNEL_LZO size is about 10% bigger than gzip; however its speed (both compression and decompression) is the fastest. +config KERNEL_LZ4 + bool "LZ4" + depends on HAVE_KERNEL_LZ4 + help + LZ4 is an LZ77-type compressor with a fixed, byte-oriented encoding. + A preliminary version of LZ4 de/compression tool is available at + . + + Its compression ratio is worse than LZO. The size of the kernel + is about 8% bigger than LZO. But the decompression speed is + faster than LZO. + endchoice config DEFAULT_HOSTNAME diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl index eb51d76e058a..04612394c53e 100644 --- a/kernel/timeconst.pl +++ b/kernel/timeconst.pl @@ -370,7 +370,7 @@ (@) } @val = @{$canned_values{$hz}}; - if (!defined(@val)) { + if (!@val) { @val = compute_values($hz); } output($hz, @val); diff --git a/lib/Kconfig b/lib/Kconfig index 8437e3692478..d4636b13a385 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -177,6 +177,15 @@ config LZO_COMPRESS config LZO_DECOMPRESS tristate +config LZ4_COMPRESS + tristate + +config LZ4HC_COMPRESS + tristate + +config LZ4_DECOMPRESS + tristate + source "lib/xz/Kconfig" # @@ -201,6 +210,10 @@ config DECOMPRESS_LZO select LZO_DECOMPRESS tristate +config DECOMPRESS_LZ4 + select LZ4_DECOMPRESS + tristate + # # Generic allocator support is selected if needed # diff --git a/lib/Makefile b/lib/Makefile index 0fbcb04fde58..c5f2b3ba397a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -71,6 +71,9 @@ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ obj-$(CONFIG_BCH) += bch.o obj-$(CONFIG_LZO_COMPRESS) += lzo/ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ +obj-$(CONFIG_LZ4_COMPRESS) += lz4/ +obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ +obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ obj-$(CONFIG_XZ_DEC) += xz/ obj-$(CONFIG_RAID6_PQ) += raid6/ @@ -79,6 +82,7 @@ lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o +lib-$(CONFIG_DECOMPRESS_LZ4) += decompress_unlz4.o obj-$(CONFIG_TEXTSEARCH) += textsearch.o obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o diff --git a/lib/decompress.c b/lib/decompress.c index 3d766b7f60ab..fc3f2dda8c3e 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,9 @@ #ifndef CONFIG_DECOMPRESS_LZO # define unlzo NULL #endif +#ifndef CONFIG_DECOMPRESS_LZ4 +# define unlz4 NULL +#endif static const struct compress_format { unsigned char magic[2]; @@ -42,6 +46,7 @@ static const struct compress_format { { {0x5d, 0x00}, "lzma", unlzma }, { {0xfd, 0x37}, "xz", unxz }, { {0x89, 0x4c}, "lzo", unlzo }, + { {0x02, 0x21}, "lz4", unlz4 }, { {0, 0}, NULL, NULL } }; diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c new file mode 100644 index 000000000000..3e67cfad16ad --- /dev/null +++ b/lib/decompress_unlz4.c @@ -0,0 +1,187 @@ +/* + * Wrapper for decompressing LZ4-compressed kernel, initramfs, and initrd + * + * Copyright (C) 2013, LG Electronics, Kyungsik Lee + * + * 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. + */ + +#ifdef STATIC +#define PREBOOT +#include "lz4/lz4_decompress.c" +#else +#include +#endif +#include +#include +#include +#include + +#include + +/* + * Note: Uncompressed chunk size is used in the compressor side + * (userspace side for compression). + * It is hardcoded because there is not proper way to extract it + * from the binary stream which is generated by the preliminary + * version of LZ4 tool so far. + */ +#define LZ4_DEFAULT_UNCOMPRESSED_CHUNK_SIZE (8 << 20) +#define ARCHIVE_MAGICNUMBER 0x184C2102 + +STATIC inline int INIT unlz4(u8 *input, int in_len, + int (*fill) (void *, unsigned int), + int (*flush) (void *, unsigned int), + u8 *output, int *posp, + void (*error) (char *x)) +{ + int ret = -1; + size_t chunksize = 0; + size_t uncomp_chunksize = LZ4_DEFAULT_UNCOMPRESSED_CHUNK_SIZE; + u8 *inp; + u8 *inp_start; + u8 *outp; + int size = in_len; +#ifdef PREBOOT + size_t out_len = get_unaligned_le32(input + in_len); +#endif + size_t dest_len; + + + if (output) { + outp = output; + } else if (!flush) { + error("NULL output pointer and no flush function provided"); + goto exit_0; + } else { + outp = large_malloc(uncomp_chunksize); + if (!outp) { + error("Could not allocate output buffer"); + goto exit_0; + } + } + + if (input && fill) { + error("Both input pointer and fill function provided,"); + goto exit_1; + } else if (input) { + inp = input; + } else if (!fill) { + error("NULL input pointer and missing fill function"); + goto exit_1; + } else { + inp = large_malloc(lz4_compressbound(uncomp_chunksize)); + if (!inp) { + error("Could not allocate input buffer"); + goto exit_1; + } + } + inp_start = inp; + + if (posp) + *posp = 0; + + if (fill) + fill(inp, 4); + + chunksize = get_unaligned_le32(inp); + if (chunksize == ARCHIVE_MAGICNUMBER) { + inp += 4; + size -= 4; + } else { + error("invalid header"); + goto exit_2; + } + + if (posp) + *posp += 4; + + for (;;) { + + if (fill) + fill(inp, 4); + + chunksize = get_unaligned_le32(inp); + if (chunksize == ARCHIVE_MAGICNUMBER) { + inp += 4; + size -= 4; + if (posp) + *posp += 4; + continue; + } + inp += 4; + size -= 4; + + if (posp) + *posp += 4; + + if (fill) { + if (chunksize > lz4_compressbound(uncomp_chunksize)) { + error("chunk length is longer than allocated"); + goto exit_2; + } + fill(inp, chunksize); + } +#ifdef PREBOOT + if (out_len >= uncomp_chunksize) { + dest_len = uncomp_chunksize; + out_len -= dest_len; + } else + dest_len = out_len; + ret = lz4_decompress(inp, &chunksize, outp, dest_len); +#else + dest_len = uncomp_chunksize; + ret = lz4_decompress_unknownoutputsize(inp, chunksize, outp, + &dest_len); +#endif + if (ret < 0) { + error("Decoding failed"); + goto exit_2; + } + + if (flush && flush(outp, dest_len) != dest_len) + goto exit_2; + if (output) + outp += dest_len; + if (posp) + *posp += chunksize; + + size -= chunksize; + + if (size == 0) + break; + else if (size < 0) { + error("data corrupted"); + goto exit_2; + } + + inp += chunksize; + if (fill) + inp = inp_start; + } + + ret = 0; +exit_2: + if (!input) + large_free(inp_start); +exit_1: + if (!output) + large_free(outp); +exit_0: + return ret; +} + +#ifdef PREBOOT +STATIC int INIT decompress(unsigned char *buf, int in_len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *posp, + void(*error)(char *x) + ) +{ + return unlz4(buf, in_len - 4, fill, flush, output, posp, error); +} +#endif diff --git a/lib/lz4/Makefile b/lib/lz4/Makefile new file mode 100644 index 000000000000..8085d04e9309 --- /dev/null +++ b/lib/lz4/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_LZ4_COMPRESS) += lz4_compress.o +obj-$(CONFIG_LZ4HC_COMPRESS) += lz4hc_compress.o +obj-$(CONFIG_LZ4_DECOMPRESS) += lz4_decompress.o diff --git a/lib/lz4/lz4_compress.c b/lib/lz4/lz4_compress.c new file mode 100644 index 000000000000..28321d8f75ef --- /dev/null +++ b/lib/lz4/lz4_compress.c @@ -0,0 +1,443 @@ +/* + * LZ4 - Fast LZ compression algorithm + * Copyright (C) 2011-2012, Yann Collet. + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at : + * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + * - LZ4 source repository : http://code.google.com/p/lz4/ + * + * Changed for kernel use by: + * Chanho Min + */ + +#include +#include +#include +#include +#include "lz4defs.h" + +/* + * LZ4_compressCtx : + * ----------------- + * Compress 'isize' bytes from 'source' into an output buffer 'dest' of + * maximum size 'maxOutputSize'. * If it cannot achieve it, compression + * will stop, and result of the function will be zero. + * return : the number of bytes written in buffer 'dest', or 0 if the + * compression fails + */ +static inline int lz4_compressctx(void *ctx, + const char *source, + char *dest, + int isize, + int maxoutputsize) +{ + HTYPE *hashtable = (HTYPE *)ctx; + const u8 *ip = (u8 *)source; +#if LZ4_ARCH64 + const BYTE * const base = ip; +#else + const int base = 0; +#endif + const u8 *anchor = ip; + const u8 *const iend = ip + isize; + const u8 *const mflimit = iend - MFLIMIT; + #define MATCHLIMIT (iend - LASTLITERALS) + + u8 *op = (u8 *) dest; + u8 *const oend = op + maxoutputsize; + int length; + const int skipstrength = SKIPSTRENGTH; + u32 forwardh; + int lastrun; + + /* Init */ + if (isize < MINLENGTH) + goto _last_literals; + + memset((void *)hashtable, 0, LZ4_MEM_COMPRESS); + + /* First Byte */ + hashtable[LZ4_HASH_VALUE(ip)] = ip - base; + ip++; + forwardh = LZ4_HASH_VALUE(ip); + + /* Main Loop */ + for (;;) { + int findmatchattempts = (1U << skipstrength) + 3; + const u8 *forwardip = ip; + const u8 *ref; + u8 *token; + + /* Find a match */ + do { + u32 h = forwardh; + int step = findmatchattempts++ >> skipstrength; + ip = forwardip; + forwardip = ip + step; + + if (unlikely(forwardip > mflimit)) + goto _last_literals; + + forwardh = LZ4_HASH_VALUE(forwardip); + ref = base + hashtable[h]; + hashtable[h] = ip - base; + } while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip))); + + /* Catch up */ + while ((ip > anchor) && (ref > (u8 *)source) && + unlikely(ip[-1] == ref[-1])) { + ip--; + ref--; + } + + /* Encode Literal length */ + length = (int)(ip - anchor); + token = op++; + /* check output limit */ + if (unlikely(op + length + (2 + 1 + LASTLITERALS) + + (length >> 8) > oend)) + return 0; + + if (length >= (int)RUN_MASK) { + int len; + *token = (RUN_MASK << ML_BITS); + len = length - RUN_MASK; + for (; len > 254 ; len -= 255) + *op++ = 255; + *op++ = (u8)len; + } else + *token = (length << ML_BITS); + + /* Copy Literals */ + LZ4_BLINDCOPY(anchor, op, length); +_next_match: + /* Encode Offset */ + LZ4_WRITE_LITTLEENDIAN_16(op, (u16)(ip - ref)); + + /* Start Counting */ + ip += MINMATCH; + /* MinMatch verified */ + ref += MINMATCH; + anchor = ip; + while (likely(ip < MATCHLIMIT - (STEPSIZE - 1))) { + #if LZ4_ARCH64 + u64 diff = A64(ref) ^ A64(ip); + #else + u32 diff = A32(ref) ^ A32(ip); + #endif + if (!diff) { + ip += STEPSIZE; + ref += STEPSIZE; + continue; + } + ip += LZ4_NBCOMMONBYTES(diff); + goto _endcount; + } + #if LZ4_ARCH64 + if ((ip < (MATCHLIMIT - 3)) && (A32(ref) == A32(ip))) { + ip += 4; + ref += 4; + } + #endif + if ((ip < (MATCHLIMIT - 1)) && (A16(ref) == A16(ip))) { + ip += 2; + ref += 2; + } + if ((ip < MATCHLIMIT) && (*ref == *ip)) + ip++; +_endcount: + /* Encode MatchLength */ + length = (int)(ip - anchor); + /* Check output limit */ + if (unlikely(op + (1 + LASTLITERALS) + (length >> 8) > oend)) + return 0; + if (length >= (int)ML_MASK) { + *token += ML_MASK; + length -= ML_MASK; + for (; length > 509 ; length -= 510) { + *op++ = 255; + *op++ = 255; + } + if (length > 254) { + length -= 255; + *op++ = 255; + } + *op++ = (u8)length; + } else + *token += length; + + /* Test end of chunk */ + if (ip > mflimit) { + anchor = ip; + break; + } + + /* Fill table */ + hashtable[LZ4_HASH_VALUE(ip-2)] = ip - 2 - base; + + /* Test next position */ + ref = base + hashtable[LZ4_HASH_VALUE(ip)]; + hashtable[LZ4_HASH_VALUE(ip)] = ip - base; + if ((ref > ip - (MAX_DISTANCE + 1)) && (A32(ref) == A32(ip))) { + token = op++; + *token = 0; + goto _next_match; + } + + /* Prepare next loop */ + anchor = ip++; + forwardh = LZ4_HASH_VALUE(ip); + } + +_last_literals: + /* Encode Last Literals */ + lastrun = (int)(iend - anchor); + if (((char *)op - dest) + lastrun + 1 + + ((lastrun + 255 - RUN_MASK) / 255) > (u32)maxoutputsize) + return 0; + + if (lastrun >= (int)RUN_MASK) { + *op++ = (RUN_MASK << ML_BITS); + lastrun -= RUN_MASK; + for (; lastrun > 254 ; lastrun -= 255) + *op++ = 255; + *op++ = (u8)lastrun; + } else + *op++ = (lastrun << ML_BITS); + memcpy(op, anchor, iend - anchor); + op += iend - anchor; + + /* End */ + return (int)(((char *)op) - dest); +} + +static inline int lz4_compress64kctx(void *ctx, + const char *source, + char *dest, + int isize, + int maxoutputsize) +{ + u16 *hashtable = (u16 *)ctx; + const u8 *ip = (u8 *) source; + const u8 *anchor = ip; + const u8 *const base = ip; + const u8 *const iend = ip + isize; + const u8 *const mflimit = iend - MFLIMIT; + #define MATCHLIMIT (iend - LASTLITERALS) + + u8 *op = (u8 *) dest; + u8 *const oend = op + maxoutputsize; + int len, length; + const int skipstrength = SKIPSTRENGTH; + u32 forwardh; + int lastrun; + + /* Init */ + if (isize < MINLENGTH) + goto _last_literals; + + memset((void *)hashtable, 0, LZ4_MEM_COMPRESS); + + /* First Byte */ + ip++; + forwardh = LZ4_HASH64K_VALUE(ip); + + /* Main Loop */ + for (;;) { + int findmatchattempts = (1U << skipstrength) + 3; + const u8 *forwardip = ip; + const u8 *ref; + u8 *token; + + /* Find a match */ + do { + u32 h = forwardh; + int step = findmatchattempts++ >> skipstrength; + ip = forwardip; + forwardip = ip + step; + + if (forwardip > mflimit) + goto _last_literals; + + forwardh = LZ4_HASH64K_VALUE(forwardip); + ref = base + hashtable[h]; + hashtable[h] = (u16)(ip - base); + } while (A32(ref) != A32(ip)); + + /* Catch up */ + while ((ip > anchor) && (ref > (u8 *)source) + && (ip[-1] == ref[-1])) { + ip--; + ref--; + } + + /* Encode Literal length */ + length = (int)(ip - anchor); + token = op++; + /* Check output limit */ + if (unlikely(op + length + (2 + 1 + LASTLITERALS) + + (length >> 8) > oend)) + return 0; + if (length >= (int)RUN_MASK) { + *token = (RUN_MASK << ML_BITS); + len = length - RUN_MASK; + for (; len > 254 ; len -= 255) + *op++ = 255; + *op++ = (u8)len; + } else + *token = (length << ML_BITS); + + /* Copy Literals */ + LZ4_BLINDCOPY(anchor, op, length); + +_next_match: + /* Encode Offset */ + LZ4_WRITE_LITTLEENDIAN_16(op, (u16)(ip - ref)); + + /* Start Counting */ + ip += MINMATCH; + /* MinMatch verified */ + ref += MINMATCH; + anchor = ip; + + while (ip < MATCHLIMIT - (STEPSIZE - 1)) { + #if LZ4_ARCH64 + u64 diff = A64(ref) ^ A64(ip); + #else + u32 diff = A32(ref) ^ A32(ip); + #endif + + if (!diff) { + ip += STEPSIZE; + ref += STEPSIZE; + continue; + } + ip += LZ4_NBCOMMONBYTES(diff); + goto _endcount; + } + #if LZ4_ARCH64 + if ((ip < (MATCHLIMIT - 3)) && (A32(ref) == A32(ip))) { + ip += 4; + ref += 4; + } + #endif + if ((ip < (MATCHLIMIT - 1)) && (A16(ref) == A16(ip))) { + ip += 2; + ref += 2; + } + if ((ip < MATCHLIMIT) && (*ref == *ip)) + ip++; +_endcount: + + /* Encode MatchLength */ + len = (int)(ip - anchor); + /* Check output limit */ + if (unlikely(op + (1 + LASTLITERALS) + (len >> 8) > oend)) + return 0; + if (len >= (int)ML_MASK) { + *token += ML_MASK; + len -= ML_MASK; + for (; len > 509 ; len -= 510) { + *op++ = 255; + *op++ = 255; + } + if (len > 254) { + len -= 255; + *op++ = 255; + } + *op++ = (u8)len; + } else + *token += len; + + /* Test end of chunk */ + if (ip > mflimit) { + anchor = ip; + break; + } + + /* Fill table */ + hashtable[LZ4_HASH64K_VALUE(ip-2)] = (u16)(ip - 2 - base); + + /* Test next position */ + ref = base + hashtable[LZ4_HASH64K_VALUE(ip)]; + hashtable[LZ4_HASH64K_VALUE(ip)] = (u16)(ip - base); + if (A32(ref) == A32(ip)) { + token = op++; + *token = 0; + goto _next_match; + } + + /* Prepare next loop */ + anchor = ip++; + forwardh = LZ4_HASH64K_VALUE(ip); + } + +_last_literals: + /* Encode Last Literals */ + lastrun = (int)(iend - anchor); + if (op + lastrun + 1 + (lastrun - RUN_MASK + 255) / 255 > oend) + return 0; + if (lastrun >= (int)RUN_MASK) { + *op++ = (RUN_MASK << ML_BITS); + lastrun -= RUN_MASK; + for (; lastrun > 254 ; lastrun -= 255) + *op++ = 255; + *op++ = (u8)lastrun; + } else + *op++ = (lastrun << ML_BITS); + memcpy(op, anchor, iend - anchor); + op += iend - anchor; + /* End */ + return (int)(((char *)op) - dest); +} + +int lz4_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem) +{ + int ret = -1; + int out_len = 0; + + if (src_len < LZ4_64KLIMIT) + out_len = lz4_compress64kctx(wrkmem, src, dst, src_len, + lz4_compressbound(src_len)); + else + out_len = lz4_compressctx(wrkmem, src, dst, src_len, + lz4_compressbound(src_len)); + + if (out_len < 0) + goto exit; + + *dst_len = out_len; + + return 0; +exit: + return ret; +} +EXPORT_SYMBOL(lz4_compress); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("LZ4 compressor"); diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c new file mode 100644 index 000000000000..7a85967060a5 --- /dev/null +++ b/lib/lz4/lz4_decompress.c @@ -0,0 +1,334 @@ +/* + * LZ4 Decompressor for Linux kernel + * + * Copyright (C) 2013, LG Electronics, Kyungsik Lee + * + * Based on LZ4 implementation by Yann Collet. + * + * LZ4 - Fast LZ compression algorithm + * Copyright (C) 2011-2012, Yann Collet. + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at : + * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + * - LZ4 source repository : http://code.google.com/p/lz4/ + */ + +#ifndef STATIC +#include +#include +#endif +#include + +#include + +#include "lz4defs.h" + +static int lz4_uncompress(const char *source, char *dest, int osize) +{ + const BYTE *ip = (const BYTE *) source; + const BYTE *ref; + BYTE *op = (BYTE *) dest; + BYTE * const oend = op + osize; + BYTE *cpy; + unsigned token; + size_t length; + size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; +#if LZ4_ARCH64 + size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3}; +#endif + + while (1) { + + /* get runlength */ + token = *ip++; + length = (token >> ML_BITS); + if (length == RUN_MASK) { + size_t len; + + len = *ip++; + for (; len == 255; length += 255) + len = *ip++; + if (unlikely(length > (size_t)(length + len))) + goto _output_error; + length += len; + } + + /* copy literals */ + cpy = op + length; + if (unlikely(cpy > oend - COPYLENGTH)) { + /* + * Error: not enough place for another match + * (min 4) + 5 literals + */ + if (cpy != oend) + goto _output_error; + + memcpy(op, ip, length); + ip += length; + break; /* EOF */ + } + LZ4_WILDCOPY(ip, op, cpy); + ip -= (op - cpy); + op = cpy; + + /* get offset */ + LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip); + ip += 2; + + /* Error: offset create reference outside destination buffer */ + if (unlikely(ref < (BYTE *const) dest)) + goto _output_error; + + /* get matchlength */ + length = token & ML_MASK; + if (length == ML_MASK) { + for (; *ip == 255; length += 255) + ip++; + if (unlikely(length > (size_t)(length + *ip))) + goto _output_error; + length += *ip++; + } + + /* copy repeated sequence */ + if (unlikely((op - ref) < STEPSIZE)) { +#if LZ4_ARCH64 + size_t dec64 = dec64table[op - ref]; +#else + const int dec64 = 0; +#endif + op[0] = ref[0]; + op[1] = ref[1]; + op[2] = ref[2]; + op[3] = ref[3]; + op += 4; + ref += 4; + ref -= dec32table[op-ref]; + PUT4(ref, op); + op += STEPSIZE - 4; + ref -= dec64; + } else { + LZ4_COPYSTEP(ref, op); + } + cpy = op + length - (STEPSIZE - 4); + if (cpy > (oend - COPYLENGTH)) { + + /* Error: request to write beyond destination buffer */ + if (cpy > oend) + goto _output_error; + LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH)); + while (op < cpy) + *op++ = *ref++; + op = cpy; + /* + * Check EOF (should never happen, since last 5 bytes + * are supposed to be literals) + */ + if (op == oend) + goto _output_error; + continue; + } + LZ4_SECURECOPY(ref, op, cpy); + op = cpy; /* correction */ + } + /* end of decoding */ + return (int) (((char *)ip) - source); + + /* write overflow error detected */ +_output_error: + return -1; +} + +static int lz4_uncompress_unknownoutputsize(const char *source, char *dest, + int isize, size_t maxoutputsize) +{ + const BYTE *ip = (const BYTE *) source; + const BYTE *const iend = ip + isize; + const BYTE *ref; + + + BYTE *op = (BYTE *) dest; + BYTE * const oend = op + maxoutputsize; + BYTE *cpy; + + size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; +#if LZ4_ARCH64 + size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3}; +#endif + + /* Main Loop */ + while (ip < iend) { + + unsigned token; + size_t length; + + /* get runlength */ + token = *ip++; + length = (token >> ML_BITS); + if (length == RUN_MASK) { + int s = 255; + while ((ip < iend) && (s == 255)) { + s = *ip++; + if (unlikely(length > (size_t)(length + s))) + goto _output_error; + length += s; + } + } + /* copy literals */ + cpy = op + length; + if ((cpy > oend - COPYLENGTH) || + (ip + length > iend - COPYLENGTH)) { + + if (cpy > oend) + goto _output_error;/* writes beyond buffer */ + + if (ip + length != iend) + goto _output_error;/* + * Error: LZ4 format requires + * to consume all input + * at this stage + */ + memcpy(op, ip, length); + op += length; + break;/* Necessarily EOF, due to parsing restrictions */ + } + LZ4_WILDCOPY(ip, op, cpy); + ip -= (op - cpy); + op = cpy; + + /* get offset */ + LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip); + ip += 2; + if (ref < (BYTE * const) dest) + goto _output_error; + /* + * Error : offset creates reference + * outside of destination buffer + */ + + /* get matchlength */ + length = (token & ML_MASK); + if (length == ML_MASK) { + while (ip < iend) { + int s = *ip++; + if (unlikely(length > (size_t)(length + s))) + goto _output_error; + length += s; + if (s == 255) + continue; + break; + } + } + + /* copy repeated sequence */ + if (unlikely((op - ref) < STEPSIZE)) { +#if LZ4_ARCH64 + size_t dec64 = dec64table[op - ref]; +#else + const int dec64 = 0; +#endif + op[0] = ref[0]; + op[1] = ref[1]; + op[2] = ref[2]; + op[3] = ref[3]; + op += 4; + ref += 4; + ref -= dec32table[op - ref]; + PUT4(ref, op); + op += STEPSIZE - 4; + ref -= dec64; + } else { + LZ4_COPYSTEP(ref, op); + } + cpy = op + length - (STEPSIZE-4); + if (cpy > oend - COPYLENGTH) { + if (cpy > oend) + goto _output_error; /* write outside of buf */ + + LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH)); + while (op < cpy) + *op++ = *ref++; + op = cpy; + /* + * Check EOF (should never happen, since last 5 bytes + * are supposed to be literals) + */ + if (op == oend) + goto _output_error; + continue; + } + LZ4_SECURECOPY(ref, op, cpy); + op = cpy; /* correction */ + } + /* end of decoding */ + return (int) (((char *) op) - dest); + + /* write overflow error detected */ +_output_error: + return -1; +} + +int lz4_decompress(const unsigned char *src, size_t *src_len, + unsigned char *dest, size_t actual_dest_len) +{ + int ret = -1; + int input_len = 0; + + input_len = lz4_uncompress(src, dest, actual_dest_len); + if (input_len < 0) + goto exit_0; + *src_len = input_len; + + return 0; +exit_0: + return ret; +} +#ifndef STATIC +EXPORT_SYMBOL(lz4_decompress); +#endif + +int lz4_decompress_unknownoutputsize(const unsigned char *src, size_t src_len, + unsigned char *dest, size_t *dest_len) +{ + int ret = -1; + int out_len = 0; + + out_len = lz4_uncompress_unknownoutputsize(src, dest, src_len, + *dest_len); + if (out_len < 0) + goto exit_0; + *dest_len = out_len; + + return 0; +exit_0: + return ret; +} +#ifndef STATIC +EXPORT_SYMBOL(lz4_decompress_unknownoutputsize); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("LZ4 Decompressor"); +#endif diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h new file mode 100644 index 000000000000..9b4182fd324c --- /dev/null +++ b/lib/lz4/lz4defs.h @@ -0,0 +1,157 @@ +/* + * lz4defs.h -- architecture specific defines + * + * Copyright (C) 2013, LG Electronics, Kyungsik Lee + * + * 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. + */ + +/* + * Detects 64 bits mode + */ +#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) \ + || defined(__ppc64__) || defined(__LP64__)) +#define LZ4_ARCH64 1 +#else +#define LZ4_ARCH64 0 +#endif + +/* + * Architecture-specific macros + */ +#define ARM_EFFICIENT_UNALIGNED_ACCESS +#define BYTE u8 +typedef struct _U16_S { u16 v; } U16_S; +typedef struct _U32_S { u32 v; } U32_S; +typedef struct _U64_S { u64 v; } U64_S; +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \ + || defined(CONFIG_ARM) && __LINUX_ARM_ARCH__ >= 6 \ + && defined(ARM_EFFICIENT_UNALIGNED_ACCESS) + +#define A16(x) (((U16_S *)(x))->v) +#define A32(x) (((U32_S *)(x))->v) +#define A64(x) (((U64_S *)(x))->v) + +#define PUT4(s, d) (A32(d) = A32(s)) +#define PUT8(s, d) (A64(d) = A64(s)) +#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \ + do { \ + A16(p) = v; \ + p += 2; \ + } while (0) +#else /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */ + +#define A64(x) get_unaligned((u64 *)&(((U16_S *)(x))->v)) +#define A32(x) get_unaligned((u32 *)&(((U16_S *)(x))->v)) +#define A16(x) get_unaligned((u16 *)&(((U16_S *)(x))->v)) + +#define PUT4(s, d) \ + put_unaligned(get_unaligned((const u32 *) s), (u32 *) d) +#define PUT8(s, d) \ + put_unaligned(get_unaligned((const u64 *) s), (u64 *) d) + +#define LZ4_WRITE_LITTLEENDIAN_16(p, v) \ + do { \ + put_unaligned(v, (u16 *)(p)); \ + p += 2; \ + } while (0) +#endif + +#define COPYLENGTH 8 +#define ML_BITS 4 +#define ML_MASK ((1U << ML_BITS) - 1) +#define RUN_BITS (8 - ML_BITS) +#define RUN_MASK ((1U << RUN_BITS) - 1) +#define MEMORY_USAGE 14 +#define MINMATCH 4 +#define SKIPSTRENGTH 6 +#define LASTLITERALS 5 +#define MFLIMIT (COPYLENGTH + MINMATCH) +#define MINLENGTH (MFLIMIT + 1) +#define MAXD_LOG 16 +#define MAXD (1 << MAXD_LOG) +#define MAXD_MASK (u32)(MAXD - 1) +#define MAX_DISTANCE (MAXD - 1) +#define HASH_LOG (MAXD_LOG - 1) +#define HASHTABLESIZE (1 << HASH_LOG) +#define MAX_NB_ATTEMPTS 256 +#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH) +#define LZ4_64KLIMIT ((1<<16) + (MFLIMIT - 1)) +#define HASHLOG64K ((MEMORY_USAGE - 2) + 1) +#define HASH64KTABLESIZE (1U << HASHLOG64K) +#define LZ4_HASH_VALUE(p) (((A32(p)) * 2654435761U) >> \ + ((MINMATCH * 8) - (MEMORY_USAGE-2))) +#define LZ4_HASH64K_VALUE(p) (((A32(p)) * 2654435761U) >> \ + ((MINMATCH * 8) - HASHLOG64K)) +#define HASH_VALUE(p) (((A32(p)) * 2654435761U) >> \ + ((MINMATCH * 8) - HASH_LOG)) + +#if LZ4_ARCH64/* 64-bit */ +#define STEPSIZE 8 + +#define LZ4_COPYSTEP(s, d) \ + do { \ + PUT8(s, d); \ + d += 8; \ + s += 8; \ + } while (0) + +#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d) + +#define LZ4_SECURECOPY(s, d, e) \ + do { \ + if (d < e) { \ + LZ4_WILDCOPY(s, d, e); \ + } \ + } while (0) +#define HTYPE u32 + +#ifdef __BIG_ENDIAN +#define LZ4_NBCOMMONBYTES(val) (__builtin_clzll(val) >> 3) +#else +#define LZ4_NBCOMMONBYTES(val) (__builtin_ctzll(val) >> 3) +#endif + +#else /* 32-bit */ +#define STEPSIZE 4 + +#define LZ4_COPYSTEP(s, d) \ + do { \ + PUT4(s, d); \ + d += 4; \ + s += 4; \ + } while (0) + +#define LZ4_COPYPACKET(s, d) \ + do { \ + LZ4_COPYSTEP(s, d); \ + LZ4_COPYSTEP(s, d); \ + } while (0) + +#define LZ4_SECURECOPY LZ4_WILDCOPY +#define HTYPE const u8* + +#ifdef __BIG_ENDIAN +#define LZ4_NBCOMMONBYTES(val) (__builtin_clz(val) >> 3) +#else +#define LZ4_NBCOMMONBYTES(val) (__builtin_ctz(val) >> 3) +#endif + +#endif + +#define LZ4_READ_LITTLEENDIAN_16(d, s, p) \ + (d = s - get_unaligned_le16(p)) + +#define LZ4_WILDCOPY(s, d, e) \ + do { \ + LZ4_COPYPACKET(s, d); \ + } while (d < e) + +#define LZ4_BLINDCOPY(s, d, l) \ + do { \ + u8 *e = (d) + l; \ + LZ4_WILDCOPY(s, d, e); \ + d = e; \ + } while (0) diff --git a/lib/lz4/lz4hc_compress.c b/lib/lz4/lz4hc_compress.c new file mode 100644 index 000000000000..f344f76b6559 --- /dev/null +++ b/lib/lz4/lz4hc_compress.c @@ -0,0 +1,539 @@ +/* + * LZ4 HC - High Compression Mode of LZ4 + * Copyright (C) 2011-2012, Yann Collet. + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at : + * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + * - LZ4 source repository : http://code.google.com/p/lz4/ + * + * Changed for kernel use by: + * Chanho Min + */ + +#include +#include +#include +#include +#include "lz4defs.h" + +struct lz4hc_data { + const u8 *base; + HTYPE hashtable[HASHTABLESIZE]; + u16 chaintable[MAXD]; + const u8 *nexttoupdate; +} __attribute__((__packed__)); + +static inline int lz4hc_init(struct lz4hc_data *hc4, const u8 *base) +{ + memset((void *)hc4->hashtable, 0, sizeof(hc4->hashtable)); + memset(hc4->chaintable, 0xFF, sizeof(hc4->chaintable)); + +#if LZ4_ARCH64 + hc4->nexttoupdate = base + 1; +#else + hc4->nexttoupdate = base; +#endif + hc4->base = base; + return 1; +} + +/* Update chains up to ip (excluded) */ +static inline void lz4hc_insert(struct lz4hc_data *hc4, const u8 *ip) +{ + u16 *chaintable = hc4->chaintable; + HTYPE *hashtable = hc4->hashtable; +#if LZ4_ARCH64 + const BYTE * const base = hc4->base; +#else + const int base = 0; +#endif + + while (hc4->nexttoupdate < ip) { + const u8 *p = hc4->nexttoupdate; + size_t delta = p - (hashtable[HASH_VALUE(p)] + base); + if (delta > MAX_DISTANCE) + delta = MAX_DISTANCE; + chaintable[(size_t)(p) & MAXD_MASK] = (u16)delta; + hashtable[HASH_VALUE(p)] = (p) - base; + hc4->nexttoupdate++; + } +} + +static inline size_t lz4hc_commonlength(const u8 *p1, const u8 *p2, + const u8 *const matchlimit) +{ + const u8 *p1t = p1; + + while (p1t < matchlimit - (STEPSIZE - 1)) { +#if LZ4_ARCH64 + u64 diff = A64(p2) ^ A64(p1t); +#else + u32 diff = A32(p2) ^ A32(p1t); +#endif + if (!diff) { + p1t += STEPSIZE; + p2 += STEPSIZE; + continue; + } + p1t += LZ4_NBCOMMONBYTES(diff); + return p1t - p1; + } +#if LZ4_ARCH64 + if ((p1t < (matchlimit-3)) && (A32(p2) == A32(p1t))) { + p1t += 4; + p2 += 4; + } +#endif + + if ((p1t < (matchlimit - 1)) && (A16(p2) == A16(p1t))) { + p1t += 2; + p2 += 2; + } + if ((p1t < matchlimit) && (*p2 == *p1t)) + p1t++; + return p1t - p1; +} + +static inline int lz4hc_insertandfindbestmatch(struct lz4hc_data *hc4, + const u8 *ip, const u8 *const matchlimit, const u8 **matchpos) +{ + u16 *const chaintable = hc4->chaintable; + HTYPE *const hashtable = hc4->hashtable; + const u8 *ref; +#if LZ4_ARCH64 + const BYTE * const base = hc4->base; +#else + const int base = 0; +#endif + int nbattempts = MAX_NB_ATTEMPTS; + size_t repl = 0, ml = 0; + u16 delta; + + /* HC4 match finder */ + lz4hc_insert(hc4, ip); + ref = hashtable[HASH_VALUE(ip)] + base; + + /* potential repetition */ + if (ref >= ip-4) { + /* confirmed */ + if (A32(ref) == A32(ip)) { + delta = (u16)(ip-ref); + repl = ml = lz4hc_commonlength(ip + MINMATCH, + ref + MINMATCH, matchlimit) + MINMATCH; + *matchpos = ref; + } + ref -= (size_t)chaintable[(size_t)(ref) & MAXD_MASK]; + } + + while ((ref >= ip - MAX_DISTANCE) && nbattempts) { + nbattempts--; + if (*(ref + ml) == *(ip + ml)) { + if (A32(ref) == A32(ip)) { + size_t mlt = + lz4hc_commonlength(ip + MINMATCH, + ref + MINMATCH, matchlimit) + MINMATCH; + if (mlt > ml) { + ml = mlt; + *matchpos = ref; + } + } + } + ref -= (size_t)chaintable[(size_t)(ref) & MAXD_MASK]; + } + + /* Complete table */ + if (repl) { + const BYTE *ptr = ip; + const BYTE *end; + end = ip + repl - (MINMATCH-1); + /* Pre-Load */ + while (ptr < end - delta) { + chaintable[(size_t)(ptr) & MAXD_MASK] = delta; + ptr++; + } + do { + chaintable[(size_t)(ptr) & MAXD_MASK] = delta; + /* Head of chain */ + hashtable[HASH_VALUE(ptr)] = (ptr) - base; + ptr++; + } while (ptr < end); + hc4->nexttoupdate = end; + } + + return (int)ml; +} + +static inline int lz4hc_insertandgetwidermatch(struct lz4hc_data *hc4, + const u8 *ip, const u8 *startlimit, const u8 *matchlimit, int longest, + const u8 **matchpos, const u8 **startpos) +{ + u16 *const chaintable = hc4->chaintable; + HTYPE *const hashtable = hc4->hashtable; +#if LZ4_ARCH64 + const BYTE * const base = hc4->base; +#else + const int base = 0; +#endif + const u8 *ref; + int nbattempts = MAX_NB_ATTEMPTS; + int delta = (int)(ip - startlimit); + + /* First Match */ + lz4hc_insert(hc4, ip); + ref = hashtable[HASH_VALUE(ip)] + base; + + while ((ref >= ip - MAX_DISTANCE) && (ref >= hc4->base) + && (nbattempts)) { + nbattempts--; + if (*(startlimit + longest) == *(ref - delta + longest)) { + if (A32(ref) == A32(ip)) { + const u8 *reft = ref + MINMATCH; + const u8 *ipt = ip + MINMATCH; + const u8 *startt = ip; + + while (ipt < matchlimit-(STEPSIZE - 1)) { + #if LZ4_ARCH64 + u64 diff = A64(reft) ^ A64(ipt); + #else + u32 diff = A32(reft) ^ A32(ipt); + #endif + + if (!diff) { + ipt += STEPSIZE; + reft += STEPSIZE; + continue; + } + ipt += LZ4_NBCOMMONBYTES(diff); + goto _endcount; + } + #if LZ4_ARCH64 + if ((ipt < (matchlimit - 3)) + && (A32(reft) == A32(ipt))) { + ipt += 4; + reft += 4; + } + ipt += 2; + #endif + if ((ipt < (matchlimit - 1)) + && (A16(reft) == A16(ipt))) { + reft += 2; + } + if ((ipt < matchlimit) && (*reft == *ipt)) + ipt++; +_endcount: + reft = ref; + + while ((startt > startlimit) + && (reft > hc4->base) + && (startt[-1] == reft[-1])) { + startt--; + reft--; + } + + if ((ipt - startt) > longest) { + longest = (int)(ipt - startt); + *matchpos = reft; + *startpos = startt; + } + } + } + ref -= (size_t)chaintable[(size_t)(ref) & MAXD_MASK]; + } + return longest; +} + +static inline int lz4_encodesequence(const u8 **ip, u8 **op, const u8 **anchor, + int ml, const u8 *ref) +{ + int length, len; + u8 *token; + + /* Encode Literal length */ + length = (int)(*ip - *anchor); + token = (*op)++; + if (length >= (int)RUN_MASK) { + *token = (RUN_MASK << ML_BITS); + len = length - RUN_MASK; + for (; len > 254 ; len -= 255) + *(*op)++ = 255; + *(*op)++ = (u8)len; + } else + *token = (length << ML_BITS); + + /* Copy Literals */ + LZ4_BLINDCOPY(*anchor, *op, length); + + /* Encode Offset */ + LZ4_WRITE_LITTLEENDIAN_16(*op, (u16)(*ip - ref)); + + /* Encode MatchLength */ + len = (int)(ml - MINMATCH); + if (len >= (int)ML_MASK) { + *token += ML_MASK; + len -= ML_MASK; + for (; len > 509 ; len -= 510) { + *(*op)++ = 255; + *(*op)++ = 255; + } + if (len > 254) { + len -= 255; + *(*op)++ = 255; + } + *(*op)++ = (u8)len; + } else + *token += len; + + /* Prepare next loop */ + *ip += ml; + *anchor = *ip; + + return 0; +} + +static int lz4_compresshcctx(struct lz4hc_data *ctx, + const char *source, + char *dest, + int isize) +{ + const u8 *ip = (const u8 *)source; + const u8 *anchor = ip; + const u8 *const iend = ip + isize; + const u8 *const mflimit = iend - MFLIMIT; + const u8 *const matchlimit = (iend - LASTLITERALS); + + u8 *op = (u8 *)dest; + + int ml, ml2, ml3, ml0; + const u8 *ref = NULL; + const u8 *start2 = NULL; + const u8 *ref2 = NULL; + const u8 *start3 = NULL; + const u8 *ref3 = NULL; + const u8 *start0; + const u8 *ref0; + int lastrun; + + ip++; + + /* Main Loop */ + while (ip < mflimit) { + ml = lz4hc_insertandfindbestmatch(ctx, ip, matchlimit, (&ref)); + if (!ml) { + ip++; + continue; + } + + /* saved, in case we would skip too much */ + start0 = ip; + ref0 = ref; + ml0 = ml; +_search2: + if (ip+ml < mflimit) + ml2 = lz4hc_insertandgetwidermatch(ctx, ip + ml - 2, + ip + 1, matchlimit, ml, &ref2, &start2); + else + ml2 = ml; + /* No better match */ + if (ml2 == ml) { + lz4_encodesequence(&ip, &op, &anchor, ml, ref); + continue; + } + + if (start0 < ip) { + /* empirical */ + if (start2 < ip + ml0) { + ip = start0; + ref = ref0; + ml = ml0; + } + } + /* + * Here, start0==ip + * First Match too small : removed + */ + if ((start2 - ip) < 3) { + ml = ml2; + ip = start2; + ref = ref2; + goto _search2; + } + +_search3: + /* + * Currently we have : + * ml2 > ml1, and + * ip1+3 <= ip2 (usually < ip1+ml1) + */ + if ((start2 - ip) < OPTIMAL_ML) { + int correction; + int new_ml = ml; + if (new_ml > OPTIMAL_ML) + new_ml = OPTIMAL_ML; + if (ip + new_ml > start2 + ml2 - MINMATCH) + new_ml = (int)(start2 - ip) + ml2 - MINMATCH; + correction = new_ml - (int)(start2 - ip); + if (correction > 0) { + start2 += correction; + ref2 += correction; + ml2 -= correction; + } + } + /* + * Now, we have start2 = ip+new_ml, + * with new_ml=min(ml, OPTIMAL_ML=18) + */ + if (start2 + ml2 < mflimit) + ml3 = lz4hc_insertandgetwidermatch(ctx, + start2 + ml2 - 3, start2, matchlimit, + ml2, &ref3, &start3); + else + ml3 = ml2; + + /* No better match : 2 sequences to encode */ + if (ml3 == ml2) { + /* ip & ref are known; Now for ml */ + if (start2 < ip+ml) + ml = (int)(start2 - ip); + + /* Now, encode 2 sequences */ + lz4_encodesequence(&ip, &op, &anchor, ml, ref); + ip = start2; + lz4_encodesequence(&ip, &op, &anchor, ml2, ref2); + continue; + } + + /* Not enough space for match 2 : remove it */ + if (start3 < ip + ml + 3) { + /* + * can write Seq1 immediately ==> Seq2 is removed, + * so Seq3 becomes Seq1 + */ + if (start3 >= (ip + ml)) { + if (start2 < ip + ml) { + int correction = + (int)(ip + ml - start2); + start2 += correction; + ref2 += correction; + ml2 -= correction; + if (ml2 < MINMATCH) { + start2 = start3; + ref2 = ref3; + ml2 = ml3; + } + } + + lz4_encodesequence(&ip, &op, &anchor, ml, ref); + ip = start3; + ref = ref3; + ml = ml3; + + start0 = start2; + ref0 = ref2; + ml0 = ml2; + goto _search2; + } + + start2 = start3; + ref2 = ref3; + ml2 = ml3; + goto _search3; + } + + /* + * OK, now we have 3 ascending matches; let's write at least + * the first one ip & ref are known; Now for ml + */ + if (start2 < ip + ml) { + if ((start2 - ip) < (int)ML_MASK) { + int correction; + if (ml > OPTIMAL_ML) + ml = OPTIMAL_ML; + if (ip + ml > start2 + ml2 - MINMATCH) + ml = (int)(start2 - ip) + ml2 + - MINMATCH; + correction = ml - (int)(start2 - ip); + if (correction > 0) { + start2 += correction; + ref2 += correction; + ml2 -= correction; + } + } else + ml = (int)(start2 - ip); + } + lz4_encodesequence(&ip, &op, &anchor, ml, ref); + + ip = start2; + ref = ref2; + ml = ml2; + + start2 = start3; + ref2 = ref3; + ml2 = ml3; + + goto _search3; + } + + /* Encode Last Literals */ + lastrun = (int)(iend - anchor); + if (lastrun >= (int)RUN_MASK) { + *op++ = (RUN_MASK << ML_BITS); + lastrun -= RUN_MASK; + for (; lastrun > 254 ; lastrun -= 255) + *op++ = 255; + *op++ = (u8) lastrun; + } else + *op++ = (lastrun << ML_BITS); + memcpy(op, anchor, iend - anchor); + op += iend - anchor; + /* End */ + return (int) (((char *)op) - dest); +} + +int lz4hc_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem) +{ + int ret = -1; + int out_len = 0; + + struct lz4hc_data *hc4 = (struct lz4hc_data *)wrkmem; + lz4hc_init(hc4, (const u8 *)src); + out_len = lz4_compresshcctx((struct lz4hc_data *)hc4, (const u8 *)src, + (char *)dst, (int)src_len); + + if (out_len < 0) + goto exit; + + *dst_len = out_len; + return 0; + +exit: + return ret; +} +EXPORT_SYMBOL(lz4hc_compress); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("LZ4HC compressor"); diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 9ffd0f1ab18f..d7356b653498 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -404,7 +404,7 @@ void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]) memset(&cp, 0, sizeof(cp)); cp.handle = cpu_to_le16(conn->handle); - memcpy(cp.ltk, ltk, sizeof(ltk)); + memcpy(cp.ltk, ltk, sizeof(cp.ltk)); hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); } diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index c02e63c908da..91ede8b74f44 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -17,6 +17,12 @@ #include #include +#define INVALID_UID ((uid_t) -1) +#define uid_valid(uid) ((uid) != -1) +#define uid_lte(a, b) ((a) <= (b)) +#define uid_eq(a, b) ((a) == (b)) +#define uid_gte(a, b) ((a) >= (b)) + int fib_default_rule_add(struct fib_rules_ops *ops, u32 pref, u32 table, u32 flags) { @@ -31,6 +37,8 @@ int fib_default_rule_add(struct fib_rules_ops *ops, r->pref = pref; r->table = table; r->flags = flags; + r->uid_start = INVALID_UID; + r->uid_end = INVALID_UID; r->fr_net = hold_net(ops->fro_net); /* The lock is not required here, the list in unreacheable @@ -177,6 +185,23 @@ void fib_rules_unregister(struct fib_rules_ops *ops) } EXPORT_SYMBOL_GPL(fib_rules_unregister); +static inline uid_t fib_nl_uid(struct nlattr *nla) +{ + return nla_get_u32(nla); +} + +static int nla_put_uid(struct sk_buff *skb, int idx, uid_t uid) +{ + return nla_put_u32(skb, idx, uid); +} + +static int fib_uid_range_match(struct flowi *fl, struct fib_rule *rule) +{ + return (!uid_valid(rule->uid_start) && !uid_valid(rule->uid_end)) || + (uid_gte(fl->flowi_uid, rule->uid_start) && + uid_lte(fl->flowi_uid, rule->uid_end)); +} + static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, struct flowi *fl, int flags) { @@ -191,6 +216,9 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) goto out; + if (!fib_uid_range_match(fl, rule)) + goto out; + ret = ops->match(rule, fl, flags); out: return (rule->flags & FIB_RULE_INVERT) ? !ret : ret; @@ -361,6 +389,19 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) } else if (rule->action == FR_ACT_GOTO) goto errout_free; + /* UID start and end must either both be valid or both unspecified. */ + rule->uid_start = rule->uid_end = INVALID_UID; + if (tb[FRA_UID_START] || tb[FRA_UID_END]) { + if (tb[FRA_UID_START] && tb[FRA_UID_END]) { + rule->uid_start = fib_nl_uid(tb[FRA_UID_START]); + rule->uid_end = fib_nl_uid(tb[FRA_UID_END]); + } + if (!uid_valid(rule->uid_start) || + !uid_valid(rule->uid_end) || + !uid_lte(rule->uid_start, rule->uid_end)) + goto errout_free; + } + err = ops->configure(rule, skb, frh, tb); if (err < 0) goto errout_free; @@ -466,6 +507,14 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK]))) continue; + if (tb[FRA_UID_START] && + !uid_eq(rule->uid_start, fib_nl_uid(tb[FRA_UID_START]))) + continue; + + if (tb[FRA_UID_END] && + !uid_eq(rule->uid_end, fib_nl_uid(tb[FRA_UID_END]))) + continue; + if (!ops->compare(rule, frh, tb)) continue; @@ -520,7 +569,9 @@ static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops, + nla_total_size(4) /* FRA_PRIORITY */ + nla_total_size(4) /* FRA_TABLE */ + nla_total_size(4) /* FRA_FWMARK */ - + nla_total_size(4); /* FRA_FWMASK */ + + nla_total_size(4) /* FRA_FWMASK */ + + nla_total_size(4) /* FRA_UID_START */ + + nla_total_size(4); /* FRA_UID_END */ if (ops->nlmsg_payload) payload += ops->nlmsg_payload(rule); @@ -578,6 +629,12 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, if (rule->target) NLA_PUT_U32(skb, FRA_GOTO, rule->target); + if (uid_valid(rule->uid_start)) + nla_put_uid(skb, FRA_UID_START, rule->uid_start); + + if (uid_valid(rule->uid_end)) + nla_put_uid(skb, FRA_UID_END, rule->uid_end); + if (ops->fill(rule, skb, frh) < 0) goto nla_put_failure; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index cbe3a68507cf..0a24199ff848 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -481,6 +481,7 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = { [RTA_METRICS] = { .type = NLA_NESTED }, [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, [RTA_FLOW] = { .type = NLA_U32 }, + [RTA_UID] = { .type = NLA_U32 }, }; static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 2cb2bf845641..eed77def6d96 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -335,6 +335,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) struct sock *sk; struct inet_sock *inet; __be32 daddr; + u32 mark = IP4_REPLY_MARK(net, skb->mark); if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb)) return; @@ -347,6 +348,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) icmp_param->data.icmph.checksum = 0; inet->tos = ip_hdr(skb)->tos; + sk->sk_mark = mark; daddr = ipc.addr = ip_hdr(skb)->saddr; ipc.opt = NULL; ipc.tx_flags = 0; @@ -358,6 +360,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) memset(&fl4, 0, sizeof(fl4)); fl4.daddr = daddr; fl4.saddr = rt->rt_spec_dst; + fl4.flowi4_mark = mark; fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); fl4.flowi4_proto = IPPROTO_ICMP; security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); @@ -376,7 +379,7 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4, struct sk_buff *skb_in, const struct iphdr *iph, - __be32 saddr, u8 tos, + __be32 saddr, u8 tos, u32 mark, int type, int code, struct icmp_bxm *param) { @@ -388,6 +391,7 @@ static struct rtable *icmp_route_lookup(struct net *net, fl4->daddr = (param->replyopts.opt.opt.srr ? param->replyopts.opt.opt.faddr : iph->saddr); fl4->saddr = saddr; + fl4->flowi4_mark = mark; fl4->flowi4_tos = RT_TOS(tos); fl4->flowi4_proto = IPPROTO_ICMP; fl4->fl4_icmp_type = type; @@ -485,6 +489,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) struct flowi4 fl4; __be32 saddr; u8 tos; + u32 mark; struct net *net; struct sock *sk; @@ -581,6 +586,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL) : iph->tos; + mark = IP4_REPLY_MARK(net, skb_in->mark); if (ip_options_echo(&icmp_param.replyopts.opt.opt, skb_in)) goto out_unlock; @@ -597,11 +603,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) icmp_param.skb = skb_in; icmp_param.offset = skb_network_offset(skb_in); inet_sk(sk)->tos = tos; + sk->sk_mark = mark; ipc.addr = iph->saddr; ipc.opt = &icmp_param.replyopts.opt; ipc.tx_flags = 0; - rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, + rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, mark, type, code, &icmp_param); if (IS_ERR(rt)) goto out_unlock; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 19d66cefd7d3..b902d589b126 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -365,7 +365,8 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), (opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr, - ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport); + ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport, + sock_i_uid(sk)); security_req_classify_flow(req, flowi4_to_flowi(fl4)); rt = ip_route_output_flow(net, fl4, sk); if (IS_ERR(rt)) @@ -398,7 +399,8 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), (opt && opt->opt.srr) ? opt->opt.faddr : ireq->rmt_addr, - ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport); + ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport, + sock_i_uid(sk)); security_req_classify_flow(req, flowi4_to_flowi(fl4)); rt = ip_route_output_flow(net, fl4, sk); if (IS_ERR(rt)) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 4910176d24ed..6f72f395eb13 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1500,12 +1500,14 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr, daddr = replyopts.opt.opt.faddr; } - flowi4_init_output(&fl4, arg->bound_dev_if, 0, + flowi4_init_output(&fl4, arg->bound_dev_if, + IP4_REPLY_MARK(sock_net(sk), skb->mark), RT_TOS(arg->tos), RT_SCOPE_UNIVERSE, sk->sk_protocol, ip_reply_arg_flowi_flags(arg), daddr, rt->rt_spec_dst, - tcp_hdr(skb)->source, tcp_hdr(skb)->dest); + tcp_hdr(skb)->source, tcp_hdr(skb)->dest, + arg->uid); security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(sock_net(sk), &fl4); if (IS_ERR(rt)) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index dca73fa2184d..d8c8b01b1428 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -561,7 +561,8 @@ static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, sk->sk_protocol, - inet_sk_flowi_flags(sk), faddr, saddr, 0, 0); + inet_sk_flowi_flags(sk), faddr, saddr, 0, 0, + sock_i_uid(sk)); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); rt = ip_route_output_flow(net, &fl4, sk); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index bbd604c68e68..b5b563d10a37 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -567,7 +567,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, RT_SCOPE_UNIVERSE, inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, - daddr, saddr, 0, 0); + daddr, saddr, 0, 0, + sock_i_uid(sk)); if (!inet->hdrincl) { err = raw_probe_proto_opt(&fl4, msg); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a0797a5e9585..2de2ee7f1657 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -741,6 +741,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) (rt1->rt_mark ^ rt2->rt_mark) | (rt1->rt_key_tos ^ rt2->rt_key_tos) | (rt1->rt_route_iif ^ rt2->rt_route_iif) | + (rt1->rt_uid ^ rt2->rt_uid) | (rt1->rt_oif ^ rt2->rt_oif)) == 0; } @@ -1881,6 +1882,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) fl4.flowi4_oif = rt->dst.dev->ifindex; fl4.flowi4_iif = skb->dev->ifindex; fl4.flowi4_mark = skb->mark; + fl4.flowi4_uid = skb->sk ? sock_i_uid(skb->sk) : 0; rcu_read_lock(); if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0) @@ -2064,6 +2066,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_iif = dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; + rth->rt_uid = 0; rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; @@ -2194,6 +2197,7 @@ static int __mkroute_input(struct sk_buff *skb, rth->rt_iif = in_dev->dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; + rth->rt_uid = 0; rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; @@ -2377,6 +2381,7 @@ out: return err; rth->rt_iif = dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; + rth->rt_uid = 0; rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->rt_peer_genid = 0; @@ -2581,6 +2586,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_iif = orig_oif ? : dev_out->ifindex; rth->rt_oif = orig_oif; rth->rt_mark = fl4->flowi4_mark; + rth->rt_uid = fl4->flowi4_uid; rth->rt_gateway = fl4->daddr; rth->rt_spec_dst= fl4->saddr; rth->rt_peer_genid = 0; @@ -2832,6 +2838,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) rt_is_output_route(rth) && rth->rt_oif == flp4->flowi4_oif && rth->rt_mark == flp4->flowi4_mark && + rth->rt_uid == flp4->flowi4_uid && !((rth->rt_key_tos ^ flp4->flowi4_tos) & (IPTOS_RT_MASK | RTO_ONLINK)) && net_eq(dev_net(rth->dst.dev), net) && @@ -2913,6 +2920,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or rt->rt_iif = ort->rt_iif; rt->rt_oif = ort->rt_oif; rt->rt_mark = ort->rt_mark; + rt->rt_uid = ort->rt_uid; rt->rt_genid = rt_genid(net); rt->rt_flags = ort->rt_flags; @@ -3010,6 +3018,9 @@ static int rt_fill_info(struct net *net, if (rt->rt_mark) NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark); + if (rt->rt_uid != (uid_t) -1) + NLA_PUT_BE32(skb, RTA_UID, rt->rt_uid); + error = rt->dst.error; if (peer) { inet_peer_refcheck(rt->peer); @@ -3129,6 +3140,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void .flowi4_tos = rtm->rtm_tos, .flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, .flowi4_mark = mark, + .flowi4_uid = tb[RTA_UID] ? nla_get_u32(tb[RTA_UID]) : current_uid(), }; rt = ip_route_output_key(net, &fl4); diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index eab2a7fb15d1..7f4dba3fce6c 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -351,7 +351,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, RT_SCOPE_UNIVERSE, IPPROTO_TCP, inet_sk_flowi_flags(sk), (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, - ireq->loc_addr, th->source, th->dest); + ireq->loc_addr, th->source, th->dest, + sock_i_uid(sk)); security_req_classify_flow(req, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(sock_net(sk), &fl4); if (IS_ERR(rt)) { diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 7a7724da9bff..2de8aa32f3d7 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -765,6 +765,13 @@ static struct ctl_table ipv4_net_table[] = { .mode = 0644, .proc_handler = ipv4_tcp_mem, }, + { + .procname = "fwmark_reflect", + .data = &init_net.ipv4.sysctl_fwmark_reflect, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { } }; diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index a9077f441cb2..bde7beba65bd 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c @@ -153,6 +153,27 @@ static void bictcp_init(struct sock *sk) tcp_sk(sk)->snd_ssthresh = initial_ssthresh; } +static void bictcp_cwnd_event(struct sock *sk, enum tcp_ca_event event) +{ + if (event == CA_EVENT_TX_START) { + struct bictcp *ca = inet_csk_ca(sk); + u32 now = tcp_time_stamp; + s32 delta; + + delta = now - tcp_sk(sk)->lsndtime; + + /* We were application limited (idle) for a while. + * Shift epoch_start to keep cwnd growth to cubic curve. + */ + if (ca->epoch_start && delta > 0) { + ca->epoch_start += delta; + if (after(ca->epoch_start, now)) + ca->epoch_start = now; + } + return; + } +} + /* calculate the cubic root of x using a table lookup followed by one * Newton-Raphson iteration. * Avg err ~= 0.195% @@ -437,6 +458,7 @@ static struct tcp_congestion_ops cubictcp __read_mostly = { .cong_avoid = bictcp_cong_avoid, .set_state = bictcp_state, .undo_cwnd = bictcp_undo_cwnd, + .cwnd_event = bictcp_cwnd_event, .pkts_acked = bictcp_acked, .owner = THIS_MODULE, .name = "cubic", diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index decdd906a504..18c43ad0620f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -931,7 +931,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk)|FLOWI_FLAG_CAN_SLEEP, - faddr, saddr, dport, inet->inet_sport); + faddr, saddr, dport, inet->inet_sport, + sock_i_uid(sk)); security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); rt = ip_route_output_flow(net, fl4, sk); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index a0b4c5da8d43..e8ee4279fd22 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -86,6 +86,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.rt.rt_iif = fl4->flowi4_iif; xdst->u.rt.rt_oif = fl4->flowi4_oif; xdst->u.rt.rt_mark = fl4->flowi4_mark; + xdst->u.rt.rt_uid = fl4->flowi4_uid; xdst->u.dst.dev = dev; dev_hold(dev); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 29625e9a51a6..1f7ab56f4215 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -701,6 +701,7 @@ int inet6_sk_rebuild_header(struct sock *sk) fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; + fl6.flowi6_uid = sock_i_uid(sk); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); final_p = fl6_update_dst(&fl6, np->opt, &final); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 76832c8dc89d..ae4d713ac88d 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -160,6 +160,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; + fl6.flowi6_uid = sock_i_uid(sk); if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST)) fl6.flowi6_oif = np->mcast_oif; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 27ac95a63429..fb8de37f32d3 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -382,6 +382,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) int len; int hlimit; int err = 0; + u32 mark = IP6_REPLY_MARK(net, skb->mark); if ((u8 *)hdr < skb->head || (skb->network_header + sizeof(*hdr)) > skb->tail) @@ -447,6 +448,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) fl6.daddr = hdr->saddr; if (saddr) fl6.saddr = *saddr; + fl6.flowi6_mark = mark; fl6.flowi6_oif = iif; fl6.fl6_icmp_type = type; fl6.fl6_icmp_code = code; @@ -455,6 +457,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) sk = icmpv6_xmit_lock(net); if (sk == NULL) return; + sk->sk_mark = mark; np = inet6_sk(sk); if (!icmpv6_xrlim_allow(sk, type, &fl6)) @@ -529,6 +532,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) struct dst_entry *dst; int err = 0; int hlimit; + u32 mark = IP6_REPLY_MARK(net, skb->mark); saddr = &ipv6_hdr(skb)->daddr; @@ -545,11 +549,13 @@ static void icmpv6_echo_reply(struct sk_buff *skb) fl6.saddr = *saddr; fl6.flowi6_oif = skb->dev->ifindex; fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY; + fl6.flowi6_mark = mark; security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); sk = icmpv6_xmit_lock(net); if (sk == NULL) return; + sk->sk_mark = mark; np = inet6_sk(sk); if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 02dd203d9eac..21ee002710f2 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -72,6 +72,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet_rsk(req)->rmt_port; fl6.fl6_sport = inet_rsk(req)->loc_port; + fl6.flowi6_uid = sock_i_uid(sk); security_req_classify_flow(req, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); @@ -223,6 +224,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) fl6.flowi6_mark = sk->sk_mark; fl6.fl6_sport = inet->inet_sport; fl6.fl6_dport = inet->inet_dport; + fl6.flowi6_uid = sock_i_uid(sk); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); final_p = fl6_update_dst(&fl6, np->opt, &final); diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c new file mode 100644 index 000000000000..0db481c6e16a --- /dev/null +++ b/net/ipv6/ping.c @@ -0,0 +1,231 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * "Ping" sockets + * + * 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. + * + * Based on ipv4/ping.c code. + * + * Authors: Lorenzo Colitti (IPv6 support) + * Vasiliy Kulikov / Openwall (IPv4 implementation, for Linux 2.6), + * Pavel Kankovsky (IPv4 implementation, for Linux 2.4.32) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct proto pingv6_prot = { + .name = "PINGv6", + .owner = THIS_MODULE, + .init = ping_init_sock, + .close = ping_close, + .connect = ip6_datagram_connect, + .disconnect = udp_disconnect, + .setsockopt = ipv6_setsockopt, + .getsockopt = ipv6_getsockopt, + .sendmsg = ping_v6_sendmsg, + .recvmsg = ping_recvmsg, + .bind = ping_bind, + .backlog_rcv = ping_queue_rcv_skb, + .hash = ping_hash, + .unhash = ping_unhash, + .get_port = ping_get_port, + .obj_size = sizeof(struct raw6_sock), +}; +EXPORT_SYMBOL_GPL(pingv6_prot); + +static struct inet_protosw pingv6_protosw = { + .type = SOCK_DGRAM, + .protocol = IPPROTO_ICMPV6, + .prot = &pingv6_prot, + .ops = &inet6_dgram_ops, + .no_check = UDP_CSUM_DEFAULT, + .flags = INET_PROTOSW_REUSE, +}; + + +/* Compatibility glue so we can support IPv6 when it's compiled as a module */ +int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) +{ + return -EAFNOSUPPORT; +} +int dummy_datagram_recv_ctl(struct sock *sk, struct msghdr *msg, + struct sk_buff *skb) +{ + return -EAFNOSUPPORT; +} +int dummy_icmpv6_err_convert(u8 type, u8 code, int *err) +{ + return -EAFNOSUPPORT; +} +void dummy_ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, + __be16 port, u32 info, u8 *payload) {} +int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr, + struct net_device *dev, int strict) +{ + return 0; +} + +int __init pingv6_init(void) +{ + pingv6_ops.ipv6_recv_error = ipv6_recv_error; + pingv6_ops.datagram_recv_ctl = datagram_recv_ctl; + pingv6_ops.icmpv6_err_convert = icmpv6_err_convert; + pingv6_ops.ipv6_icmp_error = ipv6_icmp_error; + pingv6_ops.ipv6_chk_addr = ipv6_chk_addr; + return inet6_register_protosw(&pingv6_protosw); +} + +/* This never gets called because it's not possible to unload the ipv6 module, + * but just in case. + */ +void pingv6_exit(void) +{ + pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error; + pingv6_ops.datagram_recv_ctl = dummy_datagram_recv_ctl; + pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert; + pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error; + pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr; + inet6_unregister_protosw(&pingv6_protosw); +} + +int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t len) +{ + struct inet_sock *inet = inet_sk(sk); + struct ipv6_pinfo *np = inet6_sk(sk); + struct icmp6hdr user_icmph; + int addr_type; + struct in6_addr *daddr; + int iif = 0; + struct flowi6 fl6; + int err; + int hlimit; + struct dst_entry *dst; + struct rt6_info *rt; + struct pingfakehdr pfh; + + pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); + + err = ping_common_sendmsg(AF_INET6, msg, len, &user_icmph, + sizeof(user_icmph)); + if (err) + return err; + + if (msg->msg_name) { + struct sockaddr_in6 *u = (struct sockaddr_in6 *) msg->msg_name; + if (msg->msg_namelen < sizeof(struct sockaddr_in6) || + u->sin6_family != AF_INET6) { + return -EINVAL; + } + if (sk->sk_bound_dev_if && + sk->sk_bound_dev_if != u->sin6_scope_id) { + return -EINVAL; + } + daddr = &(u->sin6_addr); + iif = u->sin6_scope_id; + } else { + if (sk->sk_state != TCP_ESTABLISHED) + return -EDESTADDRREQ; + daddr = &np->daddr; + } + + if (!iif) + iif = sk->sk_bound_dev_if; + + addr_type = ipv6_addr_type(daddr); + if (__ipv6_addr_needs_scope_id(addr_type) && !iif) + return -EINVAL; + if (addr_type & IPV6_ADDR_MAPPED) + return -EINVAL; + + /* TODO: use ip6_datagram_send_ctl to get options from cmsg */ + + memset(&fl6, 0, sizeof(fl6)); + + fl6.flowi6_proto = IPPROTO_ICMPV6; + fl6.saddr = np->saddr; + fl6.daddr = *daddr; + fl6.fl6_icmp_type = user_icmph.icmp6_type; + fl6.fl6_icmp_code = user_icmph.icmp6_code; + fl6.flowi6_uid = sock_i_uid(sk); + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + + if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) + fl6.flowi6_oif = np->mcast_oif; + else if (!fl6.flowi6_oif) + fl6.flowi6_oif = np->ucast_oif; + + dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, 1); + if (IS_ERR(dst)) + return PTR_ERR(dst); + rt = (struct rt6_info *) dst; + + np = inet6_sk(sk); + if (!np) + return -EBADF; + + if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) + fl6.flowi6_oif = np->mcast_oif; + else if (!fl6.flowi6_oif) + fl6.flowi6_oif = np->ucast_oif; + + pfh.icmph.type = user_icmph.icmp6_type; + pfh.icmph.code = user_icmph.icmp6_code; + pfh.icmph.checksum = 0; + pfh.icmph.un.echo.id = inet->inet_sport; + pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence; + pfh.iov = msg->msg_iov; + pfh.wcheck = 0; + pfh.family = AF_INET6; + + if (ipv6_addr_is_multicast(&fl6.daddr)) + hlimit = np->mcast_hops; + else + hlimit = np->hop_limit; + if (hlimit < 0) + hlimit = ip6_dst_hoplimit(dst); + +/* 2013-11-25 hobbes.song LGP_DATA_CTS_IPV6_PINGTEST [START] */ + lock_sock(sk); +/* 2013-11-25 hobbes.song LGP_DATA_CTS_IPV6_PINGTEST [END] */ + + err = ip6_append_data(sk, ping_getfrag, &pfh, len, + 0, hlimit, + np->tclass, NULL, &fl6, rt, + MSG_DONTWAIT, np->dontfrag); + + if (err) { + ICMP6_INC_STATS_BH(sock_net(sk), rt->rt6i_idev, + ICMP6_MIB_OUTERRORS); + ip6_flush_pending_frames(sk); + } else { + err = icmpv6_push_pending_frames(sk, &fl6, + (struct icmp6hdr *) &pfh.icmph, + len); + } + +/* 2013-11-25 hobbes.song LGP_DATA_CTS_IPV6_PINGTEST [START] */ + release_sock(sk); + if(err) +/* 2013-11-25 hobbes.song LGP_DATA_CTS_IPV6_PINGTEST [END] */ + return err; + +/* 2013-11-25 hobbes.song LGP_DATA_CTS_IPV6_PINGTEST [START] */ + return len; +/* 2013-11-25 hobbes.song LGP_DATA_CTS_IPV6_PINGTEST [END] */ + +} diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 5bddea778840..49ec3f8e7cea 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -761,6 +761,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_mark = sk->sk_mark; + fl6.flowi6_uid = sock_i_uid(sk); if (sin6) { if (addr_len < SIN6_LEN_RFC2133) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index bc4888d902b2..b503feda4188 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2278,6 +2278,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { [RTA_IIF] = { .type = NLA_U32 }, [RTA_PRIORITY] = { .type = NLA_U32 }, [RTA_METRICS] = { .type = NLA_NESTED }, + [RTA_UID] = { .type = NLA_U32 }, }; static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, @@ -2590,6 +2591,11 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void if (tb[RTA_OIF]) oif = nla_get_u32(tb[RTA_OIF]); + if (tb[RTA_UID]) + fl6.flowi6_uid = nla_get_u32(tb[RTA_UID]); + else + fl6.flowi6_uid = (iif ? (uid_t) -1 : current_uid()); + if (iif) { struct net_device *dev; int flags = 0; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 8e951d8d3b81..83ee321c08c7 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -244,6 +244,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet_rsk(req)->rmt_port; fl6.fl6_sport = inet_sk(sk)->inet_sport; + fl6.flowi6_uid = sock_i_uid(sk); security_req_classify_flow(req, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 166a57c47d39..1f872c332fc0 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -48,6 +48,13 @@ static ctl_table ipv6_table_template[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "fwmark_reflect", + .data = &init_net.ipv6.sysctl.fwmark_reflect, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, { } }; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 98256cf72f9d..059eb63fca1f 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -251,6 +251,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = usin->sin6_port; fl6.fl6_sport = inet->inet_sport; + fl6.flowi6_uid = sock_i_uid(sk); final_p = fl6_update_dst(&fl6, np->opt, &final); @@ -404,6 +405,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; + fl6.flowi6_uid = sock_i_uid(sk); security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); @@ -496,6 +498,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet_rsk(req)->rmt_port; fl6.fl6_sport = inet_rsk(req)->loc_port; + fl6.flowi6_uid = sock_i_uid(sk); security_req_classify_flow(req, flowi6_to_flowi(&fl6)); opt = np->opt; @@ -897,6 +900,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, fl6.flowi6_proto = IPPROTO_TCP; fl6.flowi6_oif = inet6_iif(skb); + fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark); fl6.fl6_dport = t1->dest; fl6.fl6_sport = t1->source; security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e0a508c2391c..5fd41f9f8bd7 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1085,6 +1085,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; fl6.flowi6_mark = sk->sk_mark; + fl6.flowi6_uid = sock_i_uid(sk); if (msg->msg_controllen) { opt = &opt_space; diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index b1dd35069a02..bfab2a235161 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -310,6 +310,11 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) +quiet_cmd_lz4 = LZ4 $@ +cmd_lz4 = (cat $(filter-out FORCE,$^) | \ + lz4c -l -c1 stdin stdout && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ + (rm -f $@ ; false) + # U-Boot mkimage # --------------------------------------------------------------------------- diff --git a/usr/Kconfig b/usr/Kconfig index 65b845bd4e3e..16ffe99bbade 100644 --- a/usr/Kconfig +++ b/usr/Kconfig @@ -90,6 +90,15 @@ config RD_LZO Support loading of a LZO encoded initial ramdisk or cpio buffer If unsure, say N. +config RD_LZ4 + bool "Support initial ramdisks compressed using LZ4" if EXPERT + default !EXPERT + depends on BLK_DEV_INITRD + select DECOMPRESS_LZ4 + help + Support loading of a LZ4 encoded initial ramdisk or cpio buffer + If unsure, say N. + choice prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!="" help