Commit 79486734 authored by Martin Diehl's avatar Martin Diehl Committed by Stephen Hemminger

[IRDA]: vlsi_ir v0.5 update, 3/7.

* fix error path for ring entry alloc in case pci_map failed
* get rid of BUG() - it's mostly in interrupt and there's no need
  to kill the box on such issues
* correct endianess for the hardware view of ring descriptors
parent bd1f6990
...@@ -44,6 +44,7 @@ MODULE_LICENSE("GPL"); ...@@ -44,6 +44,7 @@ MODULE_LICENSE("GPL");
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <net/irda/irda.h> #include <net/irda/irda.h>
#include <net/irda/irda_device.h> #include <net/irda/irda_device.h>
...@@ -541,7 +542,14 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr ...@@ -541,7 +542,14 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr
memset(rd, 0, sizeof(*rd)); memset(rd, 0, sizeof(*rd));
rd->hw = hwmap + i; rd->hw = hwmap + i;
rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA); rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA);
if (rd->buf == NULL) { if (rd->buf == NULL
|| !(busaddr = pci_map_single(pdev, rd->buf, len, dir))) {
if (rd->buf) {
ERROR("%s: failed to create PCI-MAP for %p",
__FUNCTION__, rd->buf);
kfree(rd->buf);
rd->buf = NULL;
}
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
rd = r->rd + j; rd = r->rd + j;
busaddr = rd_get_addr(rd); busaddr = rd_get_addr(rd);
...@@ -554,12 +562,6 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr ...@@ -554,12 +562,6 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr
kfree(r); kfree(r);
return NULL; return NULL;
} }
busaddr = pci_map_single(pdev, rd->buf, len, dir);
if (!busaddr) {
ERROR("%s: failed to create PCI-MAP for %p",
__FUNCTION__, rd->buf);
BUG();
}
rd_set_addr_status(rd, busaddr, 0); rd_set_addr_status(rd, busaddr, 0);
pci_dma_sync_single(pdev, busaddr, len, dir); pci_dma_sync_single(pdev, busaddr, len, dir);
/* initially, the dma buffer is owned by the CPU */ /* initially, the dma buffer is owned by the CPU */
...@@ -706,7 +708,9 @@ static void vlsi_fill_rx(struct vlsi_ring *r) ...@@ -706,7 +708,9 @@ static void vlsi_fill_rx(struct vlsi_ring *r)
for (rd = ring_last(r); rd != NULL; rd = ring_put(r)) { for (rd = ring_last(r); rd != NULL; rd = ring_put(r)) {
if (rd_is_active(rd)) { if (rd_is_active(rd)) {
BUG(); WARNING("%s: driver bug: rx descr race with hw\n",
__FUNCTION__);
vlsi_ring_debug(r);
break; break;
} }
if (!rd->skb) { if (!rd->skb) {
...@@ -1043,28 +1047,26 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1043,28 +1047,26 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
goto drop; goto drop;
} }
/* sanity checks - should never happen! /* sanity checks - simply drop the packet */
* simply BUGging the violation and dropping the packet
*/
rd = ring_last(r); rd = ring_last(r);
if (!rd) { /* ring full - queue should have been stopped! */ if (!rd) {
BUG(); ERROR("%s - ring full but queue wasn't stopped", __FUNCTION__);
goto drop; goto drop;
} }
if (rd_is_active(rd)) { /* entry still owned by hw! */ if (rd_is_active(rd)) {
BUG(); ERROR("%s - entry still owned by hw!", __FUNCTION__);
goto drop; goto drop;
} }
if (!rd->buf) { /* no memory for this tx entry - weird! */ if (!rd->buf) {
BUG(); ERROR("%s - tx ring entry without pci buffer", __FUNCTION__);
goto drop; goto drop;
} }
if (rd->skb) { /* hm, associated old skb still there */ if (rd->skb) {
BUG(); ERROR("%s - ring entry with old skb still attached", __FUNCTION__);
goto drop; goto drop;
} }
......
...@@ -669,21 +669,22 @@ static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s) ...@@ -669,21 +669,22 @@ static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s)
*/ */
if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) { if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) {
BUG(); ERROR("%s: pci busaddr inconsistency!\n", __FUNCTION__);
dump_stack();
return; return;
} }
a &= DMA_MASK_MSTRPAGE; /* clear highbyte to make sure we won't write a &= DMA_MASK_MSTRPAGE; /* clear highbyte to make sure we won't write
* to status - just in case MSTRPAGE_VALUE!=0 * to status - just in case MSTRPAGE_VALUE!=0
*/ */
rd->hw->rd_addr = a; rd->hw->rd_addr = cpu_to_le32(a);
wmb(); wmb();
rd_set_status(rd, s); /* may pass ownership to the hardware */ rd_set_status(rd, s); /* may pass ownership to the hardware */
} }
static inline void rd_set_count(struct ring_descr *rd, u16 c) static inline void rd_set_count(struct ring_descr *rd, u16 c)
{ {
rd->hw->rd_count = c; rd->hw->rd_count = cpu_to_le16(c);
} }
static inline u8 rd_get_status(struct ring_descr *rd) static inline u8 rd_get_status(struct ring_descr *rd)
...@@ -695,13 +696,13 @@ static inline dma_addr_t rd_get_addr(struct ring_descr *rd) ...@@ -695,13 +696,13 @@ static inline dma_addr_t rd_get_addr(struct ring_descr *rd)
{ {
dma_addr_t a; dma_addr_t a;
a = (rd->hw->rd_addr & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24); a = le32_to_cpu(rd->hw->rd_addr);
return a; return (a & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24);
} }
static inline u16 rd_get_count(struct ring_descr *rd) static inline u16 rd_get_count(struct ring_descr *rd)
{ {
return rd->hw->rd_count; return le16_to_cpu(rd->hw->rd_count);
} }
/******************************************************************/ /******************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment