diff options
| author | Bruce Evans <bde@FreeBSD.org> | 1998-12-19 16:28:57 +0000 |
|---|---|---|
| committer | Bruce Evans <bde@FreeBSD.org> | 1998-12-19 16:28:57 +0000 |
| commit | 3bc124d470749bb6ca5a13a84f85f1089ee55191 (patch) | |
| tree | cf70eef148b5a396b76bd74a15ab447f36e1f0cc /sys/dev/cy | |
| parent | dc0ba36f4dcc762735374fb805fc980d33897940 (diff) | |
Notes
Diffstat (limited to 'sys/dev/cy')
| -rw-r--r-- | sys/dev/cy/cy.c | 44 | ||||
| -rw-r--r-- | sys/dev/cy/cy_isa.c | 44 |
2 files changed, 58 insertions, 30 deletions
diff --git a/sys/dev/cy/cy.c b/sys/dev/cy/cy.c index b23cf66a3e5ab..118b4ae2a3c56 100644 --- a/sys/dev/cy/cy.c +++ b/sys/dev/cy/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 diff --git a/sys/dev/cy/cy_isa.c b/sys/dev/cy/cy_isa.c index b23cf66a3e5ab..118b4ae2a3c56 100644 --- a/sys/dev/cy/cy_isa.c +++ b/sys/dev/cy/cy_isa.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 |
