* [PATCH net-next-2.6 4/4] atm: [he] rewrite buffer handling in receive path
From: chas williams - CONTRACTOR @ 2010-05-29 19:05 UTC (permalink / raw)
To: netdev; +Cc: davem
From: chas williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Author: chas williams - CONTRACTOR <chas@relax.cmf.nrl.navy.mil>
Date: Fri May 28 19:50:47 2010 -0400
atm: [he] rewrite buffer handling in receive path
Instead of a fixed list of buffers, use the buffer pool correctly and
keep track of the outstanding buffer indexes using a fixed table.
Resolves reported HBUF_ERR's -- failures due to lack of receive buffers.
Signed-off-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index c725494..ea9cbe5 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -67,6 +67,7 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/bitmap.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -778,6 +779,8 @@ he_init_cs_block_rcm(struct he_dev *he_dev)
static int __devinit
he_init_group(struct he_dev *he_dev, int group)
{
+ struct he_buff *heb, *next;
+ dma_addr_t mapping;
int i;
he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
@@ -786,12 +789,29 @@ he_init_group(struct he_dev *he_dev, int group)
he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
G0_RBPS_BS + (group * 32));
+ /* bitmap table */
+ he_dev->rbpl_table = kmalloc(BITS_TO_LONGS(RBPL_TABLE_SIZE)
+ * sizeof(unsigned long), GFP_KERNEL);
+ if (!he_dev->rbpl_table) {
+ hprintk("unable to allocate rbpl bitmap table\n");
+ return -ENOMEM;
+ }
+ bitmap_zero(he_dev->rbpl_table, RBPL_TABLE_SIZE);
+
+ /* rbpl_virt 64-bit pointers */
+ he_dev->rbpl_virt = kmalloc(RBPL_TABLE_SIZE
+ * sizeof(struct he_buff *), GFP_KERNEL);
+ if (!he_dev->rbpl_virt) {
+ hprintk("unable to allocate rbpl virt table\n");
+ goto out_free_rbpl_table;
+ }
+
/* large buffer pool */
he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev,
- CONFIG_RBPL_BUFSIZE, 8, 0);
+ CONFIG_RBPL_BUFSIZE, 64, 0);
if (he_dev->rbpl_pool == NULL) {
hprintk("unable to create rbpl pool\n");
- return -ENOMEM;
+ goto out_free_rbpl_virt;
}
he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev,
@@ -801,30 +821,29 @@ he_init_group(struct he_dev *he_dev, int group)
goto out_destroy_rbpl_pool;
}
memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp));
- he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL);
- if (he_dev->rbpl_virt == NULL) {
- hprintk("failed to alloc rbpl_virt\n");
- goto out_free_rbpl_base;
- }
+
+ INIT_LIST_HEAD(&he_dev->rbpl_outstanding);
for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
- dma_addr_t dma_handle;
- void *cpuaddr;
- cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
- if (cpuaddr == NULL)
- goto out_free_rbpl_virt;
+ heb = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &mapping);
+ if (!heb)
+ goto out_free_rbpl;
+ heb->mapping = mapping;
+ list_add(&heb->entry, &he_dev->rbpl_outstanding);
- he_dev->rbpl_virt[i].virt = cpuaddr;
- he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
- he_dev->rbpl_base[i].phys = dma_handle;
+ set_bit(i, he_dev->rbpl_table);
+ he_dev->rbpl_virt[i] = heb;
+ he_dev->rbpl_hint = i + 1;
+ he_dev->rbpl_base[i].idx = i << RBP_IDX_OFFSET;
+ he_dev->rbpl_base[i].phys = mapping + offsetof(struct he_buff, data);
}
he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1];
he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32));
he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail),
G0_RBPL_T + (group * 32));
- he_writel(he_dev, CONFIG_RBPL_BUFSIZE/4,
+ he_writel(he_dev, (CONFIG_RBPL_BUFSIZE - sizeof(struct he_buff))/4,
G0_RBPL_BS + (group * 32));
he_writel(he_dev,
RBP_THRESH(CONFIG_RBPL_THRESH) |
@@ -838,7 +857,7 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys);
if (he_dev->rbrq_base == NULL) {
hprintk("failed to allocate rbrq\n");
- goto out_free_rbpl_virt;
+ goto out_free_rbpl;
}
memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq));
@@ -879,19 +898,19 @@ out_free_rbpq_base:
pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE *
sizeof(struct he_rbrq), he_dev->rbrq_base,
he_dev->rbrq_phys);
- i = CONFIG_RBPL_SIZE;
-out_free_rbpl_virt:
- while (i--)
- pci_pool_free(he_dev->rbpl_pool, he_dev->rbpl_virt[i].virt,
- he_dev->rbpl_base[i].phys);
- kfree(he_dev->rbpl_virt);
+out_free_rbpl:
+ list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry)
+ pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-out_free_rbpl_base:
pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE *
sizeof(struct he_rbp), he_dev->rbpl_base,
he_dev->rbpl_phys);
out_destroy_rbpl_pool:
pci_pool_destroy(he_dev->rbpl_pool);
+out_free_rbpl_virt:
+ kfree(he_dev->rbpl_virt);
+out_free_rbpl_table:
+ kfree(he_dev->rbpl_table);
return -ENOMEM;
}
@@ -1522,9 +1541,10 @@ he_start(struct atm_dev *dev)
static void
he_stop(struct he_dev *he_dev)
{
- u16 command;
- u32 gen_cntl_0, reg;
+ struct he_buff *heb, *next;
struct pci_dev *pci_dev;
+ u32 gen_cntl_0, reg;
+ u16 command;
pci_dev = he_dev->pci_dev;
@@ -1565,18 +1585,16 @@ he_stop(struct he_dev *he_dev)
he_dev->hsp, he_dev->hsp_phys);
if (he_dev->rbpl_base) {
- int i;
-
- for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
- void *cpuaddr = he_dev->rbpl_virt[i].virt;
- dma_addr_t dma_handle = he_dev->rbpl_base[i].phys;
+ list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry)
+ pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
- pci_pool_free(he_dev->rbpl_pool, cpuaddr, dma_handle);
- }
pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE
* sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys);
}
+ kfree(he_dev->rbpl_virt);
+ kfree(he_dev->rbpl_table);
+
if (he_dev->rbpl_pool)
pci_pool_destroy(he_dev->rbpl_pool);
@@ -1609,13 +1627,13 @@ static struct he_tpd *
__alloc_tpd(struct he_dev *he_dev)
{
struct he_tpd *tpd;
- dma_addr_t dma_handle;
+ dma_addr_t mapping;
- tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &dma_handle);
+ tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &mapping);
if (tpd == NULL)
return NULL;
- tpd->status = TPD_ADDR(dma_handle);
+ tpd->status = TPD_ADDR(mapping);
tpd->reserved = 0;
tpd->iovec[0].addr = 0; tpd->iovec[0].len = 0;
tpd->iovec[1].addr = 0; tpd->iovec[1].len = 0;
@@ -1644,13 +1662,12 @@ he_service_rbrq(struct he_dev *he_dev, int group)
struct he_rbrq *rbrq_tail = (struct he_rbrq *)
((unsigned long)he_dev->rbrq_base |
he_dev->hsp->group[group].rbrq_tail);
- struct he_rbp *rbp = NULL;
unsigned cid, lastcid = -1;
- unsigned buf_len = 0;
struct sk_buff *skb;
struct atm_vcc *vcc = NULL;
struct he_vcc *he_vcc;
- struct he_iovec *iov;
+ struct he_buff *heb, *next;
+ int i;
int pdus_assembled = 0;
int updated = 0;
@@ -1670,41 +1687,35 @@ he_service_rbrq(struct he_dev *he_dev, int group)
RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "",
RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : "");
- rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))];
-
- buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
- cid = RBRQ_CID(he_dev->rbrq_head);
+ i = RBRQ_ADDR(he_dev->rbrq_head) >> RBP_IDX_OFFSET;
+ heb = he_dev->rbpl_virt[i];
+ cid = RBRQ_CID(he_dev->rbrq_head);
if (cid != lastcid)
vcc = __find_vcc(he_dev, cid);
lastcid = cid;
- if (vcc == NULL) {
- hprintk("vcc == NULL (cid 0x%x)\n", cid);
- if (!RBRQ_HBUF_ERR(he_dev->rbrq_head))
- rbp->status &= ~RBP_LOANED;
+ if (vcc == NULL || (he_vcc = HE_VCC(vcc)) == NULL) {
+ hprintk("vcc/he_vcc == NULL (cid 0x%x)\n", cid);
+ if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
+ clear_bit(i, he_dev->rbpl_table);
+ list_del(&heb->entry);
+ pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
+ }
goto next_rbrq_entry;
}
- he_vcc = HE_VCC(vcc);
- if (he_vcc == NULL) {
- hprintk("he_vcc == NULL (cid 0x%x)\n", cid);
- if (!RBRQ_HBUF_ERR(he_dev->rbrq_head))
- rbp->status &= ~RBP_LOANED;
- goto next_rbrq_entry;
- }
-
if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
hprintk("HBUF_ERR! (cid 0x%x)\n", cid);
atomic_inc(&vcc->stats->rx_drop);
goto return_host_buffers;
}
- he_vcc->iov_tail->iov_base = RBRQ_ADDR(he_dev->rbrq_head);
- he_vcc->iov_tail->iov_len = buf_len;
- he_vcc->pdu_len += buf_len;
- ++he_vcc->iov_tail;
+ heb->len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
+ clear_bit(i, he_dev->rbpl_table);
+ list_move_tail(&heb->entry, &he_vcc->buffers);
+ he_vcc->pdu_len += heb->len;
if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) {
lastcid = -1;
@@ -1713,12 +1724,6 @@ he_service_rbrq(struct he_dev *he_dev, int group)
goto return_host_buffers;
}
-#ifdef notdef
- if ((he_vcc->iov_tail - he_vcc->iov_head) > HE_MAXIOV) {
- hprintk("iovec full! cid 0x%x\n", cid);
- goto return_host_buffers;
- }
-#endif
if (!RBRQ_END_PDU(he_dev->rbrq_head))
goto next_rbrq_entry;
@@ -1746,9 +1751,8 @@ he_service_rbrq(struct he_dev *he_dev, int group)
__net_timestamp(skb);
- for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov)
- memcpy(skb_put(skb, iov->iov_len),
- he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
+ list_for_each_entry(heb, &he_vcc->buffers, entry)
+ memcpy(skb_put(skb, heb->len), &heb->data, heb->len);
switch (vcc->qos.aal) {
case ATM_AAL0:
@@ -1788,12 +1792,9 @@ he_service_rbrq(struct he_dev *he_dev, int group)
return_host_buffers:
++pdus_assembled;
- for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov) {
- rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)];
- rbp->status &= ~RBP_LOANED;
- }
-
- he_vcc->iov_tail = he_vcc->iov_head;
+ list_for_each_entry_safe(heb, next, &he_vcc->buffers, entry)
+ pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
+ INIT_LIST_HEAD(&he_vcc->buffers);
he_vcc->pdu_len = 0;
next_rbrq_entry:
@@ -1897,23 +1898,43 @@ next_tbrq_entry:
static void
he_service_rbpl(struct he_dev *he_dev, int group)
{
- struct he_rbp *newtail;
+ struct he_rbp *new_tail;
struct he_rbp *rbpl_head;
+ struct he_buff *heb;
+ dma_addr_t mapping;
+ int i;
int moved = 0;
rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
RBPL_MASK(he_readl(he_dev, G0_RBPL_S)));
for (;;) {
- newtail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
+ new_tail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
RBPL_MASK(he_dev->rbpl_tail+1));
/* table 3.42 -- rbpl_tail should never be set to rbpl_head */
- if ((newtail == rbpl_head) || (newtail->status & RBP_LOANED))
+ if (new_tail == rbpl_head)
break;
- newtail->status |= RBP_LOANED;
- he_dev->rbpl_tail = newtail;
+ i = find_next_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE, he_dev->rbpl_hint);
+ if (i > (RBPL_TABLE_SIZE - 1)) {
+ i = find_first_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE);
+ if (i > (RBPL_TABLE_SIZE - 1))
+ break;
+ }
+ he_dev->rbpl_hint = i + 1;
+
+ heb = pci_pool_alloc(he_dev->rbpl_pool, GFP_ATOMIC|GFP_DMA, &mapping);
+ if (!heb)
+ break;
+ heb->mapping = mapping;
+ list_add(&heb->entry, &he_dev->rbpl_outstanding);
+ he_dev->rbpl_virt[i] = heb;
+ set_bit(i, he_dev->rbpl_table);
+ new_tail->idx = i << RBP_IDX_OFFSET;
+ new_tail->phys = mapping + offsetof(struct he_buff, data);
+
+ he_dev->rbpl_tail = new_tail;
++moved;
}
@@ -2137,7 +2158,7 @@ he_open(struct atm_vcc *vcc)
return -ENOMEM;
}
- he_vcc->iov_tail = he_vcc->iov_head;
+ INIT_LIST_HEAD(&he_vcc->buffers);
he_vcc->pdu_len = 0;
he_vcc->rc_index = -1;
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
index 8bf3264..110a27d 100644
--- a/drivers/atm/he.h
+++ b/drivers/atm/he.h
@@ -198,26 +198,33 @@ struct he_hsp {
} group[HE_NUM_GROUPS];
};
-/* figure 2.9 receive buffer pools */
+/*
+ * figure 2.9 receive buffer pools
+ *
+ * since a virtual address might be more than 32 bits, we store an index
+ * in the virt member of he_rbp. NOTE: the lower six bits in the rbrq
+ * addr member are used for buffer status further limiting us to 26 bits.
+ */
struct he_rbp {
volatile u32 phys;
- volatile u32 status;
+ volatile u32 idx; /* virt */
};
-/* NOTE: it is suggested that virt be the virtual address of the host
- buffer. on a 64-bit machine, this would not work. Instead, we
- store the real virtual address in another list, and store an index
- (and buffer status) in the virt member.
-*/
+#define RBP_IDX_OFFSET 6
+
+/*
+ * the he dma engine will try to hold an extra 16 buffers in its local
+ * caches. and add a couple buffers for safety.
+ */
-#define RBP_INDEX_OFF 6
-#define RBP_INDEX(x) (((long)(x) >> RBP_INDEX_OFF) & 0xffff)
-#define RBP_LOANED 0x80000000
-#define RBP_SMALLBUF 0x40000000
+#define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2)
-struct he_virt {
- void *virt;
+struct he_buff {
+ struct list_head entry;
+ dma_addr_t mapping;
+ unsigned long len;
+ u8 data[];
};
#ifdef notyet
@@ -286,10 +293,13 @@ struct he_dev {
struct he_rbrq *rbrq_base, *rbrq_head;
int rbrq_peak;
+ struct he_buff **rbpl_virt;
+ unsigned long *rbpl_table;
+ unsigned long rbpl_hint;
struct pci_pool *rbpl_pool;
dma_addr_t rbpl_phys;
struct he_rbp *rbpl_base, *rbpl_tail;
- struct he_virt *rbpl_virt;
+ struct list_head rbpl_outstanding;
int rbpl_peak;
dma_addr_t tbrq_phys;
@@ -304,20 +314,12 @@ struct he_dev {
struct he_dev *next;
};
-struct he_iovec
-{
- u32 iov_base;
- u32 iov_len;
-};
-
#define HE_MAXIOV 20
struct he_vcc
{
- struct he_iovec iov_head[HE_MAXIOV];
- struct he_iovec *iov_tail;
+ struct list_head buffers;
int pdu_len;
-
int rc_index;
wait_queue_head_t rx_waitq;
^ permalink raw reply related
* [PATCH net-next-2.6 3/4] atm: [he] remove small buffer allocation/handling code
From: chas williams - CONTRACTOR @ 2010-05-29 19:04 UTC (permalink / raw)
To: netdev; +Cc: davem
From: chas williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Author: chas williams - CONTRACTOR <chas@relax.cmf.nrl.navy.mil>
Date: Fri May 28 19:45:59 2010 -0400
atm: [he] remove small buffer allocation/handling code
Signed-off-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 56c2e99..c725494 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -780,59 +780,18 @@ he_init_group(struct he_dev *he_dev, int group)
{
int i;
- /* small buffer pool */
- he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev,
- CONFIG_RBPS_BUFSIZE, 8, 0);
- if (he_dev->rbps_pool == NULL) {
- hprintk("unable to create rbps pages\n");
- return -ENOMEM;
- }
-
- he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev,
- CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys);
- if (he_dev->rbps_base == NULL) {
- hprintk("failed to alloc rbps_base\n");
- goto out_destroy_rbps_pool;
- }
- memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp));
- he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL);
- if (he_dev->rbps_virt == NULL) {
- hprintk("failed to alloc rbps_virt\n");
- goto out_free_rbps_base;
- }
-
- for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
- dma_addr_t dma_handle;
- void *cpuaddr;
-
- cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
- if (cpuaddr == NULL)
- goto out_free_rbps_virt;
-
- he_dev->rbps_virt[i].virt = cpuaddr;
- he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF);
- he_dev->rbps_base[i].phys = dma_handle;
-
- }
- he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE - 1];
-
- he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32));
- he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail),
- G0_RBPS_T + (group * 32));
- he_writel(he_dev, CONFIG_RBPS_BUFSIZE/4,
- G0_RBPS_BS + (group * 32));
- he_writel(he_dev,
- RBP_THRESH(CONFIG_RBPS_THRESH) |
- RBP_QSIZE(CONFIG_RBPS_SIZE - 1) |
- RBP_INT_ENB,
- G0_RBPS_QI + (group * 32));
+ he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
+ he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
+ he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
+ he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
+ G0_RBPS_BS + (group * 32));
/* large buffer pool */
he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev,
CONFIG_RBPL_BUFSIZE, 8, 0);
if (he_dev->rbpl_pool == NULL) {
hprintk("unable to create rbpl pool\n");
- goto out_free_rbps_virt;
+ return -ENOMEM;
}
he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev,
@@ -934,19 +893,6 @@ out_free_rbpl_base:
out_destroy_rbpl_pool:
pci_pool_destroy(he_dev->rbpl_pool);
- i = CONFIG_RBPS_SIZE;
-out_free_rbps_virt:
- while (i--)
- pci_pool_free(he_dev->rbps_pool, he_dev->rbps_virt[i].virt,
- he_dev->rbps_base[i].phys);
- kfree(he_dev->rbps_virt);
-
-out_free_rbps_base:
- pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE *
- sizeof(struct he_rbp), he_dev->rbps_base,
- he_dev->rbps_phys);
-out_destroy_rbps_pool:
- pci_pool_destroy(he_dev->rbps_pool);
return -ENOMEM;
}
@@ -1634,22 +1580,6 @@ he_stop(struct he_dev *he_dev)
if (he_dev->rbpl_pool)
pci_pool_destroy(he_dev->rbpl_pool);
- if (he_dev->rbps_base) {
- int i;
-
- for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
- void *cpuaddr = he_dev->rbps_virt[i].virt;
- dma_addr_t dma_handle = he_dev->rbps_base[i].phys;
-
- pci_pool_free(he_dev->rbps_pool, cpuaddr, dma_handle);
- }
- pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE
- * sizeof(struct he_rbp), he_dev->rbps_base, he_dev->rbps_phys);
- }
-
- if (he_dev->rbps_pool)
- pci_pool_destroy(he_dev->rbps_pool);
-
if (he_dev->rbrq_base)
pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
he_dev->rbrq_base, he_dev->rbrq_phys);
@@ -1740,10 +1670,7 @@ he_service_rbrq(struct he_dev *he_dev, int group)
RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "",
RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : "");
- if (RBRQ_ADDR(he_dev->rbrq_head) & RBP_SMALLBUF)
- rbp = &he_dev->rbps_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))];
- else
- rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))];
+ rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))];
buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
cid = RBRQ_CID(he_dev->rbrq_head);
@@ -1819,15 +1746,9 @@ he_service_rbrq(struct he_dev *he_dev, int group)
__net_timestamp(skb);
- for (iov = he_vcc->iov_head;
- iov < he_vcc->iov_tail; ++iov) {
- if (iov->iov_base & RBP_SMALLBUF)
- memcpy(skb_put(skb, iov->iov_len),
- he_dev->rbps_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
- else
- memcpy(skb_put(skb, iov->iov_len),
- he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
- }
+ for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov)
+ memcpy(skb_put(skb, iov->iov_len),
+ he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
switch (vcc->qos.aal) {
case ATM_AAL0:
@@ -1867,13 +1788,8 @@ he_service_rbrq(struct he_dev *he_dev, int group)
return_host_buffers:
++pdus_assembled;
- for (iov = he_vcc->iov_head;
- iov < he_vcc->iov_tail; ++iov) {
- if (iov->iov_base & RBP_SMALLBUF)
- rbp = &he_dev->rbps_base[RBP_INDEX(iov->iov_base)];
- else
- rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)];
-
+ for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov) {
+ rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)];
rbp->status &= ~RBP_LOANED;
}
@@ -1978,7 +1894,6 @@ next_tbrq_entry:
}
}
-
static void
he_service_rbpl(struct he_dev *he_dev, int group)
{
@@ -2007,33 +1922,6 @@ he_service_rbpl(struct he_dev *he_dev, int group)
}
static void
-he_service_rbps(struct he_dev *he_dev, int group)
-{
- struct he_rbp *newtail;
- struct he_rbp *rbps_head;
- int moved = 0;
-
- rbps_head = (struct he_rbp *) ((unsigned long)he_dev->rbps_base |
- RBPS_MASK(he_readl(he_dev, G0_RBPS_S)));
-
- for (;;) {
- newtail = (struct he_rbp *) ((unsigned long)he_dev->rbps_base |
- RBPS_MASK(he_dev->rbps_tail+1));
-
- /* table 3.42 -- rbps_tail should never be set to rbps_head */
- if ((newtail == rbps_head) || (newtail->status & RBP_LOANED))
- break;
-
- newtail->status |= RBP_LOANED;
- he_dev->rbps_tail = newtail;
- ++moved;
- }
-
- if (moved)
- he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T);
-}
-
-static void
he_tasklet(unsigned long data)
{
unsigned long flags;
@@ -2055,10 +1943,8 @@ he_tasklet(unsigned long data)
HPRINTK("rbrq%d threshold\n", group);
/* fall through */
case ITYPE_RBRQ_TIMER:
- if (he_service_rbrq(he_dev, group)) {
+ if (he_service_rbrq(he_dev, group))
he_service_rbpl(he_dev, group);
- he_service_rbps(he_dev, group);
- }
break;
case ITYPE_TBRQ_THRESH:
HPRINTK("tbrq%d threshold\n", group);
@@ -2070,7 +1956,7 @@ he_tasklet(unsigned long data)
he_service_rbpl(he_dev, group);
break;
case ITYPE_RBPS_THRESH:
- he_service_rbps(he_dev, group);
+ /* shouldn't happen unless small buffers enabled */
break;
case ITYPE_PHY:
HPRINTK("phy interrupt\n");
@@ -2098,7 +1984,6 @@ he_tasklet(unsigned long data)
he_service_rbrq(he_dev, 0);
he_service_rbpl(he_dev, 0);
- he_service_rbps(he_dev, 0);
he_service_tbrq(he_dev, 0);
break;
default:
@@ -2406,8 +2291,8 @@ he_open(struct atm_vcc *vcc)
goto open_failed;
}
- rsr1 = RSR1_GROUP(0);
- rsr4 = RSR4_GROUP(0);
+ rsr1 = RSR1_GROUP(0) | RSR1_RBPL_ONLY;
+ rsr4 = RSR4_GROUP(0) | RSR4_RBPL_ONLY;
rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ?
(RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0;
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
index c2983e0..8bf3264 100644
--- a/drivers/atm/he.h
+++ b/drivers/atm/he.h
@@ -67,11 +67,6 @@
#define CONFIG_RBPL_BUFSIZE 4096
#define RBPL_MASK(x) (((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1))
-#define CONFIG_RBPS_SIZE 1024
-#define CONFIG_RBPS_THRESH 64
-#define CONFIG_RBPS_BUFSIZE 128
-#define RBPS_MASK(x) (((unsigned long)(x))&((CONFIG_RBPS_SIZE<<3)-1))
-
/* 5.1.3 initialize connection memory */
#define CONFIG_RSRA 0x00000
@@ -225,14 +220,8 @@ struct he_virt {
void *virt;
};
-#define RBPL_ALIGNMENT CONFIG_RBPL_SIZE
-#define RBPS_ALIGNMENT CONFIG_RBPS_SIZE
-
#ifdef notyet
struct he_group {
- u32 rpbs_size, rpbs_qsize;
- struct he_rbp rbps_ba;
-
u32 rpbl_size, rpbl_qsize;
struct he_rpb_entry *rbpl_ba;
};
@@ -303,12 +292,6 @@ struct he_dev {
struct he_virt *rbpl_virt;
int rbpl_peak;
- struct pci_pool *rbps_pool;
- dma_addr_t rbps_phys;
- struct he_rbp *rbps_base, *rbps_tail;
- struct he_virt *rbps_virt;
- int rbps_peak;
-
dma_addr_t tbrq_phys;
struct he_tbrq *tbrq_base, *tbrq_head;
int tbrq_peak;
^ permalink raw reply related
* Re: [PATCH] bnx2: Fix IRQ failures during kdump.
From: Michael Chan @ 2010-05-29 16:22 UTC (permalink / raw)
To: 'David Miller', grundler@parisc-linux.org
Cc: netdev@vger.kernel.org, linux-pci@vger.kernel.org
In-Reply-To: <20100528.235052.241451895.davem@davemloft.net>
David Miller wrote:
>
> The generic PCI layer very well can turn off MSI on all devices
> when it starts up or a device is plugged in.
>
> That's all he is doing.
>
> Drivers essentially expect that the device comes up in INTX mode
> when the driver probes the device. All his change is doing
> is forcing that to be true, and there is no reason the generic
> PCI code can't do that.
>
I think there may be more issues after thinking about it some more.
The device is essentially still active at this time. The PCI
layer can turn off certain things, but enabling INTX can lead to
"irq x: nobody cared" if the driver is not ready for it. The
device really needs to be reset by the driver to be totally
reliable.
^ permalink raw reply
* Re: [PATCH] bnx2: Fix IRQ failures during kdump.
From: Stephen Hemminger @ 2010-05-29 16:01 UTC (permalink / raw)
To: Michael Chan; +Cc: davem, netdev, linux-pci
In-Reply-To: <1275103462-8527-1-git-send-email-mchan@broadcom.com>
On Fri, 28 May 2010 20:24:22 -0700
"Michael Chan" <mchan@broadcom.com> wrote:
> When switching from the crashed kernel to the kdump kernel without going
> through PCI reset, IRQs may not work if a different IRQ mode is used on
> the kdump kernel. The original IRQ mode used in the crashed kernel may
> still be enabled and the new IRQ mode may not work. For example, it
> will fail when going from MSI-X mode to MSI mode.
>
> We fix this by disabling MSI/MSI-X and enabling INTX in bnx2_init_board().
>
> pci_save_state() is also moved to the end of bnx2_init_board() after
> all config register fixups (including the new IRQ fixups) have been done.
>
> Export pci_msi_off() from drivers/pci/pci.c for this purpose.
>
> Update bnx2 version to 2.0.16.
This is probably a generic problem for many drivers. So why not
get the kdump code to fix it for all.
^ permalink raw reply
* RE: Hey, Opt In Email Lists Give Away!
From: Sam L. Carl @ 2010-05-29 14:12 UTC (permalink / raw)
To: netdev
Hey,
You have to check this out if your a webmaster. http://www.traffictractor.com is giving away thousands of opt in emails.
This is huge! Everyone is talking about it now. With these opt in email addresses you can do so much. It takes years and a lot of money to build a list from scratch but now you have the chance to grab a massive list.
Use it for ezine, email, autoresponders, they will bring your website a huge amount of power, traffic and sales.
You have to check it out at http://www.traffictractor.com
All the best,
Sam L. Carl
^ permalink raw reply
* Re: pull request: wireless-2.6 2010-05-28
From: Sedat Dilek @ 2010-05-29 13:34 UTC (permalink / raw)
To: John W. Linville
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
jiajia.zheng-ral2JQCrhuEAvxtiuMwx3w, Abhijeet Kolekar,
Johannes Berg, Reinette Chatre
In-Reply-To: <20100528180952.GC2405-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Hi,
I have pulled wireless-2.6 GIT (master-2010-05-28) into Linus-tree
(2.6.34-git15) [0] and Intel Linux-Wireless Bug #2208 is present.
Two people confirmed the patch in [2] fixes:
1. iwlwifi-2.6 GIT master (commit f10a237c95abd6d64a3a24553bd1d3bcddd9108b)
2. compat-wireless (2010-05-21)
And it fixes also the above mentionned combination.
As a suggestion:
What about "copying" bug-reports (incl. its history) from IWL-BTS into
linux-wireless ML?
For example (dri-devel related) bug-reports from
bugzilla.freedesktop.org are "copied" into dri-devel ML.
Hope [2] gets quickly into wireless-2.6 GIT.
Kind Regards,
- Sedat -
References:
------------------
[0] commit 24010e460454ec0d2f4f0213b667b4349cbdb8e1:
Merge branch 'drm-linus' of git://git./linux/kernel/git/airlied/drm-2.6
[1] http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2208
[2] http://bugzilla.intellinuxwireless.org/attachment.cgi?id=2447
[3] http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2208#c8
[4] http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2208#c9
[ 446.893181] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 446.893192] IP: [<f8e9eb54>]
iwl3945_get_channels_for_scan+0xb4/0x315 [iwl3945]
[ 446.893214] *pde = 00000000
[ 446.893220] Oops: 0000 [#1] PREEMPT SMP
[ 446.893228] last sysfs file:
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
[ 446.893233] Modules linked in: btrfs zlib_deflate crc32c libcrc32c
ufs qnx4 hfsplus hfs minix ntfs vfat msdos fat jfs xfs exportfs
reiserfs ext2 radeon ttm drm_kms_helper drm i2c_algo_bit i2c_core
acpi_cpufreq mperf cpufreq_ondemand cpufreq_stats freq_table
cpufreq_performance cpufreq_conservative cpufreq_powersave sco bridge
stp bnep rfcomm l2cap bluetooth aes_i586 aes_generic ppdev lp
kvm_intel kvm binfmt_misc ipv6 af_packet fuse ext4 jbd2 crc16
snd_hda_codec_si3054 snd_hda_codec_analog snd_hda_intel snd_hda_codec
snd_hwdep snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss
snd_seq_midi arc4 snd_rawmidi ecb snd_seq_midi_event iwl3945 iwlcore
snd_seq snd_timer snd_seq_device sierra usbserial snd parport_pc
mac80211 hp_wmi parport soundcore snd_page_alloc cfg80211 rfkill
joydev pcmcia irda pcspkr intel_agp tifm_7xx1 tifm_core rng_core
iTCO_wdt iTCO_vendor_support hp_accel yenta_socket pcmcia_rsrc
pcmcia_core psmouse evdev tpm_infineon crc_ccitt wmi video output
serio_raw lis3lv02d container battery rtc_cmos tpm_tis tpm rtc_core
tpm_bios rtc_lib input_polldev ac processor button ext3 jbd mbcache
dm_mod usbhid hid sg sr_mod cdrom sd_mod fan pata_acpi ata_generic
sdhci_pci sdhci ata_piix uhci_hcd ahci libahci mmc_core led_class
ehci_hcd tg3 libata thermal scsi_mod usbcore nls_base [last unloaded:
i2c_core]
[ 446.893460]
[ 446.893466] Pid: 1312, comm: iwl3945 Not tainted
2.6.34-git15.sd.1-iniza-686-kms #1 30AC/HP Compaq nc6400 (RH572EA#ABD)
[ 446.893473] EIP: 0060:[<f8e9eb54>] EFLAGS: 00010283 CPU: 0
[ 446.893488] EIP is at iwl3945_get_channels_for_scan+0xb4/0x315 [iwl3945]
[ 446.893494] EAX: f712a000 EBX: f0548ae0 ECX: 00000000 EDX: 00000000
[ 446.893500] ESI: f05c00f2 EDI: 00000058 EBP: 00000000 ESP: f6bc5ecc
[ 446.893505] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[ 446.893511] Process iwl3945 (pid: 1312, ti=f6bc4000 task=f04c79c0
task.ti=f6bc4000)
[ 446.893516] Stack:
[ 446.893519] 00000067 f04c79ec 00000000 00000000 00000000 00210001
c10272fc c13b0401
[ 446.893532] <0> c1225b2d c13b0400 f054f0f0 0002ff00 00000058
00000021 0057f0f0 f0548ae0
[ 446.893546] <0> 00000000 00000005 f05c0000 f8ea1cc1 00000000
f05c00f2 00000000 c1071393
[ 446.893561] Call Trace:
[ 446.893572] [<c10272fc>] ? add_preempt_count+0x8f/0x91
[ 446.893581] [<c1225b2d>] ? _raw_spin_lock_irqsave+0x1c/0x35
[ 446.893598] [<f8ea1cc1>] ? iwl3945_request_scan+0x697/0x799 [iwl3945]
[ 446.893607] [<c1071393>] ? perf_event_task_sched_in+0xe/0x71
[ 446.893614] [<c1225cf8>] ? _raw_spin_unlock_irq+0x1e/0x28
[ 446.893631] [<f8e62768>] ? iwl_bg_start_internal_scan+0x280/0x299 [iwlcore]
[ 446.893639] [<c103c530>] ? run_workqueue+0x65/0xe1
[ 446.893654] [<f8e624e8>] ? iwl_bg_start_internal_scan+0x0/0x299 [iwlcore]
[ 446.893661] [<c103c65b>] ? worker_thread+0xaf/0xbb
[ 446.893669] [<c103f22a>] ? autoremove_wake_function+0x0/0x29
[ 446.893676] [<c103c5ac>] ? worker_thread+0x0/0xbb
[ 446.893683] [<c103ef3f>] ? kthread+0x5f/0x64
[ 446.893690] [<c103eee0>] ? kthread+0x0/0x64
[ 446.893698] [<c10033b6>] ? kernel_thread_helper+0x6/0x10
[ 446.893702] Code: 88 44 24 1c 83 e8 02 88 44 24 2d 8d 4f ff 0f b7
c7 89 44 24 30 66 89 4c 24 3a e9 ea 01 00 00 8b 54 24 10 8b 4c 24 08
8b 6c 90 20 <39> 4d 00 0f 85 d1 01 00 00 66 8b 4d 06 89 d8 88 4e 01 8b
54 24
[ 446.893784] EIP: [<f8e9eb54>]
iwl3945_get_channels_for_scan+0xb4/0x315 [iwl3945] SS:ESP
0068:f6bc5ecc
[ 446.893801] CR2: 0000000000000000
[ 446.893812] ---[ end trace 7a6cdfd823c4f035 ]---
On Fri, May 28, 2010 at 8:09 PM, John W. Linville
<linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org> wrote:
> Dave,
>
> Here are a few small fixes intended for 2.6.35. Included are a null
> pointer dereference fix, and a use-after-free fix, as well as some more
> minor stuff. It also include the revert of a earlier patch that I
> inadvertantly merged out of order, effectively creating a bug rather
> than fixing one. The reverted patch will now be pointed at 2.6.36
> instead.
>
> Please let me know if there are problems!
>
> Thanks,
>
> John
>
> ---
>
> The following changes since commit 045de01a174d9f0734f657eb4b3313d89b4fd5ad:
> Scott Feldman (1):
> netlink: bug fix: wrong size was calculated for vfinfo list blob
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master
>
> Christian Lamparter (1):
> ar9170usb: fix read from freed driver context
>
> Christoph Fritz (1):
> ssb: fix NULL ptr deref when pcihost_wrapper is used
>
> Johannes Berg (1):
> mac80211: make a function static
>
> John W. Linville (1):
> Revert "rt2x00: Fix rt2800usb TX descriptor writing."
>
> Justin P. Mattock (1):
> ath9k: Fix ath_print in xmit for hardware reset.
>
> Prarit Bhargava (1):
> libertas: fix uninitialized variable warning
>
> Vasanthakumar Thiagarajan (1):
> ath9k: Fix bug in the way "bf_tx_aborted" of struct ath_buf is used
>
> drivers/net/wireless/ath/ar9170/usb.c | 14 ++++++++++++--
> drivers/net/wireless/ath/ath9k/xmit.c | 6 ++++--
> drivers/net/wireless/libertas/rx.c | 5 ++---
> drivers/net/wireless/rt2x00/rt2800usb.c | 2 +-
> drivers/ssb/pci.c | 9 ++++++---
> drivers/ssb/sprom.c | 1 +
> net/mac80211/chan.c | 2 +-
> 7 files changed, 27 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
> index 82ab532..a93dc18 100644
> --- a/drivers/net/wireless/ath/ar9170/usb.c
> +++ b/drivers/net/wireless/ath/ar9170/usb.c
> @@ -739,17 +739,27 @@ err_out:
> static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
> {
> struct device *parent = aru->udev->dev.parent;
> + struct usb_device *udev;
> +
> + /*
> + * Store a copy of the usb_device pointer locally.
> + * This is because device_release_driver initiates
> + * ar9170_usb_disconnect, which in turn frees our
> + * driver context (aru).
> + */
> + udev = aru->udev;
>
> complete(&aru->firmware_loading_complete);
>
> /* unbind anything failed */
> if (parent)
> device_lock(parent);
> - device_release_driver(&aru->udev->dev);
> +
> + device_release_driver(&udev->dev);
> if (parent)
> device_unlock(parent);
>
> - usb_put_dev(aru->udev);
> + usb_put_dev(udev);
> }
>
> static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
> diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
> index 3db1917..859aa4a 100644
> --- a/drivers/net/wireless/ath/ath9k/xmit.c
> +++ b/drivers/net/wireless/ath/ath9k/xmit.c
> @@ -1198,7 +1198,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
> int r;
>
> ath_print(common, ATH_DBG_FATAL,
> - "Unable to stop TxDMA. Reset HAL!\n");
> + "Failed to stop TX DMA. Resetting hardware!\n");
>
> spin_lock_bh(&sc->sc_resetlock);
> r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
> @@ -1728,6 +1728,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
> } else
> bf->bf_isnullfunc = false;
>
> + bf->bf_tx_aborted = false;
> +
> return 0;
> }
>
> @@ -1989,7 +1991,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
> int nbad = 0;
> int isaggr = 0;
>
> - if (bf->bf_tx_aborted)
> + if (bf->bf_lastbf->bf_tx_aborted)
> return 0;
>
> isaggr = bf_isaggr(bf);
> diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
> index a115bfa..7a377f5 100644
> --- a/drivers/net/wireless/libertas/rx.c
> +++ b/drivers/net/wireless/libertas/rx.c
> @@ -329,9 +329,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
> /* create the exported radio header */
>
> /* radiotap header */
> - radiotap_hdr.hdr.it_version = 0;
> - /* XXX must check this value for pad */
> - radiotap_hdr.hdr.it_pad = 0;
> + memset(&radiotap_hdr, 0, sizeof(radiotap_hdr));
> + /* XXX must check radiotap_hdr.hdr.it_pad for pad */
> radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
> radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
> radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
> index 6991613..0f8b84b 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
> */
> rt2x00_desc_read(txi, 0, &word);
> rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
> - skb->len - TXINFO_DESC_SIZE);
> + skb->len + TXWI_DESC_SIZE);
> rt2x00_set_field32(&word, TXINFO_W0_WIV,
> !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
> rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
> diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
> index 989e275..6dcda86 100644
> --- a/drivers/ssb/pci.c
> +++ b/drivers/ssb/pci.c
> @@ -625,9 +625,12 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
> ssb_printk(KERN_ERR PFX "No SPROM available!\n");
> return -ENODEV;
> }
> -
> - bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
> - SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
> + if (bus->chipco.dev) { /* can be unavailible! */
> + bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
> + SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
> + } else {
> + bus->sprom_offset = SSB_SPROM_BASE1;
> + }
>
> buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
> if (!buf)
> diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
> index 007bc3a..4f7cc8d 100644
> --- a/drivers/ssb/sprom.c
> +++ b/drivers/ssb/sprom.c
> @@ -185,6 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus)
> /* this routine differs from specs as we do not access SPROM directly
> on PCMCIA */
> if (bus->bustype == SSB_BUSTYPE_PCI &&
> + bus->chipco.dev && /* can be unavailible! */
> bus->chipco.dev->id.revision >= 31)
> return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
>
> diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
> index 5d218c5..32be11e 100644
> --- a/net/mac80211/chan.c
> +++ b/net/mac80211/chan.c
> @@ -5,7 +5,7 @@
> #include <linux/nl80211.h>
> #include "ieee80211_i.h"
>
> -enum ieee80211_chan_mode
> +static enum ieee80211_chan_mode
> __ieee80211_get_channel_mode(struct ieee80211_local *local,
> struct ieee80211_sub_if_data *ignore)
> {
> --
> John W. Linville Someday the world will need a hero, and you
> linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org might be all we have. Be ready.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] act_nat: fix the wrong checksum when addr isn't in old_addr/mask
From: Changli Gao @ 2010-05-29 10:41 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: David S. Miller, netdev, linux-kernel, Changli Gao
fix the wrong checksum when addr isn't in old_addr/mask
When addr isn't in old_addr/mask we don't do SNAT or DNAT, and we should not
update the checksum too.
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
net/sched/act_nat.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index d885ba3..f9b12a9 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -142,24 +142,25 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
else
addr = iph->daddr;
- if (!((old_addr ^ addr) & mask)) {
- if (skb_cloned(skb) &&
- !skb_clone_writable(skb, sizeof(*iph)) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
- goto drop;
+ if ((old_addr ^ addr) & mask)
+ goto out;
- new_addr &= mask;
- new_addr |= addr & ~mask;
+ if (skb_cloned(skb) &&
+ !skb_clone_writable(skb, sizeof(*iph)) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+ goto drop;
- /* Rewrite IP header */
- iph = ip_hdr(skb);
- if (egress)
- iph->saddr = new_addr;
- else
- iph->daddr = new_addr;
+ new_addr &= mask;
+ new_addr |= addr & ~mask;
- csum_replace4(&iph->check, addr, new_addr);
- }
+ /* Rewrite IP header */
+ iph = ip_hdr(skb);
+ if (egress)
+ iph->saddr = new_addr;
+ else
+ iph->daddr = new_addr;
+
+ csum_replace4(&iph->check, addr, new_addr);
ihl = iph->ihl * 4;
@@ -247,6 +248,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
break;
}
+out:
return action;
drop:
^ permalink raw reply related
* Re: [Patch] fix packet loss and massive ping spikes with PPP multi-link
From: Richard Hartmann @ 2010-05-29 9:06 UTC (permalink / raw)
To: Paul Mackerras
Cc: Ben McKeegan, netdev, linux-ppp, Alan Cox, Alexander E. Patrakov,
linux-kernel
In-Reply-To: <20100529021624.GA2538@brick.ozlabs.ibm.com>
On Sat, May 29, 2010 at 04:16, Paul Mackerras <paulus@samba.org> wrote:
> I like this a lot better than the other proposed patch.
Not that it really matters, but we would be happy with either patch
as long as we can stop patching mainline :)
Richard
^ permalink raw reply
* Re: [PATCH] net: mac8390 - Sort out memory/MMIO accesses and casts (was: Re: drivers/net/mac8390.c: Remove useless memcpy casting)
From: Geert Uytterhoeven @ 2010-05-29 8:03 UTC (permalink / raw)
To: Finn Thain
Cc: Joe Perches, David S. Miller, netdev, Linux Kernel Mailing List,
Linux/m68k
In-Reply-To: <alpine.OSX.2.00.1005290312230.691@localhost>
On Fri, May 28, 2010 at 19:21, Finn Thain <fthain@telegraphics.com.au> wrote:
> On Sun, 23 May 2010, Geert Uytterhoeven wrote:
>> >> But here's a better solution. I do not have the hardware to test it,
>> >> though. Finn, does it {look OK,work}?
>> >
>> > It looks fine. I can't test it right now, but I will do so when I get
>> > the opportunity.
>>
>> Any news from the test front?
>
> This is commit ba0f916ca7ac79356e2ed32a85c3aa8255b104e7, right?
Yep.
> If so, it tests OK here.
Thanks for testing!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: Warning in net/ipv4/af_inet.c:154
From: David Miller @ 2010-05-29 7:21 UTC (permalink / raw)
To: eric.dumazet; +Cc: anton, netdev
In-Reply-To: <1274868776.2672.96.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 26 May 2010 12:12:56 +0200
> [PATCH] net: fix sk_forward_alloc corruptions
>
> As David found out, sock_queue_err_skb() should be called with socket
> lock hold, or we risk sk_forward_alloc corruption, since we use non
> atomic operations to update this field.
>
> This patch adds bh_lock_sock()/bh_unlock_sock() pair to three spots.
> (BH already disabled)
>
> 1) skb_tstamp_tx()
> 2) Before calling ip_icmp_error(), in __udp4_lib_err()
> 3) Before calling ipv6_icmp_error(), in __udp6_lib_err()
>
> Reported-by: Anton Blanchard <anton@samba.org>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
This wasn't the direct cause of Anton's problems but is
a serious legitimate bug.
So, applied, thanks!
^ permalink raw reply
* Re: [patch 2/2] be2net: remove superfluous externs
From: David Miller @ 2010-05-29 7:20 UTC (permalink / raw)
To: error27; +Cc: sathyap, subbus, sarveshwarb, ajitk, netdev, kernel-janitors
In-Reply-To: <20100526144739.GM22515@bicker>
From: Dan Carpenter <error27@gmail.com>
Date: Wed, 26 May 2010 16:47:39 +0200
> This fixes some sparse warnings:
> drivers/net/benet/be_cmds.c:1503:12: warning: function
> 'be_cmd_enable_magic_wol' with external linkage has definition
> drivers/net/benet/be_cmds.c:1668:12: warning: function
> 'be_cmd_get_seeprom_data' with external linkage has definition
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>
Applied.
^ permalink raw reply
* Re: [patch 1/2] be2net: add unlock on error path
From: David Miller @ 2010-05-29 7:20 UTC (permalink / raw)
To: error27; +Cc: sathyap, subbus, sarveshwarb, ajitk, netdev, kernel-janitors
In-Reply-To: <20100526144634.GL22515@bicker>
From: Dan Carpenter <error27@gmail.com>
Date: Wed, 26 May 2010 16:46:35 +0200
> The unlock accidentally got removed from the error path in dd131e76e5:
> "be2net: Bug fix to avoid disabling bottom half during firmware upgrade."
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net 1/1] Phonet: listening socket lock protects the connected socket list
From: David Miller @ 2010-05-29 7:20 UTC (permalink / raw)
To: remi.denis-courmont; +Cc: netdev
In-Reply-To: <1274870684-18428-1-git-send-email-remi.denis-courmont@nokia.com>
From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Date: Wed, 26 May 2010 13:44:44 +0300
> From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
>
> The accept()'d socket need to be unhashed while the (listen()'ing)
> socket lock is held. This fixes a race condition that could lead to an
> OOPS.
>
> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Applied.
^ permalink raw reply
* Re: [PATCH 4/17] drivers/isdn/hardware/mISDN: Add missing spin_unlock
From: David Miller @ 2010-05-29 7:19 UTC (permalink / raw)
To: julia; +Cc: isdn, netdev, linux-kernel, kernel-janitors
In-Reply-To: <Pine.LNX.4.64.1005261754560.23743@ask.diku.dk>
From: Julia Lawall <julia@diku.dk>
Date: Wed, 26 May 2010 17:55:10 +0200 (CEST)
> From: Julia Lawall <julia@diku.dk>
>
> Add a spin_unlock missing on the error path. The return value of write_reg
> seems to be completely ignored, so it seems that the lock should be
> released in every case.
>
> The semantic match that finds this problem is as follows:
> (http://coccinelle.lip6.fr/)
...
> Signed-off-by: Julia Lawall <julia@diku.dk>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 1/17] net/rds: Add missing mutex_unlock
From: David Miller @ 2010-05-29 7:19 UTC (permalink / raw)
To: andy.grover
Cc: julia, rds-devel, netdev, linux-kernel, kernel-janitors,
zach.brown
In-Reply-To: <4BFD6076.9000005@oracle.com>
From: Andy Grover <andy.grover@oracle.com>
Date: Wed, 26 May 2010 10:55:02 -0700
> Reviewed-by: Zach Brown <zach.brown@oracle.com>
> Acked-by: Andy Grover <andy.grover@oracle.com>
Applied.
^ permalink raw reply
* Re: [patch] caif: unlock on error path in cfserl_receive()
From: David Miller @ 2010-05-29 7:19 UTC (permalink / raw)
To: sjurbren; +Cc: error27, sjur.brandeland, netdev, kernel-janitors
In-Reply-To: <AANLkTimYIjrnOwzSyALY42fhNojwh1zawaFMUVC1ml6Y@mail.gmail.com>
From: Sjur Brændeland <sjurbren@gmail.com>
Date: Wed, 26 May 2010 20:18:36 +0200
> Hi Dan.
>
> Dan Carpenter <error27@gmail.com> wrote:
>> There was an spin_unlock missing on the error path. The spin_lock was
>> tucked in with the declarations so it was hard to spot. I added a new
>> line.
>>
>> Signed-off-by: Dan Carpenter <error27@gmail.com>
> Acked-by: Sjur Braendeland
Applied.
Sjur, in the future please provide your full email address in
Acked-by: lines just as you would for a Signed-off-by: tag.
I fixed it up this time.
Thanks.
^ permalink raw reply
* Re: [PATCH] fs_enet: Adjust BDs after tx error
From: David Miller @ 2010-05-29 7:16 UTC (permalink / raw)
To: mware; +Cc: linuxppc-dev, netdev, vbordug, pantelis.antoniou
In-Reply-To: <4BFDC6EC.9090804@elphinstone.net>
From: Mark Ware <mware@elphinstone.net>
Date: Thu, 27 May 2010 11:12:12 +1000
> This patch fixes an occasional transmit lockup in the mac-fcc which
> occurs after a tx error. The test scenario had the local port set
> to autoneg and the other end fixed at 100FD, resulting in a large
> number of late collisions.
>
> According to the MPC8280RM 30.10.1.3 (also 8272RM 29.10.1.3), after
> a tx error occurs, TBPTR may sometimes point beyond BDs still marked
> as ready. This patch walks back through the BDs and points TBPTR to
> the earliest one marked as ready.
>
> Tested on a custom board with a MPC8280.
>
> Signed-off-by: Mark Ware <mware@elphinstone.net>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net/fec: fix pm to survive to suspend/resume
From: David Miller @ 2010-05-29 7:15 UTC (permalink / raw)
To: eric; +Cc: s.hauer, sshtylyov, linux-arm-kernel, fabioestevam, netdev
In-Reply-To: <1274982828-13082-1-git-send-email-eric@eukrea.com>
From: Eric Bénard <eric@eukrea.com>
Date: Thu, 27 May 2010 19:53:48 +0200
> * with this patch, if the connection if active before suspend, it
> will be active after resume.
> * before this patch, it was necessary to close the interface and
> reopen it to recover the connection.
>
> Signed-off-by: Eric Bénard <eric@eukrea.com>
On resume the PHY should be reset and the link renegotiated (or set to
a fixed speed/duplex if set by the user via ethtool) just like as
happens on ->open().
You seem to be avoiding that here.
If the PHY is not functioning properly after the ->resume() triggered
reset, fix that instead.
I'm not applying this patch, it doesn't look the right thing to do at
all.
^ permalink raw reply
* Re: [PATCH] skb: make skb_recycle_check() return a bool value
From: David Miller @ 2010-05-29 7:12 UTC (permalink / raw)
To: xiaosuo; +Cc: eric.dumazet, linux-kernel, netdev
In-Reply-To: <1274970803-8051-1-git-send-email-xiaosuo@gmail.com>
From: Changli Gao <xiaosuo@gmail.com>
Date: Thu, 27 May 2010 22:33:23 +0800
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] packet_mmap: expose hw packet timestamps to network packet capture utilities
From: David Miller @ 2010-05-29 7:11 UTC (permalink / raw)
To: scott.a.mcmillan; +Cc: netdev, tcpdump-workers
In-Reply-To: <09ED21B37E0F694688A2317C4FED9ED3046E53F595@azsmsx504.amr.corp.intel.com>
From: "Mcmillan, Scott A" <scott.a.mcmillan@intel.com>
Date: Thu, 27 May 2010 09:58:19 -0700
> There was no negative feedback on this RFC, and the corresponding
> tcpdump patch was well received. Please apply.
I think lack of feedback is not an indication of agreement.
You sent that patch right around the openning of the merge window when
people (myself included) are already overwhelmed with existing tasks.
New patches aren't likely to get serious consideration during that
time.
^ permalink raw reply
* Re: [PATCH net-next]atl1c: Add AR8151 v2 support and change L0s/L1 routine
From: David Miller @ 2010-05-29 7:06 UTC (permalink / raw)
To: jie.yang; +Cc: Luis.Rodriguez, netdev, linux-kernel
In-Reply-To: <12750324381174-git-send-email-jie.yang@atheros.com>
From: <jie.yang@atheros.com>
Date: Fri, 28 May 2010 15:40:38 +0800
> From: Jie.Yang@atheros.com
>
> Add AR8151 v2.0 Gigabit 1000 support
> Change jumbo frame size to 6K
> Update L0s/L1 rountine
> Update atl1c_suspend routine.
>
> Signed-off-by: Jie.Yang@atheros.com
Your commit log message is way too terse.
You should describe in detail what your changes are.
Saying "Update L0s/L1 routine" doesn't tell us exactly what change
you are making. And more importantly, it does not tell us why you
are making this change.
This also applied to "update atl1c_suspend routine" You have to
list exactly change you are making, and why.
You should be able to write a full paragraph explaining what each
change is, and the reason for that change. This means 4 to 5 full
english sentences, which means more than 3 or 4 words in each
sentence.
Do not try to put as minimal amount of information into your commit
messages as possible, instead strive to put too much information.
Be long winded, and verbose, because you cannot predict what details
of your change and reasoning will be important to someone in the future.
Because some day someone will read your commit patch and wonder the
reasons why you made your changes.
I am not applying this patch until the commit message is made more
verbose and reasonable.
^ permalink raw reply
* Re: [PATCH] net: add rtnl assertion to linkwatch_run_queue
From: David Miller @ 2010-05-29 7:01 UTC (permalink / raw)
To: dkirjanov; +Cc: eric.dumazet, shemminger, herbert, kaber, netdev
In-Reply-To: <20100527055100.GA21234@hera.kernel.org>
From: Denis Kirjanov <dkirjanov@hera.kernel.org>
Date: Thu, 27 May 2010 05:51:00 +0000
> Add RTNL assertion to linkwatch_run_queue since function
> must be called with semaphore held
>
> Signed-off-by: Denis Kirjanov <dkirjanov@kernel.org>
This function is exported purely for netdev_wait_allrefs()'s sake
and for no other purpose.
In fact, I'd say this is entirely a private functional interface
specifically built for generic network interface tear-down.
If you are trying to use this function in another context, that's
something you need to discuss with us first before we start peppering
it with various assertions.
I am not applying this patch.
^ permalink raw reply
* Re: [Patch] r8169: use u32 instead of unsigned long
From: David Miller @ 2010-05-29 6:53 UTC (permalink / raw)
To: junchangwang; +Cc: romieu, netdev
In-Reply-To: <20100529040111.GA28225@host-a-55.ustcsz.edu.cn>
From: Junchang Wang <junchangwang@gmail.com>
Date: Sat, 29 May 2010 12:01:11 +0800
> RTL_R32 should return value with 32-bit width. But "unsigned long"
> implies u64 on some 64-bit platforms.
>
> Signed-off-by: Junchang Wang <junchangwang@gmail.com>
I fail to see why there is a need to cast the return value
of readl() at all.
It returns a 32-bit integer on all platforms.
Secondly, 8139too.c has the same unnecessary cast.
So the thing to do is to kill the casts completely from both
drivers defining this register read macro.
^ permalink raw reply
* Re: [PATCH] bnx2: Fix IRQ failures during kdump.
From: David Miller @ 2010-05-29 6:50 UTC (permalink / raw)
To: grundler; +Cc: mchan, netdev, linux-pci
In-Reply-To: <20100529064512.GA21336@lackof.org>
From: Grant Grundler <grundler@parisc-linux.org>
Date: Sat, 29 May 2010 00:45:12 -0600
> If that's true, then this can't be handled in the generic PCI layer (as
> suggested by davem) unless the device driver could register multiple interrupt
> handlers even if only one is active at a time.
The generic PCI layer very well can turn off MSI on all devices
when it starts up or a device is plugged in.
That's all he is doing.
Drivers essentially expect that the device comes up in INTX mode
when the driver probes the device. All his change is doing
is forcing that to be true, and there is no reason the generic
PCI code can't do that.
^ permalink raw reply
* Re: [PATCH] bnx2: Fix IRQ failures during kdump.
From: Grant Grundler @ 2010-05-29 6:45 UTC (permalink / raw)
To: Michael Chan; +Cc: davem, netdev, linux-pci
In-Reply-To: <1275103462-8527-1-git-send-email-mchan@broadcom.com>
On Fri, May 28, 2010 at 08:24:22PM -0700, Michael Chan wrote:
> When switching from the crashed kernel to the kdump kernel without going
> through PCI reset, IRQs may not work if a different IRQ mode is used on
> the kdump kernel. The original IRQ mode used in the crashed kernel may
> still be enabled and the new IRQ mode may not work. For example, it
> will fail when going from MSI-X mode to MSI mode.
>
> We fix this by disabling MSI/MSI-X and enabling INTX in bnx2_init_board().
>
> pci_save_state() is also moved to the end of bnx2_init_board() after
> all config register fixups (including the new IRQ fixups) have been done.
>
> Export pci_msi_off() from drivers/pci/pci.c for this purpose.
>
> Update bnx2 version to 2.0.16.
>
> Signed-off-by: Michael Chan <mchan@broadcom.com>
> ---
> drivers/net/bnx2.c | 17 ++++++++++++++---
> drivers/pci/pci.c | 1 +
> 2 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> index 188e356..1b8ba14 100644
> --- a/drivers/net/bnx2.c
> +++ b/drivers/net/bnx2.c
> @@ -58,8 +58,8 @@
> #include "bnx2_fw.h"
>
> #define DRV_MODULE_NAME "bnx2"
> -#define DRV_MODULE_VERSION "2.0.15"
> -#define DRV_MODULE_RELDATE "May 4, 2010"
> +#define DRV_MODULE_VERSION "2.0.16"
> +#define DRV_MODULE_RELDATE "May 28, 2010"
> #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-5.0.0.j6.fw"
> #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
> #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-5.0.0.j15.fw"
> @@ -7877,7 +7877,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
> }
>
> pci_set_master(pdev);
> - pci_save_state(pdev);
>
> bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
> if (bp->pm_cap == 0) {
> @@ -7953,6 +7952,16 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
> bp->flags |= BNX2_FLAG_MSI_CAP;
> }
>
> + /* When going from a crashed kernel to a kdump kernel without PCI
> + * reset, MSI/MSI-X may still be enabled. We need to disable
> + * MSI/MSI-X and enable INTX because the kdump driver may operate
> + * the device in a different IRQ mode.
> + */
> + if (bp->flags & (BNX2_FLAG_MSI_CAP | BNX2_FLAG_MSIX_CAP)) {
> + pci_msi_off(pdev);
> + pci_intx(pdev, 1);
Does the driver have to register a different Interrupt handler when
switching from MSI(-X) to IRQ interrupts?
(I'm thinking of IRQ interrupts might have DMA vs IRQ ordering dependency)
If that's true, then this can't be handled in the generic PCI layer (as
suggested by davem) unless the device driver could register multiple interrupt
handlers even if only one is active at a time.
thanks,
grant
> + }
> +
> /* 5708 cannot support DMA addresses > 40-bit. */
> if (CHIP_NUM(bp) == CHIP_NUM_5708)
> persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
> @@ -8188,6 +8197,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
> bp->timer.data = (unsigned long) bp;
> bp->timer.function = bnx2_timer;
>
> + pci_save_state(pdev);
> +
> return 0;
>
> err_out_unmap:
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 1df7c50..a46b49d 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -2294,6 +2294,7 @@ void pci_msi_off(struct pci_dev *dev)
> pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
> }
> }
> +EXPORT_SYMBOL(pci_msi_off);
>
> #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
> int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
> --
> 1.6.4.GIT
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox