aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wan
diff options
context:
space:
mode:
authorKrzysztof Halasa <khc@pm.waw.pl>2008-02-01 16:34:30 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-05 13:31:38 -0500
commit983e23041b28abb113862b2935a85cfb9aab4f5a (patch)
tree406e55e0657d308fb92b17dcaab0292b157c1c28 /drivers/net/wan
parentd2f4fbe2982b3b9e46deea8d7288ea8f8d7b5bc4 (diff)
Generic HDLC - fix kernel panic
Fixes kernel panic in Frame Relay mode Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/wan')
-rw-r--r--drivers/net/wan/hdlc_fr.c38
1 files changed, 18 insertions, 20 deletions
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 071a64cacd5c..51296c2b8b89 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -136,6 +136,10 @@ typedef struct pvc_device_struct {
136 }state; 136 }state;
137}pvc_device; 137}pvc_device;
138 138
139struct pvc_desc {
140 struct net_device_stats stats;
141 pvc_device *pvc;
142};
139 143
140struct frad_state { 144struct frad_state {
141 fr_proto settings; 145 fr_proto settings;
@@ -171,17 +175,20 @@ static inline void dlci_to_q922(u8 *hdr, u16 dlci)
171} 175}
172 176
173 177
174static inline struct frad_state * state(hdlc_device *hdlc) 178static inline struct frad_state* state(hdlc_device *hdlc)
175{ 179{
176 return(struct frad_state *)(hdlc->state); 180 return(struct frad_state *)(hdlc->state);
177} 181}
178 182
179 183static inline struct pvc_desc* pvcdev_to_desc(struct net_device *dev)
180static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
181{ 184{
182 return dev->priv; 185 return dev->priv;
183} 186}
184 187
188static inline struct net_device_stats* pvc_get_stats(struct net_device *dev)
189{
190 return &pvcdev_to_desc(dev)->stats;
191}
185 192
186static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) 193static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
187{ 194{
@@ -351,7 +358,7 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
351 358
352static int pvc_open(struct net_device *dev) 359static int pvc_open(struct net_device *dev)
353{ 360{
354 pvc_device *pvc = dev_to_pvc(dev); 361 pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
355 362
356 if ((pvc->frad->flags & IFF_UP) == 0) 363 if ((pvc->frad->flags & IFF_UP) == 0)
357 return -EIO; /* Frad must be UP in order to activate PVC */ 364 return -EIO; /* Frad must be UP in order to activate PVC */
@@ -371,7 +378,7 @@ static int pvc_open(struct net_device *dev)
371 378
372static int pvc_close(struct net_device *dev) 379static int pvc_close(struct net_device *dev)
373{ 380{
374 pvc_device *pvc = dev_to_pvc(dev); 381 pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
375 382
376 if (--pvc->open_count == 0) { 383 if (--pvc->open_count == 0) {
377 hdlc_device *hdlc = dev_to_hdlc(pvc->frad); 384 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
@@ -390,7 +397,7 @@ static int pvc_close(struct net_device *dev)
390 397
391static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 398static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
392{ 399{
393 pvc_device *pvc = dev_to_pvc(dev); 400 pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
394 fr_proto_pvc_info info; 401 fr_proto_pvc_info info;
395 402
396 if (ifr->ifr_settings.type == IF_GET_PROTO) { 403 if (ifr->ifr_settings.type == IF_GET_PROTO) {
@@ -416,17 +423,9 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
416 return -EINVAL; 423 return -EINVAL;
417} 424}
418 425
419
420static inline struct net_device_stats *pvc_get_stats(struct net_device *dev)
421{
422 return &dev_to_desc(dev)->stats;
423}
424
425
426
427static int pvc_xmit(struct sk_buff *skb, struct net_device *dev) 426static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
428{ 427{
429 pvc_device *pvc = dev_to_pvc(dev); 428 pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
430 struct net_device_stats *stats = pvc_get_stats(dev); 429 struct net_device_stats *stats = pvc_get_stats(dev);
431 430
432 if (pvc->state.active) { 431 if (pvc->state.active) {
@@ -1109,11 +1108,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1109 used = pvc_is_used(pvc); 1108 used = pvc_is_used(pvc);
1110 1109
1111 if (type == ARPHRD_ETHER) 1110 if (type == ARPHRD_ETHER)
1112 dev = alloc_netdev(sizeof(struct net_device_stats), 1111 dev = alloc_netdev(sizeof(struct pvc_desc), "pvceth%d",
1113 "pvceth%d", ether_setup); 1112 ether_setup);
1114 else 1113 else
1115 dev = alloc_netdev(sizeof(struct net_device_stats), 1114 dev = alloc_netdev(sizeof(struct pvc_desc), "pvc%d", pvc_setup);
1116 "pvc%d", pvc_setup);
1117 1115
1118 if (!dev) { 1116 if (!dev) {
1119 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", 1117 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
@@ -1137,7 +1135,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1137 dev->change_mtu = pvc_change_mtu; 1135 dev->change_mtu = pvc_change_mtu;
1138 dev->mtu = HDLC_MAX_MTU; 1136 dev->mtu = HDLC_MAX_MTU;
1139 dev->tx_queue_len = 0; 1137 dev->tx_queue_len = 0;
1140 dev->priv = pvc; 1138 pvcdev_to_desc(dev)->pvc = pvc;
1141 1139
1142 result = dev_alloc_name(dev, dev->name); 1140 result = dev_alloc_name(dev, dev->name);
1143 if (result < 0) { 1141 if (result < 0) {