diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-01-09 06:31:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-11 03:07:34 -0500 |
commit | ba7cd3ba97f81564be3e4a4ee8ee17726aa853d7 (patch) | |
tree | 30640bced4bf5bf4642e4cfe6a9146a0173bde5d /drivers | |
parent | f1405d32e392f2f5f80f4687fe186305de300bf6 (diff) |
qlge: Get rid of volatile usage for shadow register.
Putting back ql_read_sh_reg() function and using rmb() instead of
volatile.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/qlge/qlge.h | 22 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_dbg.c | 14 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 12 |
3 files changed, 34 insertions, 14 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 459663a4023d..4cb3647bb1b0 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -1145,7 +1145,7 @@ struct tx_ring { | |||
1145 | struct wqicb wqicb; /* structure used to inform chip of new queue */ | 1145 | struct wqicb wqicb; /* structure used to inform chip of new queue */ |
1146 | void *wq_base; /* pci_alloc:virtual addr for tx */ | 1146 | void *wq_base; /* pci_alloc:virtual addr for tx */ |
1147 | dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */ | 1147 | dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */ |
1148 | u32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */ | 1148 | __le32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */ |
1149 | dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */ | 1149 | dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */ |
1150 | u32 wq_size; /* size in bytes of queue area */ | 1150 | u32 wq_size; /* size in bytes of queue area */ |
1151 | u32 wq_len; /* number of entries in queue */ | 1151 | u32 wq_len; /* number of entries in queue */ |
@@ -1181,7 +1181,7 @@ struct rx_ring { | |||
1181 | u32 cq_size; | 1181 | u32 cq_size; |
1182 | u32 cq_len; | 1182 | u32 cq_len; |
1183 | u16 cq_id; | 1183 | u16 cq_id; |
1184 | volatile __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ | 1184 | __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ |
1185 | dma_addr_t prod_idx_sh_reg_dma; | 1185 | dma_addr_t prod_idx_sh_reg_dma; |
1186 | void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */ | 1186 | void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */ |
1187 | u32 cnsmr_idx; /* current sw idx */ | 1187 | u32 cnsmr_idx; /* current sw idx */ |
@@ -1459,6 +1459,24 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr) | |||
1459 | mmiowb(); | 1459 | mmiowb(); |
1460 | } | 1460 | } |
1461 | 1461 | ||
1462 | /* | ||
1463 | * Shadow Registers: | ||
1464 | * Outbound queues have a consumer index that is maintained by the chip. | ||
1465 | * Inbound queues have a producer index that is maintained by the chip. | ||
1466 | * For lower overhead, these registers are "shadowed" to host memory | ||
1467 | * which allows the device driver to track the queue progress without | ||
1468 | * PCI reads. When an entry is placed on an inbound queue, the chip will | ||
1469 | * update the relevant index register and then copy the value to the | ||
1470 | * shadow register in host memory. | ||
1471 | */ | ||
1472 | static inline u32 ql_read_sh_reg(__le32 *addr) | ||
1473 | { | ||
1474 | u32 reg; | ||
1475 | reg = le32_to_cpu(*addr); | ||
1476 | rmb(); | ||
1477 | return reg; | ||
1478 | } | ||
1479 | |||
1462 | extern char qlge_driver_name[]; | 1480 | extern char qlge_driver_name[]; |
1463 | extern const char qlge_driver_version[]; | 1481 | extern const char qlge_driver_version[]; |
1464 | extern const struct ethtool_ops qlge_ethtool_ops; | 1482 | extern const struct ethtool_ops qlge_ethtool_ops; |
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index 3f5e02d2e4a9..e705ea5b975a 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c | |||
@@ -455,10 +455,11 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) | |||
455 | printk(KERN_ERR PFX "tx_ring->base = %p.\n", tx_ring->wq_base); | 455 | printk(KERN_ERR PFX "tx_ring->base = %p.\n", tx_ring->wq_base); |
456 | printk(KERN_ERR PFX "tx_ring->base_dma = 0x%llx.\n", | 456 | printk(KERN_ERR PFX "tx_ring->base_dma = 0x%llx.\n", |
457 | (unsigned long long) tx_ring->wq_base_dma); | 457 | (unsigned long long) tx_ring->wq_base_dma); |
458 | printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg = %p.\n", | 458 | printk(KERN_ERR PFX |
459 | tx_ring->cnsmr_idx_sh_reg); | 459 | "tx_ring->cnsmr_idx_sh_reg, addr = 0x%p, value = %d.\n", |
460 | printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg_dma = 0x%llx.\n", | 460 | tx_ring->cnsmr_idx_sh_reg, |
461 | (unsigned long long) tx_ring->cnsmr_idx_sh_reg_dma); | 461 | tx_ring->cnsmr_idx_sh_reg |
462 | ? ql_read_sh_reg(tx_ring->cnsmr_idx_sh_reg) : 0); | ||
462 | printk(KERN_ERR PFX "tx_ring->size = %d.\n", tx_ring->wq_size); | 463 | printk(KERN_ERR PFX "tx_ring->size = %d.\n", tx_ring->wq_size); |
463 | printk(KERN_ERR PFX "tx_ring->len = %d.\n", tx_ring->wq_len); | 464 | printk(KERN_ERR PFX "tx_ring->len = %d.\n", tx_ring->wq_len); |
464 | printk(KERN_ERR PFX "tx_ring->prod_idx_db_reg = %p.\n", | 465 | printk(KERN_ERR PFX "tx_ring->prod_idx_db_reg = %p.\n", |
@@ -558,9 +559,10 @@ void ql_dump_rx_ring(struct rx_ring *rx_ring) | |||
558 | printk(KERN_ERR PFX "rx_ring->cq_size = %d.\n", rx_ring->cq_size); | 559 | printk(KERN_ERR PFX "rx_ring->cq_size = %d.\n", rx_ring->cq_size); |
559 | printk(KERN_ERR PFX "rx_ring->cq_len = %d.\n", rx_ring->cq_len); | 560 | printk(KERN_ERR PFX "rx_ring->cq_len = %d.\n", rx_ring->cq_len); |
560 | printk(KERN_ERR PFX | 561 | printk(KERN_ERR PFX |
561 | "rx_ring->prod_idx_sh_reg, addr = %p, value = %d.\n", | 562 | "rx_ring->prod_idx_sh_reg, addr = 0x%p, value = %d.\n", |
562 | rx_ring->prod_idx_sh_reg, | 563 | rx_ring->prod_idx_sh_reg, |
563 | rx_ring->prod_idx_sh_reg ? *(rx_ring->prod_idx_sh_reg) : 0); | 564 | rx_ring->prod_idx_sh_reg |
565 | ? ql_read_sh_reg(rx_ring->prod_idx_sh_reg) : 0); | ||
564 | printk(KERN_ERR PFX "rx_ring->prod_idx_sh_reg_dma = %llx.\n", | 566 | printk(KERN_ERR PFX "rx_ring->prod_idx_sh_reg_dma = %llx.\n", |
565 | (unsigned long long) rx_ring->prod_idx_sh_reg_dma); | 567 | (unsigned long long) rx_ring->prod_idx_sh_reg_dma); |
566 | printk(KERN_ERR PFX "rx_ring->cnsmr_idx_db_reg = %p.\n", | 568 | printk(KERN_ERR PFX "rx_ring->cnsmr_idx_db_reg = %p.\n", |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index b7e40add9586..78df7d11cef1 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -1545,7 +1545,7 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, | |||
1545 | static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) | 1545 | static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) |
1546 | { | 1546 | { |
1547 | struct ql_adapter *qdev = rx_ring->qdev; | 1547 | struct ql_adapter *qdev = rx_ring->qdev; |
1548 | u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); | 1548 | u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); |
1549 | struct ob_mac_iocb_rsp *net_rsp = NULL; | 1549 | struct ob_mac_iocb_rsp *net_rsp = NULL; |
1550 | int count = 0; | 1550 | int count = 0; |
1551 | 1551 | ||
@@ -1571,7 +1571,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) | |||
1571 | } | 1571 | } |
1572 | count++; | 1572 | count++; |
1573 | ql_update_cq(rx_ring); | 1573 | ql_update_cq(rx_ring); |
1574 | prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); | 1574 | prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); |
1575 | } | 1575 | } |
1576 | ql_write_cq_idx(rx_ring); | 1576 | ql_write_cq_idx(rx_ring); |
1577 | if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) { | 1577 | if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) { |
@@ -1591,7 +1591,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) | |||
1591 | static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) | 1591 | static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) |
1592 | { | 1592 | { |
1593 | struct ql_adapter *qdev = rx_ring->qdev; | 1593 | struct ql_adapter *qdev = rx_ring->qdev; |
1594 | u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); | 1594 | u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); |
1595 | struct ql_net_rsp_iocb *net_rsp; | 1595 | struct ql_net_rsp_iocb *net_rsp; |
1596 | int count = 0; | 1596 | int count = 0; |
1597 | 1597 | ||
@@ -1624,7 +1624,7 @@ static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) | |||
1624 | } | 1624 | } |
1625 | count++; | 1625 | count++; |
1626 | ql_update_cq(rx_ring); | 1626 | ql_update_cq(rx_ring); |
1627 | prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); | 1627 | prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); |
1628 | if (count == budget) | 1628 | if (count == budget) |
1629 | break; | 1629 | break; |
1630 | } | 1630 | } |
@@ -1787,7 +1787,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) | |||
1787 | * Check the default queue and wake handler if active. | 1787 | * Check the default queue and wake handler if active. |
1788 | */ | 1788 | */ |
1789 | rx_ring = &qdev->rx_ring[0]; | 1789 | rx_ring = &qdev->rx_ring[0]; |
1790 | if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { | 1790 | if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { |
1791 | QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n"); | 1791 | QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n"); |
1792 | ql_disable_completion_interrupt(qdev, intr_context->intr); | 1792 | ql_disable_completion_interrupt(qdev, intr_context->intr); |
1793 | queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue, | 1793 | queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue, |
@@ -1801,7 +1801,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) | |||
1801 | */ | 1801 | */ |
1802 | for (i = 1; i < qdev->rx_ring_count; i++) { | 1802 | for (i = 1; i < qdev->rx_ring_count; i++) { |
1803 | rx_ring = &qdev->rx_ring[i]; | 1803 | rx_ring = &qdev->rx_ring[i]; |
1804 | if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != | 1804 | if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != |
1805 | rx_ring->cnsmr_idx) { | 1805 | rx_ring->cnsmr_idx) { |
1806 | QPRINTK(qdev, INTR, INFO, | 1806 | QPRINTK(qdev, INTR, INFO, |
1807 | "Waking handler for rx_ring[%d].\n", i); | 1807 | "Waking handler for rx_ring[%d].\n", i); |