diff --git a/[refs] b/[refs] index 7994369be269..3cf715b60bb8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: afdef69c7ff7d0bf59e3cafc187aefb12878dbe3 +refs/heads/master: 963e5d3b76d657f1ebcf3561446d2ba1872bbfa2 diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index aa9269600ca2..375480c56eb9 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -577,14 +577,21 @@ void timer_interrupt(struct pt_regs * regs) struct clock_event_device *evt = &decrementer->event; u64 now; + /* Ensure a positive value is written to the decrementer, or else + * some CPUs will continue to take decrementer exceptions. + */ + set_dec(DECREMENTER_MAX); + + /* Some implementations of hotplug will get timer interrupts while + * offline, just ignore these + */ + if (!cpu_online(smp_processor_id())) + return; + trace_timer_interrupt_entry(regs); __get_cpu_var(irq_stat).timer_irqs++; - /* Ensure a positive value is written to the decrementer, or else - * some CPUs will continuue to take decrementer exceptions */ - set_dec(DECREMENTER_MAX); - #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); diff --git a/trunk/arch/sparc/include/asm/unistd.h b/trunk/arch/sparc/include/asm/unistd.h index 9d897b6db983..2f475d7c0b53 100644 --- a/trunk/arch/sparc/include/asm/unistd.h +++ b/trunk/arch/sparc/include/asm/unistd.h @@ -403,9 +403,8 @@ #define __NR_name_to_handle_at 332 #define __NR_open_by_handle_at 333 #define __NR_clock_adjtime 334 -#define __NR_syncfs 335 -#define NR_syscalls 336 +#define NR_syscalls 335 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/trunk/arch/sparc/kernel/auxio_64.c b/trunk/arch/sparc/kernel/auxio_64.c index 773091ac71a3..2abace076c7d 100644 --- a/trunk/arch/sparc/kernel/auxio_64.c +++ b/trunk/arch/sparc/kernel/auxio_64.c @@ -93,7 +93,7 @@ void auxio_set_lte(int on) } EXPORT_SYMBOL(auxio_set_lte); -static const struct of_device_id auxio_match[] = { +static struct of_device_id __initdata auxio_match[] = { { .name = "auxio", }, diff --git a/trunk/arch/sparc/kernel/central.c b/trunk/arch/sparc/kernel/central.c index 7eef3f741963..136d3718a74a 100644 --- a/trunk/arch/sparc/kernel/central.c +++ b/trunk/arch/sparc/kernel/central.c @@ -140,7 +140,7 @@ static int __devinit clock_board_probe(struct platform_device *op) goto out; } -static const struct of_device_id clock_board_match[] = { +static struct of_device_id __initdata clock_board_match[] = { { .name = "clock-board", }, @@ -245,7 +245,7 @@ static int __devinit fhc_probe(struct platform_device *op) goto out; } -static const struct of_device_id fhc_match[] = { +static struct of_device_id __initdata fhc_match[] = { { .name = "fhc", }, diff --git a/trunk/arch/sparc/kernel/ds.c b/trunk/arch/sparc/kernel/ds.c index 3add4de8a1a9..4a700f4b79ce 100644 --- a/trunk/arch/sparc/kernel/ds.c +++ b/trunk/arch/sparc/kernel/ds.c @@ -1218,7 +1218,7 @@ static int ds_remove(struct vio_dev *vdev) return 0; } -static const struct vio_device_id ds_match[] = { +static struct vio_device_id __initdata ds_match[] = { { .type = "domain-services-port", }, diff --git a/trunk/arch/sparc/kernel/entry.S b/trunk/arch/sparc/kernel/entry.S index 906ee3e24cc9..1504df8ddf70 100644 --- a/trunk/arch/sparc/kernel/entry.S +++ b/trunk/arch/sparc/kernel/entry.S @@ -1283,7 +1283,7 @@ linux_syscall_trace: .globl ret_from_fork ret_from_fork: call schedule_tail - ld [%g3 + TI_TASK], %o0 + mov %g3, %o0 b ret_sys_call ld [%sp + STACKFRAME_SZ + PT_I0], %o0 diff --git a/trunk/arch/sparc/kernel/mdesc.c b/trunk/arch/sparc/kernel/mdesc.c index 56db06432ce9..6addb914fcc8 100644 --- a/trunk/arch/sparc/kernel/mdesc.c +++ b/trunk/arch/sparc/kernel/mdesc.c @@ -107,7 +107,7 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size return hp; } -static void __init mdesc_memblock_free(struct mdesc_handle *hp) +static void mdesc_memblock_free(struct mdesc_handle *hp) { unsigned int alloc_size; unsigned long start; diff --git a/trunk/arch/sparc/kernel/pci_fire.c b/trunk/arch/sparc/kernel/pci_fire.c index d29a32fcc5e4..3d70f8326efd 100644 --- a/trunk/arch/sparc/kernel/pci_fire.c +++ b/trunk/arch/sparc/kernel/pci_fire.c @@ -496,7 +496,7 @@ static int __devinit fire_probe(struct platform_device *op) return err; } -static const struct of_device_id fire_match[] = { +static struct of_device_id __initdata fire_match[] = { { .name = "pci", .compatible = "pciex108e,80f0", diff --git a/trunk/arch/sparc/kernel/pci_psycho.c b/trunk/arch/sparc/kernel/pci_psycho.c index 86ae08d9b6ee..56ee745064de 100644 --- a/trunk/arch/sparc/kernel/pci_psycho.c +++ b/trunk/arch/sparc/kernel/pci_psycho.c @@ -592,7 +592,7 @@ static int __devinit psycho_probe(struct platform_device *op) return err; } -static const struct of_device_id psycho_match[] = { +static struct of_device_id __initdata psycho_match[] = { { .name = "pci", .compatible = "pci108e,8000", diff --git a/trunk/arch/sparc/kernel/pci_sabre.c b/trunk/arch/sparc/kernel/pci_sabre.c index 948068a083fc..2857073342d2 100644 --- a/trunk/arch/sparc/kernel/pci_sabre.c +++ b/trunk/arch/sparc/kernel/pci_sabre.c @@ -581,7 +581,7 @@ static int __devinit sabre_probe(struct platform_device *op) return err; } -static const struct of_device_id sabre_match[] = { +static struct of_device_id __initdata sabre_match[] = { { .name = "pci", .compatible = "pci108e,a001", diff --git a/trunk/arch/sparc/kernel/pci_schizo.c b/trunk/arch/sparc/kernel/pci_schizo.c index fecfcb2063c8..1d41af73a92f 100644 --- a/trunk/arch/sparc/kernel/pci_schizo.c +++ b/trunk/arch/sparc/kernel/pci_schizo.c @@ -1470,7 +1470,7 @@ static int __devinit schizo_probe(struct platform_device *op) * and pci108e,8001. So list the chips in reverse chronological * order. */ -static const struct of_device_id schizo_match[] = { +static struct of_device_id __initdata schizo_match[] = { { .name = "pci", .compatible = "pci108e,a801", diff --git a/trunk/arch/sparc/kernel/pci_sun4v.c b/trunk/arch/sparc/kernel/pci_sun4v.c index b01a06e9ae4e..6cf534681788 100644 --- a/trunk/arch/sparc/kernel/pci_sun4v.c +++ b/trunk/arch/sparc/kernel/pci_sun4v.c @@ -998,7 +998,7 @@ static int __devinit pci_sun4v_probe(struct platform_device *op) return err; } -static const struct of_device_id pci_sun4v_match[] = { +static struct of_device_id __initdata pci_sun4v_match[] = { { .name = "pci", .compatible = "SUNW,sun4v-pci", diff --git a/trunk/arch/sparc/kernel/power.c b/trunk/arch/sparc/kernel/power.c index cb4c0f57c024..cd725fe238b2 100644 --- a/trunk/arch/sparc/kernel/power.c +++ b/trunk/arch/sparc/kernel/power.c @@ -52,7 +52,7 @@ static int __devinit power_probe(struct platform_device *op) return 0; } -static const struct of_device_id power_match[] = { +static struct of_device_id __initdata power_match[] = { { .name = "power", }, diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S index 47ac73c32e88..4b86eaf04fe5 100644 --- a/trunk/arch/sparc/kernel/systbls_32.S +++ b/trunk/arch/sparc/kernel/systbls_32.S @@ -84,4 +84,4 @@ sys_call_table: /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime -/*335*/ .long sys_syncfs + diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 4f3170c1ef47..0331bafdf3a3 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -85,7 +85,6 @@ sys_call_table32: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime - .word sys_syncfs #endif /* CONFIG_COMPAT */ @@ -162,4 +161,3 @@ sys_call_table: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime - .word sys_syncfs diff --git a/trunk/arch/sparc/kernel/time_64.c b/trunk/arch/sparc/kernel/time_64.c index 2b8d54b2d850..95ec25faba39 100644 --- a/trunk/arch/sparc/kernel/time_64.c +++ b/trunk/arch/sparc/kernel/time_64.c @@ -442,7 +442,7 @@ static int __devinit rtc_probe(struct platform_device *op) return platform_device_register(&rtc_cmos_device); } -static const struct of_device_id rtc_match[] = { +static struct of_device_id __initdata rtc_match[] = { { .name = "rtc", .compatible = "m5819", @@ -487,7 +487,7 @@ static int __devinit bq4802_probe(struct platform_device *op) return platform_device_register(&rtc_bq4802_device); } -static const struct of_device_id bq4802_match[] = { +static struct of_device_id __initdata bq4802_match[] = { { .name = "rtc", .compatible = "bq4802", @@ -552,7 +552,7 @@ static int __devinit mostek_probe(struct platform_device *op) return platform_device_register(&m48t59_rtc); } -static const struct of_device_id mostek_match[] = { +static struct of_device_id __initdata mostek_match[] = { { .name = "eeprom", }, diff --git a/trunk/drivers/atm/solos-pci.c b/trunk/drivers/atm/solos-pci.c index cd0ff66469b2..25ef1a4556e6 100644 --- a/trunk/drivers/atm/solos-pci.c +++ b/trunk/drivers/atm/solos-pci.c @@ -165,6 +165,7 @@ 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); @@ -383,6 +384,7 @@ 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; } @@ -695,7 +697,7 @@ void solos_bh(unsigned long card_arg) size); } if (atmdebug) { - dev_info(&card->dev->dev, "Received: port %d\n", port); + dev_info(&card->dev->dev, "Received: device %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)); @@ -708,8 +710,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 VPI.VCI %d.%d on port %d\n", - le16_to_cpu(header->vpi), le16_to_cpu(header->vci), + 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), port); continue; } @@ -828,6 +830,28 @@ 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) { @@ -994,15 +1018,8 @@ 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); } @@ -1245,7 +1262,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_FOUND); + atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { diff --git a/trunk/drivers/connector/cn_queue.c b/trunk/drivers/connector/cn_queue.c index c42c9d517790..55653aba6735 100644 --- a/trunk/drivers/connector/cn_queue.c +++ b/trunk/drivers/connector/cn_queue.c @@ -31,9 +31,24 @@ #include #include +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(struct cn_queue_dev *dev, const char *name, - struct cb_id *id, +cn_queue_alloc_callback_entry(const char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq; @@ -44,23 +59,17 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, 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->callback = callback; + cbq->data.callback = callback; + + INIT_WORK(&cbq->work, &cn_queue_wrapper); return cbq; } -void cn_queue_release_callback(struct cn_callback_entry *cbq) +static void cn_queue_free_callback(struct cn_callback_entry *cbq) { - if (!atomic_dec_and_test(&cbq->refcnt)) - return; - - atomic_dec(&cbq->pdev->refcnt); + flush_workqueue(cbq->pdev->cn_queue); kfree(cbq); } @@ -76,10 +85,13 @@ 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(dev, name, id, callback); + cbq = cn_queue_alloc_callback_entry(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)) { @@ -92,7 +104,8 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, spin_unlock_bh(&dev->queue_lock); if (found) { - cn_queue_release_callback(cbq); + cn_queue_free_callback(cbq); + atomic_dec(&dev->refcnt); return -EINVAL; } @@ -117,8 +130,10 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) } spin_unlock_bh(&dev->queue_lock); - if (found) - cn_queue_release_callback(cbq); + if (found) { + cn_queue_free_callback(cbq); + atomic_dec(&dev->refcnt); + } } struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) @@ -136,6 +151,12 @@ 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; } @@ -143,6 +164,9 @@ 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); diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c index d77005849af8..f7554de3be5e 100644 --- a/trunk/drivers/connector/connector.c +++ b/trunk/drivers/connector/connector.c @@ -122,28 +122,51 @@ EXPORT_SYMBOL_GPL(cn_netlink_send); */ static int cn_call_callback(struct sk_buff *skb) { - struct cn_callback_entry *i, *cbq = NULL; + struct cn_callback_entry *__cbq, *__new_cbq; 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(i, &dev->cbdev->queue_list, callback_entry) { - if (cn_cb_equal(&i->id.id, &msg->id)) { - atomic_inc(&i->refcnt); - cbq = i; + 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; + } + } + } 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; } diff --git a/trunk/drivers/net/atlx/atl2.c b/trunk/drivers/net/atlx/atl2.c index 937ef1afa5db..e637e9f28fd4 100644 --- a/trunk/drivers/net/atlx/atl2.c +++ b/trunk/drivers/net/atlx/atl2.c @@ -1996,15 +1996,13 @@ static int atl2_set_eeprom(struct net_device *netdev, if (!eeprom_buff) return -ENOMEM; - ptr = eeprom_buff; + ptr = (u32 *)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]))) { - ret_val = -EIO; - goto out; - } + if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) + return -EIO; ptr++; } if (((eeprom->offset + eeprom->len) & 3)) { @@ -2013,22 +2011,18 @@ 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]))) { - ret_val = -EIO; - goto out; - } + &(eeprom_buff[last_dword - first_dword]))) + return -EIO; } /* 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])) { - ret_val = -EIO; - goto out; - } + if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) + return -EIO; } - out: + kfree(eeprom_buff); return ret_val; } diff --git a/trunk/drivers/net/bonding/bond_alb.h b/trunk/drivers/net/bonding/bond_alb.h index 4b3e35878406..118c28aa471e 100644 --- a/trunk/drivers/net/bonding/bond_alb.h +++ b/trunk/drivers/net/bonding/bond_alb.h @@ -74,7 +74,7 @@ struct tlb_client_info { * packets to a Client that the Hash function * gave this entry index. */ - u32 tx_bytes; /* Each Client accumulates the BytesTx that + u32 tx_bytes; /* Each Client acumulates the BytesTx that * were tranmitted to it, and after each * CallBack the LoadHistory is devided * by the balance interval diff --git a/trunk/drivers/net/irda/via-ircc.c b/trunk/drivers/net/irda/via-ircc.c index 186cd28a61cc..67c0ad42d818 100644 --- a/trunk/drivers/net/irda/via-ircc.c +++ b/trunk/drivers/net/irda/via-ircc.c @@ -75,9 +75,15 @@ static int dongle_id = 0; /* default: probe */ /* We can't guess the type of connected dongle, user *must* supply it. */ module_param(dongle_id, int, 0); +/* FIXME : we should not need this, because instances should be automatically + * managed by the PCI layer. Especially that we seem to only be using the + * first entry. Jean II */ +/* Max 4 instances for now */ +static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; + /* Some prototypes */ -static int via_ircc_open(struct pci_dev *pdev, chipio_t * info, - unsigned int id); +static int via_ircc_open(int i, chipio_t * info, unsigned int id); +static int via_ircc_close(struct via_ircc_cb *self); static int via_ircc_dma_receive(struct via_ircc_cb *self); static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, int iobase); @@ -209,7 +215,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); pci_write_config_byte(pcidev,0x5a,0xc0); WriteLPCReg(0x28, 0x70 ); - if (via_ircc_open(pcidev, &info, 0x3076) == 0) + if (via_ircc_open(0, &info,0x3076) == 0) rc=0; } else rc = -ENODEV; //IR not turn on @@ -248,7 +254,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi info.irq=FirIRQ; info.dma=FirDRQ1; info.dma2=FirDRQ0; - if (via_ircc_open(pcidev, &info, 0x3096) == 0) + if (via_ircc_open(0, &info,0x3096) == 0) rc=0; } else rc = -ENODEV; //IR not turn on !!!!! @@ -258,10 +264,48 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi return rc; } +/* + * Function via_ircc_clean () + * + * Close all configured chips + * + */ +static void via_ircc_clean(void) +{ + int i; + + IRDA_DEBUG(3, "%s()\n", __func__); + + for (i=0; i < ARRAY_SIZE(dev_self); i++) { + if (dev_self[i]) + via_ircc_close(dev_self[i]); + } +} + +static void __devexit via_remove_one (struct pci_dev *pdev) +{ + IRDA_DEBUG(3, "%s()\n", __func__); + + /* FIXME : This is ugly. We should use pci_get_drvdata(pdev); + * to get our driver instance and call directly via_ircc_close(). + * See vlsi_ir for details... + * Jean II */ + via_ircc_clean(); + + /* FIXME : This should be in via_ircc_close(), because here we may + * theoritically disable still configured devices :-( - Jean II */ + pci_disable_device(pdev); +} + static void __exit via_ircc_cleanup(void) { IRDA_DEBUG(3, "%s()\n", __func__); + /* FIXME : This should be redundant, as pci_unregister_driver() + * should call via_remove_one() on each device. + * Jean II */ + via_ircc_clean(); + /* Cleanup all instances of the driver */ pci_unregister_driver (&via_driver); } @@ -280,13 +324,12 @@ static const struct net_device_ops via_ircc_fir_ops = { }; /* - * Function via_ircc_open(pdev, iobase, irq) + * Function via_ircc_open (iobase, irq) * * Open driver instance * */ -static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, - unsigned int id) +static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) { struct net_device *dev; struct via_ircc_cb *self; @@ -294,6 +337,9 @@ static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, IRDA_DEBUG(3, "%s()\n", __func__); + if (i >= ARRAY_SIZE(dev_self)) + return -ENOMEM; + /* Allocate new instance of the driver */ dev = alloc_irdadev(sizeof(struct via_ircc_cb)); if (dev == NULL) @@ -303,8 +349,13 @@ static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, self->netdev = dev; spin_lock_init(&self->lock); - pci_set_drvdata(pdev, self); - + /* FIXME : We should store our driver instance in the PCI layer, + * using pci_set_drvdata(), not in this array. + * See vlsi_ir for details... - Jean II */ + /* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */ + /* Need to store self somewhere */ + dev_self[i] = self; + self->index = i; /* Initialize Resource */ self->io.cfg_base = info->cfg_base; self->io.fir_base = info->fir_base; @@ -363,7 +414,7 @@ static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, /* Allocate memory if needed */ self->rx_buff.head = - dma_alloc_coherent(&pdev->dev, self->rx_buff.truesize, + dma_alloc_coherent(NULL, self->rx_buff.truesize, &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; @@ -372,7 +423,7 @@ static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = - dma_alloc_coherent(&pdev->dev, self->tx_buff.truesize, + dma_alloc_coherent(NULL, self->tx_buff.truesize, &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; @@ -404,32 +455,33 @@ static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, via_hw_init(self); return 0; err_out4: - dma_free_coherent(&pdev->dev, self->tx_buff.truesize, + dma_free_coherent(NULL, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); err_out3: - dma_free_coherent(&pdev->dev, self->rx_buff.truesize, + dma_free_coherent(NULL, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); err_out2: release_region(self->io.fir_base, self->io.fir_ext); err_out1: - pci_set_drvdata(pdev, NULL); free_netdev(dev); + dev_self[i] = NULL; return err; } /* - * Function via_remove_one(pdev) + * Function via_ircc_close (self) * * Close driver instance * */ -static void __devexit via_remove_one(struct pci_dev *pdev) +static int via_ircc_close(struct via_ircc_cb *self) { - struct via_ircc_cb *self = pci_get_drvdata(pdev); int iobase; IRDA_DEBUG(3, "%s()\n", __func__); + IRDA_ASSERT(self != NULL, return -1;); + iobase = self->io.fir_base; ResetChip(iobase, 5); //hardware reset. @@ -441,16 +493,16 @@ static void __devexit via_remove_one(struct pci_dev *pdev) __func__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - dma_free_coherent(&pdev->dev, self->tx_buff.truesize, + dma_free_coherent(NULL, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - dma_free_coherent(&pdev->dev, self->rx_buff.truesize, + dma_free_coherent(NULL, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); - pci_set_drvdata(pdev, NULL); + dev_self[self->index] = NULL; free_netdev(self->netdev); - pci_disable_device(pdev); + return 0; } /* diff --git a/trunk/drivers/net/mlx4/eq.c b/trunk/drivers/net/mlx4/eq.c index 1ad1f6029af8..506cfd0372ec 100644 --- a/trunk/drivers/net/mlx4/eq.c +++ b/trunk/drivers/net/mlx4/eq.c @@ -603,9 +603,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) } for (i = 0; i < dev->caps.num_comp_vectors; ++i) { - err = mlx4_create_eq(dev, dev->caps.num_cqs - - dev->caps.reserved_cqs + - MLX4_NUM_SPARE_EQE, + err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE, (dev->flags & MLX4_FLAG_MSI_X) ? i : 0, &priv->eq_table.eq[i]); if (err) { diff --git a/trunk/drivers/net/mlx4/mcg.c b/trunk/drivers/net/mlx4/mcg.c index 37150b2f6425..e71372aa9cc4 100644 --- a/trunk/drivers/net/mlx4/mcg.c +++ b/trunk/drivers/net/mlx4/mcg.c @@ -469,6 +469,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port, /*remove from list of promisc qps */ list_del(&pqp->list); + kfree(pqp); /* set the default entry not to include the removed one */ mailbox = mlx4_alloc_cmd_mailbox(dev); @@ -527,8 +528,6 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port, out_list: if (back_to_list) list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); - else - kfree(pqp); out_mutex: mutex_unlock(&priv->mcg_table.mutex); return err; diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index e870c0698bbe..993c52c82aeb 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, u32 flags, phy_interface_t interface) { struct device *d = &phydev->dev; - int err; /* Assume that if there is no driver, that it doesn't * exist, and we should use the genphy driver. */ if (NULL == d->driver) { + int err; d->driver = &genphy_driver.driver; err = d->driver->probe(d); @@ -474,11 +474,7 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, /* Do initial configuration here, now that * we have certain key parameters * (dev_flags and interface) */ - err = phy_init_hw(phydev); - if (err) - phy_detach(phydev); - - return err; + return phy_init_hw(phydev); } /** diff --git a/trunk/drivers/net/usb/Kconfig b/trunk/drivers/net/usb/Kconfig index 3ec22c307797..6f600cced6e1 100644 --- a/trunk/drivers/net/usb/Kconfig +++ b/trunk/drivers/net/usb/Kconfig @@ -433,19 +433,4 @@ config USB_SIERRA_NET To compile this driver as a module, choose M here: the module will be called sierra_net. -config USB_VL600 - tristate "LG VL600 modem dongle" - depends on USB_NET_CDCETHER - select USB_ACM - help - Select this if you want to use an LG Electronics 4G/LTE usb modem - called VL600. This driver only handles the ethernet - interface exposed by the modem firmware. To establish a connection - you will first need a userspace program that sends the right - command to the modem through its CDC ACM port, and most - likely also a DHCP client. See this thread about using the - 4G modem from Verizon: - - http://ubuntuforums.org/showpost.php?p=10589647&postcount=17 - endmenu diff --git a/trunk/drivers/net/usb/Makefile b/trunk/drivers/net/usb/Makefile index c7ec8a5f0a90..cac170301187 100644 --- a/trunk/drivers/net/usb/Makefile +++ b/trunk/drivers/net/usb/Makefile @@ -27,5 +27,4 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o -obj-$(CONFIG_USB_VL600) += lg-vl600.o diff --git a/trunk/drivers/net/usb/cdc_ether.c b/trunk/drivers/net/usb/cdc_ether.c index 51c259b69278..9a60e415d76b 100644 --- a/trunk/drivers/net/usb/cdc_ether.c +++ b/trunk/drivers/net/usb/cdc_ether.c @@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds) __le32_to_cpu(speeds[1]) / 1000); } -void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) +static void cdc_status(struct usbnet *dev, struct urb *urb) { struct usb_cdc_notification *event; @@ -418,9 +418,8 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) break; } } -EXPORT_SYMBOL_GPL(usbnet_cdc_status); -int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf) +static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) { int status; struct cdc_state *info = (void *) &dev->data; @@ -442,7 +441,6 @@ int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf) */ return 0; } -EXPORT_SYMBOL_GPL(usbnet_cdc_bind); static int cdc_manage_power(struct usbnet *dev, int on) { @@ -454,18 +452,18 @@ static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", .flags = FLAG_ETHER, // .check_connect = cdc_check_connect, - .bind = usbnet_cdc_bind, + .bind = cdc_bind, .unbind = usbnet_cdc_unbind, - .status = usbnet_cdc_status, + .status = cdc_status, .manage_power = cdc_manage_power, }; static const struct driver_info mbm_info = { .description = "Mobile Broadband Network Device", .flags = FLAG_WWAN, - .bind = usbnet_cdc_bind, + .bind = cdc_bind, .unbind = usbnet_cdc_unbind, - .status = usbnet_cdc_status, + .status = cdc_status, .manage_power = cdc_manage_power, }; @@ -562,13 +560,6 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, -/* LG Electronics VL600 wants additional headers on every frame */ -{ - USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = 0, -}, - /* * WHITELIST!!! * diff --git a/trunk/drivers/net/usb/lg-vl600.c b/trunk/drivers/net/usb/lg-vl600.c deleted file mode 100644 index 1d83ccfd7277..000000000000 --- a/trunk/drivers/net/usb/lg-vl600.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Ethernet interface part of the LG VL600 LTE modem (4G dongle) - * - * Copyright (C) 2011 Intel Corporation - * Author: Andrzej Zaborowski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The device has a CDC ACM port for modem control (it claims to be - * CDC ACM anyway) and a CDC Ethernet port for actual network data. - * It will however ignore data on both ports that is not encapsulated - * in a specific way, any data returned is also encapsulated the same - * way. The headers don't seem to follow any popular standard. - * - * This driver adds and strips these headers from the ethernet frames - * sent/received from the CDC Ethernet port. The proprietary header - * replaces the standard ethernet header in a packet so only actual - * ethernet frames are allowed. The headers allow some form of - * multiplexing by using non standard values of the .h_proto field. - * Windows/Mac drivers do send a couple of such frames to the device - * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what - * seems to be) a flag in the .dummy_flags. This doesn't seem necessary - * for modem operation but can possibly be used for GPS or other funcitons. - */ - -struct vl600_frame_hdr { - __le32 len; - __le32 serial; - __le32 pkt_cnt; - __le32 dummy_flags; - __le32 dummy; - __le32 magic; -} __attribute__((packed)); - -struct vl600_pkt_hdr { - __le32 dummy[2]; - __le32 len; - __be16 h_proto; -} __attribute__((packed)); - -struct vl600_state { - struct sk_buff *current_rx_buf; -}; - -static int vl600_bind(struct usbnet *dev, struct usb_interface *intf) -{ - int ret; - struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL); - - if (!s) - return -ENOMEM; - - ret = usbnet_cdc_bind(dev, intf); - if (ret) { - kfree(s); - return ret; - } - - dev->driver_priv = s; - - /* ARP packets don't go through, but they're also of no use. The - * subnet has only two hosts anyway: us and the gateway / DHCP - * server (probably simulated by modem firmware or network operator) - * whose address changes everytime we connect to the intarwebz and - * who doesn't bother answering ARP requests either. So hardware - * addresses have no meaning, the destination and the source of every - * packet depend only on whether it is on the IN or OUT endpoint. */ - dev->net->flags |= IFF_NOARP; - - return ret; -} - -static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf) -{ - struct vl600_state *s = dev->driver_priv; - - if (s->current_rx_buf) - dev_kfree_skb(s->current_rx_buf); - - kfree(s); - - return usbnet_cdc_unbind(dev, intf); -} - -static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - struct vl600_frame_hdr *frame; - struct vl600_pkt_hdr *packet; - struct ethhdr *ethhdr; - int packet_len, count; - struct sk_buff *buf = skb; - struct sk_buff *clone; - struct vl600_state *s = dev->driver_priv; - - /* Frame lengths are generally 4B multiplies but every couple of - * hours there's an odd number of bytes sized yet correct frame, - * so don't require this. */ - - /* Allow a packet (or multiple packets batched together) to be - * split across many frames. We don't allow a new batch to - * begin in the same frame another one is ending however, and no - * leading or trailing pad bytes. */ - if (s->current_rx_buf) { - frame = (struct vl600_frame_hdr *) s->current_rx_buf->data; - if (skb->len + s->current_rx_buf->len > - le32_to_cpup(&frame->len)) { - netif_err(dev, ifup, dev->net, "Fragment too long\n"); - dev->net->stats.rx_length_errors++; - goto error; - } - - buf = s->current_rx_buf; - memcpy(skb_put(buf, skb->len), skb->data, skb->len); - } else if (skb->len < 4) { - netif_err(dev, ifup, dev->net, "Frame too short\n"); - dev->net->stats.rx_length_errors++; - goto error; - } - - frame = (struct vl600_frame_hdr *) buf->data; - /* NOTE: Should check that frame->magic == 0x53544448? - * Otherwise if we receive garbage at the beginning of the frame - * we may end up allocating a huge buffer and saving all the - * future incoming data into it. */ - - if (buf->len < sizeof(*frame) || - buf->len != le32_to_cpup(&frame->len)) { - /* Save this fragment for later assembly */ - if (s->current_rx_buf) - return 0; - - s->current_rx_buf = skb_copy_expand(skb, 0, - le32_to_cpup(&frame->len), GFP_ATOMIC); - if (!s->current_rx_buf) { - netif_err(dev, ifup, dev->net, "Reserving %i bytes " - "for packet assembly failed.\n", - le32_to_cpup(&frame->len)); - dev->net->stats.rx_errors++; - } - - return 0; - } - - count = le32_to_cpup(&frame->pkt_cnt); - - skb_pull(buf, sizeof(*frame)); - - while (count--) { - if (buf->len < sizeof(*packet)) { - netif_err(dev, ifup, dev->net, "Packet too short\n"); - goto error; - } - - packet = (struct vl600_pkt_hdr *) buf->data; - packet_len = sizeof(*packet) + le32_to_cpup(&packet->len); - if (packet_len > buf->len) { - netif_err(dev, ifup, dev->net, - "Bad packet length stored in header\n"); - goto error; - } - - /* Packet header is same size as the ethernet header - * (sizeof(*packet) == sizeof(*ethhdr)), additionally - * the h_proto field is in the same place so we just leave it - * alone and fill in the remaining fields. - */ - ethhdr = (struct ethhdr *) skb->data; - if (be16_to_cpup(ðhdr->h_proto) == ETH_P_ARP && - buf->len > 0x26) { - /* Copy the addresses from packet contents */ - memcpy(ethhdr->h_source, - &buf->data[sizeof(*ethhdr) + 0x8], - ETH_ALEN); - memcpy(ethhdr->h_dest, - &buf->data[sizeof(*ethhdr) + 0x12], - ETH_ALEN); - } else { - memset(ethhdr->h_source, 0, ETH_ALEN); - memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN); - } - - if (count) { - /* Not the last packet in this batch */ - clone = skb_clone(buf, GFP_ATOMIC); - if (!clone) - goto error; - - skb_trim(clone, packet_len); - usbnet_skb_return(dev, clone); - - skb_pull(buf, (packet_len + 3) & ~3); - } else { - skb_trim(buf, packet_len); - - if (s->current_rx_buf) { - usbnet_skb_return(dev, buf); - s->current_rx_buf = NULL; - return 0; - } - - return 1; - } - } - -error: - if (s->current_rx_buf) { - dev_kfree_skb_any(s->current_rx_buf); - s->current_rx_buf = NULL; - } - dev->net->stats.rx_errors++; - return 0; -} - -static struct sk_buff *vl600_tx_fixup(struct usbnet *dev, - struct sk_buff *skb, gfp_t flags) -{ - struct sk_buff *ret; - struct vl600_frame_hdr *frame; - struct vl600_pkt_hdr *packet; - static uint32_t serial = 1; - int orig_len = skb->len - sizeof(struct ethhdr); - int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3; - - frame = (struct vl600_frame_hdr *) skb->data; - if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len)) - return skb; /* Already encapsulated? */ - - if (skb->len < sizeof(struct ethhdr)) - /* Drop, device can only deal with ethernet packets */ - return NULL; - - if (!skb_cloned(skb)) { - int headroom = skb_headroom(skb); - int tailroom = skb_tailroom(skb); - - if (tailroom >= full_len - skb->len - sizeof(*frame) && - headroom >= sizeof(*frame)) - /* There's enough head and tail room */ - goto encapsulate; - - if (headroom + tailroom + skb->len >= full_len) { - /* There's enough total room, just readjust */ - skb->data = memmove(skb->head + sizeof(*frame), - skb->data, skb->len); - skb_set_tail_pointer(skb, skb->len); - goto encapsulate; - } - } - - /* Alloc a new skb with the required size */ - ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len - - skb->len - sizeof(struct vl600_frame_hdr), flags); - dev_kfree_skb_any(skb); - if (!ret) - return ret; - skb = ret; - -encapsulate: - /* Packet header is same size as ethernet packet header - * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the - * h_proto field is in the same place so we just leave it alone and - * overwrite the remaining fields. - */ - packet = (struct vl600_pkt_hdr *) skb->data; - memset(&packet->dummy, 0, sizeof(packet->dummy)); - packet->len = cpu_to_le32(orig_len); - - frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame)); - memset(frame, 0, sizeof(*frame)); - frame->len = cpu_to_le32(full_len); - frame->serial = cpu_to_le32(serial++); - frame->pkt_cnt = cpu_to_le32(1); - - if (skb->len < full_len) /* Pad */ - skb_put(skb, full_len - skb->len); - - return skb; -} - -static const struct driver_info vl600_info = { - .description = "LG VL600 modem", - .flags = FLAG_ETHER | FLAG_RX_ASSEMBLE, - .bind = vl600_bind, - .unbind = vl600_unbind, - .status = usbnet_cdc_status, - .rx_fixup = vl600_rx_fixup, - .tx_fixup = vl600_tx_fixup, -}; - -static const struct usb_device_id products[] = { - { - USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &vl600_info, - }, - {}, /* End */ -}; -MODULE_DEVICE_TABLE(usb, products); - -static struct usb_driver lg_vl600_driver = { - .name = "lg-vl600", - .id_table = products, - .probe = usbnet_probe, - .disconnect = usbnet_disconnect, - .suspend = usbnet_suspend, - .resume = usbnet_resume, -}; - -static int __init vl600_init(void) -{ - return usb_register(&lg_vl600_driver); -} -module_init(vl600_init); - -static void __exit vl600_exit(void) -{ - usb_deregister(&lg_vl600_driver); -} -module_exit(vl600_exit); - -MODULE_AUTHOR("Anrzej Zaborowski"); -MODULE_DESCRIPTION("LG-VL600 modem's ethernet link"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index cf58b7682565..95c41d56631c 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -387,12 +387,8 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) { if (dev->driver_info->rx_fixup && - !dev->driver_info->rx_fixup (dev, skb)) { - /* With RX_ASSEMBLE, rx_fixup() must update counters */ - if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE)) - dev->net->stats.rx_errors++; - goto done; - } + !dev->driver_info->rx_fixup (dev, skb)) + goto error; // else network stack removes extra byte if we forced a short packet if (skb->len) { @@ -405,8 +401,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) } netif_dbg(dev, rx_err, dev->net, "drop\n"); +error: dev->net->stats.rx_errors++; -done: skb_queue_tail(&dev->done, skb); } diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 80484af781e1..e1aee37270f5 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -1506,7 +1506,7 @@ config SERIAL_BCM63XX_CONSOLE config SERIAL_GRLIB_GAISLER_APBUART tristate "GRLIB APBUART serial support" - depends on OF && SPARC + depends on OF select SERIAL_CORE ---help--- Add support for the GRLIB APBUART serial port. diff --git a/trunk/drivers/tty/serial/apbuart.c b/trunk/drivers/tty/serial/apbuart.c index 19a943693e4c..1ab999b04ef3 100644 --- a/trunk/drivers/tty/serial/apbuart.c +++ b/trunk/drivers/tty/serial/apbuart.c @@ -555,9 +555,10 @@ static struct uart_driver grlib_apbuart_driver = { static int __devinit apbuart_probe(struct platform_device *op) { - int i; + int i = -1; struct uart_port *port = NULL; + i = 0; for (i = 0; i < grlib_apbuart_port_nr; i++) { if (op->dev.of_node == grlib_apbuart_nodes[i]) break; @@ -565,7 +566,6 @@ static int __devinit apbuart_probe(struct platform_device *op) port = &grlib_apbuart_ports[i]; port->dev = &op->dev; - port->irq = op->archdata.irqs[0]; uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port); @@ -598,12 +598,24 @@ static struct platform_driver grlib_apbuart_of_driver = { static int grlib_apbuart_configure(void) { - struct device_node *np; - int line = 0; + struct device_node *np, *rp; + const u32 *prop; + int freq_khz, line = 0; + + /* Get bus frequency */ + rp = of_find_node_by_path("/"); + if (!rp) + return -ENODEV; + rp = of_get_next_child(rp, NULL); + if (!rp) + return -ENODEV; + prop = of_get_property(rp, "clock-frequency", NULL); + if (!prop) + return -ENODEV; + freq_khz = *prop; for_each_matching_node(np, apbuart_match) { - const int *ampopts; - const u32 *freq_hz; + const int *irqs, *ampopts; const struct amba_prom_registers *regs; struct uart_port *port; unsigned long addr; @@ -611,11 +623,11 @@ static int grlib_apbuart_configure(void) ampopts = of_get_property(np, "ampopts", NULL); if (ampopts && (*ampopts == 0)) continue; /* Ignore if used by another OS instance */ + + irqs = of_get_property(np, "interrupts", NULL); regs = of_get_property(np, "reg", NULL); - /* Frequency of APB Bus is frequency of UART */ - freq_hz = of_get_property(np, "freq", NULL); - if (!regs || !freq_hz || (*freq_hz == 0)) + if (!irqs || !regs) continue; grlib_apbuart_nodes[line] = np; @@ -626,12 +638,12 @@ static int grlib_apbuart_configure(void) port->mapbase = addr; port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map)); - port->irq = 0; + port->irq = *irqs; port->iotype = UPIO_MEM; port->ops = &grlib_apbuart_ops; port->flags = UPF_BOOT_AUTOCONF; port->line = line; - port->uartclk = *freq_hz; + port->uartclk = freq_khz * 1000; port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line); line++; diff --git a/trunk/include/linux/atmdev.h b/trunk/include/linux/atmdev.h index 381f4cec8260..475f8c42c0e9 100644 --- a/trunk/include/linux/atmdev.h +++ b/trunk/include/linux/atmdev.h @@ -443,7 +443,6 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal); void vcc_insert_socket(struct sock *sk); -void atm_dev_release_vccs(struct atm_dev *dev); /* * This is approximately the algorithm used by alloc_skb. diff --git a/trunk/include/linux/connector.h b/trunk/include/linux/connector.h index 7c60d0942adb..bcafc942e5e4 100644 --- a/trunk/include/linux/connector.h +++ b/trunk/include/linux/connector.h @@ -88,6 +88,8 @@ struct cn_queue_dev { atomic_t refcnt; unsigned char name[CN_CBQ_NAMELEN]; + struct workqueue_struct *cn_queue; + struct list_head queue_list; spinlock_t queue_lock; @@ -99,13 +101,20 @@ struct cn_callback_id { struct cb_id id; }; +struct cn_callback_data { + struct sk_buff *skb; + void (*callback) (struct cn_msg *, struct netlink_skb_parms *); + + void *free; +}; + struct cn_callback_entry { struct list_head callback_entry; - atomic_t refcnt; + struct work_struct work; struct cn_queue_dev *pdev; struct cn_callback_id id; - void (*callback) (struct cn_msg *, struct netlink_skb_parms *); + struct cn_callback_data data; u32 seq, group; }; @@ -129,12 +138,13 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); -void cn_queue_release_callback(struct cn_callback_entry *); struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *); void cn_queue_free_dev(struct cn_queue_dev *dev); int cn_cb_equal(struct cb_id *, struct cb_id *); +void cn_queue_wrapper(struct work_struct *work); + #endif /* __KERNEL__ */ #endif /* __CONNECTOR_H */ diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index d9e52fa2416d..239083bfea13 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -126,7 +126,7 @@ struct sk_buff; * GRO uses frags we allocate at least 16 regardless of page size. */ #if (65536/PAGE_SIZE + 2) < 16 -#define MAX_SKB_FRAGS 16UL +#define MAX_SKB_FRAGS 16 #else #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2) #endif diff --git a/trunk/include/linux/usb/usbnet.h b/trunk/include/linux/usb/usbnet.h index 201f2228f731..44842c8d38c0 100644 --- a/trunk/include/linux/usb/usbnet.h +++ b/trunk/include/linux/usb/usbnet.h @@ -102,7 +102,6 @@ struct driver_info { * Affects statistic (counters) and short packet handling. */ #define FLAG_MULTI_PACKET 0x1000 -#define FLAG_RX_ASSEMBLE 0x2000 /* rx packets may span >1 frames */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); @@ -173,9 +172,7 @@ struct cdc_state { }; extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); -extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); -extern void usbnet_cdc_status(struct usbnet *, struct urb *); /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ diff --git a/trunk/include/net/if_inet6.h b/trunk/include/net/if_inet6.h index fccc2180c61b..04977eefb0ee 100644 --- a/trunk/include/net/if_inet6.h +++ b/trunk/include/net/if_inet6.h @@ -286,21 +286,5 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr, buf[9] = broadcast[9]; memcpy(buf + 10, addr->s6_addr + 6, 10); } - -static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr, - const unsigned char *broadcast, char *buf) -{ - if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) { - memcpy(buf, broadcast, 4); - } else { - /* v4mapped? */ - if ((addr->s6_addr32[0] | addr->s6_addr32[1] | - (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0) - return -EINVAL; - memcpy(buf, &addr->s6_addr32[3], 4); - } - return 0; -} - #endif #endif diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 7c416583b710..a4f631108c54 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -339,14 +339,6 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch buf[16] = addr & 0x0f; } -static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) -{ - if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) - memcpy(buf, broadcast, 4); - else - memcpy(buf, &naddr, sizeof(naddr)); -} - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #include #endif diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index 956a5302002a..206e771e82d1 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -1051,17 +1051,16 @@ static int atalk_release(struct socket *sock) { struct sock *sk = sock->sk; + sock_hold(sk); + lock_sock(sk); if (sk) { - sock_hold(sk); - lock_sock(sk); - sock_orphan(sk); sock->sk = NULL; atalk_destroy_socket(sk); - - release_sock(sk); - sock_put(sk); } + release_sock(sk); + sock_put(sk); + return 0; } diff --git a/trunk/net/atm/common.c b/trunk/net/atm/common.c index 22b963d06a10..1b9c52a02cd3 100644 --- a/trunk/net/atm/common.c +++ b/trunk/net/atm/common.c @@ -252,7 +252,6 @@ void atm_dev_release_vccs(struct atm_dev *dev) } write_unlock_irq(&vcc_sklist_lock); } -EXPORT_SYMBOL(atm_dev_release_vccs); static int adjust_tp(struct atm_trafprm *tp, unsigned char aal) { diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index 59660c909a7c..f61eb2eff3fd 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -1475,7 +1475,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, ip6h->payload_len == 0) return 0; - len = ntohs(ip6h->payload_len) + sizeof(*ip6h); + len = ntohs(ip6h->payload_len); if (skb->len < len) return -EINVAL; diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index 9b61d09de9b9..5593f5aec942 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) /* user has chosen a value so keep it */ if (br->flags & BR_SET_MAC_ADDR) - return false; + return; list_for_each_entry(p, &br->port_list, list) { if (addr == br_mac_zero || diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 3da9fb06d47a..563ddc28139d 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1454,27 +1454,6 @@ static inline void net_timestamp_check(struct sk_buff *skb) __net_timestamp(skb); } -static inline bool is_skb_forwardable(struct net_device *dev, - struct sk_buff *skb) -{ - unsigned int len; - - if (!(dev->flags & IFF_UP)) - return false; - - len = dev->mtu + dev->hard_header_len + VLAN_HLEN; - if (skb->len <= len) - return true; - - /* if TSO is enabled, we don't care about the length as the packet - * could be forwarded without being segmented before - */ - if (skb_is_gso(skb)) - return true; - - return false; -} - /** * dev_forward_skb - loopback an skb to another netif * @@ -1498,7 +1477,8 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb_orphan(skb); nf_reset(skb); - if (unlikely(!is_skb_forwardable(dev, skb))) { + if (unlikely(!(dev->flags & IFF_UP) || + (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) { atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index 1b74d3b64371..090d273d7865 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -215,9 +215,6 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) case ARPHRD_INFINIBAND: ip_ib_mc_map(addr, dev->broadcast, haddr); return 0; - case ARPHRD_IPGRE: - ip_ipgre_mc_map(addr, dev->broadcast, haddr); - return 0; default: if (dir) { memcpy(haddr, dev->broadcast, dev->addr_len); diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index 451088330bbb..f116ce8f1b46 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -1068,7 +1068,6 @@ static void ip_fib_net_exit(struct net *net) fib4_rules_exit(net); #endif - rtnl_lock(); for (i = 0; i < FIB_TABLE_HASHSZ; i++) { struct fib_table *tb; struct hlist_head *head; @@ -1081,7 +1080,6 @@ static void ip_fib_net_exit(struct net *net) fib_free_table(tb); } } - rtnl_unlock(); kfree(net->ipv4.fib_table_hash); } diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 92f952d093db..0e49c9db3c98 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -341,8 +341,6 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d case ARPHRD_INFINIBAND: ipv6_ib_mc_map(addr, dev->broadcast, buf); return 0; - case ARPHRD_IPGRE: - return ipv6_ipgre_mc_map(addr, dev->broadcast, buf); default: if (dir) { memcpy(buf, dev->broadcast, dev->addr_len); diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index d5bf91d04f63..152976ec0b74 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -1205,7 +1205,7 @@ SCTP_STATIC __init int sctp_init(void) if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0) continue; sctp_assoc_hashtable = (struct sctp_hashbucket *) - __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); + __get_free_pages(GFP_ATOMIC, order); } while (!sctp_assoc_hashtable && --order > 0); if (!sctp_assoc_hashtable) { pr_err("Failed association hash alloc\n"); @@ -1238,7 +1238,7 @@ SCTP_STATIC __init int sctp_init(void) if ((sctp_port_hashsize > (64 * 1024)) && order > 0) continue; sctp_port_hashtable = (struct sctp_bind_hashbucket *) - __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); + __get_free_pages(GFP_ATOMIC, order); } while (!sctp_port_hashtable && --order > 0); if (!sctp_port_hashtable) { pr_err("Failed bind hash alloc\n");