Merge "diag: Make fixes in memory device mode"
This commit is contained in:
commit
2ead4cc259
|
@ -405,6 +405,7 @@ struct diag_md_proc_info {
|
|||
int pid;
|
||||
struct task_struct *socket_process;
|
||||
struct task_struct *callback_process;
|
||||
struct task_struct *mdlog_process;
|
||||
};
|
||||
|
||||
struct diag_feature_t {
|
||||
|
@ -420,13 +421,6 @@ struct diag_feature_t {
|
|||
uint8_t sent_feature_mask;
|
||||
};
|
||||
|
||||
struct diag_mdlog_client_info {
|
||||
struct task_struct *client_process;
|
||||
int client_id;
|
||||
uint16_t notification_list;
|
||||
int signal_type;
|
||||
};
|
||||
|
||||
struct diagchar_dev {
|
||||
|
||||
/* State for the char driver */
|
||||
|
@ -538,7 +532,6 @@ struct diagchar_dev {
|
|||
int logging_mode;
|
||||
int mask_check;
|
||||
struct diag_md_proc_info md_proc[DIAG_NUM_PROC];
|
||||
struct diag_mdlog_client_info md_client_info;
|
||||
/* Power related variables */
|
||||
struct diag_ws_ref_t dci_ws;
|
||||
struct diag_ws_ref_t md_ws;
|
||||
|
|
|
@ -186,7 +186,7 @@ static uint16_t diag_get_next_delayed_rsp_id(void)
|
|||
return rsp_id;
|
||||
}
|
||||
|
||||
static int diag_switch_logging(int requested_mode);
|
||||
static int diag_switch_logging(const int requested_mode);
|
||||
|
||||
#define COPY_USER_SPACE_OR_EXIT(buf, data, length) \
|
||||
do { \
|
||||
|
@ -371,12 +371,25 @@ static void diag_close_logging_process(int pid)
|
|||
continue;
|
||||
}
|
||||
found = 1;
|
||||
if (logging_proc->socket_process)
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE, "found entry pid %d\n", pid);
|
||||
if (logging_proc->socket_process) {
|
||||
logging_proc->socket_process = NULL;
|
||||
if (logging_proc->callback_process)
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting socket proc %d to NULL, proc: %d",
|
||||
driver->md_proc[i].pid, i);
|
||||
}
|
||||
if (logging_proc->callback_process) {
|
||||
logging_proc->callback_process = NULL;
|
||||
if (driver->md_client_info.client_process)
|
||||
driver->md_client_info.client_process = NULL;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting callback proc %d to NULL, proc: %d",
|
||||
driver->md_proc[i].pid, i);
|
||||
}
|
||||
if (logging_proc->mdlog_process) {
|
||||
logging_proc->mdlog_process = NULL;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting mdlog proc %d to NULL, proc: %d",
|
||||
driver->md_proc[i].pid, i);
|
||||
}
|
||||
diag_update_proc_vote(DIAG_PROC_MEMORY_DEVICE, VOTE_DOWN, i);
|
||||
}
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
|
@ -422,6 +435,8 @@ static void diag_close_logging_process(int pid)
|
|||
if (logging_proc->pid != pid)
|
||||
continue;
|
||||
logging_proc->pid = 0;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting logging proc to 0\n");
|
||||
}
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
}
|
||||
|
@ -1101,13 +1116,14 @@ static int mask_request_validate(unsigned char mask_buf[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int diag_switch_logging(int requested_mode)
|
||||
static int diag_switch_logging(const int requested_mode)
|
||||
{
|
||||
int i;
|
||||
int err = 0;
|
||||
int mux_mode = DIAG_USB_MODE; /* set the mode from diag_mux.h */
|
||||
int new_mode = USB_MODE;
|
||||
int current_mode = driver->logging_mode;
|
||||
int found = 0;
|
||||
|
||||
switch (requested_mode) {
|
||||
case CALLBACK_MODE:
|
||||
|
@ -1127,29 +1143,40 @@ static int diag_switch_logging(int requested_mode)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"current: %d requested: %d translated: %d, pid: %d\n",
|
||||
current_mode, requested_mode, new_mode, current->tgid);
|
||||
|
||||
if (new_mode == current_mode) {
|
||||
if (requested_mode != MEMORY_DEVICE_MODE ||
|
||||
driver->real_time_mode) {
|
||||
pr_info_ratelimited("diag: Already in logging mode change requested, mode: %d\n",
|
||||
current_mode);
|
||||
}
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE, "no mode change required\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (new_mode == SOCKET_MODE &&
|
||||
driver->md_proc[DIAG_LOCAL_PROC].socket_process) {
|
||||
err = send_sig(SIGCONT,
|
||||
driver->md_proc[DIAG_LOCAL_PROC].socket_process,
|
||||
0);
|
||||
if (err) {
|
||||
pr_err("diag: In %s, error notifying socket process %d\n",
|
||||
__func__, err);
|
||||
/*
|
||||
* When any mdlog process exits, or votes for USB mode, check if the
|
||||
* process is the original requestor for the mode change. Don't allow
|
||||
* any mdlog process to vote for mode change.
|
||||
*/
|
||||
if (current_mode == MEMORY_DEVICE_MODE && new_mode == USB_MODE) {
|
||||
for (i = 0; i < DIAG_NUM_PROC && !found; i++) {
|
||||
if (driver->md_proc[i].pid == current->tgid)
|
||||
found = 1;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"switch_logging denied pid: %d saved: %d\n",
|
||||
current->tgid,
|
||||
driver->md_proc[DIAG_LOCAL_PROC].pid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_mode == MEMORY_DEVICE_MODE)
|
||||
driver->md_client_info.client_process = current;
|
||||
|
||||
mutex_lock(&driver->diagchar_mutex);
|
||||
diag_ws_reset(DIAG_WS_MUX);
|
||||
err = diag_mux_switch_logging(mux_mode);
|
||||
|
@ -1157,11 +1184,17 @@ static int diag_switch_logging(int requested_mode)
|
|||
pr_err("diag: In %s, unable to switch mode from %d to %d\n",
|
||||
__func__, current_mode, requested_mode);
|
||||
driver->logging_mode = current_mode;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"error changing logging modes\n");
|
||||
goto fail;
|
||||
}
|
||||
driver->logging_mode = new_mode;
|
||||
|
||||
pr_info("diag: Logging switched from %d to %d mode\n",
|
||||
current_mode, new_mode);
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"logging switched from %d to %d mode\n",
|
||||
current_mode, new_mode);
|
||||
|
||||
if (new_mode != MEMORY_DEVICE_MODE) {
|
||||
diag_update_real_time_vote(DIAG_PROC_MEMORY_DEVICE,
|
||||
|
@ -1176,10 +1209,35 @@ static int diag_switch_logging(int requested_mode)
|
|||
&driver->diag_real_time_work);
|
||||
}
|
||||
|
||||
for (i = 0; i < DIAG_NUM_PROC; i++) {
|
||||
driver->md_proc[i].pid = current->tgid;
|
||||
if (requested_mode == SOCKET_MODE)
|
||||
/*
|
||||
* Set the pid and context for md_proc. For callback processes, the
|
||||
* context will be set by DIAG_IOCTL_REGISTER_CALLBACK.
|
||||
*/
|
||||
for (i = 0; i < DIAG_NUM_PROC && new_mode == MEMORY_DEVICE_MODE; i++) {
|
||||
switch (requested_mode) {
|
||||
case SOCKET_MODE:
|
||||
driver->md_proc[i].pid = current->tgid;
|
||||
driver->md_proc[i].socket_process = current;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting socket process to %d, proc: %d",
|
||||
driver->md_proc[i].pid, i);
|
||||
break;
|
||||
case MEMORY_DEVICE_MODE:
|
||||
driver->md_proc[i].pid = current->tgid;
|
||||
driver->md_proc[i].mdlog_process = current;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting mdlog process to %d, proc: %d",
|
||||
driver->md_proc[i].pid, i);
|
||||
break;
|
||||
case CALLBACK_MODE:
|
||||
if (driver->md_proc[i].callback_process == current) {
|
||||
driver->md_proc[i].pid = current->tgid;
|
||||
DIAG_LOG(DIAG_DEBUG_USERSPACE,
|
||||
"setting callback process to %d, proc: %d",
|
||||
driver->md_proc[i].pid, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fail:
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
|
@ -1459,10 +1517,12 @@ static int diag_ioctl_register_callback(unsigned long ioarg)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The IOCTL will just send the context for md_proc.
|
||||
* The pid will be set by diag_switch_logging.
|
||||
*/
|
||||
mutex_lock(&driver->diagchar_mutex);
|
||||
driver->md_proc[reg.proc].pid = current->tgid;
|
||||
driver->md_proc[reg.proc].callback_process = current;
|
||||
driver->md_proc[reg.proc].socket_process = NULL;
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -2842,8 +2902,8 @@ static int __init diagchar_init(void)
|
|||
driver->md_proc[i].pid = 0;
|
||||
driver->md_proc[i].callback_process = NULL;
|
||||
driver->md_proc[i].socket_process = NULL;
|
||||
driver->md_proc[i].mdlog_process = NULL;
|
||||
}
|
||||
driver->md_client_info.client_process = NULL;
|
||||
driver->mask_check = 0;
|
||||
driver->in_busy_pktdata = 0;
|
||||
driver->in_busy_dcipktdata = 0;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
/* tracks which peripheral is undergoing SSR */
|
||||
static uint16_t reg_dirty;
|
||||
static void diag_notify_md_client(uint8_t peripheral, int data);
|
||||
|
||||
static void diag_mask_update_work_fn(struct work_struct *work)
|
||||
{
|
||||
|
@ -48,6 +49,7 @@ void diag_cntl_channel_open(struct diagfwd_info *p_info)
|
|||
return;
|
||||
driver->mask_update |= PERIPHERAL_MASK(p_info->peripheral);
|
||||
queue_work(driver->cntl_wq, &driver->mask_update_work);
|
||||
diag_notify_md_client(p_info->peripheral, DIAG_STATUS_OPEN);
|
||||
}
|
||||
|
||||
void diag_cntl_channel_close(struct diagfwd_info *p_info)
|
||||
|
@ -70,6 +72,8 @@ void diag_cntl_channel_close(struct diagfwd_info *p_info)
|
|||
driver->stm_state[peripheral] = DISABLE_STM;
|
||||
driver->stm_state_requested[peripheral] = DISABLE_STM;
|
||||
reg_dirty ^= PERIPHERAL_MASK(peripheral);
|
||||
diag_notify_md_client(peripheral, DIAG_STATUS_CLOSED);
|
||||
|
||||
flush_workqueue(driver->cntl_wq);
|
||||
}
|
||||
|
||||
|
@ -101,37 +105,42 @@ static void diag_stm_update_work_fn(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
void diag_notify_md_client(uint16_t peripheral_mask, int data)
|
||||
void diag_notify_md_client(uint8_t peripheral, int data)
|
||||
{
|
||||
int stat;
|
||||
int stat = 0;
|
||||
struct siginfo info;
|
||||
|
||||
if (driver->logging_mode != MEMORY_DEVICE_MODE)
|
||||
return;
|
||||
|
||||
memset(&info, 0, sizeof(struct siginfo));
|
||||
info.si_code = SI_QUEUE;
|
||||
info.si_int = (peripheral_mask | data);
|
||||
info.si_int = (PERIPHERAL_MASK(peripheral) | data);
|
||||
info.si_signo = SIGCONT;
|
||||
stat = send_sig_info(info.si_signo,
|
||||
&info, driver->md_client_info.client_process);
|
||||
if (stat)
|
||||
pr_err("diag: Err sending signal to memory device client, signal data: 0x%x, stat: %d\n",
|
||||
info.si_int, stat);
|
||||
if (driver->md_proc[DIAG_LOCAL_PROC].mdlog_process) {
|
||||
stat = send_sig_info(info.si_signo, &info,
|
||||
driver->md_proc[DIAG_LOCAL_PROC].mdlog_process);
|
||||
if (stat)
|
||||
pr_err("diag: Err sending signal to memory device client, signal data: 0x%x, stat: %d\n",
|
||||
info.si_int, stat);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void process_pd_status(uint8_t *buf, uint32_t len,
|
||||
uint8_t peripheral) {
|
||||
struct diag_ctrl_msg_pd_status *pd_msg =
|
||||
(struct diag_ctrl_msg_pd_status *)buf;
|
||||
uint16_t pd;
|
||||
uint8_t status;
|
||||
uint8_t peripheral)
|
||||
{
|
||||
struct diag_ctrl_msg_pd_status *pd_msg = NULL;
|
||||
uint32_t pd;
|
||||
int status = DIAG_STATUS_CLOSED;
|
||||
|
||||
if (!buf || peripheral >= NUM_PERIPHERALS || len == 0)
|
||||
if (!buf || peripheral >= NUM_PERIPHERALS || len < sizeof(*pd_msg))
|
||||
return;
|
||||
|
||||
pd_msg = (struct diag_ctrl_msg_pd_status *)buf;
|
||||
pd = pd_msg->pd_id;
|
||||
status = pd_msg->status;
|
||||
if (driver->logging_mode == MEMORY_DEVICE_MODE) {
|
||||
diag_notify_md_client(PERIPHERAL_MASK(peripheral), status);
|
||||
}
|
||||
status = (pd_msg->status == 0) ? DIAG_STATUS_OPEN : DIAG_STATUS_CLOSED;
|
||||
diag_notify_md_client(peripheral, status);
|
||||
}
|
||||
|
||||
static void enable_stm_feature(uint8_t peripheral)
|
||||
|
|
|
@ -277,5 +277,4 @@ int diag_send_buffering_tx_mode_pkt(uint8_t peripheral,
|
|||
struct diag_buffering_mode_t *params);
|
||||
int diag_send_buffering_wm_values(uint8_t peripheral,
|
||||
struct diag_buffering_mode_t *params);
|
||||
void diag_notify_md_client(uint16_t peripheral_mask, int data);
|
||||
#endif
|
||||
|
|
|
@ -76,10 +76,6 @@ static void diagfwd_cntl_open(struct diagfwd_info *fwd_info)
|
|||
{
|
||||
if (!fwd_info)
|
||||
return;
|
||||
if (driver->logging_mode == MEMORY_DEVICE_MODE) {
|
||||
diag_notify_md_client(PERIPHERAL_MASK(fwd_info->peripheral),
|
||||
DIAG_STATUS_OPEN);
|
||||
}
|
||||
diag_cntl_channel_open(fwd_info);
|
||||
}
|
||||
|
||||
|
@ -87,10 +83,6 @@ static void diagfwd_cntl_close(struct diagfwd_info *fwd_info)
|
|||
{
|
||||
if (!fwd_info)
|
||||
return;
|
||||
if (driver->logging_mode == MEMORY_DEVICE_MODE) {
|
||||
diag_notify_md_client(PERIPHERAL_MASK(fwd_info->peripheral),
|
||||
DIAG_STATUS_CLOSED);
|
||||
}
|
||||
diag_cntl_channel_close(fwd_info);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue