From 9051dc1362d0d42115c5c271423fc70997522f69 Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Fri, 5 Aug 2011 11:58:11 +0400 Subject: [PATCH] Properly convert CAM timeout value to ticks Previously, any timeout value for which (timeout * hz) will overflow the signed integer, will give weird results, since callout(9) routines will convert negative values of ticks to '1'. For unsigned integer overflow we will get sufficiently smaller timeout values than expected. This fix will work as long as the value of 'hz' will fit into 32 bits. Noticed-by: Steven Hartland Signed-off-by: Eygene Ryabinkin --- sys/cam/cam_ccb.h | 4 ++++ sys/dev/ahci/ahci.c | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index ed2a890..fadc2db 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -320,6 +320,10 @@ struct ccb_hdr { struct callout_handle timeout_ch; }; +/* Converts ccb_hdr.timeout to ticks */ +#define CCB_HDR_TIMEOUT_TO_TICKS(t) \ + (int)((u_int64_t)(t) * (u_int32_t)hz / 1000) + /* Get Device Information CCB */ struct ccb_getdev { struct ccb_hdr ccb_h; diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index ccb4bc08..f85f50d 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -1896,7 +1896,8 @@ ahci_execute_transaction(struct ahci_slot *slot) return; } /* Start command execution timeout */ - callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 2000, + callout_reset(&slot->timeout, + CCB_HDR_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout) / 2, (timeout_t*)ahci_timeout, slot); return; } @@ -1935,7 +1936,7 @@ ahci_rearm_timeout(device_t dev) if ((ch->toslots & (1 << i)) == 0) continue; callout_reset(&slot->timeout, - (int)slot->ccb->ccb_h.timeout * hz / 2000, + CCB_HDR_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout) / 2, (timeout_t*)ahci_timeout, slot); } } @@ -1969,7 +1970,7 @@ ahci_timeout(struct ahci_slot *slot) } callout_reset(&slot->timeout, - (int)slot->ccb->ccb_h.timeout * hz / 2000, + CCB_HDR_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout) / 2, (timeout_t*)ahci_timeout, slot); return; } -- 1.7.6