summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-10-05 15:52:31 +0000
committerjhb <jhb@FreeBSD.org>2012-10-05 15:52:31 +0000
commit5b58fe0895925541e45301aba29cb0703ee00570 (patch)
treefbcaa7f4d6fa89841cae7352eae3f277c2d2a87f
parent475042a78bada1856b31d1566ea7474bea17bde0 (diff)
downloadFreeBSD-src-5b58fe0895925541e45301aba29cb0703ee00570.zip
FreeBSD-src-5b58fe0895925541e45301aba29cb0703ee00570.tar.gz
Further adjust the workaround in r234501. Rounding all small requests up
to 32k swamped the controller causing firmware hangs. Instead, round requests smaller than 64k up to the next power of 2 as a general rule. To handle the one known special case of a command that accepts a 12k buffer returning a 24k-ish reply, round requests between 8k and 16k up to 32k rather than 16k. The result is that commands less than 8k should now be rounded up to a smaller size (either 4k or 8k) rather than 32k. PR: kern/155658 Tested by: Andreas Longwitz MFC after: 1 week
-rw-r--r--sys/dev/amr/amr.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index 6c7d2ea..03a6985 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -533,13 +533,19 @@ shutdown_out:
* The amr(4) firmware relies on this feature. In fact, it assumes
* the buffer is always a power of 2 up to a max of 64k. There is
* also at least one case where it assumes a buffer less than 16k is
- * greater than 16k. Force a minimum buffer size of 32k and round
- * sizes between 32k and 64k up to 64k as a workaround.
+ * greater than 16k. However, forcing all buffers to a size of 32k
+ * causes stalls in the firmware. Force each command smaller than
+ * 64k up to the next power of two except that commands between 8k
+ * and 16k are rounded up to 32k instead of 16k.
*/
static unsigned long
amr_ioctl_buffer_length(unsigned long len)
{
+ if (len <= 4 * 1024)
+ return (4 * 1024);
+ if (len <= 8 * 1024)
+ return (8 * 1024);
if (len <= 32 * 1024)
return (32 * 1024);
if (len <= 64 * 1024)
OpenPOWER on IntegriCloud