Commit da1542b0 authored by Rick Farrington's avatar Rick Farrington Committed by David S. Miller

liquidio: update debug console logging mechanism

- remove logging dependency upon global func octeon_console_debug_enabled()
- abstract debug console logging using console structure (via function ptr)
  to allow for more flexible logging
Signed-off-by: default avatarRick Farrington <ricardo.farrington@cavium.com>
Signed-off-by: default avatarRaghu Vatsavayi <raghu.vatsavayi@cavium.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f5b58948
...@@ -73,7 +73,7 @@ MODULE_PARM_DESC(console_bitmask, ...@@ -73,7 +73,7 @@ MODULE_PARM_DESC(console_bitmask,
* @param console console to check * @param console console to check
* @returns 1 = enabled. 0 otherwise * @returns 1 = enabled. 0 otherwise
*/ */
int octeon_console_debug_enabled(u32 console) static int octeon_console_debug_enabled(u32 console)
{ {
return (console_bitmask >> (console)) & 0x1; return (console_bitmask >> (console)) & 0x1;
} }
...@@ -185,6 +185,9 @@ struct octeon_device_priv { ...@@ -185,6 +185,9 @@ struct octeon_device_priv {
static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs); static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs);
#endif #endif
static int octeon_dbg_console_print(struct octeon_device *oct, u32 console_num,
char *prefix, char *suffix);
static int octeon_device_init(struct octeon_device *); static int octeon_device_init(struct octeon_device *);
static int liquidio_stop(struct net_device *netdev); static int liquidio_stop(struct net_device *netdev);
static void liquidio_remove(struct pci_dev *pdev); static void liquidio_remove(struct pci_dev *pdev);
...@@ -4556,6 +4559,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev) ...@@ -4556,6 +4559,7 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
int j, ret; int j, ret;
int fw_loaded = 0; int fw_loaded = 0;
char bootcmd[] = "\n"; char bootcmd[] = "\n";
char *dbg_enb = NULL;
struct octeon_device_priv *oct_priv = struct octeon_device_priv *oct_priv =
(struct octeon_device_priv *)octeon_dev->priv; (struct octeon_device_priv *)octeon_dev->priv;
atomic_set(&octeon_dev->status, OCT_DEV_BEGIN_STATE); atomic_set(&octeon_dev->status, OCT_DEV_BEGIN_STATE);
...@@ -4762,10 +4766,19 @@ static int octeon_device_init(struct octeon_device *octeon_dev) ...@@ -4762,10 +4766,19 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
dev_err(&octeon_dev->pci_dev->dev, "Could not access board consoles\n"); dev_err(&octeon_dev->pci_dev->dev, "Could not access board consoles\n");
return 1; return 1;
} }
ret = octeon_add_console(octeon_dev, 0); /* If console debug enabled, specify empty string to use default
* enablement ELSE specify NULL string for 'disabled'.
*/
dbg_enb = octeon_console_debug_enabled(0) ? "" : NULL;
ret = octeon_add_console(octeon_dev, 0, dbg_enb);
if (ret) { if (ret) {
dev_err(&octeon_dev->pci_dev->dev, "Could not access board console\n"); dev_err(&octeon_dev->pci_dev->dev, "Could not access board console\n");
return 1; return 1;
} else if (octeon_console_debug_enabled(0)) {
/* If console was added AND we're logging console output
* then set our console print function.
*/
octeon_dev->console[0].print = octeon_dbg_console_print;
} }
atomic_set(&octeon_dev->status, OCT_DEV_CONSOLE_INIT_DONE); atomic_set(&octeon_dev->status, OCT_DEV_CONSOLE_INIT_DONE);
...@@ -4800,6 +4813,33 @@ static int octeon_device_init(struct octeon_device *octeon_dev) ...@@ -4800,6 +4813,33 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
return 0; return 0;
} }
/**
* \brief Debug console print function
* @param octeon_dev octeon device
* @param console_num console number
* @param prefix first portion of line to display
* @param suffix second portion of line to display
*
* The OCTEON debug console outputs entire lines (excluding '\n').
* Normally, the line will be passed in the 'prefix' parameter.
* However, due to buffering, it is possible for a line to be split into two
* parts, in which case they will be passed as the 'prefix' parameter and
* 'suffix' parameter.
*/
static int octeon_dbg_console_print(struct octeon_device *oct, u32 console_num,
char *prefix, char *suffix)
{
if (prefix && suffix)
dev_info(&oct->pci_dev->dev, "%u: %s%s\n", console_num, prefix,
suffix);
else if (prefix)
dev_info(&oct->pci_dev->dev, "%u: %s\n", console_num, prefix);
else if (suffix)
dev_info(&oct->pci_dev->dev, "%u: %s\n", console_num, suffix);
return 0;
}
/** /**
* \brief Exits the module * \brief Exits the module
*/ */
......
...@@ -437,20 +437,31 @@ static void output_console_line(struct octeon_device *oct, ...@@ -437,20 +437,31 @@ static void output_console_line(struct octeon_device *oct,
{ {
char *line; char *line;
s32 i; s32 i;
size_t len;
line = console_buffer; line = console_buffer;
for (i = 0; i < bytes_read; i++) { for (i = 0; i < bytes_read; i++) {
/* Output a line at a time, prefixed */ /* Output a line at a time, prefixed */
if (console_buffer[i] == '\n') { if (console_buffer[i] == '\n') {
console_buffer[i] = '\0'; console_buffer[i] = '\0';
if (console->leftover[0]) { /* We need to output 'line', prefaced by 'leftover'.
dev_info(&oct->pci_dev->dev, "%lu: %s%s\n", * However, it is possible we're being called to
console_num, console->leftover, * output 'leftover' by itself (in the case of nothing
* having been read from the console).
*
* To avoid duplication, check for this condition.
*/
if (console->leftover[0] &&
(line != console->leftover)) {
if (console->print)
(*console->print)(oct, (u32)console_num,
console->leftover,
line); line);
console->leftover[0] = '\0'; console->leftover[0] = '\0';
} else { } else {
dev_info(&oct->pci_dev->dev, "%lu: %s\n", if (console->print)
console_num, line); (*console->print)(oct, (u32)console_num,
line, NULL);
} }
line = &console_buffer[i + 1]; line = &console_buffer[i + 1];
} }
...@@ -459,13 +470,16 @@ static void output_console_line(struct octeon_device *oct, ...@@ -459,13 +470,16 @@ static void output_console_line(struct octeon_device *oct,
/* Save off any leftovers */ /* Save off any leftovers */
if (line != &console_buffer[bytes_read]) { if (line != &console_buffer[bytes_read]) {
console_buffer[bytes_read] = '\0'; console_buffer[bytes_read] = '\0';
strcpy(console->leftover, line); len = strlen(console->leftover);
strncpy(&console->leftover[len], line,
sizeof(console->leftover) - len);
} }
} }
static void check_console(struct work_struct *work) static void check_console(struct work_struct *work)
{ {
s32 bytes_read, tries, total_read; s32 bytes_read, tries, total_read;
size_t len;
struct octeon_console *console; struct octeon_console *console;
struct cavium_wk *wk = (struct cavium_wk *)work; struct cavium_wk *wk = (struct cavium_wk *)work;
struct octeon_device *oct = (struct octeon_device *)wk->ctxptr; struct octeon_device *oct = (struct octeon_device *)wk->ctxptr;
...@@ -487,7 +501,7 @@ static void check_console(struct work_struct *work) ...@@ -487,7 +501,7 @@ static void check_console(struct work_struct *work)
total_read += bytes_read; total_read += bytes_read;
if (console->waiting) if (console->waiting)
octeon_console_handle_result(oct, console_num); octeon_console_handle_result(oct, console_num);
if (octeon_console_debug_enabled(console_num)) { if (console->print) {
output_console_line(oct, console, console_num, output_console_line(oct, console, console_num,
console_buffer, bytes_read); console_buffer, bytes_read);
} }
...@@ -502,10 +516,13 @@ static void check_console(struct work_struct *work) ...@@ -502,10 +516,13 @@ static void check_console(struct work_struct *work)
/* If nothing is read after polling the console, /* If nothing is read after polling the console,
* output any leftovers if any * output any leftovers if any
*/ */
if (octeon_console_debug_enabled(console_num) && if (console->print && (total_read == 0) &&
(total_read == 0) && (console->leftover[0])) { (console->leftover[0])) {
dev_info(&oct->pci_dev->dev, "%u: %s\n", /* append '\n' as terminator for 'output_console_line' */
console_num, console->leftover); len = strlen(console->leftover);
console->leftover[len] = '\n';
output_console_line(oct, console, console_num,
console->leftover, (s32)(len + 1));
console->leftover[0] = '\0'; console->leftover[0] = '\0';
} }
...@@ -557,7 +574,8 @@ int octeon_init_consoles(struct octeon_device *oct) ...@@ -557,7 +574,8 @@ int octeon_init_consoles(struct octeon_device *oct)
return ret; return ret;
} }
int octeon_add_console(struct octeon_device *oct, u32 console_num) int octeon_add_console(struct octeon_device *oct, u32 console_num,
char *dbg_enb)
{ {
int ret = 0; int ret = 0;
u32 delay; u32 delay;
...@@ -599,11 +617,11 @@ int octeon_add_console(struct octeon_device *oct, u32 console_num) ...@@ -599,11 +617,11 @@ int octeon_add_console(struct octeon_device *oct, u32 console_num)
delay = OCTEON_CONSOLE_POLL_INTERVAL_MS; delay = OCTEON_CONSOLE_POLL_INTERVAL_MS;
schedule_delayed_work(work, msecs_to_jiffies(delay)); schedule_delayed_work(work, msecs_to_jiffies(delay));
if (octeon_console_debug_enabled(console_num)) { /* an empty string means use default debug console enablement */
ret = octeon_console_send_cmd(oct, if (dbg_enb && !dbg_enb[0])
"setenv pci_console_active 1", dbg_enb = "setenv pci_console_active 1";
2000); if (dbg_enb)
} ret = octeon_console_send_cmd(oct, dbg_enb, 2000);
console->active = 1; console->active = 1;
} }
......
...@@ -194,6 +194,8 @@ struct octeon_reg_list { ...@@ -194,6 +194,8 @@ struct octeon_reg_list {
}; };
#define OCTEON_CONSOLE_MAX_READ_BYTES 512 #define OCTEON_CONSOLE_MAX_READ_BYTES 512
typedef int (*octeon_console_print_fn)(struct octeon_device *oct,
u32 num, char *pre, char *suf);
struct octeon_console { struct octeon_console {
u32 active; u32 active;
u32 waiting; u32 waiting;
...@@ -201,6 +203,7 @@ struct octeon_console { ...@@ -201,6 +203,7 @@ struct octeon_console {
u32 buffer_size; u32 buffer_size;
u64 input_base_addr; u64 input_base_addr;
u64 output_base_addr; u64 output_base_addr;
octeon_console_print_fn print;
char leftover[OCTEON_CONSOLE_MAX_READ_BYTES]; char leftover[OCTEON_CONSOLE_MAX_READ_BYTES];
}; };
...@@ -740,16 +743,20 @@ int octeon_wait_for_bootloader(struct octeon_device *oct, ...@@ -740,16 +743,20 @@ int octeon_wait_for_bootloader(struct octeon_device *oct,
*/ */
int octeon_init_consoles(struct octeon_device *oct); int octeon_init_consoles(struct octeon_device *oct);
int octeon_console_debug_enabled(u32 console);
/** /**
* Adds access to a console to the device. * Adds access to a console to the device.
* *
* @param oct which octeon to add to * @param oct: which octeon to add to
* @param console_num which console * @param console_num: which console
* @param dbg_enb: ptr to debug enablement string, one of:
* * NULL for no debug output (i.e. disabled)
* * empty string enables debug output (via default method)
* * specific string to enable debug console output
*
* @return Zero on success, negative on failure. * @return Zero on success, negative on failure.
*/ */
int octeon_add_console(struct octeon_device *oct, u32 console_num); int octeon_add_console(struct octeon_device *oct, u32 console_num,
char *dbg_enb);
/** write or read from a console */ /** write or read from a console */
int octeon_console_write(struct octeon_device *oct, u32 console_num, int octeon_console_write(struct octeon_device *oct, u32 console_num,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment