diff options
author | Vipul Pandya <vipul@chelsio.com> | 2012-10-02 23:22:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-10-03 16:34:15 -0400 |
commit | 8c357ebd5693b95ca6bb21242838ca3738a68450 (patch) | |
tree | 22b80fdfc6e11cbe68ea73254a4fc84dfce23d2f /drivers/net | |
parent | 864499449f256e32815575a9b860267ebefa6d70 (diff) |
cxgb4: Dynamically allocate memory in t4_memory_rw() and get_vpd_params()
This patch changes memory allocation to reduce stack footprint
Signed-off-by: Jay Hernandez <jay@chelsio.com>
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 35b81d8b59e9..137a24438d9c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -408,7 +408,8 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, | |||
408 | __be32 *buf, int dir) | 408 | __be32 *buf, int dir) |
409 | { | 409 | { |
410 | u32 pos, start, end, offset, memoffset; | 410 | u32 pos, start, end, offset, memoffset; |
411 | int ret; | 411 | int ret = 0; |
412 | __be32 *data; | ||
412 | 413 | ||
413 | /* | 414 | /* |
414 | * Argument sanity checks ... | 415 | * Argument sanity checks ... |
@@ -416,6 +417,10 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, | |||
416 | if ((addr & 0x3) || (len & 0x3)) | 417 | if ((addr & 0x3) || (len & 0x3)) |
417 | return -EINVAL; | 418 | return -EINVAL; |
418 | 419 | ||
420 | data = vmalloc(MEMWIN0_APERTURE/sizeof(__be32)); | ||
421 | if (!data) | ||
422 | return -ENOMEM; | ||
423 | |||
419 | /* | 424 | /* |
420 | * Offset into the region of memory which is being accessed | 425 | * Offset into the region of memory which is being accessed |
421 | * MEM_EDC0 = 0 | 426 | * MEM_EDC0 = 0 |
@@ -438,7 +443,6 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, | |||
438 | offset = (addr - start)/sizeof(__be32); | 443 | offset = (addr - start)/sizeof(__be32); |
439 | 444 | ||
440 | for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) { | 445 | for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) { |
441 | __be32 data[MEMWIN0_APERTURE/sizeof(__be32)]; | ||
442 | 446 | ||
443 | /* | 447 | /* |
444 | * If we're writing, copy the data from the caller's memory | 448 | * If we're writing, copy the data from the caller's memory |
@@ -452,7 +456,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, | |||
452 | if (offset || len < MEMWIN0_APERTURE) { | 456 | if (offset || len < MEMWIN0_APERTURE) { |
453 | ret = t4_mem_win_rw(adap, pos, data, 1); | 457 | ret = t4_mem_win_rw(adap, pos, data, 1); |
454 | if (ret) | 458 | if (ret) |
455 | return ret; | 459 | break; |
456 | } | 460 | } |
457 | while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) && | 461 | while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) && |
458 | len > 0) { | 462 | len > 0) { |
@@ -466,7 +470,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, | |||
466 | */ | 470 | */ |
467 | ret = t4_mem_win_rw(adap, pos, data, dir); | 471 | ret = t4_mem_win_rw(adap, pos, data, dir); |
468 | if (ret) | 472 | if (ret) |
469 | return ret; | 473 | break; |
470 | 474 | ||
471 | /* | 475 | /* |
472 | * If we're reading, copy the data into the caller's memory | 476 | * If we're reading, copy the data into the caller's memory |
@@ -480,7 +484,8 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len, | |||
480 | } | 484 | } |
481 | } | 485 | } |
482 | 486 | ||
483 | return 0; | 487 | vfree(data); |
488 | return ret; | ||
484 | } | 489 | } |
485 | 490 | ||
486 | int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, | 491 | int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, |
@@ -519,16 +524,21 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
519 | u32 cclk_param, cclk_val; | 524 | u32 cclk_param, cclk_val; |
520 | int i, ret; | 525 | int i, ret; |
521 | int ec, sn; | 526 | int ec, sn; |
522 | u8 vpd[VPD_LEN], csum; | 527 | u8 *vpd, csum; |
523 | unsigned int vpdr_len, kw_offset, id_len; | 528 | unsigned int vpdr_len, kw_offset, id_len; |
524 | 529 | ||
525 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd); | 530 | vpd = vmalloc(VPD_LEN); |
531 | if (!vpd) | ||
532 | return -ENOMEM; | ||
533 | |||
534 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd); | ||
526 | if (ret < 0) | 535 | if (ret < 0) |
527 | return ret; | 536 | goto out; |
528 | 537 | ||
529 | if (vpd[0] != PCI_VPD_LRDT_ID_STRING) { | 538 | if (vpd[0] != PCI_VPD_LRDT_ID_STRING) { |
530 | dev_err(adapter->pdev_dev, "missing VPD ID string\n"); | 539 | dev_err(adapter->pdev_dev, "missing VPD ID string\n"); |
531 | return -EINVAL; | 540 | ret = -EINVAL; |
541 | goto out; | ||
532 | } | 542 | } |
533 | 543 | ||
534 | id_len = pci_vpd_lrdt_size(vpd); | 544 | id_len = pci_vpd_lrdt_size(vpd); |
@@ -538,21 +548,24 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
538 | i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA); | 548 | i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA); |
539 | if (i < 0) { | 549 | if (i < 0) { |
540 | dev_err(adapter->pdev_dev, "missing VPD-R section\n"); | 550 | dev_err(adapter->pdev_dev, "missing VPD-R section\n"); |
541 | return -EINVAL; | 551 | ret = -EINVAL; |
552 | goto out; | ||
542 | } | 553 | } |
543 | 554 | ||
544 | vpdr_len = pci_vpd_lrdt_size(&vpd[i]); | 555 | vpdr_len = pci_vpd_lrdt_size(&vpd[i]); |
545 | kw_offset = i + PCI_VPD_LRDT_TAG_SIZE; | 556 | kw_offset = i + PCI_VPD_LRDT_TAG_SIZE; |
546 | if (vpdr_len + kw_offset > VPD_LEN) { | 557 | if (vpdr_len + kw_offset > VPD_LEN) { |
547 | dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len); | 558 | dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len); |
548 | return -EINVAL; | 559 | ret = -EINVAL; |
560 | goto out; | ||
549 | } | 561 | } |
550 | 562 | ||
551 | #define FIND_VPD_KW(var, name) do { \ | 563 | #define FIND_VPD_KW(var, name) do { \ |
552 | var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \ | 564 | var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \ |
553 | if (var < 0) { \ | 565 | if (var < 0) { \ |
554 | dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \ | 566 | dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \ |
555 | return -EINVAL; \ | 567 | ret = -EINVAL; \ |
568 | goto out; \ | ||
556 | } \ | 569 | } \ |
557 | var += PCI_VPD_INFO_FLD_HDR_SIZE; \ | 570 | var += PCI_VPD_INFO_FLD_HDR_SIZE; \ |
558 | } while (0) | 571 | } while (0) |
@@ -564,7 +577,8 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
564 | if (csum) { | 577 | if (csum) { |
565 | dev_err(adapter->pdev_dev, | 578 | dev_err(adapter->pdev_dev, |
566 | "corrupted VPD EEPROM, actual csum %u\n", csum); | 579 | "corrupted VPD EEPROM, actual csum %u\n", csum); |
567 | return -EINVAL; | 580 | ret = -EINVAL; |
581 | goto out; | ||
568 | } | 582 | } |
569 | 583 | ||
570 | FIND_VPD_KW(ec, "EC"); | 584 | FIND_VPD_KW(ec, "EC"); |
@@ -587,6 +601,9 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | |||
587 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); | 601 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); |
588 | ret = t4_query_params(adapter, adapter->mbox, 0, 0, | 602 | ret = t4_query_params(adapter, adapter->mbox, 0, 0, |
589 | 1, &cclk_param, &cclk_val); | 603 | 1, &cclk_param, &cclk_val); |
604 | |||
605 | out: | ||
606 | vfree(vpd); | ||
590 | if (ret) | 607 | if (ret) |
591 | return ret; | 608 | return ret; |
592 | p->cclk = cclk_val; | 609 | p->cclk = cclk_val; |