[Nouveau] [PATCH] Use nanosleep instead of usleep when waiting the hardware.
Francisco Jerez
currojerez at riseup.net
Wed Jun 10 08:35:03 PDT 2009
usleep() was being used without checking its return value. When the
server receives SIGALRM or SIGIO the waits are shortened and random
modesetting failures happen: Use nanosleep and loop around it until
the requested time has elapsed.
---
src/nouveau_hw.c | 2 +-
src/nouveau_local.h | 6 ++++++
src/nv_bios.c | 2 +-
src/nv_crtc.c | 2 +-
src/nv_include.h | 1 +
src/nv_output.c | 10 +++++-----
6 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/src/nouveau_hw.c b/src/nouveau_hw.c
index 7d210d7..c2cad37 100644
--- a/src/nouveau_hw.c
+++ b/src/nouveau_hw.c
@@ -208,7 +208,7 @@ static void setPLL_single(ScrnInfoPtr pScrn, uint32_t reg,
if (chip_version < 0x17 && chip_version != 0x11)
/* wait a bit on older chips */
- usleep(64000);
+ nouveau_usleep(64000);
NVReadRAMDAC(pNv, 0, reg);
/* then write the other half as well */
diff --git a/src/nouveau_local.h b/src/nouveau_local.h
index d44e2dc..3a8bdf7 100644
--- a/src/nouveau_local.h
+++ b/src/nouveau_local.h
@@ -43,4 +43,10 @@
#define NOUVEAU_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
+static inline void nouveau_usleep(unsigned long usec){
+ struct timespec t = { usec/1000000, (usec % 1000000)*1000 };
+
+ while (nanosleep(&t, &t) && errno == EINTR) {}
+}
+
#endif
diff --git a/src/nv_bios.c b/src/nv_bios.c
index 182456a..b7490c1 100644
--- a/src/nv_bios.c
+++ b/src/nv_bios.c
@@ -41,7 +41,7 @@
#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip, fmt, ##arg)
#define LOG_OLD_VALUE(x) //x
-#define BIOS_USLEEP(n) usleep(n)
+#define BIOS_USLEEP(n) nouveau_usleep(n)
#define ROM16(x) le16_to_cpu(*(uint16_t *)&(x))
#define ROM32(x) le32_to_cpu(*(uint32_t *)&(x))
diff --git a/src/nv_crtc.c b/src/nv_crtc.c
index b8524fb..1ffb267 100644
--- a/src/nv_crtc.c
+++ b/src/nv_crtc.c
@@ -212,7 +212,7 @@ nv_crtc_dpms(xf86CrtcPtr crtc, int mode)
seq1 |= (NVReadVgaSeq(pNv, nv_crtc->head, NV_VIO_SR_CLOCK_INDEX) & ~0x20);
NVWriteVgaSeq(pNv, nv_crtc->head, NV_VIO_SR_CLOCK_INDEX, seq1);
crtc17 |= (NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CR_MODE_INDEX) & ~0x80);
- usleep(10000);
+ nouveau_usleep(10000);
NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CR_MODE_INDEX, crtc17);
NVVgaSeqReset(pNv, nv_crtc->head, false);
diff --git a/src/nv_include.h b/src/nv_include.h
index 0409c89..46f809b 100644
--- a/src/nv_include.h
+++ b/src/nv_include.h
@@ -12,6 +12,7 @@
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <time.h>
/* All drivers should typically include these */
#include "xf86.h"
diff --git a/src/nv_output.c b/src/nv_output.c
index 0979bb9..d18bcd2 100644
--- a/src/nv_output.c
+++ b/src/nv_output.c
@@ -162,7 +162,7 @@ static bool nv_legacy_load_detect(ScrnInfoPtr pScrn)
NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL,
saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
- usleep(10000);
+ nouveau_usleep(10000);
saved_pi = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX);
NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX,
@@ -258,7 +258,7 @@ nv_nv17_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
}
- usleep(4000);
+ nouveau_usleep(4000);
saved_routput = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset);
head = (saved_routput & 0x100) >> 8;
@@ -269,7 +269,7 @@ nv_nv17_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset,
(saved_routput & 0xfffffece) | head << 8);
- usleep(1000);
+ nouveau_usleep(1000);
temp = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset);
NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1);
@@ -279,7 +279,7 @@ nv_nv17_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
temp = NVReadRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL);
NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL,
temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
- usleep(1000);
+ nouveau_usleep(1000);
present = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) &
NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI;
@@ -871,7 +871,7 @@ nv_output_prepare(xf86OutputPtr output)
*/
NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL,
FP_TG_CONTROL_OFF);
- usleep(50000);
+ nouveau_usleep(50000);
}
/* don't inadvertently turn it on when state written later */
crtcstate[head].fp_control = FP_TG_CONTROL_OFF;
--
1.6.0.6
More information about the Nouveau
mailing list