summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/cy.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1998-12-19 16:28:57 +0000
committerbde <bde@FreeBSD.org>1998-12-19 16:28:57 +0000
commit3bb6da1b8bd389ccaa080145eaf3abe256420078 (patch)
tree609bc2a35f7933426ace9c00b3a7762da44ac4f3 /sys/i386/isa/cy.c
parent4b4a7fe6816e06375812af04ae8bdf7b92d91bcd (diff)
downloadFreeBSD-src-3bb6da1b8bd389ccaa080145eaf3abe256420078.zip
FreeBSD-src-3bb6da1b8bd389ccaa080145eaf3abe256420078.tar.gz
Wait for channel commands to complete after issuing the commands.
The optimisation of only waiting before issuing new commands is obviously invalid in general and it caused many errors in NIST-PCTS. I think the errors were mostly for characters sent with the wrong parity, etc., after a half complete tcsetattr(). Use microtime() instead of a magic loop count to limit the wait. The wait is a busy-wait :-( and normally takes about 500 usec.
Diffstat (limited to 'sys/i386/isa/cy.c')
-rw-r--r--sys/i386/isa/cy.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/sys/i386/isa/cy.c b/sys/i386/isa/cy.c
index b23cf66..118b4ae 100644
--- a/sys/i386/isa/cy.c
+++ b/sys/i386/isa/cy.c
@@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: cy.c,v 1.79 1998/12/17 18:43:08 bde Exp $
+ * $Id: cy.c,v 1.80 1998/12/17 19:23:09 bde Exp $
*/
#include "opt_compat.h"
@@ -355,6 +355,7 @@ ointhand2_t siointr;
static int cy_units __P((cy_addr cy_iobase, int cy_align));
static int sioattach __P((struct isa_device *dev));
static void cd1400_channel_cmd __P((struct com_s *com, int cmd));
+static void cd1400_channel_cmd_wait __P((struct com_s *com));
static void cd_etc __P((struct com_s *com, int etc));
static int cd_getreg __P((struct com_s *com, int reg));
static void cd_setreg __P((struct com_s *com, int reg, int val));
@@ -2682,22 +2683,35 @@ cd1400_channel_cmd(com, cmd)
struct com_s *com;
int cmd;
{
- /* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
- as the card is probed every round? Replaced delaycount with 8k.
- Either delaycount has to be implemented in FreeBSD or more sensible
- way of doing these should be implemented. DELAY isn't enough here.
- */
- u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
-
- /* wait for processing of previous command to complete */
- while (cd_getreg(com, CD1400_CCR) && maxwait--)
- ;
+ cd1400_channel_cmd_wait(com);
+ cd_setreg(com, CD1400_CCR, cmd);
+ cd1400_channel_cmd_wait(com);
+}
- if (!maxwait)
- log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
- 5 * 8 * 1024);
+static void
+cd1400_channel_cmd_wait(com)
+ struct com_s *com;
+{
+ struct timeval start;
+ struct timeval tv;
+ long usec;
- cd_setreg(com, CD1400_CCR, cmd);
+ if (cd_getreg(com, CD1400_CCR) == 0)
+ return;
+ microtime(&start);
+ for (;;) {
+ if (cd_getreg(com, CD1400_CCR) == 0)
+ return;
+ microtime(&tv);
+ usec = 1000000 * (tv.tv_sec - start.tv_sec) +
+ tv.tv_usec - start.tv_usec;
+ if (usec >= 5000) {
+ log(LOG_ERR,
+ "cy%d: channel command timeout (%ld usec)\n",
+ com->unit, usec);
+ return;
+ }
+ }
}
static void
OpenPOWER on IntegriCloud