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: Rick Farrington <ricardo.farrington@cavium.com> Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@cavium.com> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f5b589488e
commit
da1542b01b
@ -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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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
|
||||||
line);
|
* 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);
|
||||||
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,
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#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 {
|
|||||||
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,
|
|||||||
*/
|
*/
|
||||||
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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user