aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-01-28 20:17:09 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-01-28 20:17:09 -0500
commitc6428e52facd03dfac971a44abca4bc058104fec (patch)
tree2d1c5cc8069d689049642c1dc97746baeff21b35
parenta0641cc49a1d1436b3591a9aa4be8159f84b662c (diff)
solos: Fix various bugs in status packet handling
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--drivers/atm/solos-pci.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 8121f8556ea8..5e228a3f7502 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -293,13 +293,15 @@ static char *next_string(struct sk_buff *skb)
293{ 293{
294 int i = 0; 294 int i = 0;
295 char *this = skb->data; 295 char *this = skb->data;
296 296
297 while (i < skb->len) { 297 for (i = 0; i < skb->len; i++) {
298 if (this[i] == '\n') { 298 if (this[i] == '\n') {
299 this[i] = 0; 299 this[i] = 0;
300 skb_pull(skb, i); 300 skb_pull(skb, i + 1);
301 return this; 301 return this;
302 } 302 }
303 if (!isprint(this[i]))
304 return NULL;
303 } 305 }
304 return NULL; 306 return NULL;
305} 307}
@@ -316,7 +318,7 @@ static char *next_string(struct sk_buff *skb)
316static int process_status(struct solos_card *card, int port, struct sk_buff *skb) 318static int process_status(struct solos_card *card, int port, struct sk_buff *skb)
317{ 319{
318 char *str, *end, *state_str; 320 char *str, *end, *state_str;
319 int ver, rate_up, rate_down, state, snr, attn; 321 int ver, rate_up, rate_down, state;
320 322
321 if (!card->atmdev[port]) 323 if (!card->atmdev[port])
322 return -ENODEV; 324 return -ENODEV;
@@ -333,16 +335,22 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
333 } 335 }
334 336
335 str = next_string(skb); 337 str = next_string(skb);
338 if (!str)
339 return -EIO;
336 rate_up = simple_strtol(str, &end, 10); 340 rate_up = simple_strtol(str, &end, 10);
337 if (*end) 341 if (*end)
338 return -EIO; 342 return -EIO;
339 343
340 str = next_string(skb); 344 str = next_string(skb);
345 if (!str)
346 return -EIO;
341 rate_down = simple_strtol(str, &end, 10); 347 rate_down = simple_strtol(str, &end, 10);
342 if (*end) 348 if (*end)
343 return -EIO; 349 return -EIO;
344 350
345 state_str = next_string(skb); 351 state_str = next_string(skb);
352 if (!state_str)
353 return -EIO;
346 if (!strcmp(state_str, "Showtime")) 354 if (!strcmp(state_str, "Showtime"))
347 state = ATM_PHY_SIG_FOUND; 355 state = ATM_PHY_SIG_FOUND;
348 else { 356 else {
@@ -350,25 +358,24 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
350 release_vccs(card->atmdev[port]); 358 release_vccs(card->atmdev[port]);
351 } 359 }
352 360
353 str = next_string(skb); 361 if (state == ATM_PHY_SIG_LOST) {
354 snr = simple_strtol(str, &end, 10);
355 if (*end)
356 return -EIO;
357
358 str = next_string(skb);
359 attn = simple_strtol(str, &end, 10);
360 if (*end)
361 return -EIO;
362
363 if (state == ATM_PHY_SIG_LOST && !rate_up && !rate_down)
364 dev_info(&card->dev->dev, "Port %d ATM state: %s\n", 362 dev_info(&card->dev->dev, "Port %d ATM state: %s\n",
365 port, state_str); 363 port, state_str);
366 else 364 } else {
367 dev_info(&card->dev->dev, "Port %d ATM state: %s (%d/%d kb/s, SNR %ddB, Attn %ddB)\n", 365 char *snr, *attn;
368 port, state_str, rate_up/1000, rate_down/1000, 366
369 snr, attn); 367 snr = next_string(skb);
370 368 if (!str)
371 card->atmdev[port]->link_rate = rate_down; 369 return -EIO;
370 attn = next_string(skb);
371 if (!attn)
372 return -EIO;
373
374 dev_info(&card->dev->dev, "Port %d: %s (%d/%d kb/s%s%s%s%s)\n",
375 port, state_str, rate_down/1000, rate_up/1000,
376 snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn);
377 }
378 card->atmdev[port]->link_rate = rate_down / 424;
372 card->atmdev[port]->signal = state; 379 card->atmdev[port]->signal = state;
373 380
374 return 0; 381 return 0;