diff --git a/[refs] b/[refs] index 728d39466eee..920113027ce4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5dbc2f543d2eb5499f3839d1abb72105cf0c03af +refs/heads/master: e7fb9c4ad351a8da7c09e182bd2e7ccd043daf08 diff --git a/trunk/Documentation/networking/Makefile b/trunk/Documentation/networking/Makefile index 5aba7a33aeeb..6d8af1ac56c4 100644 --- a/trunk/Documentation/networking/Makefile +++ b/trunk/Documentation/networking/Makefile @@ -6,5 +6,3 @@ hostprogs-y := ifenslave # Tell kbuild to always build the programs always := $(hostprogs-y) - -obj-m := timestamping/ diff --git a/trunk/Documentation/networking/timestamping/Makefile b/trunk/Documentation/networking/timestamping/Makefile index e79973443e9f..2a1489fdc036 100644 --- a/trunk/Documentation/networking/timestamping/Makefile +++ b/trunk/Documentation/networking/timestamping/Makefile @@ -1,13 +1,6 @@ -# kbuild trick to avoid linker error. Can be omitted if a module is built. -obj- := dummy.o +CPPFLAGS = -I../../../include -# List of programs to build -hostprogs-y := timestamping - -# Tell kbuild to always build the programs -always := $(hostprogs-y) - -HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include +timestamping: timestamping.c clean: rm -f timestamping diff --git a/trunk/Documentation/networking/timestamping/timestamping.c b/trunk/Documentation/networking/timestamping/timestamping.c index 8ba82bfe6a33..bab619a48214 100644 --- a/trunk/Documentation/networking/timestamping/timestamping.c +++ b/trunk/Documentation/networking/timestamping/timestamping.c @@ -41,9 +41,9 @@ #include #include -#include -#include -#include +#include "asm/types.h" +#include "linux/net_tstamp.h" +#include "linux/errqueue.h" #ifndef SO_TIMESTAMPING # define SO_TIMESTAMPING 37 @@ -164,7 +164,7 @@ static void printpacket(struct msghdr *msg, int res, gettimeofday(&now, 0); - printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n", + printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n", (long)now.tv_sec, (long)now.tv_usec, (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", res, @@ -173,7 +173,7 @@ static void printpacket(struct msghdr *msg, int res, for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { - printf(" cmsg len %zu: ", cmsg->cmsg_len); + printf(" cmsg len %d: ", cmsg->cmsg_len); switch (cmsg->cmsg_level) { case SOL_SOCKET: printf("SOL_SOCKET "); diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 382eaa4d0068..47cc449d89d8 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5214,21 +5214,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git S: Maintained F: arch/sparc/ -SPARC SERIAL DRIVERS -M: "David S. Miller" -L: sparclinux@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git -S: Maintained -F: drivers/serial/suncore.c -F: drivers/serial/suncore.h -F: drivers/serial/sunhv.c -F: drivers/serial/sunsab.c -F: drivers/serial/sunsab.h -F: drivers/serial/sunsu.c -F: drivers/serial/sunzilog.c -F: drivers/serial/sunzilog.h - SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER M: Roger Wolff S: Supported diff --git a/trunk/drivers/atm/lanai.c b/trunk/drivers/atm/lanai.c index 23d95054705b..7fe7c324e7ef 100644 --- a/trunk/drivers/atm/lanai.c +++ b/trunk/drivers/atm/lanai.c @@ -306,10 +306,11 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai, const unsigned long *lp, void (*func)(struct lanai_dev *,vci_t vci)) { - vci_t vci; - - for_each_set_bit(vci, lp, NUM_VCI) + vci_t vci = find_first_bit(lp, NUM_VCI); + while (vci < NUM_VCI) { func(lanai, vci); + vci = find_next_bit(lp, NUM_VCI, vci + 1); + } } /* -------------------- BUFFER UTILITIES: */ diff --git a/trunk/drivers/base/memory.c b/trunk/drivers/base/memory.c index db0848e54cc6..2f8691511190 100644 --- a/trunk/drivers/base/memory.c +++ b/trunk/drivers/base/memory.c @@ -429,16 +429,12 @@ static inline int memory_fail_init(void) * differentiation between which *physical* devices each * section belongs to... */ -int __weak arch_get_memory_phys_device(unsigned long start_pfn) -{ - return 0; -} static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) + unsigned long state, int phys_device, + enum mem_add_context context) { struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); - unsigned long start_pfn; int ret = 0; if (!mem) @@ -447,8 +443,7 @@ static int add_memory_block(int nid, struct mem_section *section, mem->phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); - mem->phys_device = arch_get_memory_phys_device(start_pfn); + mem->phys_device = phys_device; ret = register_memory(mem, section); if (!ret) @@ -520,7 +515,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -553,7 +548,7 @@ int __init memory_dev_init(void) if (!present_section_nr(i)) continue; err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + 0, BOOT); if (!ret) ret = err; } diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index 9c5eea3ea4de..e481c5938bad 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -215,7 +215,9 @@ static void hpet_timer_set_irq(struct hpet_dev *devp) else v &= ~0xffff; - for_each_set_bit(irq, &v, HPET_MAX_IRQ) { + for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; + irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { + if (irq >= nr_irqs) { irq = HPET_MAX_IRQ; break; diff --git a/trunk/drivers/isdn/gigaset/capi.c b/trunk/drivers/isdn/gigaset/capi.c index 0220c19351d9..6643d6533ccb 100644 --- a/trunk/drivers/isdn/gigaset/capi.c +++ b/trunk/drivers/isdn/gigaset/capi.c @@ -1301,7 +1301,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, } /* check parameter: CIP Value */ - if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) || + if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) || (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) { dev_notice(cs->dev, "%s: unknown CIP value %d\n", "CONNECT_REQ", cmsg->CIPValue); @@ -2191,24 +2191,36 @@ static const struct file_operations gigaset_proc_fops = { .release = single_release, }; +static struct capi_driver capi_driver_gigaset = { + .name = "gigaset", + .revision = "1.0", +}; + /** - * gigaset_isdn_regdev() - register device to LL + * gigaset_isdn_register() - register to LL * @cs: device descriptor structure. * @isdnid: device name. * + * Called by main module to register the device with the LL. + * * Return value: 1 for success, 0 for failure */ -int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) +int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) { struct gigaset_capi_ctr *iif; int rc; + pr_info("Kernel CAPI interface\n"); + iif = kmalloc(sizeof(*iif), GFP_KERNEL); if (!iif) { pr_err("%s: out of memory\n", __func__); return 0; } + /* register driver with CAPI (ToDo: what for?) */ + register_capi_driver(&capi_driver_gigaset); + /* prepare controller structure */ iif->ctr.owner = THIS_MODULE; iif->ctr.driverdata = cs; @@ -2229,6 +2241,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) rc = attach_capi_ctr(&iif->ctr); if (rc) { pr_err("attach_capi_ctr failed (%d)\n", rc); + unregister_capi_driver(&capi_driver_gigaset); kfree(iif); return 0; } @@ -2239,36 +2252,17 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) } /** - * gigaset_isdn_unregdev() - unregister device from LL + * gigaset_isdn_unregister() - unregister from LL * @cs: device descriptor structure. + * + * Called by main module to unregister the device from the LL. */ -void gigaset_isdn_unregdev(struct cardstate *cs) +void gigaset_isdn_unregister(struct cardstate *cs) { struct gigaset_capi_ctr *iif = cs->iif; detach_capi_ctr(&iif->ctr); kfree(iif); cs->iif = NULL; -} - -static struct capi_driver capi_driver_gigaset = { - .name = "gigaset", - .revision = "1.0", -}; - -/** - * gigaset_isdn_regdrv() - register driver to LL - */ -void gigaset_isdn_regdrv(void) -{ - pr_info("Kernel CAPI interface\n"); - register_capi_driver(&capi_driver_gigaset); -} - -/** - * gigaset_isdn_unregdrv() - unregister driver from LL - */ -void gigaset_isdn_unregdrv(void) -{ unregister_capi_driver(&capi_driver_gigaset); } diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index bdc01cb9f0ab..85de3399a2f2 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -507,7 +507,7 @@ void gigaset_freecs(struct cardstate *cs) case 2: /* error in initcshw */ /* Deregister from LL */ make_invalid(cs, VALID_ID); - gigaset_isdn_unregdev(cs); + gigaset_isdn_unregister(cs); /* fall through */ case 1: /* error when registering to LL */ @@ -769,7 +769,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, cs->cmdbytes = 0; gig_dbg(DEBUG_INIT, "setting up iif"); - if (!gigaset_isdn_regdev(cs, modulename)) { + if (!gigaset_isdn_register(cs, modulename)) { pr_err("error registering ISDN device\n"); goto error; } @@ -1205,13 +1205,11 @@ static int __init gigaset_init_module(void) gigaset_debuglevel = DEBUG_DEFAULT; pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n"); - gigaset_isdn_regdrv(); return 0; } static void __exit gigaset_exit_module(void) { - gigaset_isdn_unregdrv(); } module_init(gigaset_init_module); diff --git a/trunk/drivers/isdn/gigaset/dummyll.c b/trunk/drivers/isdn/gigaset/dummyll.c index bd0b1eaa7572..5b27c996af6d 100644 --- a/trunk/drivers/isdn/gigaset/dummyll.c +++ b/trunk/drivers/isdn/gigaset/dummyll.c @@ -57,20 +57,12 @@ void gigaset_isdn_stop(struct cardstate *cs) { } -int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) -{ - return 1; -} - -void gigaset_isdn_unregdev(struct cardstate *cs) -{ -} - -void gigaset_isdn_regdrv(void) +int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) { pr_info("no ISDN subsystem interface\n"); + return 1; } -void gigaset_isdn_unregdrv(void) +void gigaset_isdn_unregister(struct cardstate *cs) { } diff --git a/trunk/drivers/isdn/gigaset/ev-layer.c b/trunk/drivers/isdn/gigaset/ev-layer.c index 206c380c5235..c8f89b78b233 100644 --- a/trunk/drivers/isdn/gigaset/ev-layer.c +++ b/trunk/drivers/isdn/gigaset/ev-layer.c @@ -1258,10 +1258,14 @@ static void do_action(int action, struct cardstate *cs, * note that bcs may be NULL if no B channel is free */ at_state2->ConState = 700; - for (i = 0; i < STR_NUM; ++i) { - kfree(at_state2->str_var[i]); - at_state2->str_var[i] = NULL; - } + kfree(at_state2->str_var[STR_NMBR]); + at_state2->str_var[STR_NMBR] = NULL; + kfree(at_state2->str_var[STR_ZCPN]); + at_state2->str_var[STR_ZCPN] = NULL; + kfree(at_state2->str_var[STR_ZBC]); + at_state2->str_var[STR_ZBC] = NULL; + kfree(at_state2->str_var[STR_ZHLC]); + at_state2->str_var[STR_ZHLC] = NULL; at_state2->int_var[VAR_ZCTP] = -1; spin_lock_irqsave(&cs->lock, flags); diff --git a/trunk/drivers/isdn/gigaset/gigaset.h b/trunk/drivers/isdn/gigaset/gigaset.h index cdd144ecdc5f..1875ab80b335 100644 --- a/trunk/drivers/isdn/gigaset/gigaset.h +++ b/trunk/drivers/isdn/gigaset/gigaset.h @@ -675,10 +675,8 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); */ /* Called from common.c for setting up/shutting down with the ISDN subsystem */ -void gigaset_isdn_regdrv(void); -void gigaset_isdn_unregdrv(void); -int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid); -void gigaset_isdn_unregdev(struct cardstate *cs); +int gigaset_isdn_register(struct cardstate *cs, const char *isdnid); +void gigaset_isdn_unregister(struct cardstate *cs); /* Called from hardware module to indicate completion of an skb */ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); diff --git a/trunk/drivers/isdn/gigaset/i4l.c b/trunk/drivers/isdn/gigaset/i4l.c index c22e5ace8276..f0acb9dc9e33 100644 --- a/trunk/drivers/isdn/gigaset/i4l.c +++ b/trunk/drivers/isdn/gigaset/i4l.c @@ -592,13 +592,15 @@ void gigaset_isdn_stop(struct cardstate *cs) } /** - * gigaset_isdn_regdev() - register to LL + * gigaset_isdn_register() - register to LL * @cs: device descriptor structure. * @isdnid: device name. * + * Called by main module to register the device with the LL. + * * Return value: 1 for success, 0 for failure */ -int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) +int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) { isdn_if *iif; @@ -648,29 +650,15 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) } /** - * gigaset_isdn_unregdev() - unregister device from LL + * gigaset_isdn_unregister() - unregister from LL * @cs: device descriptor structure. + * + * Called by main module to unregister the device from the LL. */ -void gigaset_isdn_unregdev(struct cardstate *cs) +void gigaset_isdn_unregister(struct cardstate *cs) { gig_dbg(DEBUG_CMD, "sending UNLOAD"); gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); kfree(cs->iif); cs->iif = NULL; } - -/** - * gigaset_isdn_regdrv() - register driver to LL - */ -void gigaset_isdn_regdrv(void) -{ - /* nothing to do */ -} - -/** - * gigaset_isdn_unregdrv() - unregister driver from LL - */ -void gigaset_isdn_unregdrv(void) -{ - /* nothing to do */ -} diff --git a/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c index f0dc6c9cc283..a1bcbc21ff71 100644 --- a/trunk/drivers/isdn/gigaset/interface.c +++ b/trunk/drivers/isdn/gigaset/interface.c @@ -628,6 +628,7 @@ void gigaset_if_receive(struct cardstate *cs, if (tty == NULL) gig_dbg(DEBUG_IF, "receive on closed device"); else { + tty_buffer_request_room(tty, len); tty_insert_flip_string(tty, buffer, len); tty_flip_buffer_push(tty); } diff --git a/trunk/drivers/isdn/hardware/eicon/message.c b/trunk/drivers/isdn/hardware/eicon/message.c index 341ef17c22ac..ae89fb89da64 100644 --- a/trunk/drivers/isdn/hardware/eicon/message.c +++ b/trunk/drivers/isdn/hardware/eicon/message.c @@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, for (i = 0; i < w; i++) ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i]; ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; - len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + len = offsetof(T30_INFO, station_id) + 20; w = fax_parms[5].length; if (w > 20) w = 20; @@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) { - len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + len = offsetof(T30_INFO, station_id) + 20; if (plci->fax_connect_info_length < len) { ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; @@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, break; } ncpi = &m_parms[1]; - len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + len = offsetof(T30_INFO, station_id) + 20; if (plci->fax_connect_info_length < len) { ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; @@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci) if(((T30_INFO *)plci->NL.RBuffer->P)->station_id_len) { plci->ncpi_buffer[len] = 20; - for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++) + for (i = 0; i < 20; i++) plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i]; } if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) @@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci) if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) { - i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; + i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; while (i < plci->NL.RBuffer->length) plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; } @@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) } } /* copy station id to NLC */ - for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++) + for(i=0; i<20; i++) { if(istation_id[i] = ' '; } } - ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH; + ((T30_INFO *)&nlc[1])->station_id_len = 20; /* copy head line to NLC */ if(b3_config_parms[3].length) { - pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH]))); + pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20]))); if (pos != 0) { if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE) pos = 0; else { - nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; - nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; + ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; len = (byte)b3_config_parms[2].length; if (len > 20) len = 20; if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) { for (i = 0; i < len; i++) - nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; - nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; - nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; + ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; + ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; } } } @@ -8444,8 +8444,9 @@ static word add_b23(PLCI *plci, API_PARSE *bp) ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); nlc[0] += (byte)(pos + len); for (i = 0; i < len; i++) - nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; - } else + ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; + } + else ((T30_INFO *)&nlc[1])->head_line_len = 0; plci->nsf_control_bits = 0; @@ -8472,7 +8473,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; } len = nlc[0]; - pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + pos = offsetof(T30_INFO, station_id) + 20; if (pos < plci->fax_connect_info_length) { for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) @@ -8524,7 +8525,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) } PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); - len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + len = offsetof(T30_INFO, station_id) + 20; for (i = 0; i < len; i++) plci->fax_connect_info_buffer[i] = nlc[1+i]; ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c b/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c index 8affba3e569d..ad36df9b759c 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -5265,8 +5265,6 @@ static const struct hm_map hfcm_map[] = { /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0, HFC_IO_MODE_EMBSD, XHFC_IRQ}, /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0}, -/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, -/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, }; #undef H @@ -5302,10 +5300,6 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = { PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - 0xb761, 0, 0, H(33)}, /* BN2S PCIe */ - { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, - 0xb762, 0, 0, H(34)}, /* BN4S PCIe */ /* Cards with HFC-8S Chip */ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, diff --git a/trunk/drivers/isdn/hysdn/hysdn_boot.c b/trunk/drivers/isdn/hysdn/hysdn_boot.c index 4f541ef14f9e..be787e16bb79 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_boot.c +++ b/trunk/drivers/isdn/hysdn/hysdn_boot.c @@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int datlen) (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA", datlen, boot->pof_recoffset); - if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0) + if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0)) return (boot->last_error); /* error writing data */ if (boot->pof_recoffset + datlen >= boot->pof_reclen) diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 505eb64c329c..e0b64312e66a 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -15,8 +15,6 @@ config LEDS_CLASS This option enables the led sysfs class in /sys/class/leds. You'll need this to do anything useful with LEDs. If unsure, say N. -if LEDS_CLASS - comment "LED drivers" config LEDS_88PM860X @@ -28,73 +26,73 @@ config LEDS_88PM860X config LEDS_ATMEL_PWM tristate "LED Support using Atmel PWM outputs" - depends on ATMEL_PWM + depends on LEDS_CLASS && ATMEL_PWM help This option enables support for LEDs driven using outputs of the dedicated PWM controller found on newer Atmel SOCs. config LEDS_LOCOMO tristate "LED Support for Locomo device" - depends on SHARP_LOCOMO + depends on LEDS_CLASS && SHARP_LOCOMO help This option enables support for the LEDs on Sharp Locomo. Zaurus models SL-5500 and SL-5600. config LEDS_MIKROTIK_RB532 tristate "LED Support for Mikrotik Routerboard 532" - depends on MIKROTIK_RB532 + depends on LEDS_CLASS && MIKROTIK_RB532 help This option enables support for the so called "User LED" of Mikrotik's Routerboard 532. config LEDS_S3C24XX tristate "LED Support for Samsung S3C24XX GPIO LEDs" - depends on ARCH_S3C2410 + depends on LEDS_CLASS && ARCH_S3C2410 help This option enables support for LEDs connected to GPIO lines on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. config LEDS_AMS_DELTA tristate "LED Support for the Amstrad Delta (E3)" - depends on MACH_AMS_DELTA + depends on LEDS_CLASS && MACH_AMS_DELTA help This option enables support for the LEDs on Amstrad Delta (E3). config LEDS_NET48XX tristate "LED Support for Soekris net48xx series Error LED" - depends on SCx200_GPIO + depends on LEDS_CLASS && SCx200_GPIO help This option enables support for the Soekris net4801 and net4826 error LED. config LEDS_FSG tristate "LED Support for the Freecom FSG-3" - depends on MACH_FSG + depends on LEDS_CLASS && MACH_FSG help This option enables support for the LEDs on the Freecom FSG-3. config LEDS_WRAP tristate "LED Support for the WRAP series LEDs" - depends on SCx200_GPIO + depends on LEDS_CLASS && SCx200_GPIO help This option enables support for the PCEngines WRAP programmable LEDs. config LEDS_ALIX2 tristate "LED Support for ALIX.2 and ALIX.3 series" - depends on X86 && !GPIO_CS5535 && !CS5535_GPIO + depends on LEDS_CLASS && X86 && EXPERIMENTAL help This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. You have to set leds-alix2.force=1 for boards with Award BIOS. config LEDS_H1940 tristate "LED Support for iPAQ H1940 device" - depends on ARCH_H1940 + depends on LEDS_CLASS && ARCH_H1940 help This option enables support for the LEDs on the h1940. config LEDS_COBALT_QUBE tristate "LED Support for the Cobalt Qube series front LED" - depends on MIPS_COBALT + depends on LEDS_CLASS && MIPS_COBALT help This option enables support for the front LED on Cobalt Qube series @@ -107,7 +105,7 @@ config LEDS_COBALT_RAQ config LEDS_SUNFIRE tristate "LED support for SunFire servers." - depends on SPARC64 + depends on LEDS_CLASS && SPARC64 select LEDS_TRIGGERS help This option enables support for the Left, Middle, and Right @@ -115,14 +113,14 @@ config LEDS_SUNFIRE config LEDS_HP6XX tristate "LED Support for the HP Jornada 6xx" - depends on SH_HP6XX + depends on LEDS_CLASS && SH_HP6XX help This option enables LED support for the handheld HP Jornada 620/660/680/690. config LEDS_PCA9532 tristate "LED driver for PCA9532 dimmer" - depends on I2C && INPUT && EXPERIMENTAL + depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL help This option enables support for NXP pca9532 LED controller. It is generally only useful @@ -130,7 +128,7 @@ config LEDS_PCA9532 config LEDS_GPIO tristate "LED Support for GPIO connected LEDs" - depends on GENERIC_GPIO + depends on LEDS_CLASS && GENERIC_GPIO help This option enables support for the LEDs connected to GPIO outputs. To be useful the particular board must have LEDs @@ -157,7 +155,7 @@ config LEDS_GPIO_OF config LEDS_LP3944 tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" - depends on I2C + depends on LEDS_CLASS && I2C help This option enables support for LEDs connected to the National Semiconductor LP3944 Lighting Management Unit (LMU) also known as @@ -168,7 +166,7 @@ config LEDS_LP3944 config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" - depends on X86 && SERIO_I8042 && DMI + depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI help This driver makes the mail LED accessible from userspace programs through the leds subsystem. This LED have three @@ -198,7 +196,7 @@ config LEDS_CLEVO_MAIL config LEDS_PCA955X tristate "LED Support for PCA955x I2C chips" - depends on I2C + depends on LEDS_CLASS && I2C help This option enables support for LEDs connected to PCA955x LED driver chips accessed via the I2C bus. Supported @@ -206,54 +204,54 @@ config LEDS_PCA955X config LEDS_WM831X_STATUS tristate "LED support for status LEDs on WM831x PMICs" - depends on MFD_WM831X + depends on LEDS_CLASS && MFD_WM831X help This option enables support for the status LEDs of the WM831x series of PMICs. config LEDS_WM8350 tristate "LED Support for WM8350 AudioPlus PMIC" - depends on MFD_WM8350 + depends on LEDS_CLASS && MFD_WM8350 help This option enables support for LEDs driven by the Wolfson Microelectronics WM8350 AudioPlus PMIC. config LEDS_DA903X tristate "LED Support for DA9030/DA9034 PMIC" - depends on PMIC_DA903X + depends on LEDS_CLASS && PMIC_DA903X help This option enables support for on-chip LED drivers found on Dialog Semiconductor DA9030/DA9034 PMICs. config LEDS_DAC124S085 tristate "LED Support for DAC124S085 SPI DAC" - depends on SPI + depends on LEDS_CLASS && SPI help This option enables support for DAC124S085 SPI DAC from NatSemi, which can be used to control up to four LEDs. config LEDS_PWM tristate "PWM driven LED Support" - depends on HAVE_PWM + depends on LEDS_CLASS && HAVE_PWM help This option enables support for pwm driven LEDs config LEDS_REGULATOR tristate "REGULATOR driven LED support" - depends on REGULATOR + depends on LEDS_CLASS && REGULATOR help This option enables support for regulator driven LEDs. config LEDS_BD2802 tristate "LED driver for BD2802 RGB LED" - depends on I2C + depends on LEDS_CLASS && I2C help This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. config LEDS_INTEL_SS4200 tristate "LED driver for Intel NAS SS4200 series" - depends on PCI && DMI + depends on LEDS_CLASS && PCI && DMI help This option enables support for the Intel SS4200 series of Network Attached Storage servers. You may control the hard @@ -262,7 +260,7 @@ config LEDS_INTEL_SS4200 config LEDS_LT3593 tristate "LED driver for LT3593 controllers" - depends on GENERIC_GPIO + depends on LEDS_CLASS && GENERIC_GPIO help This option enables support for LEDs driven by a Linear Technology LT3593 controller. This controller uses a special one-wire pulse @@ -270,7 +268,7 @@ config LEDS_LT3593 config LEDS_ADP5520 tristate "LED Support for ADP5520/ADP5501 PMIC" - depends on PMIC_ADP5520 + depends on LEDS_CLASS && PMIC_ADP5520 help This option enables support for on-chip LED drivers found on Analog Devices ADP5520/ADP5501 PMICs. @@ -278,12 +276,7 @@ config LEDS_ADP5520 To compile this driver as a module, choose M here: the module will be called leds-adp5520. -config LEDS_DELL_NETBOOKS - tristate "External LED on Dell Business Netbooks" - depends on X86 && ACPI_WMI - help - This adds support for the Latitude 2100 and similar - notebooks that have an external LED. +comment "LED Triggers" config LEDS_TRIGGERS bool "LED Trigger support" @@ -292,12 +285,9 @@ config LEDS_TRIGGERS These triggers allow kernel events to drive the LEDs and can be configured via sysfs. If unsure, say Y. -if LEDS_TRIGGERS - -comment "LED Triggers" - config LEDS_TRIGGER_TIMER tristate "LED Timer Trigger" + depends on LEDS_TRIGGERS help This allows LEDs to be controlled by a programmable timer via sysfs. Some LED hardware can be programmed to start @@ -308,13 +298,14 @@ config LEDS_TRIGGER_TIMER config LEDS_TRIGGER_IDE_DISK bool "LED IDE Disk Trigger" - depends on IDE_GD_ATA + depends on LEDS_TRIGGERS && IDE_GD_ATA help This allows LEDs to be controlled by IDE disk activity. If unsure, say Y. config LEDS_TRIGGER_HEARTBEAT tristate "LED Heartbeat Trigger" + depends on LEDS_TRIGGERS help This allows LEDs to be controlled by a CPU load average. The flash frequency is a hyperbolic function of the 1-minute @@ -323,6 +314,7 @@ config LEDS_TRIGGER_HEARTBEAT config LEDS_TRIGGER_BACKLIGHT tristate "LED backlight Trigger" + depends on LEDS_TRIGGERS help This allows LEDs to be controlled as a backlight device: they turn off and on when the display is blanked and unblanked. @@ -331,6 +323,7 @@ config LEDS_TRIGGER_BACKLIGHT config LEDS_TRIGGER_GPIO tristate "LED GPIO Trigger" + depends on LEDS_TRIGGERS depends on GPIOLIB help This allows LEDs to be controlled by gpio events. It's good @@ -343,6 +336,7 @@ config LEDS_TRIGGER_GPIO config LEDS_TRIGGER_DEFAULT_ON tristate "LED Default ON Trigger" + depends on LEDS_TRIGGERS help This allows LEDs to be initialised in the ON state. If unsure, say Y. @@ -350,8 +344,4 @@ config LEDS_TRIGGER_DEFAULT_ON comment "iptables trigger is under Netfilter config (LED target)" depends on LEDS_TRIGGERS -endif # LEDS_TRIGGERS - -endif # LEDS_CLASS - endif # NEW_LEDS diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index 0cd8b9957380..d76fb32b77c0 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o -obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/trunk/drivers/leds/dell-led.c b/trunk/drivers/leds/dell-led.c deleted file mode 100644 index ee310891fff8..000000000000 --- a/trunk/drivers/leds/dell-led.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * dell_led.c - Dell LED Driver - * - * Copyright (C) 2010 Dell Inc. - * Louis Davis - * Jim Dailey - * - * 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. - * - */ - -#include -#include - -MODULE_AUTHOR("Louis Davis/Jim Dailey"); -MODULE_DESCRIPTION("Dell LED Control Driver"); -MODULE_LICENSE("GPL"); - -#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396" -MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID); - -/* Error Result Codes: */ -#define INVALID_DEVICE_ID 250 -#define INVALID_PARAMETER 251 -#define INVALID_BUFFER 252 -#define INTERFACE_ERROR 253 -#define UNSUPPORTED_COMMAND 254 -#define UNSPECIFIED_ERROR 255 - -/* Device ID */ -#define DEVICE_ID_PANEL_BACK 1 - -/* LED Commands */ -#define CMD_LED_ON 16 -#define CMD_LED_OFF 17 -#define CMD_LED_BLINK 18 - -struct bios_args { - unsigned char length; - unsigned char result_code; - unsigned char device_id; - unsigned char command; - unsigned char on_time; - unsigned char off_time; -}; - -static int dell_led_perform_fn(u8 length, - u8 result_code, - u8 device_id, - u8 command, - u8 on_time, - u8 off_time) -{ - struct bios_args *bios_return; - u8 return_code; - union acpi_object *obj; - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_buffer input; - acpi_status status; - - struct bios_args args; - args.length = length; - args.result_code = result_code; - args.device_id = device_id; - args.command = command; - args.on_time = on_time; - args.off_time = off_time; - - input.length = sizeof(struct bios_args); - input.pointer = &args; - - status = wmi_evaluate_method(DELL_LED_BIOS_GUID, - 1, - 1, - &input, - &output); - - if (ACPI_FAILURE(status)) - return status; - - obj = output.pointer; - - if (!obj) - return -EINVAL; - else if (obj->type != ACPI_TYPE_BUFFER) { - kfree(obj); - return -EINVAL; - } - - bios_return = ((struct bios_args *)obj->buffer.pointer); - return_code = bios_return->result_code; - - kfree(obj); - - return return_code; -} - -static int led_on(void) -{ - return dell_led_perform_fn(3, /* Length of command */ - INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ - DEVICE_ID_PANEL_BACK, /* Device ID */ - CMD_LED_ON, /* Command */ - 0, /* not used */ - 0); /* not used */ -} - -static int led_off(void) -{ - return dell_led_perform_fn(3, /* Length of command */ - INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ - DEVICE_ID_PANEL_BACK, /* Device ID */ - CMD_LED_OFF, /* Command */ - 0, /* not used */ - 0); /* not used */ -} - -static int led_blink(unsigned char on_eighths, - unsigned char off_eighths) -{ - return dell_led_perform_fn(5, /* Length of command */ - INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ - DEVICE_ID_PANEL_BACK, /* Device ID */ - CMD_LED_BLINK, /* Command */ - on_eighths, /* blink on in eigths of a second */ - off_eighths); /* blink off in eights of a second */ -} - -static void dell_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value == LED_OFF) - led_off(); - else - led_on(); -} - -static int dell_led_blink(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - unsigned long on_eighths; - unsigned long off_eighths; - - /* The Dell LED delay is based on 125ms intervals. - Need to round up to next interval. */ - - on_eighths = (*delay_on + 124) / 125; - if (0 == on_eighths) - on_eighths = 1; - if (on_eighths > 255) - on_eighths = 255; - *delay_on = on_eighths * 125; - - off_eighths = (*delay_off + 124) / 125; - if (0 == off_eighths) - off_eighths = 1; - if (off_eighths > 255) - off_eighths = 255; - *delay_off = off_eighths * 125; - - led_blink(on_eighths, off_eighths); - - return 0; -} - -static struct led_classdev dell_led = { - .name = "dell::lid", - .brightness = LED_OFF, - .max_brightness = 1, - .brightness_set = dell_led_set, - .blink_set = dell_led_blink, - .flags = LED_CORE_SUSPENDRESUME, -}; - -static int __init dell_led_init(void) -{ - int error = 0; - - if (!wmi_has_guid(DELL_LED_BIOS_GUID)) - return -ENODEV; - - error = led_off(); - if (error != 0) - return -ENODEV; - - return led_classdev_register(NULL, &dell_led); -} - -static void __exit dell_led_exit(void) -{ - led_classdev_unregister(&dell_led); - - led_off(); -} - -module_init(dell_led_init); -module_exit(dell_led_exit); diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c index 69e7d86a5143..782f95822eab 100644 --- a/trunk/drivers/leds/led-class.c +++ b/trunk/drivers/leds/led-class.c @@ -72,14 +72,11 @@ static ssize_t led_max_brightness_show(struct device *dev, return sprintf(buf, "%u\n", led_cdev->max_brightness); } -static struct device_attribute led_class_attrs[] = { - __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), - __ATTR(max_brightness, 0644, led_max_brightness_show, NULL), +static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); +static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL); #ifdef CONFIG_LEDS_TRIGGERS - __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), +static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); #endif - __ATTR_NULL, -}; /** * led_classdev_suspend - suspend an led_classdev. @@ -130,11 +127,18 @@ static int led_resume(struct device *dev) */ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { + int rc; + led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, "%s", led_cdev->name); if (IS_ERR(led_cdev->dev)) return PTR_ERR(led_cdev->dev); + /* register the attributes */ + rc = device_create_file(led_cdev->dev, &dev_attr_brightness); + if (rc) + goto err_out; + #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); #endif @@ -146,18 +150,36 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; + rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness); + if (rc) + goto err_out_attr_max; + led_update_brightness(led_cdev); #ifdef CONFIG_LEDS_TRIGGERS + rc = device_create_file(led_cdev->dev, &dev_attr_trigger); + if (rc) + goto err_out_led_list; + led_trigger_set_default(led_cdev); #endif - printk(KERN_DEBUG "Registered led device: %s\n", + printk(KERN_INFO "Registered led device: %s\n", led_cdev->name); return 0; -} +#ifdef CONFIG_LEDS_TRIGGERS +err_out_led_list: + device_remove_file(led_cdev->dev, &dev_attr_max_brightness); +#endif +err_out_attr_max: + device_remove_file(led_cdev->dev, &dev_attr_brightness); + list_del(&led_cdev->node); +err_out: + device_unregister(led_cdev->dev); + return rc; +} EXPORT_SYMBOL_GPL(led_classdev_register); /** @@ -168,7 +190,10 @@ EXPORT_SYMBOL_GPL(led_classdev_register); */ void led_classdev_unregister(struct led_classdev *led_cdev) { + device_remove_file(led_cdev->dev, &dev_attr_max_brightness); + device_remove_file(led_cdev->dev, &dev_attr_brightness); #ifdef CONFIG_LEDS_TRIGGERS + device_remove_file(led_cdev->dev, &dev_attr_trigger); down_write(&led_cdev->trigger_lock); if (led_cdev->trigger) led_trigger_set(led_cdev, NULL); @@ -190,7 +215,6 @@ static int __init leds_init(void) return PTR_ERR(leds_class); leds_class->suspend = led_suspend; leds_class->resume = led_resume; - leds_class->dev_attrs = led_class_attrs; return 0; } diff --git a/trunk/drivers/leds/leds-gpio.c b/trunk/drivers/leds/leds-gpio.c index 0823e2622e8c..e5225d28f392 100644 --- a/trunk/drivers/leds/leds-gpio.c +++ b/trunk/drivers/leds/leds-gpio.c @@ -211,6 +211,7 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device_node *np = ofdev->node, *child; + struct gpio_led led; struct gpio_led_of_platform_data *pdata; int count = 0, ret; @@ -225,8 +226,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, if (!pdata) return -ENOMEM; + memset(&led, 0, sizeof(led)); for_each_child_of_node(np, child) { - struct gpio_led led = {}; enum of_gpio_flags flags; const char *state; diff --git a/trunk/drivers/leds/leds-ss4200.c b/trunk/drivers/leds/leds-ss4200.c index 51477ec71391..97f04984c1ca 100644 --- a/trunk/drivers/leds/leds-ss4200.c +++ b/trunk/drivers/leds/leds-ss4200.c @@ -63,7 +63,7 @@ MODULE_LICENSE("GPL"); /* * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. */ -static const struct pci_device_id ich7_lpc_pci_id[] = +static struct pci_device_id ich7_lpc_pci_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, diff --git a/trunk/drivers/net/benet/be_cmds.c b/trunk/drivers/net/benet/be_cmds.c index 50e6259b50e4..c59215361f4e 100644 --- a/trunk/drivers/net/benet/be_cmds.c +++ b/trunk/drivers/net/benet/be_cmds.c @@ -673,7 +673,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_MCC_CREATE, sizeof(*req)); - req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); + req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index 6c042a72d6cc..ed785a30e98b 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -893,6 +893,7 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) u16 prod; u16 cons; + barrier(); /* Tell compiler that prod and cons can change */ prod = fp->tx_bd_prod; cons = fp->tx_bd_cons; @@ -962,7 +963,7 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp) * start_xmit() will miss it and cause the queue to be stopped * forever. */ - smp_mb(); + smp_wmb(); /* TBD need a thresh? */ if (unlikely(netif_tx_queue_stopped(txq))) { @@ -11428,12 +11429,9 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { netif_tx_stop_queue(txq); - - /* paired memory barrier is in bnx2x_tx_int(), we have to keep - * ordering of set_bit() in netif_tx_stop_queue() and read of - * fp->bd_tx_cons */ + /* We want bnx2x_tx_int to "see" the updated tx_bd_prod + if we put Tx into XOFF state. */ smp_mb(); - fp->eth_q_stats.driver_xoff++; if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) netif_tx_wake_queue(txq); diff --git a/trunk/drivers/net/davinci_emac.c b/trunk/drivers/net/davinci_emac.c index 2b8edd2efbf6..8bd086aee56d 100644 --- a/trunk/drivers/net/davinci_emac.c +++ b/trunk/drivers/net/davinci_emac.c @@ -29,6 +29,10 @@ * PHY layer usage */ +/** Pending Items in this driver: + * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions) + */ + #include #include #include @@ -500,6 +504,12 @@ static unsigned long mdio_max_freq; /* Cache macros - Packet buffers would be from skb pool which is cached */ #define EMAC_VIRT_NOCACHE(addr) (addr) +#define EMAC_CACHE_INVALIDATE(addr, size) \ + dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE) +#define EMAC_CACHE_WRITEBACK(addr, size) \ + dma_cache_maint((void *)addr, size, DMA_TO_DEVICE) +#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \ + dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL) /* DM644x does not have BD's in cached memory - so no cache functions */ #define BD_CACHE_INVALIDATE(addr, size) @@ -1225,10 +1235,6 @@ static void emac_txch_teardown(struct emac_priv *priv, u32 ch) if (1 == txch->queue_active) { curr_bd = txch->active_queue_head; while (curr_bd != NULL) { - dma_unmap_single(emac_dev, curr_bd->buff_ptr, - curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, - DMA_TO_DEVICE); - emac_net_tx_complete(priv, (void __force *) &curr_bd->buf_token, 1, ch); if (curr_bd != txch->active_queue_tail) @@ -1321,11 +1327,6 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) txch->queue_active = 0; /* end of queue */ } } - - dma_unmap_single(emac_dev, curr_bd->buff_ptr, - curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, - DMA_TO_DEVICE); - *tx_complete_ptr = (u32) curr_bd->buf_token; ++tx_complete_ptr; ++tx_complete_cnt; @@ -1386,8 +1387,8 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) txch->bd_pool_head = curr_bd->next; curr_bd->buf_token = buf_list->buf_token; - curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr, - buf_list->length, DMA_TO_DEVICE); + /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ + curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr); curr_bd->off_b_len = buf_list->length; curr_bd->h_next = 0; curr_bd->next = NULL; @@ -1467,6 +1468,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) tx_buf.length = skb->len; tx_buf.buf_token = (void *)skb; tx_buf.data_ptr = skb->data; + EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len); ndev->trans_start = jiffies; ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH); if (unlikely(ret_code != 0)) { @@ -1541,6 +1543,7 @@ static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size, p_skb->dev = ndev; skb_reserve(p_skb, NET_IP_ALIGN); *data_token = (void *) p_skb; + EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size); return p_skb->data; } @@ -1609,8 +1612,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param) /* populate the hardware descriptor */ curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head, priv); - curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr, - rxch->buf_size, DMA_FROM_DEVICE); + /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ + curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr); curr_bd->off_b_len = rxch->buf_size; curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT; @@ -1694,12 +1697,6 @@ static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch) curr_bd = rxch->active_queue_head; while (curr_bd) { if (curr_bd->buf_token) { - dma_unmap_single(&priv->ndev->dev, - curr_bd->buff_ptr, - curr_bd->off_b_len - & EMAC_RX_BD_BUF_SIZE, - DMA_FROM_DEVICE); - dev_kfree_skb_any((struct sk_buff *)\ curr_bd->buf_token); } @@ -1874,8 +1871,8 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, /* populate the hardware descriptor */ curr_bd->h_next = 0; - curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer, - rxch->buf_size, DMA_FROM_DEVICE); + /* FIXME buff_ptr = dma_map_single(... buffer ...) */ + curr_bd->buff_ptr = virt_to_phys(buffer); curr_bd->off_b_len = rxch->buf_size; curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT; curr_bd->next = NULL; @@ -1930,6 +1927,7 @@ static int emac_net_rx_cb(struct emac_priv *priv, p_skb = (struct sk_buff *)net_pkt_list->pkt_token; /* set length of packet */ skb_put(p_skb, net_pkt_list->pkt_length); + EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len); p_skb->protocol = eth_type_trans(p_skb, priv->ndev); netif_receive_skb(p_skb); priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length; @@ -1992,11 +1990,6 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr; rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE; rx_buf_obj->buf_token = curr_bd->buf_token; - - dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr, - curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, - DMA_FROM_DEVICE); - curr_pkt->pkt_token = curr_pkt->buf_list->buf_token; curr_pkt->num_bufs = 1; curr_pkt->pkt_length = @@ -2827,37 +2820,31 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) return 0; } -static int davinci_emac_suspend(struct device *dev) +static +int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state) { - struct platform_device *pdev = to_platform_device(dev); - struct net_device *ndev = platform_get_drvdata(pdev); + struct net_device *dev = platform_get_drvdata(pdev); - if (netif_running(ndev)) - emac_dev_stop(ndev); + if (netif_running(dev)) + emac_dev_stop(dev); clk_disable(emac_clk); return 0; } -static int davinci_emac_resume(struct device *dev) +static int davinci_emac_resume(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(dev); - struct net_device *ndev = platform_get_drvdata(pdev); + struct net_device *dev = platform_get_drvdata(pdev); clk_enable(emac_clk); - if (netif_running(ndev)) - emac_dev_open(ndev); + if (netif_running(dev)) + emac_dev_open(dev); return 0; } -static const struct dev_pm_ops davinci_emac_pm_ops = { - .suspend = davinci_emac_suspend, - .resume = davinci_emac_resume, -}; - /** * davinci_emac_driver: EMAC platform driver structure */ @@ -2865,10 +2852,11 @@ static struct platform_driver davinci_emac_driver = { .driver = { .name = "davinci_emac", .owner = THIS_MODULE, - .pm = &davinci_emac_pm_ops, }, .probe = davinci_emac_probe, .remove = __devexit_p(davinci_emac_remove), + .suspend = davinci_emac_suspend, + .resume = davinci_emac_resume, }; /** diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index b997e578e58f..a26ccab057d5 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -2858,7 +2858,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, } nic->cbs_pool = pci_pool_create(netdev->name, nic->pdev, - nic->params.cbs.max * sizeof(struct cb), + nic->params.cbs.count * sizeof(struct cb), sizeof(u32), 0); DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", diff --git a/trunk/drivers/net/irda/w83977af_ir.c b/trunk/drivers/net/irda/w83977af_ir.c index 980625feb2c0..551810fd2976 100644 --- a/trunk/drivers/net/irda/w83977af_ir.c +++ b/trunk/drivers/net/irda/w83977af_ir.c @@ -65,6 +65,7 @@ #undef CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */ #define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */ #endif +#undef CONFIG_USE_INTERNAL_TIMER /* Just cannot make that timer work */ #define CONFIG_USE_W977_PNP /* Currently needed */ #define PIO_MAX_SPEED 115200 @@ -532,6 +533,25 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb, self->tx_buff.len = skb->len; mtt = irda_get_mtt(skb); +#ifdef CONFIG_USE_INTERNAL_TIMER + if (mtt > 50) { + /* Adjust for timer resolution */ + mtt /= 1000+1; + + /* Setup timer */ + switch_bank(iobase, SET4); + outb(mtt & 0xff, iobase+TMRL); + outb((mtt >> 8) & 0x0f, iobase+TMRH); + + /* Start timer */ + outb(IR_MSL_EN_TMR, iobase+IR_MSL); + self->io.direction = IO_XMIT; + + /* Enable timer interrupt */ + switch_bank(iobase, SET0); + outb(ICR_ETMRI, iobase+ICR); + } else { +#endif IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt); if (mtt) udelay(mtt); @@ -540,6 +560,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb, switch_bank(iobase, SET0); outb(ICR_EDMAI, iobase+ICR); w83977af_dma_write(self, iobase); +#ifdef CONFIG_USE_INTERNAL_TIMER + } +#endif } else { self->tx_buff.data = self->tx_buff.head; self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, @@ -853,7 +876,20 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self) /* Check if we have transferred all data to memory */ switch_bank(iobase, SET0); if (inb(iobase+USR) & USR_RDR) { +#ifdef CONFIG_USE_INTERNAL_TIMER + /* Put this entry back in fifo */ + st_fifo->head--; + st_fifo->len++; + st_fifo->entries[st_fifo->head].status = status; + st_fifo->entries[st_fifo->head].len = len; + + /* Restore set register */ + outb(set, iobase+SSR); + + return FALSE; /* I'll be back! */ +#else udelay(80); /* Should be enough!? */ +#endif } skb = dev_alloc_skb(len+1); diff --git a/trunk/drivers/net/ksz884x.c b/trunk/drivers/net/ksz884x.c index 0f59099ee72f..7264a3e5c2c0 100644 --- a/trunk/drivers/net/ksz884x.c +++ b/trunk/drivers/net/ksz884x.c @@ -4899,10 +4899,8 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev) struct sk_buff *org_skb = skb; skb = dev_alloc_skb(org_skb->len); - if (!skb) { - rc = NETDEV_TX_BUSY; - goto unlock; - } + if (!skb) + return NETDEV_TX_BUSY; skb_copy_and_csum_dev(org_skb, skb->data); org_skb->ip_summed = 0; skb->len = org_skb->len; @@ -4916,7 +4914,7 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); rc = NETDEV_TX_BUSY; } -unlock: + spin_unlock_irq(&hw_priv->hwlock); return rc; diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index e84dd3ee9c5a..676c513e12fc 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -3687,6 +3687,7 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) if (status != 0) { dev_err(&mgp->pdev->dev, "failed reset\n"); goto abort_with_fw; + return; } mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot); diff --git a/trunk/drivers/net/ne.c b/trunk/drivers/net/ne.c index f4347f88b6f2..992dbfffdb05 100644 --- a/trunk/drivers/net/ne.c +++ b/trunk/drivers/net/ne.c @@ -142,7 +142,7 @@ bad_clone_list[] __initdata = { {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ #ifdef CONFIG_MACH_TX49XX - {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ + {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ #endif {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ {NULL,} diff --git a/trunk/drivers/net/pppol2tp.c b/trunk/drivers/net/pppol2tp.c index 449a9825200d..9fbb2eba9a06 100644 --- a/trunk/drivers/net/pppol2tp.c +++ b/trunk/drivers/net/pppol2tp.c @@ -756,7 +756,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) /* Try to dequeue as many skbs from reorder_q as we can. */ pppol2tp_recv_dequeue(session); - sock_put(sock); return 0; @@ -773,7 +772,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0); tunnel->stats.rx_errors++; kfree_skb(skb); - sock_put(sock); return 0; @@ -1182,8 +1180,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Calculate UDP checksum if configured to do so */ if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) skb->ip_summed = CHECKSUM_NONE; - else if ((skb_dst(skb) && skb_dst(skb)->dev) && - (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) { + else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { skb->ip_summed = CHECKSUM_COMPLETE; csum = skb_checksum(skb, 0, udp_len, 0); uh->check = csum_tcpudp_magic(inet->inet_saddr, @@ -1664,7 +1661,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, if (tunnel_sock == NULL) goto end; - sock_hold(tunnel_sock); tunnel = tunnel_sock->sk_user_data; } else { tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel); diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 2eb7f8a0d926..df70657260dd 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -5819,8 +5819,10 @@ static void s2io_vpd_read(struct s2io_nic *nic) } } - if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) + if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) { + memset(nic->product_name, 0, vpd_data[1]); memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); + } kfree(vpd_data); swstats->mem_freed += 256; } diff --git a/trunk/drivers/net/usb/Kconfig b/trunk/drivers/net/usb/Kconfig index ba56ce4382d9..32d93564a74d 100644 --- a/trunk/drivers/net/usb/Kconfig +++ b/trunk/drivers/net/usb/Kconfig @@ -204,14 +204,6 @@ config USB_NET_DM9601 This option adds support for Davicom DM9601 based USB 1.1 10/100 Ethernet adapters. -config USB_NET_SMSC75XX - tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" - depends on USB_USBNET - select CRC32 - help - This option adds support for SMSC LAN95XX based USB 2.0 - Gigabit Ethernet adapters. - config USB_NET_SMSC95XX tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" depends on USB_USBNET diff --git a/trunk/drivers/net/usb/Makefile b/trunk/drivers/net/usb/Makefile index 82ea62955b56..e17afb78f372 100644 --- a/trunk/drivers/net/usb/Makefile +++ b/trunk/drivers/net/usb/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_USB_NET_AX8817X) += asix.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o -obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o obj-$(CONFIG_USB_NET_GL620A) += gl620a.o obj-$(CONFIG_USB_NET_NET1080) += net1080.o diff --git a/trunk/drivers/net/usb/hso.c b/trunk/drivers/net/usb/hso.c index be0cc99e881a..6895f1531238 100644 --- a/trunk/drivers/net/usb/hso.c +++ b/trunk/drivers/net/usb/hso.c @@ -1155,6 +1155,9 @@ static void _hso_serial_set_termios(struct tty_struct *tty, static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) { int result; +#ifdef CONFIG_HSO_AUTOPM + usb_mark_last_busy(urb->dev); +#endif /* We are done with this URB, resubmit it. Prep the USB to wait for * another frame */ usb_fill_bulk_urb(urb, serial->parent->usb, diff --git a/trunk/drivers/net/usb/smsc75xx.c b/trunk/drivers/net/usb/smsc75xx.c deleted file mode 100644 index 300e3e764fa2..000000000000 --- a/trunk/drivers/net/usb/smsc75xx.c +++ /dev/null @@ -1,1288 +0,0 @@ - /*************************************************************************** - * - * Copyright (C) 2007-2010 SMSC - * - * 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 -#include -#include "smsc75xx.h" - -#define SMSC_CHIPNAME "smsc75xx" -#define SMSC_DRIVER_VERSION "1.0.0" -#define HS_USB_PKT_SIZE (512) -#define FS_USB_PKT_SIZE (64) -#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE) -#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE) -#define DEFAULT_BULK_IN_DELAY (0x00002000) -#define MAX_SINGLE_PACKET_SIZE (9000) -#define LAN75XX_EEPROM_MAGIC (0x7500) -#define EEPROM_MAC_OFFSET (0x01) -#define DEFAULT_TX_CSUM_ENABLE (true) -#define DEFAULT_RX_CSUM_ENABLE (true) -#define DEFAULT_TSO_ENABLE (true) -#define SMSC75XX_INTERNAL_PHY_ID (1) -#define SMSC75XX_TX_OVERHEAD (8) -#define MAX_RX_FIFO_SIZE (20 * 1024) -#define MAX_TX_FIFO_SIZE (12 * 1024) -#define USB_VENDOR_ID_SMSC (0x0424) -#define USB_PRODUCT_ID_LAN7500 (0x7500) -#define USB_PRODUCT_ID_LAN7505 (0x7505) - -#define check_warn(ret, fmt, args...) \ - ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) - -#define check_warn_return(ret, fmt, args...) \ - ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } }) - -#define check_warn_goto_done(ret, fmt, args...) \ - ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } }) - -struct smsc75xx_priv { - struct usbnet *dev; - u32 rfe_ctl; - u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN]; - bool use_rx_csum; - struct mutex dataport_mutex; - spinlock_t rfe_ctl_lock; - struct work_struct set_multicast; -}; - -struct usb_context { - struct usb_ctrlrequest req; - struct usbnet *dev; -}; - -static int turbo_mode = true; -module_param(turbo_mode, bool, 0644); -MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - -static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, - u32 *data) -{ - u32 *buf = kmalloc(4, GFP_KERNEL); - int ret; - - BUG_ON(!dev); - - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - USB_VENDOR_REQUEST_READ_REGISTER, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); - - if (unlikely(ret < 0)) - netdev_warn(dev->net, - "Failed to read register index 0x%08x", index); - - le32_to_cpus(buf); - *data = *buf; - kfree(buf); - - return ret; -} - -static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, - u32 data) -{ - u32 *buf = kmalloc(4, GFP_KERNEL); - int ret; - - BUG_ON(!dev); - - if (!buf) - return -ENOMEM; - - *buf = data; - cpu_to_le32s(buf); - - ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - USB_VENDOR_REQUEST_WRITE_REGISTER, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); - - if (unlikely(ret < 0)) - netdev_warn(dev->net, - "Failed to write register index 0x%08x", index); - - kfree(buf); - - return ret; -} - -/* Loop until the read is completed with timeout - * called with phy_mutex held */ -static int smsc75xx_phy_wait_not_busy(struct usbnet *dev) -{ - unsigned long start_time = jiffies; - u32 val; - int ret; - - do { - ret = smsc75xx_read_reg(dev, MII_ACCESS, &val); - check_warn_return(ret, "Error reading MII_ACCESS"); - - if (!(val & MII_ACCESS_BUSY)) - return 0; - } while (!time_after(jiffies, start_time + HZ)); - - return -EIO; -} - -static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx) -{ - struct usbnet *dev = netdev_priv(netdev); - u32 val, addr; - int ret; - - mutex_lock(&dev->phy_mutex); - - /* confirm MII not busy */ - ret = smsc75xx_phy_wait_not_busy(dev); - check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read"); - - /* set the address, index & direction (read from PHY) */ - phy_id &= dev->mii.phy_id_mask; - idx &= dev->mii.reg_num_mask; - addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) - | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) - | MII_ACCESS_READ; - ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); - check_warn_goto_done(ret, "Error writing MII_ACCESS"); - - ret = smsc75xx_phy_wait_not_busy(dev); - check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx); - - ret = smsc75xx_read_reg(dev, MII_DATA, &val); - check_warn_goto_done(ret, "Error reading MII_DATA"); - - ret = (u16)(val & 0xFFFF); - -done: - mutex_unlock(&dev->phy_mutex); - return ret; -} - -static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx, - int regval) -{ - struct usbnet *dev = netdev_priv(netdev); - u32 val, addr; - int ret; - - mutex_lock(&dev->phy_mutex); - - /* confirm MII not busy */ - ret = smsc75xx_phy_wait_not_busy(dev); - check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write"); - - val = regval; - ret = smsc75xx_write_reg(dev, MII_DATA, val); - check_warn_goto_done(ret, "Error writing MII_DATA"); - - /* set the address, index & direction (write to PHY) */ - phy_id &= dev->mii.phy_id_mask; - idx &= dev->mii.reg_num_mask; - addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) - | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) - | MII_ACCESS_WRITE; - ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); - check_warn_goto_done(ret, "Error writing MII_ACCESS"); - - ret = smsc75xx_phy_wait_not_busy(dev); - check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx); - -done: - mutex_unlock(&dev->phy_mutex); -} - -static int smsc75xx_wait_eeprom(struct usbnet *dev) -{ - unsigned long start_time = jiffies; - u32 val; - int ret; - - do { - ret = smsc75xx_read_reg(dev, E2P_CMD, &val); - check_warn_return(ret, "Error reading E2P_CMD"); - - if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT)) - break; - udelay(40); - } while (!time_after(jiffies, start_time + HZ)); - - if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) { - netdev_warn(dev->net, "EEPROM read operation timeout"); - return -EIO; - } - - return 0; -} - -static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev) -{ - unsigned long start_time = jiffies; - u32 val; - int ret; - - do { - ret = smsc75xx_read_reg(dev, E2P_CMD, &val); - check_warn_return(ret, "Error reading E2P_CMD"); - - if (!(val & E2P_CMD_BUSY)) - return 0; - - udelay(40); - } while (!time_after(jiffies, start_time + HZ)); - - netdev_warn(dev->net, "EEPROM is busy"); - return -EIO; -} - -static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length, - u8 *data) -{ - u32 val; - int i, ret; - - BUG_ON(!dev); - BUG_ON(!data); - - ret = smsc75xx_eeprom_confirm_not_busy(dev); - if (ret) - return ret; - - for (i = 0; i < length; i++) { - val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR); - ret = smsc75xx_write_reg(dev, E2P_CMD, val); - check_warn_return(ret, "Error writing E2P_CMD"); - - ret = smsc75xx_wait_eeprom(dev); - if (ret < 0) - return ret; - - ret = smsc75xx_read_reg(dev, E2P_DATA, &val); - check_warn_return(ret, "Error reading E2P_DATA"); - - data[i] = val & 0xFF; - offset++; - } - - return 0; -} - -static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length, - u8 *data) -{ - u32 val; - int i, ret; - - BUG_ON(!dev); - BUG_ON(!data); - - ret = smsc75xx_eeprom_confirm_not_busy(dev); - if (ret) - return ret; - - /* Issue write/erase enable command */ - val = E2P_CMD_BUSY | E2P_CMD_EWEN; - ret = smsc75xx_write_reg(dev, E2P_CMD, val); - check_warn_return(ret, "Error writing E2P_CMD"); - - ret = smsc75xx_wait_eeprom(dev); - if (ret < 0) - return ret; - - for (i = 0; i < length; i++) { - - /* Fill data register */ - val = data[i]; - ret = smsc75xx_write_reg(dev, E2P_DATA, val); - check_warn_return(ret, "Error writing E2P_DATA"); - - /* Send "write" command */ - val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR); - ret = smsc75xx_write_reg(dev, E2P_CMD, val); - check_warn_return(ret, "Error writing E2P_CMD"); - - ret = smsc75xx_wait_eeprom(dev); - if (ret < 0) - return ret; - - offset++; - } - - return 0; -} - -static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev) -{ - int i, ret; - - for (i = 0; i < 100; i++) { - u32 dp_sel; - ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); - check_warn_return(ret, "Error reading DP_SEL"); - - if (dp_sel & DP_SEL_DPRDY) - return 0; - - udelay(40); - } - - netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out"); - - return -EIO; -} - -static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr, - u32 length, u32 *buf) -{ - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - u32 dp_sel; - int i, ret; - - mutex_lock(&pdata->dataport_mutex); - - ret = smsc75xx_dataport_wait_not_busy(dev); - check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry"); - - ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); - check_warn_goto_done(ret, "Error reading DP_SEL"); - - dp_sel &= ~DP_SEL_RSEL; - dp_sel |= ram_select; - ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel); - check_warn_goto_done(ret, "Error writing DP_SEL"); - - for (i = 0; i < length; i++) { - ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i); - check_warn_goto_done(ret, "Error writing DP_ADDR"); - - ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]); - check_warn_goto_done(ret, "Error writing DP_DATA"); - - ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE); - check_warn_goto_done(ret, "Error writing DP_CMD"); - - ret = smsc75xx_dataport_wait_not_busy(dev); - check_warn_goto_done(ret, "smsc75xx_dataport_write timeout"); - } - -done: - mutex_unlock(&pdata->dataport_mutex); - return ret; -} - -/* returns hash bit number for given MAC address */ -static u32 smsc75xx_hash(char addr[ETH_ALEN]) -{ - return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff; -} - -static void smsc75xx_deferred_multicast_write(struct work_struct *param) -{ - struct smsc75xx_priv *pdata = - container_of(param, struct smsc75xx_priv, set_multicast); - struct usbnet *dev = pdata->dev; - int ret; - - netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x", - pdata->rfe_ctl); - - smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN, - DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table); - - ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); - check_warn(ret, "Error writing RFE_CRL"); -} - -static void smsc75xx_set_multicast(struct net_device *netdev) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - unsigned long flags; - int i; - - spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); - - pdata->rfe_ctl &= - ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF); - pdata->rfe_ctl |= RFE_CTL_AB; - - for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++) - pdata->multicast_hash_table[i] = 0; - - if (dev->net->flags & IFF_PROMISC) { - netif_dbg(dev, drv, dev->net, "promiscuous mode enabled"); - pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU; - } else if (dev->net->flags & IFF_ALLMULTI) { - netif_dbg(dev, drv, dev->net, "receive all multicast enabled"); - pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF; - } else if (!netdev_mc_empty(dev->net)) { - struct dev_mc_list *mc_list; - - netif_dbg(dev, drv, dev->net, "receive multicast hash filter"); - - pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF; - - netdev_for_each_mc_addr(mc_list, netdev) { - u32 bitnum = smsc75xx_hash(mc_list->dmi_addr); - pdata->multicast_hash_table[bitnum / 32] |= - (1 << (bitnum % 32)); - } - } else { - netif_dbg(dev, drv, dev->net, "receive own packets only"); - pdata->rfe_ctl |= RFE_CTL_DPF; - } - - spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); - - /* defer register writes to a sleepable context */ - schedule_work(&pdata->set_multicast); -} - -static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex, - u16 lcladv, u16 rmtadv) -{ - u32 flow = 0, fct_flow = 0; - int ret; - - if (duplex == DUPLEX_FULL) { - u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); - - if (cap & FLOW_CTRL_TX) { - flow = (FLOW_TX_FCEN | 0xFFFF); - /* set fct_flow thresholds to 20% and 80% */ - fct_flow = (8 << 8) | 32; - } - - if (cap & FLOW_CTRL_RX) - flow |= FLOW_RX_FCEN; - - netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s", - (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), - (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); - } else { - netif_dbg(dev, link, dev->net, "half duplex"); - } - - ret = smsc75xx_write_reg(dev, FLOW, flow); - check_warn_return(ret, "Error writing FLOW"); - - ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow); - check_warn_return(ret, "Error writing FCT_FLOW"); - - return 0; -} - -static int smsc75xx_link_reset(struct usbnet *dev) -{ - struct mii_if_info *mii = &dev->mii; - struct ethtool_cmd ecmd; - u16 lcladv, rmtadv; - int ret; - - /* clear interrupt status */ - ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); - check_warn_return(ret, "Error reading PHY_INT_SRC"); - - ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); - check_warn_return(ret, "Error writing INT_STS"); - - mii_check_media(mii, 1, 1); - mii_ethtool_gset(&dev->mii, &ecmd); - lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); - rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA); - - netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x" - " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv); - - return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv); -} - -static void smsc75xx_status(struct usbnet *dev, struct urb *urb) -{ - u32 intdata; - - if (urb->actual_length != 4) { - netdev_warn(dev->net, - "unexpected urb length %d", urb->actual_length); - return; - } - - memcpy(&intdata, urb->transfer_buffer, 4); - le32_to_cpus(&intdata); - - netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata); - - if (intdata & INT_ENP_PHY_INT) - usbnet_defer_kevent(dev, EVENT_LINK_RESET); - else - netdev_warn(dev->net, - "unexpected interrupt, intdata=0x%08X", intdata); -} - -/* Enable or disable Rx checksum offload engine */ -static int smsc75xx_set_rx_csum_offload(struct usbnet *dev) -{ - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - unsigned long flags; - int ret; - - spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); - - if (pdata->use_rx_csum) - pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM; - else - pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM); - - spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); - - ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); - check_warn_return(ret, "Error writing RFE_CTL"); - - return 0; -} - -static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net) -{ - return MAX_EEPROM_SIZE; -} - -static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev, - struct ethtool_eeprom *ee, u8 *data) -{ - struct usbnet *dev = netdev_priv(netdev); - - ee->magic = LAN75XX_EEPROM_MAGIC; - - return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data); -} - -static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev, - struct ethtool_eeprom *ee, u8 *data) -{ - struct usbnet *dev = netdev_priv(netdev); - - if (ee->magic != LAN75XX_EEPROM_MAGIC) { - netdev_warn(dev->net, - "EEPROM: magic value mismatch: 0x%x", ee->magic); - return -EINVAL; - } - - return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data); -} - -static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - - return pdata->use_rx_csum; -} - -static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - - pdata->use_rx_csum = !!val; - - return smsc75xx_set_rx_csum_offload(dev); -} - -static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data) -{ - if (data) - netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; - else - netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} - -static const struct ethtool_ops smsc75xx_ethtool_ops = { - .get_link = usbnet_get_link, - .nway_reset = usbnet_nway_reset, - .get_drvinfo = usbnet_get_drvinfo, - .get_msglevel = usbnet_get_msglevel, - .set_msglevel = usbnet_set_msglevel, - .get_settings = usbnet_get_settings, - .set_settings = usbnet_set_settings, - .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len, - .get_eeprom = smsc75xx_ethtool_get_eeprom, - .set_eeprom = smsc75xx_ethtool_set_eeprom, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .get_rx_csum = smsc75xx_ethtool_get_rx_csum, - .set_rx_csum = smsc75xx_ethtool_set_rx_csum, - .get_tso = ethtool_op_get_tso, - .set_tso = smsc75xx_ethtool_set_tso, -}; - -static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) -{ - struct usbnet *dev = netdev_priv(netdev); - - if (!netif_running(netdev)) - return -EINVAL; - - return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); -} - -static void smsc75xx_init_mac_address(struct usbnet *dev) -{ - /* try reading mac address from EEPROM */ - if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, - dev->net->dev_addr) == 0) { - if (is_valid_ether_addr(dev->net->dev_addr)) { - /* eeprom values are valid so use them */ - netif_dbg(dev, ifup, dev->net, - "MAC address read from EEPROM"); - return; - } - } - - /* no eeprom, or eeprom values are invalid. generate random MAC */ - random_ether_addr(dev->net->dev_addr); - netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr"); -} - -static int smsc75xx_set_mac_address(struct usbnet *dev) -{ - u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | - dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; - u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; - - int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi); - check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret); - - ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo); - check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret); - - addr_hi |= ADDR_FILTX_FB_VALID; - ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi); - check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret); - - ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo); - check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret); - - return 0; -} - -static int smsc75xx_phy_initialize(struct usbnet *dev) -{ - int bmcr, timeout = 0; - - /* Initialize MII structure */ - dev->mii.dev = dev->net; - dev->mii.mdio_read = smsc75xx_mdio_read; - dev->mii.mdio_write = smsc75xx_mdio_write; - dev->mii.phy_id_mask = 0x1f; - dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; - - /* reset phy and wait for reset to complete */ - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - - do { - msleep(10); - bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); - check_warn_return(bmcr, "Error reading MII_BMCR"); - timeout++; - } while ((bmcr & MII_BMCR) && (timeout < 100)); - - if (timeout >= 100) { - netdev_warn(dev->net, "timeout on PHY Reset"); - return -EIO; - } - - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, - ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | - ADVERTISE_PAUSE_ASYM); - - /* read to clear */ - smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); - check_warn_return(bmcr, "Error reading PHY_INT_SRC"); - - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, - PHY_INT_MASK_DEFAULT); - mii_nway_restart(&dev->mii); - - netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); - return 0; -} - -static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) -{ - int ret = 0; - u32 buf; - bool rxenabled; - - ret = smsc75xx_read_reg(dev, MAC_RX, &buf); - check_warn_return(ret, "Failed to read MAC_RX: %d", ret); - - rxenabled = ((buf & MAC_RX_RXEN) != 0); - - if (rxenabled) { - buf &= ~MAC_RX_RXEN; - ret = smsc75xx_write_reg(dev, MAC_RX, buf); - check_warn_return(ret, "Failed to write MAC_RX: %d", ret); - } - - /* add 4 to size for FCS */ - buf &= ~MAC_RX_MAX_SIZE; - buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE); - - ret = smsc75xx_write_reg(dev, MAC_RX, buf); - check_warn_return(ret, "Failed to write MAC_RX: %d", ret); - - if (rxenabled) { - buf |= MAC_RX_RXEN; - ret = smsc75xx_write_reg(dev, MAC_RX, buf); - check_warn_return(ret, "Failed to write MAC_RX: %d", ret); - } - - return 0; -} - -static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) -{ - struct usbnet *dev = netdev_priv(netdev); - - int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); - check_warn_return(ret, "Failed to set mac rx frame length"); - - return usbnet_change_mtu(netdev, new_mtu); -} - -static int smsc75xx_reset(struct usbnet *dev) -{ - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - u32 buf; - int ret = 0, timeout; - - netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset"); - - ret = smsc75xx_read_reg(dev, HW_CFG, &buf); - check_warn_return(ret, "Failed to read HW_CFG: %d", ret); - - buf |= HW_CFG_LRST; - - ret = smsc75xx_write_reg(dev, HW_CFG, buf); - check_warn_return(ret, "Failed to write HW_CFG: %d", ret); - - timeout = 0; - do { - msleep(10); - ret = smsc75xx_read_reg(dev, HW_CFG, &buf); - check_warn_return(ret, "Failed to read HW_CFG: %d", ret); - timeout++; - } while ((buf & HW_CFG_LRST) && (timeout < 100)); - - if (timeout >= 100) { - netdev_warn(dev->net, "timeout on completion of Lite Reset"); - return -EIO; - } - - netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY"); - - ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); - check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); - - buf |= PMT_CTL_PHY_RST; - - ret = smsc75xx_write_reg(dev, PMT_CTL, buf); - check_warn_return(ret, "Failed to write PMT_CTL: %d", ret); - - timeout = 0; - do { - msleep(10); - ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); - check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); - timeout++; - } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100)); - - if (timeout >= 100) { - netdev_warn(dev->net, "timeout waiting for PHY Reset"); - return -EIO; - } - - netif_dbg(dev, ifup, dev->net, "PHY reset complete"); - - smsc75xx_init_mac_address(dev); - - ret = smsc75xx_set_mac_address(dev); - check_warn_return(ret, "Failed to set mac address"); - - netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr); - - ret = smsc75xx_read_reg(dev, HW_CFG, &buf); - check_warn_return(ret, "Failed to read HW_CFG: %d", ret); - - netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf); - - buf |= HW_CFG_BIR; - - ret = smsc75xx_write_reg(dev, HW_CFG, buf); - check_warn_return(ret, "Failed to write HW_CFG: %d", ret); - - ret = smsc75xx_read_reg(dev, HW_CFG, &buf); - check_warn_return(ret, "Failed to read HW_CFG: %d", ret); - - netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after " - "writing HW_CFG_BIR: 0x%08x", buf); - - if (!turbo_mode) { - buf = 0; - dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; - } else if (dev->udev->speed == USB_SPEED_HIGH) { - buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; - dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; - } else { - buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; - dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; - } - - netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld", - (ulong)dev->rx_urb_size); - - ret = smsc75xx_write_reg(dev, BURST_CAP, buf); - check_warn_return(ret, "Failed to write BURST_CAP: %d", ret); - - ret = smsc75xx_read_reg(dev, BURST_CAP, &buf); - check_warn_return(ret, "Failed to read BURST_CAP: %d", ret); - - netif_dbg(dev, ifup, dev->net, - "Read Value from BURST_CAP after writing: 0x%08x", buf); - - ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); - check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret); - - ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf); - check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret); - - netif_dbg(dev, ifup, dev->net, - "Read Value from BULK_IN_DLY after writing: 0x%08x", buf); - - if (turbo_mode) { - ret = smsc75xx_read_reg(dev, HW_CFG, &buf); - check_warn_return(ret, "Failed to read HW_CFG: %d", ret); - - netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf); - - buf |= (HW_CFG_MEF | HW_CFG_BCE); - - ret = smsc75xx_write_reg(dev, HW_CFG, buf); - check_warn_return(ret, "Failed to write HW_CFG: %d", ret); - - ret = smsc75xx_read_reg(dev, HW_CFG, &buf); - check_warn_return(ret, "Failed to read HW_CFG: %d", ret); - - netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf); - } - - /* set FIFO sizes */ - buf = (MAX_RX_FIFO_SIZE - 512) / 512; - ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf); - check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret); - - netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf); - - buf = (MAX_TX_FIFO_SIZE - 512) / 512; - ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf); - check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret); - - netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf); - - ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); - check_warn_return(ret, "Failed to write INT_STS: %d", ret); - - ret = smsc75xx_read_reg(dev, ID_REV, &buf); - check_warn_return(ret, "Failed to read ID_REV: %d", ret); - - netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf); - - /* Configure GPIO pins as LED outputs */ - ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf); - check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret); - - buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL); - buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL; - - ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf); - check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret); - - ret = smsc75xx_write_reg(dev, FLOW, 0); - check_warn_return(ret, "Failed to write FLOW: %d", ret); - - ret = smsc75xx_write_reg(dev, FCT_FLOW, 0); - check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret); - - /* Don't need rfe_ctl_lock during initialisation */ - ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); - check_warn_return(ret, "Failed to read RFE_CTL: %d", ret); - - pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF; - - ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); - check_warn_return(ret, "Failed to write RFE_CTL: %d", ret); - - ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); - check_warn_return(ret, "Failed to read RFE_CTL: %d", ret); - - netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl); - - /* Enable or disable checksum offload engines */ - ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE); - ret = smsc75xx_set_rx_csum_offload(dev); - check_warn_return(ret, "Failed to set rx csum offload: %d", ret); - - smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE); - - smsc75xx_set_multicast(dev->net); - - ret = smsc75xx_phy_initialize(dev); - check_warn_return(ret, "Failed to initialize PHY: %d", ret); - - ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf); - check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret); - - /* enable PHY interrupts */ - buf |= INT_ENP_PHY_INT; - - ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); - check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); - - ret = smsc75xx_read_reg(dev, MAC_TX, &buf); - check_warn_return(ret, "Failed to read MAC_TX: %d", ret); - - buf |= MAC_TX_TXEN; - - ret = smsc75xx_write_reg(dev, MAC_TX, buf); - check_warn_return(ret, "Failed to write MAC_TX: %d", ret); - - netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf); - - ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf); - check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret); - - buf |= FCT_TX_CTL_EN; - - ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf); - check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret); - - netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf); - - ret = smsc75xx_set_rx_max_frame_length(dev, 1514); - check_warn_return(ret, "Failed to set max rx frame length"); - - ret = smsc75xx_read_reg(dev, MAC_RX, &buf); - check_warn_return(ret, "Failed to read MAC_RX: %d", ret); - - buf |= MAC_RX_RXEN; - - ret = smsc75xx_write_reg(dev, MAC_RX, buf); - check_warn_return(ret, "Failed to write MAC_RX: %d", ret); - - netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf); - - ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf); - check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret); - - buf |= FCT_RX_CTL_EN; - - ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf); - check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret); - - netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf); - - netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0"); - return 0; -} - -static const struct net_device_ops smsc75xx_netdev_ops = { - .ndo_open = usbnet_open, - .ndo_stop = usbnet_stop, - .ndo_start_xmit = usbnet_start_xmit, - .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_change_mtu = smsc75xx_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_do_ioctl = smsc75xx_ioctl, - .ndo_set_multicast_list = smsc75xx_set_multicast, -}; - -static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) -{ - struct smsc75xx_priv *pdata = NULL; - int ret; - - printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); - - ret = usbnet_get_endpoints(dev, intf); - check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret); - - dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv), - GFP_KERNEL); - - pdata = (struct smsc75xx_priv *)(dev->data[0]); - if (!pdata) { - netdev_warn(dev->net, "Unable to allocate smsc75xx_priv"); - return -ENOMEM; - } - - pdata->dev = dev; - - spin_lock_init(&pdata->rfe_ctl_lock); - mutex_init(&pdata->dataport_mutex); - - INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); - - pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; - - /* We have to advertise SG otherwise TSO cannot be enabled */ - dev->net->features |= NETIF_F_SG; - - /* Init all registers */ - ret = smsc75xx_reset(dev); - - dev->net->netdev_ops = &smsc75xx_netdev_ops; - dev->net->ethtool_ops = &smsc75xx_ethtool_ops; - dev->net->flags |= IFF_MULTICAST; - dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; - return 0; -} - -static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) -{ - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - if (pdata) { - netif_dbg(dev, ifdown, dev->net, "free pdata"); - kfree(pdata); - pdata = NULL; - dev->data[0] = 0; - } -} - -static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a, - u32 rx_cmd_b) -{ - if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) { - skb->ip_summed = CHECKSUM_NONE; - } else { - skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT)); - skb->ip_summed = CHECKSUM_COMPLETE; - } -} - -static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - - while (skb->len > 0) { - u32 rx_cmd_a, rx_cmd_b, align_count, size; - struct sk_buff *ax_skb; - unsigned char *packet; - - memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a)); - le32_to_cpus(&rx_cmd_a); - skb_pull(skb, 4); - - memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b)); - le32_to_cpus(&rx_cmd_b); - skb_pull(skb, 4 + NET_IP_ALIGN); - - packet = skb->data; - - /* get the packet length */ - size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN; - align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; - - if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { - netif_dbg(dev, rx_err, dev->net, - "Error rx_cmd_a=0x%08x", rx_cmd_a); - dev->net->stats.rx_errors++; - dev->net->stats.rx_dropped++; - - if (rx_cmd_a & RX_CMD_A_FCS) - dev->net->stats.rx_crc_errors++; - else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) - dev->net->stats.rx_frame_errors++; - } else { - /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (ETH_FRAME_LEN + 12))) { - netif_dbg(dev, rx_err, dev->net, - "size err rx_cmd_a=0x%08x", rx_cmd_a); - return 0; - } - - /* last frame in this batch */ - if (skb->len == size) { - if (pdata->use_rx_csum) - smsc75xx_rx_csum_offload(skb, rx_cmd_a, - rx_cmd_b); - else - skb->ip_summed = CHECKSUM_NONE; - - skb_trim(skb, skb->len - 4); /* remove fcs */ - skb->truesize = size + sizeof(struct sk_buff); - - return 1; - } - - ax_skb = skb_clone(skb, GFP_ATOMIC); - if (unlikely(!ax_skb)) { - netdev_warn(dev->net, "Error allocating skb"); - return 0; - } - - ax_skb->len = size; - ax_skb->data = packet; - skb_set_tail_pointer(ax_skb, size); - - if (pdata->use_rx_csum) - smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a, - rx_cmd_b); - else - ax_skb->ip_summed = CHECKSUM_NONE; - - skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ - ax_skb->truesize = size + sizeof(struct sk_buff); - - usbnet_skb_return(dev, ax_skb); - } - - skb_pull(skb, size); - - /* padding bytes before the next frame starts */ - if (skb->len) - skb_pull(skb, align_count); - } - - if (unlikely(skb->len < 0)) { - netdev_warn(dev->net, "invalid rx length<0 %d", skb->len); - return 0; - } - - return 1; -} - -static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, - struct sk_buff *skb, gfp_t flags) -{ - u32 tx_cmd_a, tx_cmd_b; - - skb_linearize(skb); - - if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { - struct sk_buff *skb2 = - skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); - dev_kfree_skb_any(skb); - skb = skb2; - if (!skb) - return NULL; - } - - tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS; - - if (skb->ip_summed == CHECKSUM_PARTIAL) - tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE; - - if (skb_is_gso(skb)) { - u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN); - tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS; - - tx_cmd_a |= TX_CMD_A_LSO; - } else { - tx_cmd_b = 0; - } - - skb_push(skb, 4); - cpu_to_le32s(&tx_cmd_b); - memcpy(skb->data, &tx_cmd_b, 4); - - skb_push(skb, 4); - cpu_to_le32s(&tx_cmd_a); - memcpy(skb->data, &tx_cmd_a, 4); - - return skb; -} - -static const struct driver_info smsc75xx_info = { - .description = "smsc75xx USB 2.0 Gigabit Ethernet", - .bind = smsc75xx_bind, - .unbind = smsc75xx_unbind, - .link_reset = smsc75xx_link_reset, - .reset = smsc75xx_reset, - .rx_fixup = smsc75xx_rx_fixup, - .tx_fixup = smsc75xx_tx_fixup, - .status = smsc75xx_status, - .flags = FLAG_ETHER | FLAG_SEND_ZLP, -}; - -static const struct usb_device_id products[] = { - { - /* SMSC7500 USB Gigabit Ethernet Device */ - USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500), - .driver_info = (unsigned long) &smsc75xx_info, - }, - { - /* SMSC7500 USB Gigabit Ethernet Device */ - USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505), - .driver_info = (unsigned long) &smsc75xx_info, - }, - { }, /* END */ -}; -MODULE_DEVICE_TABLE(usb, products); - -static struct usb_driver smsc75xx_driver = { - .name = SMSC_CHIPNAME, - .id_table = products, - .probe = usbnet_probe, - .suspend = usbnet_suspend, - .resume = usbnet_resume, - .disconnect = usbnet_disconnect, -}; - -static int __init smsc75xx_init(void) -{ - return usb_register(&smsc75xx_driver); -} -module_init(smsc75xx_init); - -static void __exit smsc75xx_exit(void) -{ - usb_deregister(&smsc75xx_driver); -} -module_exit(smsc75xx_exit); - -MODULE_AUTHOR("Nancy Lin"); -MODULE_AUTHOR("Steve Glendinning "); -MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/usb/smsc75xx.h b/trunk/drivers/net/usb/smsc75xx.h deleted file mode 100644 index 16e98c778344..000000000000 --- a/trunk/drivers/net/usb/smsc75xx.h +++ /dev/null @@ -1,421 +0,0 @@ - /*************************************************************************** - * - * Copyright (C) 2007-2010 SMSC - * - * 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. - * - *****************************************************************************/ - -#ifndef _SMSC75XX_H -#define _SMSC75XX_H - -/* Tx command words */ -#define TX_CMD_A_LSO (0x08000000) -#define TX_CMD_A_IPE (0x04000000) -#define TX_CMD_A_TPE (0x02000000) -#define TX_CMD_A_IVTG (0x01000000) -#define TX_CMD_A_RVTG (0x00800000) -#define TX_CMD_A_FCS (0x00400000) -#define TX_CMD_A_LEN (0x000FFFFF) - -#define TX_CMD_B_MSS (0x3FFF0000) -#define TX_CMD_B_MSS_SHIFT (16) -#define TX_MSS_MIN ((u16)8) -#define TX_CMD_B_VTAG (0x0000FFFF) - -/* Rx command words */ -#define RX_CMD_A_ICE (0x80000000) -#define RX_CMD_A_TCE (0x40000000) -#define RX_CMD_A_IPV (0x20000000) -#define RX_CMD_A_PID (0x18000000) -#define RX_CMD_A_PID_NIP (0x00000000) -#define RX_CMD_A_PID_TCP (0x08000000) -#define RX_CMD_A_PID_UDP (0x10000000) -#define RX_CMD_A_PID_PP (0x18000000) -#define RX_CMD_A_PFF (0x04000000) -#define RX_CMD_A_BAM (0x02000000) -#define RX_CMD_A_MAM (0x01000000) -#define RX_CMD_A_FVTG (0x00800000) -#define RX_CMD_A_RED (0x00400000) -#define RX_CMD_A_RWT (0x00200000) -#define RX_CMD_A_RUNT (0x00100000) -#define RX_CMD_A_LONG (0x00080000) -#define RX_CMD_A_RXE (0x00040000) -#define RX_CMD_A_DRB (0x00020000) -#define RX_CMD_A_FCS (0x00010000) -#define RX_CMD_A_UAM (0x00008000) -#define RX_CMD_A_LCSM (0x00004000) -#define RX_CMD_A_LEN (0x00003FFF) - -#define RX_CMD_B_CSUM (0xFFFF0000) -#define RX_CMD_B_CSUM_SHIFT (16) -#define RX_CMD_B_VTAG (0x0000FFFF) - -/* SCSRs */ -#define ID_REV (0x0000) - -#define FPGA_REV (0x0004) - -#define BOND_CTL (0x0008) - -#define INT_STS (0x000C) -#define INT_STS_RDFO_INT (0x00400000) -#define INT_STS_TXE_INT (0x00200000) -#define INT_STS_MACRTO_INT (0x00100000) -#define INT_STS_TX_DIS_INT (0x00080000) -#define INT_STS_RX_DIS_INT (0x00040000) -#define INT_STS_PHY_INT_ (0x00020000) -#define INT_STS_MAC_ERR_INT (0x00008000) -#define INT_STS_TDFU (0x00004000) -#define INT_STS_TDFO (0x00002000) -#define INT_STS_GPIOS (0x00000FFF) -#define INT_STS_CLEAR_ALL (0xFFFFFFFF) - -#define HW_CFG (0x0010) -#define HW_CFG_SMDET_STS (0x00008000) -#define HW_CFG_SMDET_EN (0x00004000) -#define HW_CFG_EEM (0x00002000) -#define HW_CFG_RST_PROTECT (0x00001000) -#define HW_CFG_PORT_SWAP (0x00000800) -#define HW_CFG_PHY_BOOST (0x00000600) -#define HW_CFG_PHY_BOOST_NORMAL (0x00000000) -#define HW_CFG_PHY_BOOST_4 (0x00002000) -#define HW_CFG_PHY_BOOST_8 (0x00004000) -#define HW_CFG_PHY_BOOST_12 (0x00006000) -#define HW_CFG_LEDB (0x00000100) -#define HW_CFG_BIR (0x00000080) -#define HW_CFG_SBP (0x00000040) -#define HW_CFG_IME (0x00000020) -#define HW_CFG_MEF (0x00000010) -#define HW_CFG_ETC (0x00000008) -#define HW_CFG_BCE (0x00000004) -#define HW_CFG_LRST (0x00000002) -#define HW_CFG_SRST (0x00000001) - -#define PMT_CTL (0x0014) -#define PMT_CTL_PHY_PWRUP (0x00000400) -#define PMT_CTL_RES_CLR_WKP_EN (0x00000100) -#define PMT_CTL_DEV_RDY (0x00000080) -#define PMT_CTL_SUS_MODE (0x00000060) -#define PMT_CTL_SUS_MODE_0 (0x00000000) -#define PMT_CTL_SUS_MODE_1 (0x00000020) -#define PMT_CTL_SUS_MODE_2 (0x00000040) -#define PMT_CTL_SUS_MODE_3 (0x00000060) -#define PMT_CTL_PHY_RST (0x00000010) -#define PMT_CTL_WOL_EN (0x00000008) -#define PMT_CTL_ED_EN (0x00000004) -#define PMT_CTL_WUPS (0x00000003) -#define PMT_CTL_WUPS_NO (0x00000000) -#define PMT_CTL_WUPS_ED (0x00000001) -#define PMT_CTL_WUPS_WOL (0x00000002) -#define PMT_CTL_WUPS_MULTI (0x00000003) - -#define LED_GPIO_CFG (0x0018) -#define LED_GPIO_CFG_LED2_FUN_SEL (0x80000000) -#define LED_GPIO_CFG_LED10_FUN_SEL (0x40000000) -#define LED_GPIO_CFG_LEDGPIO_EN (0x0000F000) -#define LED_GPIO_CFG_LEDGPIO_EN_0 (0x00001000) -#define LED_GPIO_CFG_LEDGPIO_EN_1 (0x00002000) -#define LED_GPIO_CFG_LEDGPIO_EN_2 (0x00004000) -#define LED_GPIO_CFG_LEDGPIO_EN_3 (0x00008000) -#define LED_GPIO_CFG_GPBUF (0x00000F00) -#define LED_GPIO_CFG_GPBUF_0 (0x00000100) -#define LED_GPIO_CFG_GPBUF_1 (0x00000200) -#define LED_GPIO_CFG_GPBUF_2 (0x00000400) -#define LED_GPIO_CFG_GPBUF_3 (0x00000800) -#define LED_GPIO_CFG_GPDIR (0x000000F0) -#define LED_GPIO_CFG_GPDIR_0 (0x00000010) -#define LED_GPIO_CFG_GPDIR_1 (0x00000020) -#define LED_GPIO_CFG_GPDIR_2 (0x00000040) -#define LED_GPIO_CFG_GPDIR_3 (0x00000080) -#define LED_GPIO_CFG_GPDATA (0x0000000F) -#define LED_GPIO_CFG_GPDATA_0 (0x00000001) -#define LED_GPIO_CFG_GPDATA_1 (0x00000002) -#define LED_GPIO_CFG_GPDATA_2 (0x00000004) -#define LED_GPIO_CFG_GPDATA_3 (0x00000008) - -#define GPIO_CFG (0x001C) -#define GPIO_CFG_SHIFT (24) -#define GPIO_CFG_GPEN (0xFF000000) -#define GPIO_CFG_GPBUF (0x00FF0000) -#define GPIO_CFG_GPDIR (0x0000FF00) -#define GPIO_CFG_GPDATA (0x000000FF) - -#define GPIO_WAKE (0x0020) -#define GPIO_WAKE_PHY_LINKUP_EN (0x80000000) -#define GPIO_WAKE_POL (0x0FFF0000) -#define GPIO_WAKE_POL_SHIFT (16) -#define GPIO_WAKE_WK (0x00000FFF) - -#define DP_SEL (0x0024) -#define DP_SEL_DPRDY (0x80000000) -#define DP_SEL_RSEL (0x0000000F) -#define DP_SEL_URX (0x00000000) -#define DP_SEL_VHF (0x00000001) -#define DP_SEL_VHF_HASH_LEN (16) -#define DP_SEL_VHF_VLAN_LEN (128) -#define DP_SEL_LSO_HEAD (0x00000002) -#define DP_SEL_FCT_RX (0x00000003) -#define DP_SEL_FCT_TX (0x00000004) -#define DP_SEL_DESCRIPTOR (0x00000005) -#define DP_SEL_WOL (0x00000006) - -#define DP_CMD (0x0028) -#define DP_CMD_WRITE (0x01) -#define DP_CMD_READ (0x00) - -#define DP_ADDR (0x002C) - -#define DP_DATA (0x0030) - -#define BURST_CAP (0x0034) -#define BURST_CAP_MASK (0x0000000F) - -#define INT_EP_CTL (0x0038) -#define INT_EP_CTL_INTEP_ON (0x80000000) -#define INT_EP_CTL_RDFO_EN (0x00400000) -#define INT_EP_CTL_TXE_EN (0x00200000) -#define INT_EP_CTL_MACROTO_EN (0x00100000) -#define INT_EP_CTL_TX_DIS_EN (0x00080000) -#define INT_EP_CTL_RX_DIS_EN (0x00040000) -#define INT_EP_CTL_PHY_EN_ (0x00020000) -#define INT_EP_CTL_MAC_ERR_EN (0x00008000) -#define INT_EP_CTL_TDFU_EN (0x00004000) -#define INT_EP_CTL_TDFO_EN (0x00002000) -#define INT_EP_CTL_RX_FIFO_EN (0x00001000) -#define INT_EP_CTL_GPIOX_EN (0x00000FFF) - -#define BULK_IN_DLY (0x003C) -#define BULK_IN_DLY_MASK (0xFFFF) - -#define E2P_CMD (0x0040) -#define E2P_CMD_BUSY (0x80000000) -#define E2P_CMD_MASK (0x70000000) -#define E2P_CMD_READ (0x00000000) -#define E2P_CMD_EWDS (0x10000000) -#define E2P_CMD_EWEN (0x20000000) -#define E2P_CMD_WRITE (0x30000000) -#define E2P_CMD_WRAL (0x40000000) -#define E2P_CMD_ERASE (0x50000000) -#define E2P_CMD_ERAL (0x60000000) -#define E2P_CMD_RELOAD (0x70000000) -#define E2P_CMD_TIMEOUT (0x00000400) -#define E2P_CMD_LOADED (0x00000200) -#define E2P_CMD_ADDR (0x000001FF) - -#define MAX_EEPROM_SIZE (512) - -#define E2P_DATA (0x0044) -#define E2P_DATA_MASK_ (0x000000FF) - -#define RFE_CTL (0x0060) -#define RFE_CTL_TCPUDP_CKM (0x00001000) -#define RFE_CTL_IP_CKM (0x00000800) -#define RFE_CTL_AB (0x00000400) -#define RFE_CTL_AM (0x00000200) -#define RFE_CTL_AU (0x00000100) -#define RFE_CTL_VS (0x00000080) -#define RFE_CTL_UF (0x00000040) -#define RFE_CTL_VF (0x00000020) -#define RFE_CTL_SPF (0x00000010) -#define RFE_CTL_MHF (0x00000008) -#define RFE_CTL_DHF (0x00000004) -#define RFE_CTL_DPF (0x00000002) -#define RFE_CTL_RST_RF (0x00000001) - -#define VLAN_TYPE (0x0064) -#define VLAN_TYPE_MASK (0x0000FFFF) - -#define FCT_RX_CTL (0x0090) -#define FCT_RX_CTL_EN (0x80000000) -#define FCT_RX_CTL_RST (0x40000000) -#define FCT_RX_CTL_SBF (0x02000000) -#define FCT_RX_CTL_OVERFLOW (0x01000000) -#define FCT_RX_CTL_FRM_DROP (0x00800000) -#define FCT_RX_CTL_RX_NOT_EMPTY (0x00400000) -#define FCT_RX_CTL_RX_EMPTY (0x00200000) -#define FCT_RX_CTL_RX_DISABLED (0x00100000) -#define FCT_RX_CTL_RXUSED (0x0000FFFF) - -#define FCT_TX_CTL (0x0094) -#define FCT_TX_CTL_EN (0x80000000) -#define FCT_TX_CTL_RST (0x40000000) -#define FCT_TX_CTL_TX_NOT_EMPTY (0x00400000) -#define FCT_TX_CTL_TX_EMPTY (0x00200000) -#define FCT_TX_CTL_TX_DISABLED (0x00100000) -#define FCT_TX_CTL_TXUSED (0x0000FFFF) - -#define FCT_RX_FIFO_END (0x0098) -#define FCT_RX_FIFO_END_MASK (0x0000007F) - -#define FCT_TX_FIFO_END (0x009C) -#define FCT_TX_FIFO_END_MASK (0x0000003F) - -#define FCT_FLOW (0x00A0) -#define FCT_FLOW_THRESHOLD_OFF (0x00007F00) -#define FCT_FLOW_THRESHOLD_OFF_SHIFT (8) -#define FCT_FLOW_THRESHOLD_ON (0x0000007F) - -/* MAC CSRs */ -#define MAC_CR (0x100) -#define MAC_CR_ADP (0x00002000) -#define MAC_CR_ADD (0x00001000) -#define MAC_CR_ASD (0x00000800) -#define MAC_CR_INT_LOOP (0x00000400) -#define MAC_CR_BOLMT (0x000000C0) -#define MAC_CR_FDPX (0x00000008) -#define MAC_CR_CFG (0x00000006) -#define MAC_CR_CFG_10 (0x00000000) -#define MAC_CR_CFG_100 (0x00000002) -#define MAC_CR_CFG_1000 (0x00000004) -#define MAC_CR_RST (0x00000001) - -#define MAC_RX (0x104) -#define MAC_RX_MAX_SIZE (0x3FFF0000) -#define MAC_RX_MAX_SIZE_SHIFT (16) -#define MAC_RX_FCS_STRIP (0x00000010) -#define MAC_RX_FSE (0x00000004) -#define MAC_RX_RXD (0x00000002) -#define MAC_RX_RXEN (0x00000001) - -#define MAC_TX (0x108) -#define MAC_TX_BFCS (0x00000004) -#define MAC_TX_TXD (0x00000002) -#define MAC_TX_TXEN (0x00000001) - -#define FLOW (0x10C) -#define FLOW_FORCE_FC (0x80000000) -#define FLOW_TX_FCEN (0x40000000) -#define FLOW_RX_FCEN (0x20000000) -#define FLOW_FPF (0x10000000) -#define FLOW_PAUSE_TIME (0x0000FFFF) - -#define RAND_SEED (0x110) -#define RAND_SEED_MASK (0x0000FFFF) - -#define ERR_STS (0x114) -#define ERR_STS_FCS_ERR (0x00000100) -#define ERR_STS_LFRM_ERR (0x00000080) -#define ERR_STS_RUNT_ERR (0x00000040) -#define ERR_STS_COLLISION_ERR (0x00000010) -#define ERR_STS_ALIGN_ERR (0x00000008) -#define ERR_STS_URUN_ERR (0x00000004) - -#define RX_ADDRH (0x118) -#define RX_ADDRH_MASK (0x0000FFFF) - -#define RX_ADDRL (0x11C) - -#define MII_ACCESS (0x120) -#define MII_ACCESS_PHY_ADDR (0x0000F800) -#define MII_ACCESS_PHY_ADDR_SHIFT (11) -#define MII_ACCESS_REG_ADDR (0x000007C0) -#define MII_ACCESS_REG_ADDR_SHIFT (6) -#define MII_ACCESS_READ (0x00000000) -#define MII_ACCESS_WRITE (0x00000002) -#define MII_ACCESS_BUSY (0x00000001) - -#define MII_DATA (0x124) -#define MII_DATA_MASK (0x0000FFFF) - -#define WUCSR (0x140) -#define WUCSR_PFDA_FR (0x00000080) -#define WUCSR_WUFR (0x00000040) -#define WUCSR_MPR (0x00000020) -#define WUCSR_BCAST_FR (0x00000010) -#define WUCSR_PFDA_EN (0x00000008) -#define WUCSR_WUEN (0x00000004) -#define WUCSR_MPEN (0x00000002) -#define WUCSR_BCST_EN (0x00000001) - -#define WUF_CFGX (0x144) -#define WUF_CFGX_EN (0x80000000) -#define WUF_CFGX_ATYPE (0x03000000) -#define WUF_CFGX_ATYPE_UNICAST (0x00000000) -#define WUF_CFGX_ATYPE_MULTICAST (0x02000000) -#define WUF_CFGX_ATYPE_ALL (0x03000000) -#define WUF_CFGX_PATTERN_OFFSET (0x007F0000) -#define WUF_CFGX_PATTERN_OFFSET_SHIFT (16) -#define WUF_CFGX_CRC16 (0x0000FFFF) -#define WUF_NUM (8) - -#define WUF_MASKX (0x170) -#define WUF_MASKX_AVALID (0x80000000) -#define WUF_MASKX_ATYPE (0x40000000) - -#define ADDR_FILTX (0x300) -#define ADDR_FILTX_FB_VALID (0x80000000) -#define ADDR_FILTX_FB_TYPE (0x40000000) -#define ADDR_FILTX_FB_ADDRHI (0x0000FFFF) -#define ADDR_FILTX_SB_ADDRLO (0xFFFFFFFF) - -#define WUCSR2 (0x500) -#define WUCSR2_NS_RCD (0x00000040) -#define WUCSR2_ARP_RCD (0x00000020) -#define WUCSR2_TCPSYN_RCD (0x00000010) -#define WUCSR2_NS_OFFLOAD (0x00000004) -#define WUCSR2_ARP_OFFLOAD (0x00000002) -#define WUCSR2_TCPSYN_OFFLOAD (0x00000001) - -#define WOL_FIFO_STS (0x504) - -#define IPV6_ADDRX (0x510) - -#define IPV4_ADDRX (0x590) - - -/* Vendor-specific PHY Definitions */ - -/* Mode Control/Status Register */ -#define PHY_MODE_CTRL_STS (17) -#define MODE_CTRL_STS_EDPWRDOWN ((u16)0x2000) -#define MODE_CTRL_STS_ENERGYON ((u16)0x0002) - -#define PHY_INT_SRC (29) -#define PHY_INT_SRC_ENERGY_ON ((u16)0x0080) -#define PHY_INT_SRC_ANEG_COMP ((u16)0x0040) -#define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020) -#define PHY_INT_SRC_LINK_DOWN ((u16)0x0010) - -#define PHY_INT_MASK (30) -#define PHY_INT_MASK_ENERGY_ON ((u16)0x0080) -#define PHY_INT_MASK_ANEG_COMP ((u16)0x0040) -#define PHY_INT_MASK_REMOTE_FAULT ((u16)0x0020) -#define PHY_INT_MASK_LINK_DOWN ((u16)0x0010) -#define PHY_INT_MASK_DEFAULT (PHY_INT_MASK_ANEG_COMP | \ - PHY_INT_MASK_LINK_DOWN) - -#define PHY_SPECIAL (31) -#define PHY_SPECIAL_SPD ((u16)0x001C) -#define PHY_SPECIAL_SPD_10HALF ((u16)0x0004) -#define PHY_SPECIAL_SPD_10FULL ((u16)0x0014) -#define PHY_SPECIAL_SPD_100HALF ((u16)0x0008) -#define PHY_SPECIAL_SPD_100FULL ((u16)0x0018) - -/* USB Vendor Requests */ -#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 -#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 -#define USB_VENDOR_REQUEST_GET_STATS 0xA2 - -/* Interrupt Endpoint status word bitfields */ -#define INT_ENP_RDFO_INT ((u32)BIT(22)) -#define INT_ENP_TXE_INT ((u32)BIT(21)) -#define INT_ENP_TX_DIS_INT ((u32)BIT(19)) -#define INT_ENP_RX_DIS_INT ((u32)BIT(18)) -#define INT_ENP_PHY_INT ((u32)BIT(17)) -#define INT_ENP_MAC_ERR_INT ((u32)BIT(15)) -#define INT_ENP_RX_FIFO_DATA_INT ((u32)BIT(12)) - -#endif /* _SMSC75XX_H */ diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index d222d7e25273..df9179a1c93b 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -709,8 +709,6 @@ static void smsc95xx_start_rx_path(struct usbnet *dev) static int smsc95xx_phy_initialize(struct usbnet *dev) { - int bmcr, timeout = 0; - /* Initialize MII structure */ dev->mii.dev = dev->net; dev->mii.mdio_read = smsc95xx_mdio_read; @@ -719,20 +717,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) dev->mii.reg_num_mask = 0x1f; dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID; - /* reset phy and wait for reset to complete */ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); - - do { - msleep(10); - bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); - timeout++; - } while ((bmcr & MII_BMCR) && (timeout < 100)); - - if (timeout >= 100) { - netdev_warn(dev->net, "timeout on PHY Reset"); - return -EIO; - } - smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); diff --git a/trunk/drivers/pcmcia/i82092.c b/trunk/drivers/pcmcia/i82092.c index f5da62653313..a04f21c8170f 100644 --- a/trunk/drivers/pcmcia/i82092.c +++ b/trunk/drivers/pcmcia/i82092.c @@ -133,7 +133,6 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de sockets[i].socket.map_size = 0x1000; sockets[i].socket.irq_mask = 0; sockets[i].socket.pci_irq = dev->irq; - sockets[i].socket.cb_dev = dev; sockets[i].socket.owner = THIS_MODULE; sockets[i].number = i; diff --git a/trunk/drivers/pcmcia/i82365.h b/trunk/drivers/pcmcia/i82365.h index 3f84d7a2dc84..849ef1b5d687 100644 --- a/trunk/drivers/pcmcia/i82365.h +++ b/trunk/drivers/pcmcia/i82365.h @@ -95,7 +95,6 @@ #define I365_CSC_DETECT 0x08 #define I365_CSC_ANY 0x0F #define I365_CSC_GPI 0x10 -#define I365_CSC_IRQ_MASK 0xF0 /* Flags for I365_ADDRWIN */ #define I365_ENA_IO(map) (0x40 << (map)) diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index c4612c52e4cb..b2df04199a21 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -256,7 +256,6 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, { struct pcmcia_socket *s; config_t *c; - int ret; s = p_dev->socket; @@ -265,13 +264,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, if (!(s->state & SOCKET_PRESENT)) { dev_dbg(&s->dev, "No card present\n"); - ret = -ENODEV; - goto unlock; + mutex_unlock(&s->ops_mutex); + return -ENODEV; } if (!(c->state & CONFIG_LOCKED)) { dev_dbg(&s->dev, "Configuration isnt't locked\n"); - ret = -EACCES; - goto unlock; + mutex_unlock(&s->ops_mutex); + return -EACCES; } if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { @@ -287,8 +286,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, if (mod->Attributes & CONF_VCC_CHANGE_VALID) { dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); - ret = -EINVAL; - goto unlock; + return -EINVAL; } /* We only allow changing Vpp1 and Vpp2 to the same value */ @@ -296,21 +294,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { if (mod->Vpp1 != mod->Vpp2) { dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); - ret = -EINVAL; - goto unlock; + mutex_unlock(&s->ops_mutex); + return -EINVAL; } s->socket.Vpp = mod->Vpp1; if (s->ops->set_socket(s, &s->socket)) { + mutex_unlock(&s->ops_mutex); dev_printk(KERN_WARNING, &s->dev, "Unable to set VPP\n"); - ret = -EIO; - goto unlock; + return -EIO; } } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); - ret = -EINVAL; - goto unlock; + mutex_unlock(&s->ops_mutex); + return -EINVAL; } if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { @@ -334,11 +332,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, s->ops->set_io_map(s, &io_on); } } - ret = 0; -unlock: mutex_unlock(&s->ops_mutex); - return ret; + return 0; } /* modify_configuration */ EXPORT_SYMBOL(pcmcia_modify_configuration); @@ -756,6 +752,14 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) #ifdef CONFIG_PCMCIA_PROBE +#ifdef IRQ_NOAUTOEN + /* if the underlying IRQ infrastructure allows for it, only allocate + * the IRQ, but do not enable it + */ + if (!(req->Handler)) + type |= IRQ_NOAUTOEN; +#endif /* IRQ_NOAUTOEN */ + if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must be the same */ irq = s->irq.AssignedIRQ; diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index 7ba57a565cd7..7c204910a777 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -671,7 +671,6 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, socket[i].socket.map_size = 0x1000; socket[i].socket.irq_mask = mask; socket[i].socket.pci_irq = dev->irq; - socket[i].socket.cb_dev = dev; socket[i].socket.owner = THIS_MODULE; socket[i].number = i; diff --git a/trunk/drivers/pcmcia/ti113x.h b/trunk/drivers/pcmcia/ti113x.h index 9ffa97d0b16c..aaa70227bfb0 100644 --- a/trunk/drivers/pcmcia/ti113x.h +++ b/trunk/drivers/pcmcia/ti113x.h @@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket) u8 new, reg = exca_readb(socket, I365_INTCTL); new = reg & ~I365_INTR_ENA; - if (socket->dev->irq) + if (socket->cb_irq) new |= I365_INTR_ENA; if (new != reg) exca_writeb(socket, I365_INTCTL, new); @@ -316,47 +316,14 @@ static int ti_override(struct yenta_socket *socket) return 0; } -static void ti113x_use_isa_irq(struct yenta_socket *socket) -{ - int isa_irq = -1; - u8 intctl; - u32 isa_irq_mask = 0; - - if (!isa_probe) - return; - - /* get a free isa int */ - isa_irq_mask = yenta_probe_irq(socket, isa_interrupts); - if (!isa_irq_mask) - return; /* no useable isa irq found */ - - /* choose highest available */ - for (; isa_irq_mask; isa_irq++) - isa_irq_mask >>= 1; - socket->cb_irq = isa_irq; - - exca_writeb(socket, I365_CSCINT, (isa_irq << 4)); - - intctl = exca_readb(socket, I365_INTCTL); - intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK); /* CSC Enable */ - exca_writeb(socket, I365_INTCTL, intctl); - - dev_info(&socket->dev->dev, - "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq); -} - - static int ti113x_override(struct yenta_socket *socket) { u8 cardctl; cardctl = config_readb(socket, TI113X_CARD_CONTROL); cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); - if (socket->dev->irq) + if (socket->cb_irq) cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; - else - ti113x_use_isa_irq(socket); - config_writeb(socket, TI113X_CARD_CONTROL, cardctl); return ti_override(socket); diff --git a/trunk/drivers/pcmcia/vrc4171_card.c b/trunk/drivers/pcmcia/vrc4171_card.c index aaccdb9f4ba1..c9fcbdc164ea 100644 --- a/trunk/drivers/pcmcia/vrc4171_card.c +++ b/trunk/drivers/pcmcia/vrc4171_card.c @@ -105,7 +105,6 @@ typedef struct vrc4171_socket { char name[24]; int csc_irq; int io_irq; - spinlock_t lock; } vrc4171_socket_t; static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS]; @@ -328,7 +327,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) slot = sock->sock; socket = &vrc4171_sockets[slot]; - spin_lock_irq(&socket->lock); + spin_lock_irq(&sock->lock); voltage = set_Vcc_value(state->Vcc); exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); @@ -371,7 +370,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) cscint |= I365_CSC_DETECT; exca_write_byte(slot, I365_CSCINT, cscint); - spin_unlock_irq(&socket->lock); + spin_unlock_irq(&sock->lock); return 0; } diff --git a/trunk/drivers/pcmcia/yenta_socket.c b/trunk/drivers/pcmcia/yenta_socket.c index 418988ab6edf..967c766f53ba 100644 --- a/trunk/drivers/pcmcia/yenta_socket.c +++ b/trunk/drivers/pcmcia/yenta_socket.c @@ -42,18 +42,6 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444); MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " "or 'default' (uses recommended behaviour for the detected bridge)"); -/* - * Only probe "regular" interrupts, don't - * touch dangerous spots like the mouse irq, - * because there are mice that apparently - * get really confused if they get fondled - * too intimately. - * - * Default to 11, 10, 9, 7, 6, 5, 4, 3. - */ -static u32 isa_interrupts = 0x0ef8; - - #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args) /* Don't ask.. */ @@ -66,8 +54,6 @@ static u32 isa_interrupts = 0x0ef8; */ #ifdef CONFIG_YENTA_TI static int yenta_probe_cb_irq(struct yenta_socket *socket); -static unsigned int yenta_probe_irq(struct yenta_socket *socket, - u32 isa_irq_mask); #endif @@ -343,8 +329,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) /* ISA interrupt control? */ intr = exca_readb(socket, I365_INTCTL); intr = (intr & ~0xf); - if (!socket->dev->irq) { - intr |= socket->cb_irq ? socket->cb_irq : state->io_irq; + if (!socket->cb_irq) { + intr |= state->io_irq; bridge |= CB_BRIDGE_INTR; } exca_writeb(socket, I365_INTCTL, intr); @@ -354,7 +340,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA); reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; - if (state->io_irq != socket->dev->irq) { + if (state->io_irq != socket->cb_irq) { reg |= state->io_irq; bridge |= CB_BRIDGE_INTR; } @@ -370,9 +356,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) exca_writeb(socket, I365_POWER, reg); /* CSC interrupt: no ISA irq for CSC */ - reg = exca_readb(socket, I365_CSCINT); - reg &= I365_CSC_IRQ_MASK; - reg |= I365_CSC_DETECT; + reg = I365_CSC_DETECT; if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG; @@ -912,12 +896,22 @@ static struct cardbus_type cardbus_type[] = { }; +/* + * Only probe "regular" interrupts, don't + * touch dangerous spots like the mouse irq, + * because there are mice that apparently + * get really confused if they get fondled + * too intimately. + * + * Default to 11, 10, 9, 7, 6, 5, 4, 3. + */ +static u32 isa_interrupts = 0x0ef8; + static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) { int i; unsigned long val; u32 mask; - u8 reg; /* * Probe for usable interrupts using the force @@ -925,7 +919,6 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas */ cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); - reg = exca_readb(socket, I365_CSCINT); exca_writeb(socket, I365_CSCINT, 0); val = probe_irq_on() & isa_irq_mask; for (i = 1; i < 16; i++) { @@ -937,7 +930,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas cb_writel(socket, CB_SOCKET_EVENT, -1); } cb_writel(socket, CB_SOCKET_MASK, 0); - exca_writeb(socket, I365_CSCINT, reg); + exca_writeb(socket, I365_CSCINT, 0); mask = probe_irq_mask(val) & 0xffff; @@ -974,8 +967,6 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id) /* probes the PCI interrupt, use only on override functions */ static int yenta_probe_cb_irq(struct yenta_socket *socket) { - u8 reg; - if (!socket->cb_irq) return -1; @@ -988,8 +979,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) } /* generate interrupt, wait */ - reg = exca_readb(socket, I365_CSCINT); - exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG); + exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); @@ -998,7 +988,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) /* disable interrupts */ cb_writel(socket, CB_SOCKET_MASK, 0); - exca_writeb(socket, I365_CSCINT, reg); + exca_writeb(socket, I365_CSCINT, 0); cb_writel(socket, CB_SOCKET_EVENT, -1); exca_readb(socket, I365_CSC); diff --git a/trunk/drivers/s390/char/sclp_cmd.c b/trunk/drivers/s390/char/sclp_cmd.c index fc7ae05ce48a..b3beab610da4 100644 --- a/trunk/drivers/s390/char/sclp_cmd.c +++ b/trunk/drivers/s390/char/sclp_cmd.c @@ -704,13 +704,6 @@ int sclp_chp_deconfigure(struct chp_id chpid) return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); } -int arch_get_memory_phys_device(unsigned long start_pfn) -{ - if (!rzm) - return 0; - return PFN_PHYS(start_pfn) / rzm; -} - struct chp_info_sccb { struct sccb_header header; u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.c b/trunk/drivers/scsi/pcmcia/nsp_cs.c index 021246454872..c2341af587a3 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.c +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.c @@ -1717,7 +1717,6 @@ static int nsp_cs_config(struct pcmcia_device *link) cfg_mem->data = data; ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); - if (ret) goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) { diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index d2e0321049e2..d514e28d0755 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; - up->interrupt_mask0 |= SAB82532_IMR0_TCD; + up->interrupt_mask0 |= SAB82532_ISR0_TCD; writeb(up->interrupt_mask1, &up->regs->w.imr0); } diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index feaff4f04b58..dabe804ba575 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -914,7 +914,7 @@ config FB_XVR2500 config FB_XVR1000 bool "Sun XVR-1000 support" - depends on (FB = y) && SPARC64 + depends on SPARC64 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index 0c77fc610212..c025c84601b0 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -31,6 +31,13 @@ config LCD_CORGI Say y here to support the LCD panels usually found on SHARP corgi (C7x0) and spitz (Cxx00) models. +config LCD_L4F00242T03 + tristate "Epson L4F00242T03 LCD" + depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO + help + SPI driver for Epson L4F00242T03. This provides basic support + for init and powering the LCD up/down through a sysfs interface. + config LCD_LMS283GF05 tristate "Samsung LMS283GF05 LCD" depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO diff --git a/trunk/drivers/video/backlight/Makefile b/trunk/drivers/video/backlight/Makefile index 6c704d41462d..09d1f14d6257 100644 --- a/trunk/drivers/video/backlight/Makefile +++ b/trunk/drivers/video/backlight/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o +obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o obj-$(CONFIG_LCD_ILI9320) += ili9320.o diff --git a/trunk/drivers/video/backlight/l4f00242t03.c b/trunk/drivers/video/backlight/l4f00242t03.c new file mode 100644 index 000000000000..42d061e1403b --- /dev/null +++ b/trunk/drivers/video/backlight/l4f00242t03.c @@ -0,0 +1,256 @@ +/* + * l4f00242t03.c -- support for Epson L4F00242T03 LCD + * + * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Copyright (c) 2009 Alberto Panizzo + * Inspired by Marek Vasut work in l4f00242t03.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct l4f00242t03_priv { + struct spi_device *spi; + struct lcd_device *ld; + int lcd_on:1; + struct regulator *io_reg; + struct regulator *core_reg; +}; + + +static void l4f00242t03_reset(unsigned int gpio) +{ + pr_debug("l4f00242t03_reset.\n"); + gpio_set_value(gpio, 1); + mdelay(100); + gpio_set_value(gpio, 0); + mdelay(10); /* tRES >= 100us */ + gpio_set_value(gpio, 1); + mdelay(20); +} + +#define param(x) ((x) | 0x100) + +static void l4f00242t03_lcd_init(struct spi_device *spi) +{ + struct l4f00242t03_pdata *pdata = spi->dev.platform_data; + struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) }; + + dev_dbg(&spi->dev, "initializing LCD\n"); + + if (priv->io_reg) { + regulator_set_voltage(priv->io_reg, 1800000, 1800000); + regulator_enable(priv->io_reg); + } + + if (priv->core_reg) { + regulator_set_voltage(priv->core_reg, 2800000, 2800000); + regulator_enable(priv->core_reg); + } + + gpio_set_value(pdata->data_enable_gpio, 1); + msleep(60); + spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16)); +} + +static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) +{ + struct l4f00242t03_priv *priv = lcd_get_data(ld); + struct spi_device *spi = priv->spi; + + const u16 slpout = 0x11; + const u16 dison = 0x29; + + const u16 slpin = 0x10; + const u16 disoff = 0x28; + + if (power) { + if (priv->lcd_on) + return 0; + + dev_dbg(&spi->dev, "turning on LCD\n"); + + spi_write(spi, (const u8 *)&slpout, sizeof(u16)); + msleep(60); + spi_write(spi, (const u8 *)&dison, sizeof(u16)); + + priv->lcd_on = 1; + } else { + if (!priv->lcd_on) + return 0; + + dev_dbg(&spi->dev, "turning off LCD\n"); + + spi_write(spi, (const u8 *)&disoff, sizeof(u16)); + msleep(60); + spi_write(spi, (const u8 *)&slpin, sizeof(u16)); + + priv->lcd_on = 0; + } + + return 0; +} + +static struct lcd_ops l4f_ops = { + .set_power = l4f00242t03_lcd_power_set, + .get_power = NULL, +}; + +static int __devinit l4f00242t03_probe(struct spi_device *spi) +{ + struct l4f00242t03_priv *priv; + struct l4f00242t03_pdata *pdata = spi->dev.platform_data; + int ret; + + if (pdata == NULL) { + dev_err(&spi->dev, "Uninitialized platform data.\n"); + return -EINVAL; + } + + priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL); + + if (priv == NULL) { + dev_err(&spi->dev, "No memory for this device.\n"); + ret = -ENOMEM; + goto err; + } + + dev_set_drvdata(&spi->dev, priv); + spi->bits_per_word = 9; + spi_setup(spi); + + priv->spi = spi; + + ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset"); + if (ret) { + dev_err(&spi->dev, + "Unable to get the lcd l4f00242t03 reset gpio.\n"); + return ret; + } + + ret = gpio_direction_output(pdata->reset_gpio, 1); + if (ret) + goto err2; + + ret = gpio_request(pdata->data_enable_gpio, + "lcd l4f00242t03 data enable"); + if (ret) { + dev_err(&spi->dev, + "Unable to get the lcd l4f00242t03 data en gpio.\n"); + return ret; + } + + ret = gpio_direction_output(pdata->data_enable_gpio, 0); + if (ret) + goto err3; + + if (pdata->io_supply) { + priv->io_reg = regulator_get(NULL, pdata->io_supply); + + if (IS_ERR(priv->io_reg)) { + pr_err("%s: Unable to get the IO regulator\n", + __func__); + goto err3; + } + } + + if (pdata->core_supply) { + priv->core_reg = regulator_get(NULL, pdata->core_supply); + + if (IS_ERR(priv->core_reg)) { + pr_err("%s: Unable to get the core regulator\n", + __func__); + goto err4; + } + } + + priv->ld = lcd_device_register("l4f00242t03", + &spi->dev, priv, &l4f_ops); + if (IS_ERR(priv->ld)) { + ret = PTR_ERR(priv->ld); + goto err5; + } + + /* Init the LCD */ + l4f00242t03_reset(pdata->reset_gpio); + l4f00242t03_lcd_init(spi); + l4f00242t03_lcd_power_set(priv->ld, 1); + + dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); + + return 0; + +err5: + if (priv->core_reg) + regulator_put(priv->core_reg); +err4: + if (priv->io_reg) + regulator_put(priv->io_reg); +err3: + gpio_free(pdata->data_enable_gpio); +err2: + gpio_free(pdata->reset_gpio); +err: + kfree(priv); + + return ret; +} + +static int __devexit l4f00242t03_remove(struct spi_device *spi) +{ + struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; + + l4f00242t03_lcd_power_set(priv->ld, 0); + lcd_device_unregister(priv->ld); + + gpio_free(pdata->data_enable_gpio); + gpio_free(pdata->reset_gpio); + + if (priv->io_reg) + regulator_put(priv->core_reg); + if (priv->core_reg) + regulator_put(priv->io_reg); + + kfree(priv); + + return 0; +} + +static struct spi_driver l4f00242t03_driver = { + .driver = { + .name = "l4f00242t03", + .owner = THIS_MODULE, + }, + .probe = l4f00242t03_probe, + .remove = __devexit_p(l4f00242t03_remove), +}; + +static __init int l4f00242t03_init(void) +{ + return spi_register_driver(&l4f00242t03_driver); +} + +static __exit void l4f00242t03_exit(void) +{ + spi_unregister_driver(&l4f00242t03_driver); +} + +module_init(l4f00242t03_init); +module_exit(l4f00242t03_exit); + +MODULE_AUTHOR("Alberto Panizzo "); +MODULE_DESCRIPTION("EPSON L4F00242T03 LCD"); diff --git a/trunk/fs/jffs2/readinode.c b/trunk/fs/jffs2/readinode.c index d32ee9412cb9..e22de8397b74 100644 --- a/trunk/fs/jffs2/readinode.c +++ b/trunk/fs/jffs2/readinode.c @@ -567,7 +567,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) else BUG(); } } - *list = RB_ROOT; + list->rb_node = NULL; } static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) diff --git a/trunk/fs/ntfs/super.c b/trunk/fs/ntfs/super.c index 0de1db6cddbf..1cf39dfaee7a 100644 --- a/trunk/fs/ntfs/super.c +++ b/trunk/fs/ntfs/super.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "sysctl.h" #include "logfile.h" @@ -2459,6 +2458,7 @@ static void ntfs_put_super(struct super_block *sb) static s64 get_nr_free_clusters(ntfs_volume *vol) { s64 nr_free = vol->nr_clusters; + u32 *kaddr; struct address_space *mapping = vol->lcnbmp_ino->i_mapping; struct page *page; pgoff_t index, max_index; @@ -2477,8 +2477,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.", max_index, PAGE_CACHE_SIZE / 4); for (index = 0; index < max_index; index++) { - unsigned long *kaddr; - + unsigned int i; /* * Read the page from page cache, getting it from backing store * if necessary, and increment the use count. @@ -2491,16 +2490,16 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) nr_free -= PAGE_CACHE_SIZE * 8; continue; } - kaddr = kmap_atomic(page, KM_USER0); + kaddr = (u32*)kmap_atomic(page, KM_USER0); /* - * Subtract the number of set bits. If this + * For each 4 bytes, subtract the number of set bits. If this * is the last page and it is partial we don't really care as * it just means we do a little extra work but it won't affect * the result as all out of range bytes are set to zero by * ntfs_readpage(). */ - nr_free -= bitmap_weight(kaddr, - PAGE_CACHE_SIZE * BITS_PER_BYTE); + for (i = 0; i < PAGE_CACHE_SIZE / 4; i++) + nr_free -= (s64)hweight32(kaddr[i]); kunmap_atomic(kaddr, KM_USER0); page_cache_release(page); } @@ -2539,6 +2538,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, s64 nr_free, const pgoff_t max_index) { + u32 *kaddr; struct address_space *mapping = vol->mftbmp_ino->i_mapping; struct page *page; pgoff_t index; @@ -2548,8 +2548,7 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = " "0x%lx.", max_index, PAGE_CACHE_SIZE / 4); for (index = 0; index < max_index; index++) { - unsigned long *kaddr; - + unsigned int i; /* * Read the page from page cache, getting it from backing store * if necessary, and increment the use count. @@ -2562,16 +2561,16 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, nr_free -= PAGE_CACHE_SIZE * 8; continue; } - kaddr = kmap_atomic(page, KM_USER0); + kaddr = (u32*)kmap_atomic(page, KM_USER0); /* - * Subtract the number of set bits. If this + * For each 4 bytes, subtract the number of set bits. If this * is the last page and it is partial we don't really care as * it just means we do a little extra work but it won't affect * the result as all out of range bytes are set to zero by * ntfs_readpage(). */ - nr_free -= bitmap_weight(kaddr, - PAGE_CACHE_SIZE * BITS_PER_BYTE); + for (i = 0; i < PAGE_CACHE_SIZE / 4; i++) + nr_free -= (s64)hweight32(kaddr[i]); kunmap_atomic(kaddr, KM_USER0); page_cache_release(page); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_aops.c b/trunk/fs/xfs/linux-2.6/xfs_aops.c index 99628508cb11..9083357f9e44 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.c @@ -932,9 +932,6 @@ xfs_aops_discard_page( if (!xfs_is_delayed_page(page, IOMAP_DELAY)) goto out_invalidate; - if (XFS_FORCED_SHUTDOWN(ip->i_mount)) - goto out_invalidate; - xfs_fs_cmn_err(CE_ALERT, ip->i_mount, "page discard on page %p, inode 0x%llx, offset %llu.", page, ip->i_ino, offset); @@ -967,10 +964,8 @@ xfs_aops_discard_page( if (error) { /* something screwed, just bail */ - if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { - xfs_fs_cmn_err(CE_ALERT, ip->i_mount, - "page discard failed delalloc mapping lookup."); - } + xfs_fs_cmn_err(CE_ALERT, ip->i_mount, + "page discard failed delalloc mapping lookup."); break; } if (!nimaps) { @@ -996,10 +991,8 @@ xfs_aops_discard_page( ASSERT(!flist.xbf_count && !flist.xbf_first); if (error) { /* something screwed, just bail */ - if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { - xfs_fs_cmn_err(CE_ALERT, ip->i_mount, + xfs_fs_cmn_err(CE_ALERT, ip->i_mount, "page discard unable to remove delalloc mapping."); - } break; } next_buffer: diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index bd111b7e1daa..6f76ba85f193 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -167,6 +167,75 @@ test_page_region( return (mask && (page_private(page) & mask) == mask); } +/* + * Mapping of multi-page buffers into contiguous virtual space + */ + +typedef struct a_list { + void *vm_addr; + struct a_list *next; +} a_list_t; + +static a_list_t *as_free_head; +static int as_list_len; +static DEFINE_SPINLOCK(as_lock); + +/* + * Try to batch vunmaps because they are costly. + */ +STATIC void +free_address( + void *addr) +{ + a_list_t *aentry; + +#ifdef CONFIG_XEN + /* + * Xen needs to be able to make sure it can get an exclusive + * RO mapping of pages it wants to turn into a pagetable. If + * a newly allocated page is also still being vmap()ed by xfs, + * it will cause pagetable construction to fail. This is a + * quick workaround to always eagerly unmap pages so that Xen + * is happy. + */ + vunmap(addr); + return; +#endif + + aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); + if (likely(aentry)) { + spin_lock(&as_lock); + aentry->next = as_free_head; + aentry->vm_addr = addr; + as_free_head = aentry; + as_list_len++; + spin_unlock(&as_lock); + } else { + vunmap(addr); + } +} + +STATIC void +purge_addresses(void) +{ + a_list_t *aentry, *old; + + if (as_free_head == NULL) + return; + + spin_lock(&as_lock); + aentry = as_free_head; + as_free_head = NULL; + as_list_len = 0; + spin_unlock(&as_lock); + + while ((old = aentry) != NULL) { + vunmap(aentry->vm_addr); + aentry = aentry->next; + kfree(old); + } +} + /* * Internal xfs_buf_t object manipulation */ @@ -268,8 +337,7 @@ xfs_buf_free( uint i; if (xfs_buf_is_vmapped(bp)) - vm_unmap_ram(bp->b_addr - bp->b_offset, - bp->b_page_count); + free_address(bp->b_addr - bp->b_offset); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -389,8 +457,10 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, - -1, PAGE_KERNEL); + if (as_list_len > 64) + purge_addresses(); + bp->b_addr = vmap(bp->b_pages, bp->b_page_count, + VM_MAP, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) return -ENOMEM; bp->b_addr += bp->b_offset; @@ -1885,6 +1955,9 @@ xfsbufd( xfs_buf_iostrategy(bp); count++; } + + if (as_list_len > 0) + purge_addresses(); if (count) blk_run_address_space(target->bt_mapping); diff --git a/trunk/include/linux/memory.h b/trunk/include/linux/memory.h index 85582e1bcee9..1adfe779eb99 100644 --- a/trunk/include/linux/memory.h +++ b/trunk/include/linux/memory.h @@ -36,8 +36,6 @@ struct memory_block { struct sys_device sysdev; }; -int arch_get_memory_phys_device(unsigned long start_pfn); - /* These states are exposed to userspace as text strings in sysfs */ #define MEM_ONLINE (1<<0) /* exposed to userspace */ #define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */ diff --git a/trunk/include/linux/spi/l4f00242t03.h b/trunk/include/linux/spi/l4f00242t03.h new file mode 100644 index 000000000000..aee1dbda4edc --- /dev/null +++ b/trunk/include/linux/spi/l4f00242t03.h @@ -0,0 +1,31 @@ +/* + * l4f00242t03.h -- Platform glue for Epson L4F00242T03 LCD + * + * Copyright (c) 2009 Alberto Panizzo + * Based on Marek Vasut work in lms283gf05.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 +*/ + +#ifndef _INCLUDE_LINUX_SPI_L4F00242T03_H_ +#define _INCLUDE_LINUX_SPI_L4F00242T03_H_ + +struct l4f00242t03_pdata { + unsigned int reset_gpio; + unsigned int data_enable_gpio; + const char *io_supply; /* will be set to 1.8 V */ + const char *core_supply; /* will be set to 2.8 V */ +}; + +#endif /* _INCLUDE_LINUX_SPI_L4F00242T03_H_ */ diff --git a/trunk/mm/page_cgroup.c b/trunk/mm/page_cgroup.c index 6c0081441a32..3dd88539a0e6 100644 --- a/trunk/mm/page_cgroup.c +++ b/trunk/mm/page_cgroup.c @@ -284,7 +284,6 @@ static DEFINE_MUTEX(swap_cgroup_mutex); struct swap_cgroup_ctrl { struct page **map; unsigned long length; - spinlock_t lock; }; struct swap_cgroup_ctrl swap_cgroup_ctrl[MAX_SWAPFILES]; @@ -354,22 +353,16 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, struct swap_cgroup_ctrl *ctrl; struct page *mappage; struct swap_cgroup *sc; - unsigned long flags; - unsigned short retval; ctrl = &swap_cgroup_ctrl[type]; mappage = ctrl->map[idx]; sc = page_address(mappage); sc += pos; - spin_lock_irqsave(&ctrl->lock, flags); - retval = sc->id; - if (retval == old) - sc->id = new; + if (cmpxchg(&sc->id, old, new) == old) + return old; else - retval = 0; - spin_unlock_irqrestore(&ctrl->lock, flags); - return retval; + return 0; } /** @@ -390,17 +383,13 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) struct page *mappage; struct swap_cgroup *sc; unsigned short old; - unsigned long flags; ctrl = &swap_cgroup_ctrl[type]; mappage = ctrl->map[idx]; sc = page_address(mappage); sc += pos; - spin_lock_irqsave(&ctrl->lock, flags); - old = sc->id; - sc->id = id; - spin_unlock_irqrestore(&ctrl->lock, flags); + old = xchg(&sc->id, id); return old; } @@ -452,7 +441,6 @@ int swap_cgroup_swapon(int type, unsigned long max_pages) mutex_lock(&swap_cgroup_mutex); ctrl->length = length; ctrl->map = array; - spin_lock_init(&ctrl->lock); if (swap_cgroup_prepare(type)) { /* memory shortage */ ctrl->map = NULL; diff --git a/trunk/net/bridge/br_device.c b/trunk/net/bridge/br_device.c index 90a9024e5c1e..eb7062d2e9e5 100644 --- a/trunk/net/bridge/br_device.c +++ b/trunk/net/bridge/br_device.c @@ -40,7 +40,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) goto out; mdst = br_mdb_get(br, skb); - if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) + if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) br_multicast_deliver(mdst, skb); else br_flood_deliver(br, skb); diff --git a/trunk/net/bridge/br_forward.c b/trunk/net/bridge/br_forward.c index 8dbec83e50ca..d61e6f741125 100644 --- a/trunk/net/bridge/br_forward.c +++ b/trunk/net/bridge/br_forward.c @@ -19,11 +19,6 @@ #include #include "br_private.h" -static int deliver_clone(const struct net_bridge_port *prev, - struct sk_buff *skb, - void (*__packet_hook)(const struct net_bridge_port *p, - struct sk_buff *skb)); - /* Don't forward packets to originating port or forwarding diasabled */ static inline int should_deliver(const struct net_bridge_port *p, const struct sk_buff *skb) @@ -99,22 +94,17 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) } /* called with rcu_read_lock */ -void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0) +void br_forward(const struct net_bridge_port *to, struct sk_buff *skb) { if (should_deliver(to, skb)) { - if (skb0) - deliver_clone(to, skb, __br_forward); - else - __br_forward(to, skb); + __br_forward(to, skb); return; } - if (!skb0) - kfree_skb(skb); + kfree_skb(skb); } -static int deliver_clone(const struct net_bridge_port *prev, - struct sk_buff *skb, +static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, void (*__packet_hook)(const struct net_bridge_port *p, struct sk_buff *skb)) { diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index d74d570fc848..53b39851d87d 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -70,7 +70,7 @@ int br_handle_frame_finish(struct sk_buff *skb) if (is_multicast_ether_addr(dest)) { mdst = br_mdb_get(br, skb); - if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { + if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) { if ((mdst && !hlist_unhashed(&mdst->mglist)) || br_multicast_is_router(br)) skb2 = skb; @@ -90,7 +90,7 @@ int br_handle_frame_finish(struct sk_buff *skb) if (skb) { if (dst) - br_forward(dst->dst, skb, skb2); + br_forward(dst->dst, skb); else br_flood_forward(br, skb, skb2); } diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index 6980625537ca..fd96a8dc97f4 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -49,23 +49,22 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( static struct net_bridge_mdb_entry *br_mdb_ip_get( struct net_bridge_mdb_htable *mdb, __be32 dst) { - if (!mdb) - return NULL; - return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); } struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, struct sk_buff *skb) { - if (br->multicast_disabled) + struct net_bridge_mdb_htable *mdb = br->mdb; + + if (!mdb || br->multicast_disabled) return NULL; switch (skb->protocol) { case htons(ETH_P_IP): if (BR_INPUT_SKB_CB(skb)->igmp) break; - return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr); + return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr); } return NULL; @@ -852,8 +851,8 @@ static int br_multicast_query(struct net_bridge *br, if (ih3->nsrcs) goto out; - max_delay = ih3->code ? - IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; + max_delay = ih3->code ? 1 : + IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); } if (!group) @@ -991,7 +990,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, err = pskb_trim_rcsum(skb2, len); if (err) - goto err_out; + return err; } len -= ip_hdrlen(skb2); @@ -1013,7 +1012,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, case CHECKSUM_NONE: skb2->csum = 0; if (skb_checksum_complete(skb2)) - goto out; + return -EINVAL; } err = 0; @@ -1040,7 +1039,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, out: __skb_push(skb2, offset); -err_out: if (skb2 != skb) kfree_skb(skb2); return err; diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 846d7d1e2075..fef0384e3c0b 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -206,20 +206,12 @@ struct net_bridge struct br_input_skb_cb { struct net_device *brdev; -#ifdef CONFIG_BRIDGE_IGMP_SNOOPING int igmp; int mrouters_only; -#endif }; #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) -#ifdef CONFIG_BRIDGE_IGMP_SNOOPING -# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only) -#else -# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0) -#endif - extern struct notifier_block br_device_notifier; extern const u8 br_group_address[ETH_ALEN]; @@ -260,7 +252,7 @@ extern void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb); extern int br_dev_queue_push_xmit(struct sk_buff *skb); extern void br_forward(const struct net_bridge_port *to, - struct sk_buff *skb, struct sk_buff *skb0); + struct sk_buff *skb); extern int br_forward_finish(struct sk_buff *skb); extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index d4ec38fa64e6..7aa697253765 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -735,7 +735,7 @@ int netpoll_setup(struct netpoll *np) npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); if (!npinfo) { err = -ENOMEM; - goto put; + goto release; } npinfo->rx_flags = 0; @@ -845,7 +845,7 @@ int netpoll_setup(struct netpoll *np) kfree(npinfo); } -put: + dev_put(ndev); return err; } diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 4071eaf2b361..b195c4feaa0a 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -998,11 +998,11 @@ static struct inet_protosw dccp_v4_protosw = { static int __net_init dccp_v4_init_net(struct net *net) { - if (dccp_hashinfo.bhash == NULL) - return -ESOCKTNOSUPPORT; + int err; - return inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET, - SOCK_DCCP, IPPROTO_DCCP, net); + err = inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET, + SOCK_DCCP, IPPROTO_DCCP, net); + return err; } static void __net_exit dccp_v4_exit_net(struct net *net) diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index af3394df63b7..1aec6349e858 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -1191,11 +1191,11 @@ static struct inet_protosw dccp_v6_protosw = { static int __net_init dccp_v6_init_net(struct net *net) { - if (dccp_hashinfo.bhash == NULL) - return -ESOCKTNOSUPPORT; + int err; - return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, - SOCK_DCCP, IPPROTO_DCCP, net); + err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, + SOCK_DCCP, IPPROTO_DCCP, net); + return err; } static void __net_exit dccp_v6_exit_net(struct net *net) diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index aa4cef374fd0..0ef7061920c0 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -1036,7 +1036,7 @@ static int __init dccp_init(void) FIELD_SIZEOF(struct sk_buff, cb)); rc = percpu_counter_init(&dccp_orphan_count, 0); if (rc) - goto out_fail; + goto out; rc = -ENOBUFS; inet_hashinfo_init(&dccp_hashinfo); dccp_hashinfo.bind_bucket_cachep = @@ -1125,9 +1125,8 @@ static int __init dccp_init(void) goto out_sysctl_exit; dccp_timestamping_init(); - - return 0; - +out: + return rc; out_sysctl_exit: dccp_sysctl_exit(); out_ackvec_exit: @@ -1136,19 +1135,18 @@ static int __init dccp_init(void) dccp_mib_exit(); out_free_dccp_bhash: free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order); + dccp_hashinfo.bhash = NULL; out_free_dccp_locks: inet_ehash_locks_free(&dccp_hashinfo); out_free_dccp_ehash: free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order); + dccp_hashinfo.ehash = NULL; out_free_bind_bucket_cachep: kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); + dccp_hashinfo.bind_bucket_cachep = NULL; out_free_percpu: percpu_counter_destroy(&dccp_orphan_count); -out_fail: - dccp_hashinfo.bhash = NULL; - dccp_hashinfo.ehash = NULL; - dccp_hashinfo.bind_bucket_cachep = NULL; - return rc; + goto out; } static void __exit dccp_fini(void) diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index a770df2493d2..d9b40248b97f 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -932,8 +932,10 @@ static void rt_secret_rebuild_oneshot(struct net *net) { del_timer_sync(&net->ipv4.rt_secret_timer); rt_cache_invalidate(net); - if (ip_rt_secret_interval) - mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); + if (ip_rt_secret_interval) { + net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval; + add_timer(&net->ipv4.rt_secret_timer); + } } static void rt_emergency_hash_rebuild(struct net *net) @@ -3101,20 +3103,22 @@ static void rt_secret_reschedule(int old) rtnl_lock(); for_each_net(net) { int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); - long time; if (!new) continue; if (deleted) { - time = net->ipv4.rt_secret_timer.expires - jiffies; + long time = net->ipv4.rt_secret_timer.expires - jiffies; if (time <= 0 || (time += diff) <= 0) time = 0; + + net->ipv4.rt_secret_timer.expires = time; } else - time = new; + net->ipv4.rt_secret_timer.expires = new; - mod_timer(&net->ipv4.rt_secret_timer, jiffies + time); + net->ipv4.rt_secret_timer.expires += jiffies; + add_timer(&net->ipv4.rt_secret_timer); } rtnl_unlock(); } diff --git a/trunk/net/phonet/pn_dev.c b/trunk/net/phonet/pn_dev.c index 5c6ae0c701c0..c597cc53a6fb 100644 --- a/trunk/net/phonet/pn_dev.c +++ b/trunk/net/phonet/pn_dev.c @@ -107,7 +107,8 @@ static void phonet_device_destroy(struct net_device *dev) if (pnd) { u8 addr; - for_each_set_bit(addr, pnd->addrs, 64) + for (addr = find_first_bit(pnd->addrs, 64); addr < 64; + addr = find_next_bit(pnd->addrs, 64, 1+addr)) phonet_address_notify(RTM_DELADDR, dev, addr); kfree(pnd); } diff --git a/trunk/net/phonet/pn_netlink.c b/trunk/net/phonet/pn_netlink.c index fe2e7088ee07..2e6c7eb8e76a 100644 --- a/trunk/net/phonet/pn_netlink.c +++ b/trunk/net/phonet/pn_netlink.c @@ -141,7 +141,8 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb) continue; addr_idx = 0; - for_each_set_bit(addr, pnd->addrs, 64) { + for (addr = find_first_bit(pnd->addrs, 64); addr < 64; + addr = find_next_bit(pnd->addrs, 64, 1+addr)) { if (addr_idx++ < addr_start_idx) continue; diff --git a/trunk/net/tipc/ref.c b/trunk/net/tipc/ref.c index 8dea66500cf5..414fc34b8bea 100644 --- a/trunk/net/tipc/ref.c +++ b/trunk/net/tipc/ref.c @@ -153,11 +153,11 @@ void tipc_ref_table_stop(void) u32 tipc_ref_acquire(void *object, spinlock_t **lock) { + struct reference *entry; u32 index; u32 index_mask; u32 next_plus_upper; u32 ref; - struct reference *entry = NULL; if (!object) { err("Attempt to acquire reference to non-existent object\n"); @@ -175,36 +175,30 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) index = tipc_ref_table.first_free; entry = &(tipc_ref_table.entries[index]); index_mask = tipc_ref_table.index_mask; + /* take lock in case a previous user of entry still holds it */ + spin_lock_bh(&entry->lock); next_plus_upper = entry->ref; tipc_ref_table.first_free = next_plus_upper & index_mask; ref = (next_plus_upper & ~index_mask) + index; + entry->ref = ref; + entry->object = object; + *lock = &entry->lock; } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { index = tipc_ref_table.init_point++; entry = &(tipc_ref_table.entries[index]); spin_lock_init(&entry->lock); + spin_lock_bh(&entry->lock); ref = tipc_ref_table.start_mask + index; + entry->ref = ref; + entry->object = object; + *lock = &entry->lock; } else { ref = 0; } write_unlock_bh(&ref_table_lock); - /* - * Grab the lock so no one else can modify this entry - * While we assign its ref value & object pointer - */ - if (entry) { - spin_lock_bh(&entry->lock); - entry->ref = ref; - entry->object = object; - *lock = &entry->lock; - /* - * keep it locked, the caller is responsible - * for unlocking this when they're done with it - */ - } - return ref; }