Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Oct 2012 15:52:32 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241228 - head/sys/dev/amr
Message-ID:  <201210051552.q95FqWNM096204@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Oct  5 15:52:31 2012
New Revision: 241228
URL: http://svn.freebsd.org/changeset/base/241228

Log:
  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

Modified:
  head/sys/dev/amr/amr.c

Modified: head/sys/dev/amr/amr.c
==============================================================================
--- head/sys/dev/amr/amr.c	Fri Oct  5 15:36:30 2012	(r241227)
+++ head/sys/dev/amr/amr.c	Fri Oct  5 15:52:31 2012	(r241228)
@@ -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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210051552.q95FqWNM096204>