diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2009-12-14 17:12:20 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-21 18:56:18 -0500 |
commit | b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4b (patch) | |
tree | f841ac15c38fe72b53bd80339962d7677d5b3566 /drivers/net/wireless/iwlwifi/iwl3945-base.c | |
parent | a9e1cb6a78ea8a74c49bf76726a2942f636a833b (diff) |
iwlwifi: on-screen event log dump
This feature enables the on-screen uCode event log dump. The original
method will append the event log to syslog; with this capability,
we also enable the user to write script to capture the
events which provide additional flexibility to help uCode debugging
Method
1) change to debugfs directory (sys/kernel/debug/phyX/iwlagn/data)
2) #cat log_event
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 101 |
1 files changed, 71 insertions, 30 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2a28a1f8b1fe..f7c7ff4264fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1560,8 +1560,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
1560 | * iwl3945_print_event_log - Dump error event log to syslog | 1560 | * iwl3945_print_event_log - Dump error event log to syslog |
1561 | * | 1561 | * |
1562 | */ | 1562 | */ |
1563 | static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | 1563 | static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, |
1564 | u32 num_events, u32 mode) | 1564 | u32 num_events, u32 mode, |
1565 | int pos, char **buf, size_t bufsz) | ||
1565 | { | 1566 | { |
1566 | u32 i; | 1567 | u32 i; |
1567 | u32 base; /* SRAM byte address of event log header */ | 1568 | u32 base; /* SRAM byte address of event log header */ |
@@ -1571,7 +1572,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1571 | unsigned long reg_flags; | 1572 | unsigned long reg_flags; |
1572 | 1573 | ||
1573 | if (num_events == 0) | 1574 | if (num_events == 0) |
1574 | return; | 1575 | return pos; |
1575 | 1576 | ||
1576 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 1577 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
1577 | 1578 | ||
@@ -1597,26 +1598,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1597 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1598 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1598 | if (mode == 0) { | 1599 | if (mode == 0) { |
1599 | /* data, ev */ | 1600 | /* data, ev */ |
1600 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); | 1601 | if (bufsz) { |
1601 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); | 1602 | pos += scnprintf(*buf + pos, bufsz - pos, |
1603 | "0x%08x:%04u\n", | ||
1604 | time, ev); | ||
1605 | } else { | ||
1606 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); | ||
1607 | trace_iwlwifi_dev_ucode_event(priv, 0, | ||
1608 | time, ev); | ||
1609 | } | ||
1602 | } else { | 1610 | } else { |
1603 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1611 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1604 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); | 1612 | if (bufsz) { |
1605 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); | 1613 | pos += scnprintf(*buf + pos, bufsz - pos, |
1614 | "%010u:0x%08x:%04u\n", | ||
1615 | time, data, ev); | ||
1616 | } else { | ||
1617 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", | ||
1618 | time, data, ev); | ||
1619 | trace_iwlwifi_dev_ucode_event(priv, time, | ||
1620 | data, ev); | ||
1621 | } | ||
1606 | } | 1622 | } |
1607 | } | 1623 | } |
1608 | 1624 | ||
1609 | /* Allow device to power down */ | 1625 | /* Allow device to power down */ |
1610 | iwl_release_nic_access(priv); | 1626 | iwl_release_nic_access(priv); |
1611 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | 1627 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); |
1628 | return pos; | ||
1612 | } | 1629 | } |
1613 | 1630 | ||
1614 | /** | 1631 | /** |
1615 | * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog | 1632 | * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog |
1616 | */ | 1633 | */ |
1617 | static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | 1634 | static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, |
1618 | u32 num_wraps, u32 next_entry, | 1635 | u32 num_wraps, u32 next_entry, |
1619 | u32 size, u32 mode) | 1636 | u32 size, u32 mode, |
1637 | int pos, char **buf, size_t bufsz) | ||
1620 | { | 1638 | { |
1621 | /* | 1639 | /* |
1622 | * display the newest DEFAULT_LOG_ENTRIES entries | 1640 | * display the newest DEFAULT_LOG_ENTRIES entries |
@@ -1624,21 +1642,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1624 | */ | 1642 | */ |
1625 | if (num_wraps) { | 1643 | if (num_wraps) { |
1626 | if (next_entry < size) { | 1644 | if (next_entry < size) { |
1627 | iwl3945_print_event_log(priv, | 1645 | pos = iwl3945_print_event_log(priv, |
1628 | capacity - (size - next_entry), | 1646 | capacity - (size - next_entry), |
1629 | size - next_entry, mode); | 1647 | size - next_entry, mode, |
1630 | iwl3945_print_event_log(priv, 0, | 1648 | pos, buf, bufsz); |
1631 | next_entry, mode); | 1649 | pos = iwl3945_print_event_log(priv, 0, |
1650 | next_entry, mode, | ||
1651 | pos, buf, bufsz); | ||
1632 | } else | 1652 | } else |
1633 | iwl3945_print_event_log(priv, next_entry - size, | 1653 | pos = iwl3945_print_event_log(priv, next_entry - size, |
1634 | size, mode); | 1654 | size, mode, |
1655 | pos, buf, bufsz); | ||
1635 | } else { | 1656 | } else { |
1636 | if (next_entry < size) | 1657 | if (next_entry < size) |
1637 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 1658 | pos = iwl3945_print_event_log(priv, 0, |
1659 | next_entry, mode, | ||
1660 | pos, buf, bufsz); | ||
1638 | else | 1661 | else |
1639 | iwl3945_print_event_log(priv, next_entry - size, | 1662 | pos = iwl3945_print_event_log(priv, next_entry - size, |
1640 | size, mode); | 1663 | size, mode, |
1664 | pos, buf, bufsz); | ||
1641 | } | 1665 | } |
1666 | return pos; | ||
1642 | } | 1667 | } |
1643 | 1668 | ||
1644 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | 1669 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ |
@@ -1646,7 +1671,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1646 | 1671 | ||
1647 | #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) | 1672 | #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) |
1648 | 1673 | ||
1649 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | 1674 | int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
1675 | char **buf, bool display) | ||
1650 | { | 1676 | { |
1651 | u32 base; /* SRAM byte address of event log header */ | 1677 | u32 base; /* SRAM byte address of event log header */ |
1652 | u32 capacity; /* event log capacity in # entries */ | 1678 | u32 capacity; /* event log capacity in # entries */ |
@@ -1654,11 +1680,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1654 | u32 num_wraps; /* # times uCode wrapped to top of log */ | 1680 | u32 num_wraps; /* # times uCode wrapped to top of log */ |
1655 | u32 next_entry; /* index of next entry to be written by uCode */ | 1681 | u32 next_entry; /* index of next entry to be written by uCode */ |
1656 | u32 size; /* # entries that we'll print */ | 1682 | u32 size; /* # entries that we'll print */ |
1683 | int pos = 0; | ||
1684 | size_t bufsz = 0; | ||
1657 | 1685 | ||
1658 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 1686 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
1659 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { | 1687 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { |
1660 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); | 1688 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); |
1661 | return; | 1689 | return pos; |
1662 | } | 1690 | } |
1663 | 1691 | ||
1664 | /* event log header */ | 1692 | /* event log header */ |
@@ -1684,7 +1712,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1684 | /* bail out if nothing in log */ | 1712 | /* bail out if nothing in log */ |
1685 | if (size == 0) { | 1713 | if (size == 0) { |
1686 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | 1714 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
1687 | return; | 1715 | return pos; |
1688 | } | 1716 | } |
1689 | 1717 | ||
1690 | #ifdef CONFIG_IWLWIFI_DEBUG | 1718 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -1700,25 +1728,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1700 | size); | 1728 | size); |
1701 | 1729 | ||
1702 | #ifdef CONFIG_IWLWIFI_DEBUG | 1730 | #ifdef CONFIG_IWLWIFI_DEBUG |
1731 | if (display) { | ||
1732 | if (full_log) | ||
1733 | bufsz = capacity * 48; | ||
1734 | else | ||
1735 | bufsz = size * 48; | ||
1736 | *buf = kmalloc(bufsz, GFP_KERNEL); | ||
1737 | if (!*buf) | ||
1738 | return pos; | ||
1739 | } | ||
1703 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | 1740 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { |
1704 | /* if uCode has wrapped back to top of log, | 1741 | /* if uCode has wrapped back to top of log, |
1705 | * start at the oldest entry, | 1742 | * start at the oldest entry, |
1706 | * i.e the next one that uCode would fill. | 1743 | * i.e the next one that uCode would fill. |
1707 | */ | 1744 | */ |
1708 | if (num_wraps) | 1745 | if (num_wraps) |
1709 | iwl3945_print_event_log(priv, next_entry, | 1746 | pos = iwl3945_print_event_log(priv, next_entry, |
1710 | capacity - next_entry, mode); | 1747 | capacity - next_entry, mode, |
1748 | pos, buf, bufsz); | ||
1711 | 1749 | ||
1712 | /* (then/else) start at top of log */ | 1750 | /* (then/else) start at top of log */ |
1713 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 1751 | pos = iwl3945_print_event_log(priv, 0, next_entry, mode, |
1752 | pos, buf, bufsz); | ||
1714 | } else | 1753 | } else |
1715 | iwl3945_print_last_event_logs(priv, capacity, num_wraps, | 1754 | pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, |
1716 | next_entry, size, mode); | 1755 | next_entry, size, mode, |
1756 | pos, buf, bufsz); | ||
1717 | #else | 1757 | #else |
1718 | iwl3945_print_last_event_logs(priv, capacity, num_wraps, | 1758 | pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, |
1719 | next_entry, size, mode); | 1759 | next_entry, size, mode, |
1760 | pos, buf, bufsz); | ||
1720 | #endif | 1761 | #endif |
1721 | 1762 | return pos; | |
1722 | } | 1763 | } |
1723 | 1764 | ||
1724 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) | 1765 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) |