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