mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 17:18:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
350
drivers/usb/notify/usblog_proc_notify.c
Executable file
350
drivers/usb/notify/usblog_proc_notify.c
Executable file
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
* drivers/usb/notify/usblog_proc_notify.c
|
||||
*
|
||||
* Copyright (C) 2016 Samsung, Inc.
|
||||
* Author: Dongrak Shin <dongrak.shin@samsung.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/* usb notify layer v2.0 */
|
||||
|
||||
#define pr_fmt(fmt) "usb_notify: " fmt
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/usb_notify.h>
|
||||
|
||||
#define USBLOG_MAX_BUF_SIZE (1 << 7) /* 128 */
|
||||
#define USBLOG_MAX_STRING_SIZE (1 << 4) /* 16 */
|
||||
#define USBLOG_CMP_INDEX 3
|
||||
|
||||
struct mode_buf {
|
||||
unsigned long long ts_nsec;
|
||||
char usbmode_str[USBLOG_MAX_STRING_SIZE];
|
||||
};
|
||||
|
||||
struct state_buf {
|
||||
unsigned long long ts_nsec;
|
||||
int usbstate;
|
||||
};
|
||||
|
||||
struct event_buf {
|
||||
unsigned long long ts_nsec;
|
||||
unsigned long event;
|
||||
int enable;
|
||||
};
|
||||
|
||||
struct usblog_buf {
|
||||
unsigned long long mode_count;
|
||||
unsigned long long state_count;
|
||||
unsigned long long event_count;
|
||||
unsigned long mode_index;
|
||||
unsigned long state_index;
|
||||
unsigned long event_index;
|
||||
struct mode_buf mode_buffer[USBLOG_MAX_BUF_SIZE];
|
||||
struct state_buf state_buffer[USBLOG_MAX_BUF_SIZE];
|
||||
struct event_buf event_buffer[USBLOG_MAX_BUF_SIZE];
|
||||
};
|
||||
|
||||
struct usblog_root_str {
|
||||
struct usblog_buf *usblog_buffer;
|
||||
spinlock_t usblog_lock;
|
||||
};
|
||||
|
||||
static struct usblog_root_str usblog_root;
|
||||
|
||||
static const char *usbstate_string(enum usblog_state usbstate)
|
||||
{
|
||||
switch (usbstate) {
|
||||
case NOTIFY_CONFIGURED:
|
||||
return "CONFIGURED";
|
||||
case NOTIFY_CONNECTED:
|
||||
return "CONNECTED";
|
||||
case NOTIFY_DISCONNECTED:
|
||||
return "DISCONNECTED";
|
||||
case NOTIFY_RESET:
|
||||
return "RESET";
|
||||
case NOTIFY_ACCSTART:
|
||||
return "ACCSTART";
|
||||
default:
|
||||
return "UNDEFINED";
|
||||
}
|
||||
}
|
||||
|
||||
static int usblog_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct usblog_buf *temp_usblog_buffer;
|
||||
unsigned long long ts;
|
||||
unsigned long rem_nsec;
|
||||
int i;
|
||||
|
||||
temp_usblog_buffer = usblog_root.usblog_buffer;
|
||||
|
||||
if (!temp_usblog_buffer)
|
||||
goto err;
|
||||
|
||||
seq_printf(m,
|
||||
"usblog USB_MODE: count=%llu maxline=%d\n",
|
||||
temp_usblog_buffer->mode_count, USBLOG_MAX_BUF_SIZE);
|
||||
|
||||
if (temp_usblog_buffer->mode_count >= USBLOG_MAX_BUF_SIZE) {
|
||||
for (i = temp_usblog_buffer->mode_index;
|
||||
i < USBLOG_MAX_BUF_SIZE; i++) {
|
||||
ts = temp_usblog_buffer->mode_buffer[i].ts_nsec;
|
||||
rem_nsec = do_div(ts, 1000000000);
|
||||
seq_printf(m, "[%5lu.%06lu] %s\n", (unsigned long)ts,
|
||||
rem_nsec / 1000,
|
||||
temp_usblog_buffer->mode_buffer[i].usbmode_str);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < temp_usblog_buffer->mode_index; i++) {
|
||||
ts = temp_usblog_buffer->mode_buffer[i].ts_nsec;
|
||||
rem_nsec = do_div(ts, 1000000000);
|
||||
seq_printf(m, "[%5lu.%06lu] %s\n", (unsigned long)ts,
|
||||
rem_nsec / 1000,
|
||||
temp_usblog_buffer->mode_buffer[i].usbmode_str);
|
||||
}
|
||||
seq_printf(m,
|
||||
"\n\n");
|
||||
seq_printf(m,
|
||||
"usblog USB STATE: count=%llu maxline=%d\n",
|
||||
temp_usblog_buffer->state_count, USBLOG_MAX_BUF_SIZE);
|
||||
|
||||
if (temp_usblog_buffer->state_count >= USBLOG_MAX_BUF_SIZE) {
|
||||
for (i = temp_usblog_buffer->state_index;
|
||||
i < USBLOG_MAX_BUF_SIZE; i++) {
|
||||
ts = temp_usblog_buffer->state_buffer[i].ts_nsec;
|
||||
rem_nsec = do_div(ts, 1000000000);
|
||||
seq_printf(m, "[%5lu.%06lu] %s\n", (unsigned long)ts,
|
||||
rem_nsec / 1000,
|
||||
usbstate_string(temp_usblog_buffer->
|
||||
state_buffer[i].usbstate));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < temp_usblog_buffer->state_index; i++) {
|
||||
ts = temp_usblog_buffer->state_buffer[i].ts_nsec;
|
||||
rem_nsec = do_div(ts, 1000000000);
|
||||
seq_printf(m, "[%5lu.%06lu] %s\n", (unsigned long)ts,
|
||||
rem_nsec / 1000,
|
||||
usbstate_string(temp_usblog_buffer->state_buffer[i].usbstate));
|
||||
}
|
||||
seq_printf(m,
|
||||
"\n\n");
|
||||
seq_printf(m,
|
||||
"usblog USB EVENT: count=%llu maxline=%d\n",
|
||||
temp_usblog_buffer->event_count, USBLOG_MAX_BUF_SIZE);
|
||||
|
||||
if (temp_usblog_buffer->event_count >= USBLOG_MAX_BUF_SIZE) {
|
||||
for (i = temp_usblog_buffer->event_index;
|
||||
i < USBLOG_MAX_BUF_SIZE; i++) {
|
||||
ts = temp_usblog_buffer->event_buffer[i].ts_nsec;
|
||||
rem_nsec = do_div(ts, 1000000000);
|
||||
seq_printf(m, "[%5lu.%06lu] %s %s\n", (unsigned long)ts,
|
||||
rem_nsec / 1000,
|
||||
event_string(temp_usblog_buffer->event_buffer[i].event),
|
||||
status_string(temp_usblog_buffer->
|
||||
event_buffer[i].enable));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < temp_usblog_buffer->event_index; i++) {
|
||||
ts = temp_usblog_buffer->event_buffer[i].ts_nsec;
|
||||
rem_nsec = do_div(ts, 1000000000);
|
||||
seq_printf(m, "[%5lu.%06lu] %s %s\n", (unsigned long)ts,
|
||||
rem_nsec / 1000,
|
||||
event_string(temp_usblog_buffer->event_buffer[i].event),
|
||||
status_string(temp_usblog_buffer->event_buffer[i].enable));
|
||||
}
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usblog_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, usblog_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations usblog_proc_fops = {
|
||||
.open = usblog_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
void mode_store_usblog_notify(int type, char *param1)
|
||||
{
|
||||
struct mode_buf *md_buffer;
|
||||
unsigned long long *target_count;
|
||||
unsigned long *target_index;
|
||||
char buf[256], buf2[4];
|
||||
char *b, *name;
|
||||
|
||||
target_count = &usblog_root.usblog_buffer->mode_count;
|
||||
target_index = &usblog_root.usblog_buffer->mode_index;
|
||||
md_buffer = &usblog_root.usblog_buffer->mode_buffer[*target_index];
|
||||
if (md_buffer == NULL) {
|
||||
pr_err("%s target_buffer error\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
md_buffer->ts_nsec = local_clock();
|
||||
|
||||
strlcpy(buf, param1, sizeof(buf));
|
||||
b = strim(buf);
|
||||
if (b) {
|
||||
name = strsep(&b, ",");
|
||||
strlcpy(buf2, name, sizeof(buf2));
|
||||
strncpy(md_buffer->usbmode_str, buf2,
|
||||
sizeof(md_buffer->usbmode_str)-1);
|
||||
}
|
||||
while (b) {
|
||||
name = strsep(&b, ",");
|
||||
if (!name)
|
||||
continue;
|
||||
if (USBLOG_MAX_STRING_SIZE
|
||||
- strlen(md_buffer->usbmode_str) < 5) {
|
||||
strncpy(md_buffer->usbmode_str, "overflow",
|
||||
sizeof(md_buffer->usbmode_str)-1);
|
||||
b = NULL;
|
||||
} else {
|
||||
strncat(md_buffer->usbmode_str, ",", 1);
|
||||
strncat(md_buffer->usbmode_str, name, 3);
|
||||
}
|
||||
}
|
||||
|
||||
*target_index = (*target_index+1)%USBLOG_MAX_BUF_SIZE;
|
||||
(*target_count)++;
|
||||
err:
|
||||
return;
|
||||
}
|
||||
|
||||
void state_store_usblog_notify(int type, char *param1)
|
||||
{
|
||||
struct state_buf *st_buffer;
|
||||
unsigned long long *target_count;
|
||||
unsigned long *target_index;
|
||||
char buf[256], index;
|
||||
char *b, *name;
|
||||
int usbstate;
|
||||
|
||||
target_count = &usblog_root.usblog_buffer->state_count;
|
||||
target_index = &usblog_root.usblog_buffer->state_index;
|
||||
st_buffer = &usblog_root.usblog_buffer->state_buffer[*target_index];
|
||||
if (st_buffer == NULL) {
|
||||
pr_err("%s target_buffer error\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
st_buffer->ts_nsec = local_clock();
|
||||
|
||||
strlcpy(buf, param1, sizeof(buf));
|
||||
b = strim(buf);
|
||||
name = strsep(&b, "=");
|
||||
|
||||
index = *(b+USBLOG_CMP_INDEX);
|
||||
|
||||
switch (index) {
|
||||
case 'F': /* CONFIGURED */
|
||||
usbstate = NOTIFY_CONFIGURED;
|
||||
break;
|
||||
case 'N': /* CONNECTED */
|
||||
usbstate = NOTIFY_CONNECTED;
|
||||
break;
|
||||
case 'C': /* DISCONNECTED */
|
||||
usbstate = NOTIFY_DISCONNECTED;
|
||||
break;
|
||||
case 'E': /* RESET */
|
||||
usbstate = NOTIFY_RESET;
|
||||
break;
|
||||
case 'R': /* ACCESSORY START */
|
||||
usbstate = NOTIFY_ACCSTART;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s state param error. state=%s\n", __func__, param1);
|
||||
goto err;
|
||||
}
|
||||
|
||||
st_buffer->usbstate = usbstate;
|
||||
|
||||
*target_index = (*target_index+1)%USBLOG_MAX_BUF_SIZE;
|
||||
(*target_count)++;
|
||||
err:
|
||||
return;
|
||||
}
|
||||
|
||||
void event_store_usblog_notify(int type, unsigned long *param1, int *param2)
|
||||
{
|
||||
struct event_buf *ev_buffer;
|
||||
unsigned long long *target_count;
|
||||
unsigned long *target_index;
|
||||
|
||||
target_count = &usblog_root.usblog_buffer->event_count;
|
||||
target_index = &usblog_root.usblog_buffer->event_index;
|
||||
ev_buffer = &usblog_root.usblog_buffer->event_buffer[*target_index];
|
||||
if (ev_buffer == NULL) {
|
||||
pr_err("%s target_buffer error\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
ev_buffer->ts_nsec = local_clock();
|
||||
ev_buffer->event = *param1;
|
||||
ev_buffer->enable = *param2;
|
||||
|
||||
*target_index = (*target_index+1)%USBLOG_MAX_BUF_SIZE;
|
||||
(*target_count)++;
|
||||
err:
|
||||
return;
|
||||
}
|
||||
|
||||
void store_usblog_notify(int type, void *param1, void *parma2)
|
||||
{
|
||||
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock_irqsave(&usblog_root.usblog_lock, flags);
|
||||
|
||||
if (!usblog_root.usblog_buffer) {
|
||||
pr_err("%s usblog_buffer is null\n", __func__);
|
||||
spin_unlock_irqrestore(&usblog_root.usblog_lock,flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == NOTIFY_EVENT)
|
||||
event_store_usblog_notify(type,
|
||||
(unsigned long *)param1, (int *)parma2);
|
||||
else if (type == NOTIFY_USBMODE)
|
||||
mode_store_usblog_notify(type, (char *)param1);
|
||||
else if (type == NOTIFY_USBSTATE)
|
||||
state_store_usblog_notify(type, (char *)param1);
|
||||
else
|
||||
pr_err("%s type error %d\n", __func__, type);
|
||||
|
||||
spin_unlock_irqrestore(&usblog_root.usblog_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(store_usblog_notify);
|
||||
|
||||
int register_usblog_proc(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
proc_create("usblog", 0, NULL, &usblog_proc_fops);
|
||||
|
||||
usblog_root.usblog_buffer
|
||||
= kzalloc(sizeof(struct usblog_buf), GFP_KERNEL);
|
||||
if (!usblog_root.usblog_buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
pr_info("%s size=%zu\n", __func__, sizeof(struct usblog_buf));
|
||||
spin_lock_init(&usblog_root.usblog_lock);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(register_usblog_proc);
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue