Skip to content

Commit

Permalink
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…davem/net-2.6
  • Loading branch information
David S. Miller committed Mar 31, 2011
2 parents 6aba74f + a84b50c commit 4e700bc
Show file tree
Hide file tree
Showing 25 changed files with 531 additions and 216 deletions.
39 changes: 11 additions & 28 deletions drivers/atm/solos-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *);
static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
static void release_vccs(struct atm_dev *dev);
static int atm_init(struct solos_card *, struct device *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
Expand Down Expand Up @@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
/* Anything but 'Showtime' is down */
if (strcmp(state_str, "Showtime")) {
atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST);
release_vccs(card->atmdev[port]);
dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
return 0;
}
Expand Down Expand Up @@ -697,7 +695,7 @@ void solos_bh(unsigned long card_arg)
size);
}
if (atmdebug) {
dev_info(&card->dev->dev, "Received: device %d\n", port);
dev_info(&card->dev->dev, "Received: port %d\n", port);
dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
size, le16_to_cpu(header->vpi),
le16_to_cpu(header->vci));
Expand All @@ -710,8 +708,8 @@ void solos_bh(unsigned long card_arg)
le16_to_cpu(header->vci));
if (!vcc) {
if (net_ratelimit())
dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
port);
continue;
}
Expand Down Expand Up @@ -830,28 +828,6 @@ static int list_vccs(int vci)
return num_found;
}

static void release_vccs(struct atm_dev *dev)
{
int i;

write_lock_irq(&vcc_sklist_lock);
for (i = 0; i < VCC_HTABLE_SIZE; i++) {
struct hlist_head *head = &vcc_hash[i];
struct hlist_node *node, *tmp;
struct sock *s;
struct atm_vcc *vcc;

sk_for_each_safe(s, node, tmp, head) {
vcc = atm_sk(s);
if (vcc->dev == dev) {
vcc_release_async(vcc, -EPIPE);
sk_del_node_init(s);
}
}
}
write_unlock_irq(&vcc_sklist_lock);
}


static int popen(struct atm_vcc *vcc)
{
Expand Down Expand Up @@ -1018,8 +994,15 @@ static uint32_t fpga_tx(struct solos_card *card)

/* Clean up and free oldskb now it's gone */
if (atmdebug) {
struct pkt_hdr *header = (void *)oldskb->data;
int size = le16_to_cpu(header->size);

skb_pull(oldskb, sizeof(*header));
dev_info(&card->dev->dev, "Transmitted: port %d\n",
port);
dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
size, le16_to_cpu(header->vpi),
le16_to_cpu(header->vci));
print_buffer(oldskb);
}

Expand Down Expand Up @@ -1262,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
card->atmdev[i]->ci_range.vci_bits = 16;
card->atmdev[i]->dev_data = card;
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN);
atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);

skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
if (!skb) {
Expand Down
58 changes: 17 additions & 41 deletions drivers/connector/cn_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,9 @@
#include <linux/connector.h>
#include <linux/delay.h>

void cn_queue_wrapper(struct work_struct *work)
{
struct cn_callback_entry *cbq =
container_of(work, struct cn_callback_entry, work);
struct cn_callback_data *d = &cbq->data;
struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);

d->callback(msg, nsp);

kfree_skb(d->skb);
d->skb = NULL;

kfree(d->free);
}

static struct cn_callback_entry *
cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
struct cb_id *id,
void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
{
struct cn_callback_entry *cbq;
Expand All @@ -59,17 +44,23 @@ cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
return NULL;
}

atomic_set(&cbq->refcnt, 1);

atomic_inc(&dev->refcnt);
cbq->pdev = dev;

snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
cbq->data.callback = callback;

INIT_WORK(&cbq->work, &cn_queue_wrapper);
cbq->callback = callback;
return cbq;
}

static void cn_queue_free_callback(struct cn_callback_entry *cbq)
void cn_queue_release_callback(struct cn_callback_entry *cbq)
{
flush_workqueue(cbq->pdev->cn_queue);
if (!atomic_dec_and_test(&cbq->refcnt))
return;

atomic_dec(&cbq->pdev->refcnt);
kfree(cbq);
}

Expand All @@ -85,13 +76,10 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
struct cn_callback_entry *cbq, *__cbq;
int found = 0;

