Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe1c7c3a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: Make fixes in memory device mode"

parents 59c5e352 c951e85b
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -404,6 +404,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 {
@@ -419,13 +420,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 */
@@ -537,7 +531,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;
+82 −25
Original line number Diff line number Diff line
@@ -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);
	}
@@ -1104,13 +1119,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:
@@ -1130,30 +1146,39 @@ 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;
	}

	mutex_lock(&driver->diagchar_mutex);
	if (requested_mode == MEMORY_DEVICE_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);
		}
		driver->md_proc[DIAG_LOCAL_PROC].socket_process = NULL;
	/*
	 * 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 (new_mode == MEMORY_DEVICE_MODE)
		driver->md_client_info.client_process = current;
		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;
		}
	}

	mutex_lock(&driver->diagchar_mutex);
	diag_ws_reset(DIAG_WS_MUX);
@@ -1162,11 +1187,16 @@ 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,
@@ -1181,10 +1211,35 @@ static int diag_switch_logging(int requested_mode)
			   &driver->diag_real_time_work);
	}

	for (i = 0; i < DIAG_NUM_PROC; i++) {
	/*
	 * 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;
		if (requested_mode == SOCKET_MODE)
			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);
@@ -1464,10 +1519,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;
@@ -2848,8 +2905,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 −18
Original line number Diff line number Diff line
@@ -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)
@@ -67,6 +69,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);
}

@@ -98,37 +102,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 (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)
+0 −1
Original line number Diff line number Diff line
@@ -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
+0 −8
Original line number Diff line number Diff line
@@ -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);
}