PTI feature to allow user to name and mark masterchannel request.

This feature addition provides a new parameter in
pti_request_masterchannel() to allow the user
to provide their own name to mark the request when
the trace is viewed in a PTI SW trace viewer
(like MPTA).  If a name is not provided and
NULL is provided, the 'current' process name is used.
API function header documentation documents this.

Signed-off-by: Jeremy Rocher <rocher.jeremy@gmail.com>
Signed-off-by: J Freyensee <james_p_freyensee@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
J Freyensee 2011-06-17 15:09:53 -07:00 коммит произвёл Greg Kroah-Hartman
Родитель fc360ee7a7
Коммит 8168e9c2de
2 изменённых файлов: 62 добавлений и 40 удалений

Просмотреть файл

@ -146,45 +146,54 @@ static void pti_write_to_aperture(struct pti_masterchannel *mc,
/** /**
* pti_control_frame_built_and_sent()- control frame build and send function. * pti_control_frame_built_and_sent()- control frame build and send function.
* *
* @mc: The master / channel structure on which the function * @mc: The master / channel structure on which the function
* built a control frame. * built a control frame.
* @thread_name: The thread name associated with the master / channel or
* 'NULL' if using the 'current' global variable.
* *
* To be able to post process the PTI contents on host side, a control frame * To be able to post process the PTI contents on host side, a control frame
* is added before sending any PTI content. So the host side knows on * is added before sending any PTI content. So the host side knows on
* each PTI frame the name of the thread using a dedicated master / channel. * each PTI frame the name of the thread using a dedicated master / channel.
* The thread name is retrieved from the 'current' global variable. * The thread name is retrieved from 'current' global variable if 'thread_name'
* is 'NULL', else it is retrieved from 'thread_name' parameter.
* This function builds this frame and sends it to a master ID CONTROL_ID. * This function builds this frame and sends it to a master ID CONTROL_ID.
* The overhead is only 32 bytes since the driver only writes to HW * The overhead is only 32 bytes since the driver only writes to HW
* in 32 byte chunks. * in 32 byte chunks.
*/ */
static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc,
static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc) const char *thread_name)
{ {
struct pti_masterchannel mccontrol = {.master = CONTROL_ID, struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
.channel = 0}; .channel = 0};
const char *thread_name_p;
const char *control_format = "%3d %3d %s"; const char *control_format = "%3d %3d %s";
u8 control_frame[CONTROL_FRAME_LEN]; u8 control_frame[CONTROL_FRAME_LEN];
/* if (!thread_name) {
* Since we access the comm member in current's task_struct, /*
* we only need to be as large as what 'comm' in that * Since we access the comm member in current's task_struct,
* structure is. * we only need to be as large as what 'comm' in that
*/ * structure is.
char comm[TASK_COMM_LEN]; */
char comm[TASK_COMM_LEN];
if (!in_interrupt()) if (!in_interrupt())
get_task_comm(comm, current); get_task_comm(comm, current);
else else
strncpy(comm, "Interrupt", TASK_COMM_LEN); strncpy(comm, "Interrupt", TASK_COMM_LEN);
/* Absolutely ensure our buffer is zero terminated. */ /* Absolutely ensure our buffer is zero terminated. */
comm[TASK_COMM_LEN-1] = 0; comm[TASK_COMM_LEN-1] = 0;
thread_name_p = comm;
} else {
thread_name_p = thread_name;
}
mccontrol.channel = pti_control_channel; mccontrol.channel = pti_control_channel;
pti_control_channel = (pti_control_channel + 1) & 0x7f; pti_control_channel = (pti_control_channel + 1) & 0x7f;
snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master, snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
mc->channel, comm); mc->channel, thread_name_p);
pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame)); pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
} }
@ -206,18 +215,20 @@ static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
const unsigned char *buf, const unsigned char *buf,
int len) int len)
{ {
pti_control_frame_built_and_sent(mc); pti_control_frame_built_and_sent(mc, NULL);
pti_write_to_aperture(mc, (u8 *)buf, len); pti_write_to_aperture(mc, (u8 *)buf, len);
} }
/** /**
* get_id()- Allocate a master and channel ID. * get_id()- Allocate a master and channel ID.
* *
* @id_array: an array of bits representing what channel * @id_array: an array of bits representing what channel
* id's are allocated for writing. * id's are allocated for writing.
* @max_ids: The max amount of available write IDs to use. * @max_ids: The max amount of available write IDs to use.
* @base_id: The starting SW channel ID, based on the Intel * @base_id: The starting SW channel ID, based on the Intel
* PTI arch. * PTI arch.
* @thread_name: The thread name associated with the master / channel or
* 'NULL' if using the 'current' global variable.
* *
* Returns: * Returns:
* pti_masterchannel struct with master, channel ID address * pti_masterchannel struct with master, channel ID address
@ -227,7 +238,10 @@ static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
* channel id. The bit is one if the id is taken and 0 if free. For * channel id. The bit is one if the id is taken and 0 if free. For
* every master there are 128 channel id's. * every master there are 128 channel id's.
*/ */
static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id) static struct pti_masterchannel *get_id(u8 *id_array,
int max_ids,
int base_id,
const char *thread_name)
{ {
struct pti_masterchannel *mc; struct pti_masterchannel *mc;
int i, j, mask; int i, j, mask;
@ -257,7 +271,7 @@ static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id)
mc->master = base_id; mc->master = base_id;
mc->channel = ((i & 0xf)<<3) + j; mc->channel = ((i & 0xf)<<3) + j;
/* write new master Id / channel Id allocation to channel control */ /* write new master Id / channel Id allocation to channel control */
pti_control_frame_built_and_sent(mc); pti_control_frame_built_and_sent(mc, thread_name);
return mc; return mc;
} }
@ -273,18 +287,22 @@ static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id)
* a master, channel ID address * a master, channel ID address
* to write to PTI HW. * to write to PTI HW.
* *
* @type: 0- request Application master, channel aperture ID write address. * @type: 0- request Application master, channel aperture ID
* 1- request OS master, channel aperture ID write * write address.
* address. * 1- request OS master, channel aperture ID write
* 2- request Modem master, channel aperture ID * address.
* write address. * 2- request Modem master, channel aperture ID
* Other values, error. * write address.
* Other values, error.
* @thread_name: The thread name associated with the master / channel or
* 'NULL' if using the 'current' global variable.
* *
* Returns: * Returns:
* pti_masterchannel struct * pti_masterchannel struct
* 0 for error * 0 for error
*/ */
struct pti_masterchannel *pti_request_masterchannel(u8 type) struct pti_masterchannel *pti_request_masterchannel(u8 type,
const char *thread_name)
{ {
struct pti_masterchannel *mc; struct pti_masterchannel *mc;
@ -293,15 +311,18 @@ struct pti_masterchannel *pti_request_masterchannel(u8 type)
switch (type) { switch (type) {
case 0: case 0:
mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID); mc = get_id(drv_data->ia_app, MAX_APP_IDS,
APP_BASE_ID, thread_name);
break; break;
case 1: case 1:
mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID); mc = get_id(drv_data->ia_os, MAX_OS_IDS,
OS_BASE_ID, thread_name);
break; break;
case 2: case 2:
mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID); mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS,
MODEM_BASE_ID, thread_name);
break; break;
default: default:
mc = NULL; mc = NULL;
@ -471,9 +492,9 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENOMEM; return -ENOMEM;
if (idx == PTITTY_MINOR_START) if (idx == PTITTY_MINOR_START)
pti_tty_data->mc = pti_request_masterchannel(0); pti_tty_data->mc = pti_request_masterchannel(0, NULL);
else else
pti_tty_data->mc = pti_request_masterchannel(2); pti_tty_data->mc = pti_request_masterchannel(2, NULL);
if (pti_tty_data->mc == NULL) if (pti_tty_data->mc == NULL)
return -ENXIO; return -ENXIO;
@ -560,7 +581,7 @@ static int pti_char_open(struct inode *inode, struct file *filp)
* before assigning the value to filp->private_data. * before assigning the value to filp->private_data.
* Slightly easier to debug if this driver needs debugging. * Slightly easier to debug if this driver needs debugging.
*/ */
mc = pti_request_masterchannel(0); mc = pti_request_masterchannel(0, NULL);
if (mc == NULL) if (mc == NULL)
return -ENOMEM; return -ENOMEM;
filp->private_data = mc; filp->private_data = mc;

Просмотреть файл

@ -36,7 +36,8 @@ struct pti_masterchannel {
/* the following functions are defined in misc/pti.c */ /* the following functions are defined in misc/pti.c */
void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count); void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count);
struct pti_masterchannel *pti_request_masterchannel(u8 type); struct pti_masterchannel *pti_request_masterchannel(u8 type,
const char *thread_name);
void pti_release_masterchannel(struct pti_masterchannel *mc); void pti_release_masterchannel(struct pti_masterchannel *mc);
#endif /*PTI_H_*/ #endif /*PTI_H_*/