cbq = cn_queue_alloc_callback_entry(name, id, callback);
cbq = cn_queue_alloc_callback_entry(dev, name, id, callback);
if (!cbq)
return -ENOMEM;

atomic_inc(&dev->refcnt);
cbq->pdev = dev;

spin_lock_bh(&dev->queue_lock);
list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->id.id, id)) {
Expand All @@ -104,8 +92,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
spin_unlock_bh(&dev->queue_lock);

if (found) {
cn_queue_free_callback(cbq);
atomic_dec(&dev->refcnt);
cn_queue_release_callback(cbq);
return -EINVAL;
}

Expand All @@ -130,10 +117,8 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
}
spin_unlock_bh(&dev->queue_lock);

if (found) {
cn_queue_free_callback(cbq);
atomic_dec(&dev->refcnt);
}
if (found)
cn_queue_release_callback(cbq);
}

struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
Expand All @@ -151,22 +136,13 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)

dev->nls = nls;

dev->cn_queue = alloc_ordered_workqueue(dev->name, 0);
if (!dev->cn_queue) {
kfree(dev);
return NULL;
}

return dev;
}

void cn_queue_free_dev(struct cn_queue_dev *dev)
{
struct cn_callback_entry *cbq, *n;

flush_workqueue(dev->cn_queue);
destroy_workqueue(dev->cn_queue);

spin_lock_bh(&dev->queue_lock);
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
list_del(&cbq->callback_entry);
Expand Down
47 changes: 12 additions & 35 deletions drivers/connector/connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,51 +122,28 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
*/
static int cn_call_callback(struct sk_buff *skb)
{
struct cn_callback_entry *__cbq, *__new_cbq;
struct cn_callback_entry *i, *cbq = NULL;
struct cn_dev *dev = &cdev;
struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
struct netlink_skb_parms *nsp = &NETLINK_CB(skb);
int err = -ENODEV;

spin_lock_bh(&dev->cbdev->queue_lock);
list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
if (likely(!work_pending(&__cbq->work) &&
__cbq->data.skb == NULL)) {
__cbq->data.skb = skb;

if (queue_work(dev->cbdev->cn_queue,
&__cbq->work))
err = 0;
else
err = -EINVAL;
} else {
struct cn_callback_data *d;

err = -ENOMEM;
__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
if (__new_cbq) {
d = &__new_cbq->data;
d->skb = skb;
d->callback = __cbq->data.callback;
d->free = __new_cbq;

INIT_WORK(&__new_cbq->work,
&cn_queue_wrapper);

if (queue_work(dev->cbdev->cn_queue,
&__new_cbq->work))
err = 0;
else {
kfree(__new_cbq);
err = -EINVAL;
}
}
}
list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) {
if (cn_cb_equal(&i->id.id, &msg->id)) {
atomic_inc(&i->refcnt);
cbq = i;
break;
}
}
spin_unlock_bh(&dev->cbdev->queue_lock);

if (cbq != NULL) {
cbq->callback(msg, nsp);
kfree_skb(skb);
cn_queue_release_callback(cbq);
}

return err;
}

Expand Down
22 changes: 14 additions & 8 deletions drivers/net/atlx/atl2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1996,13 +1996,15 @@ static int atl2_set_eeprom(struct net_device *netdev,
if (!eeprom_buff)
return -ENOMEM;

ptr = (u32 *)eeprom_buff;
ptr = eeprom_buff;

if (eeprom->offset & 3) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0])))
return -EIO;
if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
ret_val = -EIO;
goto out;
}
ptr++;
}
if (((eeprom->offset + eeprom->len) & 3)) {
Expand All @@ -2011,18 +2013,22 @@ static int atl2_set_eeprom(struct net_device *netdev,
* only the first byte of the word is being modified
*/
if (!atl2_read_eeprom(hw, last_dword * 4,
&(eeprom_buff[last_dword - first_dword])))
return -EIO;
&(eeprom_buff[last_dword - first_dword]))) {
ret_val = -EIO;
goto out;
}
}

/* Device's eeprom is always little-endian, word addressable */
memcpy(ptr, bytes, eeprom->len);

for (i = 0; i < last_dword - first_dword + 1; i++) {
if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i]))
return -EIO;
if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
ret_val = -EIO;
goto out;
}
}

out:
kfree(eeprom_buff);
return ret_val;
}
Expand Down
Loading

0 comments on commit 4e700bc

Please sign in to comment.