1The Intel MID PTI project is HW implemented in Intel Atom 2system-on-a-chip designs based on the Parallel Trace 3Interface for MIPI P1149.7 cJTAG standard. The kernel solution 4for this platform involves the following files: 5 6./include/linux/pti.h 7./drivers/.../n_tracesink.h 8./drivers/.../n_tracerouter.c 9./drivers/.../n_tracesink.c 10./drivers/.../pti.c 11 12pti.c is the driver that enables various debugging features 13popular on platforms from certain mobile manufacturers. 14n_tracerouter.c and n_tracesink.c allow extra system information to 15be collected and routed to the pti driver, such as trace 16debugging data from a modem. Although n_tracerouter 17and n_tracesink are a part of the complete PTI solution, 18these two line disciplines can work separately from 19pti.c and route any data stream from one /dev/tty node 20to another /dev/tty node via kernel-space. This provides 21a stable, reliable connection that will not break unless 22the user-space application shuts down (plus avoids 23kernel->user->kernel context switch overheads of routing 24data). 25 26An example debugging usage for this driver system: 27 *Hook /dev/ttyPTI0 to syslogd. Opening this port will also start 28 a console device to further capture debugging messages to PTI. 29 *Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW. 30 This is where n_tracerouter and n_tracesink are used. 31 *Hook /dev/pti to a user-level debugging application for writing 32 to PTI HW. 33 *Use mipi_* Kernel Driver API in other device drivers for 34 debugging to PTI by first requesting a PTI write address via 35 mipi_request_masterchannel(1). 36 37Below is example pseudo-code on how a 'privileged' application 38can hook up n_tracerouter and n_tracesink to any tty on 39a system. 'Privileged' means the application has enough 40privileges to successfully manipulate the ldisc drivers 41but is not just blindly executing as 'root'. Keep in mind 42the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter 43and n_tracesink line discpline drivers but is a generic 44operation for a program to use a line discpline driver 45on a tty port other than the default n_tty. 46 47/////////// To hook up n_tracerouter and n_tracesink ///////// 48 49// Note that n_tracerouter depends on n_tracesink. 50#include <errno.h> 51#define ONE_TTY "/dev/ttyOne" 52#define TWO_TTY "/dev/ttyTwo" 53 54// needed global to hand onto ldisc connection 55static int g_fd_source = -1; 56static int g_fd_sink = -1; 57 58// these two vars used to grab LDISC values from loaded ldisc drivers 59// in OS. Look at /proc/tty/ldiscs to get the right numbers from 60// the ldiscs loaded in the system. 61int source_ldisc_num, sink_ldisc_num = -1; 62int retval; 63 64g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W 65g_fd_sink = open(TWO_TTY, O_RDWR); // must be R/W 66 67if (g_fd_source <= 0) || (g_fd_sink <= 0) { 68 // doubt you'll want to use these exact error lines of code 69 printf("Error on open(). errno: %d\n",errno); 70 return errno; 71} 72 73retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num); 74if (retval < 0) { 75 printf("Error on ioctl(). errno: %d\n", errno); 76 return errno; 77} 78 79retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num); 80if (retval < 0) { 81 printf("Error on ioctl(). errno: %d\n", errno); 82 return errno; 83} 84 85/////////// To disconnect n_tracerouter and n_tracesink //////// 86 87// First make sure data through the ldiscs has stopped. 88 89// Second, disconnect ldiscs. This provides a 90// little cleaner shutdown on tty stack. 91sink_ldisc_num = 0; 92source_ldisc_num = 0; 93ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num); 94ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num); 95 96// Three, program closes connection, and cleanup: 97close(g_fd_uart); 98close(g_fd_gadget); 99g_fd_uart = g_fd_gadget = NULL; 100