Handle tsc rollover.
authorKevin O'Connor <kevin@koconnor.net>
Fri, 23 Oct 2009 02:30:37 +0000 (22:30 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Fri, 23 Oct 2009 02:30:37 +0000 (22:30 -0400)
Handle case where timetamp counter overflows while waiting.

src/ata.c
src/cdrom.c
src/clock.c
src/ps2port.c
src/usb-ohci.c
src/usb-uhci.c
src/util.h

index 2312f7d064552a9b3317d5235f9c12d69b2c59ec..050269e7f59efc45a2262ecb262ab9213a7f76ee 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -36,7 +36,7 @@ await_ide(u8 mask, u8 flags, u16 base, u16 timeout)
         u8 status = inb(base+ATA_CB_STAT);
         if ((status & mask) == flags)
             return status;
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "IDE time out\n");
             return -1;
         }
@@ -107,7 +107,7 @@ ata_reset(struct drive_s *drive_g)
             if (inb(iobase1 + ATA_CB_DH) == ATA_CB_DH_DEV1)
                 break;
             // Change drive request failed to take effect - retry.
-            if (rdtscll() > end) {
+            if (check_time(end)) {
                 dprintf(1, "ata_reset slave time out\n");
                 goto done;
             }
@@ -649,7 +649,7 @@ powerup_await_non_bsy(u16 base, u64 end)
             dprintf(1, "powerup IDE floating\n");
             return orstatus;
         }
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "powerup IDE time out\n");
             return -1;
         }
index ba533d0f354bc4dfd3eb760af26f970cabafa5e3..8d1ec9adafdf94e0cd670304b57e049db4a96dcc 100644 (file)
@@ -228,7 +228,7 @@ atapi_is_ready(struct drive_s *drive_g)
     int in_progress = 0;
     u64 end = calc_future_tsc(5000);
     for (;;) {
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "read capacity failed\n");
             return -1;
         }
index 0592a4ec82768de18b85d5dfd9650e3ec41b7f43..7735c70a3e994eaeb26405652aecc37c1f64200e 100644 (file)
@@ -93,11 +93,11 @@ calibrate_tsc()
 }
 
 static void
-tscsleep(u64 diff)
+tscdelay(u64 diff)
 {
     u64 start = rdtscll();
     u64 end = start + diff;
-    while (rdtscll() <= end)
+    while (!check_time(end))
         cpu_relax();
 }
 
@@ -105,19 +105,19 @@ void
 ndelay(u32 count)
 {
     u32 khz = GET_GLOBAL(cpu_khz);
-    tscsleep(count * khz / 1000000);
+    tscdelay(count * khz / 1000000);
 }
 void
 udelay(u32 count)
 {
     u32 khz = GET_GLOBAL(cpu_khz);
-    tscsleep(count * khz / 1000);
+    tscdelay(count * khz / 1000);
 }
 void
 mdelay(u32 count)
 {
     u32 khz = GET_GLOBAL(cpu_khz);
-    tscsleep(count * khz);
+    tscdelay(count * khz);
 }
 
 // Return the TSC value that is 'msecs' time in the future.
@@ -156,7 +156,7 @@ rtc_updating()
     do {
         if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0)
             return 0;
-    } while (rdtscll() <= end);
+    } while (!check_time(end));
 
     // update-in-progress never transitioned to 0
     return -1;
index 01e8b3d607b45f4ef72f0eed21dac5da2c19386f..25d45446808573ec3b0f8f457104d75b824ebf20 100644 (file)
@@ -152,7 +152,7 @@ ps2_recvbyte(int aux, int needack, int timeout)
 {
     u64 end = calc_future_tsc(timeout);
     for (;;) {
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "ps2_recvbyte timeout\n");
             return -1;
         }
index f1ca559d24e8d5fae5ffb7622407bb16c177481e..71202f84232669d842021860ffb8c185ba622b62 100644 (file)
@@ -34,7 +34,7 @@ start_ohci(struct usb_s *cntl, struct ohci_hcca *hcca)
         u32 status = readl(&cntl->ohci.regs->cmdstatus);
         if (! status & OHCI_HCR)
             break;
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "Timeout on ohci software reset\n");
             return -1;
         }
@@ -181,7 +181,7 @@ wait_ed(struct ohci_ed *ed)
     for (;;) {
         if (ed->hwHeadP == ed->hwTailP)
             return 0;
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "Timeout on wait_ed %p\n", ed);
             return -1;
         }
index 5829069c99f16ed4b5b7743a8bef112012a3704b..14a53007ae5b59369f65393af8bad7d66d7f3738 100644 (file)
@@ -160,7 +160,7 @@ wait_qh(struct uhci_qh *qh)
     for (;;) {
         if (qh->element & UHCI_PTR_TERM)
             return 0;
-        if (rdtscll() > end) {
+        if (check_time(end)) {
             dprintf(1, "Timeout on wait_qh %p\n", qh);
             return -1;
         }
index 6cf27ac0dfbc1a16928e4213fd6e5d00b652034d..f95cdb598e803e39808ac61054f5793d85994b74 100644 (file)
@@ -214,6 +214,9 @@ void serial_setup();
 void lpt_setup();
 
 // clock.c
+static inline int check_time(u64 end) {
+    return (s64)(rdtscll() - end) > 0;
+}
 void timer_setup();
 void ndelay(u32 count);
 void udelay(u32 count);