From: Greg Kroah-Hartman Date: Wed, 17 Oct 2012 21:54:48 +0000 (-0700) Subject: 3.6-stable patches X-Git-Tag: v3.0.47~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71608a5a835030cad262d8ab92fa64a1747d8918;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch mcs7830-fix-link-state-detection.patch mtd-nand-allow-nand_no_subpage_write-to-be-set-from-driver.patch tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch usb-gadget-at91_udc-fix-dt-support.patch --- diff --git a/queue-3.6/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch b/queue-3.6/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch new file mode 100644 index 00000000000..0936c33e0e4 --- /dev/null +++ b/queue-3.6/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch @@ -0,0 +1,81 @@ +From 8edc0e624db3756783233e464879eb2e3b904c13 Mon Sep 17 00:00:00 2001 +From: Hiroaki SHIMODA +Date: Wed, 10 Oct 2012 15:34:20 +0000 +Subject: e1000e: Change wthresh to 1 to avoid possible Tx stalls + +From: Hiroaki SHIMODA + +commit 8edc0e624db3756783233e464879eb2e3b904c13 upstream. + +This patch originated from Hiroaki SHIMODA but has been modified +by Intel with some minor cleanups and additional commit log text. + +Denys Fedoryshchenko and others reported Tx stalls on e1000e with +BQL enabled. Issue was root caused to hardware delays. They were +introduced because some of the e1000e hardware with transmit +writeback bursting enabled, waits until the driver does an +explict flush OR there are WTHRESH descriptors to write back. + +Sometimes the delays in question were on the order of seconds, +causing visible lag for ssh sessions and unacceptable tx +completion latency, especially for BQL enabled kernels. + +To avoid possible Tx stalls, change WTHRESH back to 1. + +The current plan is to investigate a method for re-enabling +WTHRESH while not harming BQL, but those patches will be later +for net-next if they work. + +please enqueue for stable since v3.3 as this bug was introduced in +commit 3f0cfa3bc11e7f00c9994e0f469cbc0e7da7b00c +Author: Tom Herbert +Date: Mon Nov 28 16:33:16 2011 +0000 + + e1000e: Support for byte queue limits + + Changes to e1000e to use byte queue limits. + +Reported-by: Denys Fedoryshchenko +Tested-by: Denys Fedoryshchenko +Signed-off-by: Hiroaki SHIMODA +CC: eric.dumazet@gmail.com +CC: therbert@google.com +Signed-off-by: Jesse Brandeburg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/e1000e/e1000.h | 6 +++--- + drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/e1000.h ++++ b/drivers/net/ethernet/intel/e1000e/e1000.h +@@ -175,13 +175,13 @@ struct e1000_info; + /* + * in the case of WTHRESH, it appears at least the 82571/2 hardware + * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when +- * WTHRESH=4, and since we want 64 bytes at a time written back, set +- * it to 5 ++ * WTHRESH=4, so a setting of 5 gives the most efficient bus ++ * utilization but to avoid possible Tx stalls, set it to 1 + */ + #define E1000_TXDCTL_DMA_BURST_ENABLE \ + (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \ + E1000_TXDCTL_COUNT_DESC | \ +- (5 << 16) | /* wthresh must be +1 more than desired */\ ++ (1 << 16) | /* wthresh must be +1 more than desired */\ + (1 << 8) | /* hthresh */ \ + 0x1f) /* pthresh */ + +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -2831,7 +2831,7 @@ static void e1000_configure_tx(struct e1 + * set up some performance related parameters to encourage the + * hardware to use the bus more efficiently in bursts, depends + * on the tx_int_delay to be enabled, +- * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time ++ * wthresh = 1 ==> burst write is disabled to avoid Tx stalls + * hthresh = 1 ==> prefetch when one or more available + * pthresh = 0x1f ==> prefetch if internal cache 31 or less + * BEWARE: this seems to work but should be considered first if diff --git a/queue-3.6/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch b/queue-3.6/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch new file mode 100644 index 00000000000..d08d7dcaf33 --- /dev/null +++ b/queue-3.6/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch @@ -0,0 +1,230 @@ +From 09e05d4805e6c524c1af74e524e5d0528bb3fef3 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 11 Jul 2012 23:16:25 +0200 +Subject: jbd: Fix assertion failure in commit code due to lacking transaction credits + +From: Jan Kara + +commit 09e05d4805e6c524c1af74e524e5d0528bb3fef3 upstream. + +ext3 users of data=journal mode with blocksize < pagesize were occasionally +hitting assertion failure in journal_commit_transaction() checking whether the +transaction has at least as many credits reserved as buffers attached. The +core of the problem is that when a file gets truncated, buffers that still need +checkpointing or that are attached to the committing transaction are left with +buffer_mapped set. When this happens to buffers beyond i_size attached to a +page stradding i_size, subsequent write extending the file will see these +buffers and as they are mapped (but underlying blocks were freed) things go +awry from here. + +The assertion failure just coincidentally (and in this case luckily as we would +start corrupting filesystem) triggers due to journal_head not being properly +cleaned up as well. + +Under some rare circumstances this bug could even hit data=ordered mode users. +There the assertion won't trigger and we would end up corrupting the +filesystem. + +We fix the problem by unmapping buffers if possible (in lots of cases we just +need a buffer attached to a transaction as a place holder but it must not be +written out anyway). And in one case, we just have to bite the bullet and wait +for transaction commit to finish. + +Reviewed-by: Josef Bacik +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd/commit.c | 45 +++++++++++++++++++++++++++-------- + fs/jbd/transaction.c | 64 +++++++++++++++++++++++++++++++++++---------------- + 2 files changed, 78 insertions(+), 31 deletions(-) + +--- a/fs/jbd/commit.c ++++ b/fs/jbd/commit.c +@@ -86,7 +86,12 @@ nope: + static void release_data_buffer(struct buffer_head *bh) + { + if (buffer_freed(bh)) { ++ WARN_ON_ONCE(buffer_dirty(bh)); + clear_buffer_freed(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; + release_buffer_page(bh); + } else + put_bh(bh); +@@ -866,17 +871,35 @@ restart_loop: + * there's no point in keeping a checkpoint record for + * it. */ + +- /* A buffer which has been freed while still being +- * journaled by a previous transaction may end up still +- * being dirty here, but we want to avoid writing back +- * that buffer in the future after the "add to orphan" +- * operation been committed, That's not only a performance +- * gain, it also stops aliasing problems if the buffer is +- * left behind for writeback and gets reallocated for another +- * use in a different page. */ +- if (buffer_freed(bh) && !jh->b_next_transaction) { +- clear_buffer_freed(bh); +- clear_buffer_jbddirty(bh); ++ /* ++ * A buffer which has been freed while still being journaled by ++ * a previous transaction. ++ */ ++ if (buffer_freed(bh)) { ++ /* ++ * If the running transaction is the one containing ++ * "add to orphan" operation (b_next_transaction != ++ * NULL), we have to wait for that transaction to ++ * commit before we can really get rid of the buffer. ++ * So just clear b_modified to not confuse transaction ++ * credit accounting and refile the buffer to ++ * BJ_Forget of the running transaction. If the just ++ * committed transaction contains "add to orphan" ++ * operation, we can completely invalidate the buffer ++ * now. We are rather throughout in that since the ++ * buffer may be still accessible when blocksize < ++ * pagesize and it is attached to the last partial ++ * page. ++ */ ++ jh->b_modified = 0; ++ if (!jh->b_next_transaction) { ++ clear_buffer_freed(bh); ++ clear_buffer_jbddirty(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; ++ } + } + + if (buffer_jbddirty(bh)) { +--- a/fs/jbd/transaction.c ++++ b/fs/jbd/transaction.c +@@ -1843,15 +1843,16 @@ static int __dispose_buffer(struct journ + * We're outside-transaction here. Either or both of j_running_transaction + * and j_committing_transaction may be NULL. + */ +-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) ++static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, ++ int partial_page) + { + transaction_t *transaction; + struct journal_head *jh; + int may_free = 1; +- int ret; + + BUFFER_TRACE(bh, "entry"); + ++retry: + /* + * It is safe to proceed here without the j_list_lock because the + * buffers cannot be stolen by try_to_free_buffers as long as we are +@@ -1879,10 +1880,18 @@ static int journal_unmap_buffer(journal_ + * clear the buffer dirty bit at latest at the moment when the + * transaction marking the buffer as freed in the filesystem + * structures is committed because from that moment on the +- * buffer can be reallocated and used by a different page. ++ * block can be reallocated and used by a different page. + * Since the block hasn't been freed yet but the inode has + * already been added to orphan list, it is safe for us to add + * the buffer to BJ_Forget list of the newest transaction. ++ * ++ * Also we have to clear buffer_mapped flag of a truncated buffer ++ * because the buffer_head may be attached to the page straddling ++ * i_size (can happen only when blocksize < pagesize) and thus the ++ * buffer_head can be reused when the file is extended again. So we end ++ * up keeping around invalidated buffers attached to transactions' ++ * BJ_Forget list just to stop checkpointing code from cleaning up ++ * the transaction this buffer was modified in. + */ + transaction = jh->b_transaction; + if (transaction == NULL) { +@@ -1909,13 +1918,9 @@ static int journal_unmap_buffer(journal_ + * committed, the buffer won't be needed any + * longer. */ + JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget"); +- ret = __dispose_buffer(jh, ++ may_free = __dispose_buffer(jh, + journal->j_running_transaction); +- journal_put_journal_head(jh); +- spin_unlock(&journal->j_list_lock); +- jbd_unlock_bh_state(bh); +- spin_unlock(&journal->j_state_lock); +- return ret; ++ goto zap_buffer; + } else { + /* There is no currently-running transaction. So the + * orphan record which we wrote for this file must have +@@ -1923,13 +1928,9 @@ static int journal_unmap_buffer(journal_ + * the committing transaction, if it exists. */ + if (journal->j_committing_transaction) { + JBUFFER_TRACE(jh, "give to committing trans"); +- ret = __dispose_buffer(jh, ++ may_free = __dispose_buffer(jh, + journal->j_committing_transaction); +- journal_put_journal_head(jh); +- spin_unlock(&journal->j_list_lock); +- jbd_unlock_bh_state(bh); +- spin_unlock(&journal->j_state_lock); +- return ret; ++ goto zap_buffer; + } else { + /* The orphan record's transaction has + * committed. We can cleanse this buffer */ +@@ -1950,10 +1951,24 @@ static int journal_unmap_buffer(journal_ + } + /* + * The buffer is committing, we simply cannot touch +- * it. So we just set j_next_transaction to the +- * running transaction (if there is one) and mark +- * buffer as freed so that commit code knows it should +- * clear dirty bits when it is done with the buffer. ++ * it. If the page is straddling i_size we have to wait ++ * for commit and try again. ++ */ ++ if (partial_page) { ++ tid_t tid = journal->j_committing_transaction->t_tid; ++ ++ journal_put_journal_head(jh); ++ spin_unlock(&journal->j_list_lock); ++ jbd_unlock_bh_state(bh); ++ spin_unlock(&journal->j_state_lock); ++ log_wait_commit(journal, tid); ++ goto retry; ++ } ++ /* ++ * OK, buffer won't be reachable after truncate. We just set ++ * j_next_transaction to the running transaction (if there is ++ * one) and mark buffer as freed so that commit code knows it ++ * should clear dirty bits when it is done with the buffer. + */ + set_buffer_freed(bh); + if (journal->j_running_transaction && buffer_jbddirty(bh)) +@@ -1976,6 +1991,14 @@ static int journal_unmap_buffer(journal_ + } + + zap_buffer: ++ /* ++ * This is tricky. Although the buffer is truncated, it may be reused ++ * if blocksize < pagesize and it is attached to the page straddling ++ * EOF. Since the buffer might have been added to BJ_Forget list of the ++ * running transaction, journal_get_write_access() won't clear ++ * b_modified and credit accounting gets confused. So clear b_modified ++ * here. */ ++ jh->b_modified = 0; + journal_put_journal_head(jh); + zap_buffer_no_jh: + spin_unlock(&journal->j_list_lock); +@@ -2024,7 +2047,8 @@ void journal_invalidatepage(journal_t *j + if (offset <= curr_off) { + /* This block is wholly outside the truncation point */ + lock_buffer(bh); +- may_free &= journal_unmap_buffer(journal, bh); ++ may_free &= journal_unmap_buffer(journal, bh, ++ offset > 0); + unlock_buffer(bh); + } + curr_off = next_off; diff --git a/queue-3.6/mcs7830-fix-link-state-detection.patch b/queue-3.6/mcs7830-fix-link-state-detection.patch new file mode 100644 index 00000000000..5235c20a6a2 --- /dev/null +++ b/queue-3.6/mcs7830-fix-link-state-detection.patch @@ -0,0 +1,75 @@ +From dabdaf0caa3af520dbc1df87b2fb4e77224037bd Mon Sep 17 00:00:00 2001 +From: Ondrej Zary +Date: Thu, 11 Oct 2012 22:51:41 +0000 +Subject: mcs7830: Fix link state detection + +From: Ondrej Zary + +commit dabdaf0caa3af520dbc1df87b2fb4e77224037bd upstream. + +The device had an undocumented "feature": it can provide a sequence of +spurious link-down status data even if the link is up all the time. +A sequence of 10 was seen so update the link state only after the device +reports the same link state 20 times. + +Signed-off-by: Ondrej Zary +Reported-by: Michael Leun +Tested-by: Michael Leun +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/usb/mcs7830.c | 30 +++++++++++++++++++++--------- + 1 file changed, 21 insertions(+), 9 deletions(-) + +--- a/drivers/net/usb/mcs7830.c ++++ b/drivers/net/usb/mcs7830.c +@@ -117,6 +117,7 @@ enum { + struct mcs7830_data { + u8 multi_filter[8]; + u8 config; ++ u8 link_counter; + }; + + static const char driver_name[] = "MOSCHIP usb-ethernet driver"; +@@ -632,20 +633,31 @@ static int mcs7830_rx_fixup(struct usbne + static void mcs7830_status(struct usbnet *dev, struct urb *urb) + { + u8 *buf = urb->transfer_buffer; +- bool link; ++ bool link, link_changed; ++ struct mcs7830_data *data = mcs7830_get_data(dev); + + if (urb->actual_length < 16) + return; + + link = !(buf[1] & 0x20); +- if (netif_carrier_ok(dev->net) != link) { +- if (link) { +- netif_carrier_on(dev->net); +- usbnet_defer_kevent(dev, EVENT_LINK_RESET); +- } else +- netif_carrier_off(dev->net); +- netdev_dbg(dev->net, "Link Status is: %d\n", link); +- } ++ link_changed = netif_carrier_ok(dev->net) != link; ++ if (link_changed) { ++ data->link_counter++; ++ /* ++ track link state 20 times to guard against erroneous ++ link state changes reported sometimes by the chip ++ */ ++ if (data->link_counter > 20) { ++ data->link_counter = 0; ++ if (link) { ++ netif_carrier_on(dev->net); ++ usbnet_defer_kevent(dev, EVENT_LINK_RESET); ++ } else ++ netif_carrier_off(dev->net); ++ netdev_dbg(dev->net, "Link Status is: %d\n", link); ++ } ++ } else ++ data->link_counter = 0; + } + + static const struct driver_info moschip_info = { diff --git a/queue-3.6/mtd-nand-allow-nand_no_subpage_write-to-be-set-from-driver.patch b/queue-3.6/mtd-nand-allow-nand_no_subpage_write-to-be-set-from-driver.patch new file mode 100644 index 00000000000..18a870cea38 --- /dev/null +++ b/queue-3.6/mtd-nand-allow-nand_no_subpage_write-to-be-set-from-driver.patch @@ -0,0 +1,71 @@ +From bf7a01bf7987b63b121d572b240c132ec44129c4 Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Fri, 13 Jul 2012 09:28:24 -0700 +Subject: mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver + +From: Brian Norris + +commit bf7a01bf7987b63b121d572b240c132ec44129c4 upstream. + +The NAND_CHIPOPTIONS_MSK has limited utility and is causing real bugs. It +silently masks off at least one flag that might be set by the driver +(NAND_NO_SUBPAGE_WRITE). This breaks the GPMI NAND driver and possibly +others. + +Really, as long as driver writers exercise a small amount of care with +NAND_* options, this mask is not necessary at all; it was only here to +prevent certain options from accidentally being set by the driver. But the +original thought turns out to be a bad idea occasionally. Thus, kill it. + +Note, this patch fixes some major gpmi-nand breakage. + +Signed-off-by: Brian Norris +Tested-by: Huang Shijie +Cc: stable@vger.kernel.org +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + + +index a11253a..c429abd 100644 +--- + drivers/mtd/nand/nand_base.c | 8 +++----- + include/linux/mtd/nand.h | 3 --- + 2 files changed, 3 insertions(+), 8 deletions(-) + +--- a/drivers/mtd/nand/nand_base.c ++++ b/drivers/mtd/nand/nand_base.c +@@ -2914,8 +2914,7 @@ static int nand_flash_detect_onfi(struct + if (le16_to_cpu(p->features) & 1) + *busw = NAND_BUSWIDTH_16; + +- chip->options &= ~NAND_CHIPOPTIONS_MSK; +- chip->options |= NAND_NO_READRDY & NAND_CHIPOPTIONS_MSK; ++ chip->options |= NAND_NO_READRDY; + + pr_info("ONFI flash detected\n"); + return 1; +@@ -3080,9 +3079,8 @@ static struct nand_flash_dev *nand_get_f + mtd->erasesize <<= ((id_data[3] & 0x03) << 1); + } + } +- /* Get chip options, preserve non chip based options */ +- chip->options &= ~NAND_CHIPOPTIONS_MSK; +- chip->options |= type->options & NAND_CHIPOPTIONS_MSK; ++ /* Get chip options */ ++ chip->options |= type->options; + + /* + * Check if chip is not a Samsung device. Do not clear the +--- a/include/linux/mtd/nand.h ++++ b/include/linux/mtd/nand.h +@@ -212,9 +212,6 @@ typedef enum { + #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \ + && (chip->page_shift > 9)) + +-/* Mask to zero out the chip options, which come from the id table */ +-#define NAND_CHIPOPTIONS_MSK 0x0000ffff +- + /* Non chip related options */ + /* This option skips the bbt scan during initialization. */ + #define NAND_SKIP_BBTSCAN 0x00010000 diff --git a/queue-3.6/series b/queue-3.6/series index 0b4462fec2a..ab1240da639 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -59,3 +59,9 @@ drm-i915-remove-useless-bug_on-which-caused-a-regression-in-3.5.patch drm-i915-set-guardband-clipping-workaround-bit-in-the-right-register.patch drm-nouveau-bios-fix-shadowing-of-acpi-roms-larger-than-64kib.patch drm-i915-use-adjusted_mode-instead-of-mode-for-checking-the-6bpc-force-flag.patch +mcs7830-fix-link-state-detection.patch +jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch +mtd-nand-allow-nand_no_subpage_write-to-be-set-from-driver.patch +e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch +tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch +usb-gadget-at91_udc-fix-dt-support.patch diff --git a/queue-3.6/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch b/queue-3.6/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch new file mode 100644 index 00000000000..6d4e56b615d --- /dev/null +++ b/queue-3.6/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch @@ -0,0 +1,95 @@ +From abce9ac292e13da367bbd22c1f7669f988d931ac Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Thu, 27 Sep 2012 16:09:33 +0200 +Subject: tpm: Propagate error from tpm_transmit to fix a timeout hang + +From: Peter Huewe + +commit abce9ac292e13da367bbd22c1f7669f988d931ac upstream. + +tpm_write calls tpm_transmit without checking the return value and +assigns the return value unconditionally to chip->pending_data, even if +it's an error value. +This causes three bugs. + +So if we write to /dev/tpm0 with a tpm_param_size bigger than +TPM_BUFSIZE=0x1000 (e.g. 0x100a) +and a bufsize also bigger than TPM_BUFSIZE (e.g. 0x100a) +tpm_transmit returns -E2BIG which is assigned to chip->pending_data as +-7, but tpm_write returns that TPM_BUFSIZE bytes have been successfully +been written to the TPM, altough this is not true (bug #1). + +As we did write more than than TPM_BUFSIZE bytes but tpm_write reports +that only TPM_BUFSIZE bytes have been written the vfs tries to write +the remaining bytes (in this case 10 bytes) to the tpm device driver via +tpm_write which then blocks at + + /* cannot perform a write until the read has cleared + either via tpm_read or a user_read_timer timeout */ + while (atomic_read(&chip->data_pending) != 0) + msleep(TPM_TIMEOUT); + +for 60 seconds, since data_pending is -7 and nobody is able to +read it (since tpm_read luckily checks if data_pending is greater than +0) (#bug 2). + +After that the remaining bytes are written to the TPM which are +interpreted by the tpm as a normal command. (bug #3) +So if the last bytes of the command stream happen to be a e.g. +tpm_force_clear this gets accidentally sent to the TPM. + +This patch fixes all three bugs, by propagating the error code of +tpm_write and returning -E2BIG if the input buffer is too big, +since the response from the tpm for a truncated value is bogus anyway. +Moreover it returns -EBUSY to userspace if there is a response ready to be +read. + +Signed-off-by: Peter Huewe +Signed-off-by: Kent Yoder +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -1186,17 +1186,20 @@ ssize_t tpm_write(struct file *file, con + size_t size, loff_t *off) + { + struct tpm_chip *chip = file->private_data; +- size_t in_size = size, out_size; ++ size_t in_size = size; ++ ssize_t out_size; + + /* cannot perform a write until the read has cleared +- either via tpm_read or a user_read_timer timeout */ +- while (atomic_read(&chip->data_pending) != 0) +- msleep(TPM_TIMEOUT); +- +- mutex_lock(&chip->buffer_mutex); ++ either via tpm_read or a user_read_timer timeout. ++ This also prevents splitted buffered writes from blocking here. ++ */ ++ if (atomic_read(&chip->data_pending) != 0) ++ return -EBUSY; + + if (in_size > TPM_BUFSIZE) +- in_size = TPM_BUFSIZE; ++ return -E2BIG; ++ ++ mutex_lock(&chip->buffer_mutex); + + if (copy_from_user + (chip->data_buffer, (void __user *) buf, in_size)) { +@@ -1206,6 +1209,10 @@ ssize_t tpm_write(struct file *file, con + + /* atomic tpm command send and result receive */ + out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); ++ if (out_size < 0) { ++ mutex_unlock(&chip->buffer_mutex); ++ return out_size; ++ } + + atomic_set(&chip->data_pending, out_size); + mutex_unlock(&chip->buffer_mutex); diff --git a/queue-3.6/usb-gadget-at91_udc-fix-dt-support.patch b/queue-3.6/usb-gadget-at91_udc-fix-dt-support.patch new file mode 100644 index 00000000000..b4ac10673f4 --- /dev/null +++ b/queue-3.6/usb-gadget-at91_udc-fix-dt-support.patch @@ -0,0 +1,31 @@ +From 9c6d196d5aa35e07482f23c3e37755e7a82140e0 Mon Sep 17 00:00:00 2001 +From: Fabio Porcedda +Date: Fri, 7 Sep 2012 15:27:42 +0200 +Subject: usb: gadget: at91_udc: fix dt support + +From: Fabio Porcedda + +commit 9c6d196d5aa35e07482f23c3e37755e7a82140e0 upstream. + +Don't fail the initialization check for the platform_data +if there is avaiable an associated device tree node. + +Signed-off-by: Fabio Porcedda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/at91_udc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/at91_udc.c ++++ b/drivers/usb/gadget/at91_udc.c +@@ -1699,7 +1699,7 @@ static int __devinit at91udc_probe(struc + int retval; + struct resource *res; + +- if (!dev->platform_data) { ++ if (!dev->platform_data && !pdev->dev.of_node) { + /* small (so we copy it) but critical! */ + DBG("missing platform_data\n"); + return -ENODEV;