diff options
author | Linas Vepstas <linas@austin.ibm.com> | 2007-06-11 14:48:55 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-08 22:16:41 -0400 |
commit | 9948357d49c84102151bc14233c2f489552c1f57 (patch) | |
tree | 526313c77056d5c08d1a34bed86a3b0e201890cc /drivers | |
parent | e6311d855e100184d42c0165ab9d5215fd792c89 (diff) |
spidernet: enhance the dump routine
Crazy device problems are hard to debug, when one does not have
good trace info. This patch makes a major enhancement to the
device dump routine.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/spider_net.c | 78 |
1 files changed, 70 insertions, 8 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 4c8243a7f9c1..4d180072de4d 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -1022,34 +1022,94 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, | |||
1022 | netif_receive_skb(skb); | 1022 | netif_receive_skb(skb); |
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | #ifdef DEBUG | ||
1026 | static void show_rx_chain(struct spider_net_card *card) | 1025 | static void show_rx_chain(struct spider_net_card *card) |
1027 | { | 1026 | { |
1028 | struct spider_net_descr_chain *chain = &card->rx_chain; | 1027 | struct spider_net_descr_chain *chain = &card->rx_chain; |
1029 | struct spider_net_descr *start= chain->tail; | 1028 | struct spider_net_descr *start= chain->tail; |
1030 | struct spider_net_descr *descr= start; | 1029 | struct spider_net_descr *descr= start; |
1030 | struct spider_net_hw_descr *hwd = start->hwdescr; | ||
1031 | struct device *dev = &card->netdev->dev; | ||
1032 | u32 curr_desc, next_desc; | ||
1031 | int status; | 1033 | int status; |
1032 | 1034 | ||
1035 | int tot = 0; | ||
1033 | int cnt = 0; | 1036 | int cnt = 0; |
1034 | int cstat = spider_net_get_descr_status(descr); | 1037 | int off = start - chain->ring; |
1035 | printk(KERN_INFO "RX chain tail at descr=%ld\n", | 1038 | int cstat = hwd->dmac_cmd_status; |
1036 | (start - card->descr) - card->tx_chain.num_desc); | 1039 | |
1040 | dev_info(dev, "Total number of descrs=%d\n", | ||
1041 | chain->num_desc); | ||
1042 | dev_info(dev, "Chain tail located at descr=%d, status=0x%x\n", | ||
1043 | off, cstat); | ||
1044 | |||
1045 | curr_desc = spider_net_read_reg(card, SPIDER_NET_GDACTDPA); | ||
1046 | next_desc = spider_net_read_reg(card, SPIDER_NET_GDACNEXTDA); | ||
1047 | |||
1037 | status = cstat; | 1048 | status = cstat; |
1038 | do | 1049 | do |
1039 | { | 1050 | { |
1040 | status = spider_net_get_descr_status(descr); | 1051 | hwd = descr->hwdescr; |
1052 | off = descr - chain->ring; | ||
1053 | status = hwd->dmac_cmd_status; | ||
1054 | |||
1055 | if (descr == chain->head) | ||
1056 | dev_info(dev, "Chain head is at %d, head status=0x%x\n", | ||
1057 | off, status); | ||
1058 | |||
1059 | if (curr_desc == descr->bus_addr) | ||
1060 | dev_info(dev, "HW curr desc (GDACTDPA) is at %d, status=0x%x\n", | ||
1061 | off, status); | ||
1062 | |||
1063 | if (next_desc == descr->bus_addr) | ||
1064 | dev_info(dev, "HW next desc (GDACNEXTDA) is at %d, status=0x%x\n", | ||
1065 | off, status); | ||
1066 | |||
1067 | if (hwd->next_descr_addr == 0) | ||
1068 | dev_info(dev, "chain is cut at %d\n", off); | ||
1069 | |||
1041 | if (cstat != status) { | 1070 | if (cstat != status) { |
1042 | printk(KERN_INFO "Have %d descrs with stat=x%08x\n", cnt, cstat); | 1071 | int from = (chain->num_desc + off - cnt) % chain->num_desc; |
1072 | int to = (chain->num_desc + off - 1) % chain->num_desc; | ||
1073 | dev_info(dev, "Have %d (from %d to %d) descrs " | ||
1074 | "with stat=0x%08x\n", cnt, from, to, cstat); | ||
1043 | cstat = status; | 1075 | cstat = status; |
1044 | cnt = 0; | 1076 | cnt = 0; |
1045 | } | 1077 | } |
1078 | |||
1046 | cnt ++; | 1079 | cnt ++; |
1080 | tot ++; | ||
1081 | descr = descr->next; | ||
1082 | } while (descr != start); | ||
1083 | |||
1084 | dev_info(dev, "Last %d descrs with stat=0x%08x " | ||
1085 | "for a total of %d descrs\n", cnt, cstat, tot); | ||
1086 | |||
1087 | #ifdef DEBUG | ||
1088 | /* Now dump the whole ring */ | ||
1089 | descr = start; | ||
1090 | do | ||
1091 | { | ||
1092 | struct spider_net_hw_descr *hwd = descr->hwdescr; | ||
1093 | status = spider_net_get_descr_status(hwd); | ||
1094 | cnt = descr - chain->ring; | ||
1095 | dev_info(dev, "Descr %d stat=0x%08x skb=%p\n", | ||
1096 | cnt, status, descr->skb); | ||
1097 | dev_info(dev, "bus addr=%08x buf addr=%08x sz=%d\n", | ||
1098 | descr->bus_addr, hwd->buf_addr, hwd->buf_size); | ||
1099 | dev_info(dev, "next=%08x result sz=%d valid sz=%d\n", | ||
1100 | hwd->next_descr_addr, hwd->result_size, | ||
1101 | hwd->valid_size); | ||
1102 | dev_info(dev, "dmac=%08x data stat=%08x data err=%08x\n", | ||
1103 | hwd->dmac_cmd_status, hwd->data_status, | ||
1104 | hwd->data_error); | ||
1105 | dev_info(dev, "\n"); | ||
1106 | |||
1047 | descr = descr->next; | 1107 | descr = descr->next; |
1048 | } while (descr != start); | 1108 | } while (descr != start); |
1049 | printk(KERN_INFO "Last %d descrs with stat=x%08x\n", cnt, cstat); | ||
1050 | } | ||
1051 | #endif | 1109 | #endif |
1052 | 1110 | ||
1111 | } | ||
1112 | |||
1053 | /** | 1113 | /** |
1054 | * spider_net_resync_head_ptr - Advance head ptr past empty descrs | 1114 | * spider_net_resync_head_ptr - Advance head ptr past empty descrs |
1055 | * | 1115 | * |
@@ -1195,6 +1255,8 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1195 | return 1; | 1255 | return 1; |
1196 | 1256 | ||
1197 | bad_desc: | 1257 | bad_desc: |
1258 | if (netif_msg_rx_err(card)) | ||
1259 | show_rx_chain(card); | ||
1198 | dev_kfree_skb_irq(descr->skb); | 1260 | dev_kfree_skb_irq(descr->skb); |
1199 | descr->skb = NULL; | 1261 | descr->skb = NULL; |
1200 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1262 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |