Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Oct 2011 14:04:18 GMT
From:      Steven Hartland <killing@multiplay.co.uk>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/161901: cam / ata timeout limited to 2147 due to overflow
Message-ID:  <201110221404.p9ME4IWI085487@red.freebsd.org>
Resent-Message-ID: <201110221410.p9MEAE2f086056@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         161901
>Category:       misc
>Synopsis:       cam / ata timeout limited to 2147 due to overflow
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 22 14:10:13 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Steven Hartland
>Release:        8.2-RELEASE
>Organization:
Multiplay
>Environment:
FreeBSD test1 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Fri Mar 18 10:58:44 UTC 2011     root@test1:/usr/obj/usr/src/sys/MULTIPLAY  amd64
>Description:
I'm working on adding security methods to camcontrol and have
come up against a strange issue. It seems that the timeout
value for cam, at least on ata (ahci), is limited to less than
2148 seconds.

This can be seen by running:-
camcontrol identify ada0 -t 2148 -v
(pass0:ahcich0:0:0:0): ATA_IDENTIFY. ACB: ec 00 00 00 00 40 00 00 00 00 00 00
(pass0:ahcich0:0:0:0): CAM status: Command timeout

Also seen in /var/log/messages at this time is:-
Aug  4 23:29:51 cfdev kernel: ahcich0: Timeout on slot 24
Aug  4 23:29:51 cfdev kernel: ahcich0: is 00000000 cs 01000000 ss 00000000 rs 01000000 tfd d0 serr 00000000

Dropping the timeout down to 2147 and the command runs fine.

I've done some digging and it seems like this is implemented via:-
sys/dev/ahci/ahci.c
ahci_execute_transaction(struct ahci_slot *slot)
{
..
    /* Start command execution timeout */
    callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 2000,
        (timeout_t*)ahci_timeout, slot);

Now its documented that:-
"Non-positive values of ticks are silently converted to the value 1"

So I suspect that this is what's happening resulting in an extremely
small timeout instead of a large one. Now I know that passed in value
to the timeout is seconds * 1000 so we should be seeing 2148000
for ccb->ccb_h.timeout now multiply that by 1000 (hz) and your over
the int wrap point 2147483647.

So instead of the wrap point being 2147483 seconds (24 days), I suspect
because of the way this is structured its actually 2147 seconds (26mins).

If this is the case the fix is likely to be something like:-
 callout_reset(&slot->timeout, (int)(ccb->ccb_h.timeout * (hz / 2000)),

Does this sound reasonable? What I don't understand is why the /2000?

For reference the reason for wanting a large timeout is that a
secure erase of large media could take many hours so I'm using
the erase time reported by the drive for this, in my case here is
400 minutes.

Currently this instantly fails with a Command timeout which is
clearly not right.

Additional discussion can be found here:-
http://lists.freebsd.org/pipermail/freebsd-hackers/2011-August/036060.html

Updated patches may be found here:-
http://blog.multiplay.co.uk/2011/08/timeout-overflow-in-cam-drivers-under-freebsd-8-2/

>How-To-Repeat:
Request a cam timeout larger that 2147 seconds.
>Fix:
Apply the attached patch.
Original patch updated by Eygene Ryabinkin and added revised to include changes to mps driver added to stable by myself.

Patch attached with submission follows:

>From fa3a368f0a69d84b93e3af3fa956136aa8890164 Mon Sep 17 00:00:00 2001
From: Eygene Ryabinkin <rea@freebsd.org>
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 <killing@multiplay.co.uk>
Signed-off-by: Eygene Ryabinkin <rea@freebsd.org>
---
 sys/cam/cam_ccb.h            |    4 ++++
 sys/cam/cam_xpt.c            |    5 +++--
 sys/dev/advansys/advansys.c  |    6 +++---
 sys/dev/advansys/adwcam.c    |    2 +-
 sys/dev/aha/aha.c            |    4 ++--
 sys/dev/ahb/ahb.c            |    4 ++--
 sys/dev/ahci/ahci.c          |    7 ++++---
 sys/dev/aic/aic.c            |    6 +++---
 sys/dev/amd/amd.c            |    2 +-
 sys/dev/arcmsr/arcmsr.c      |    4 +++-
 sys/dev/asr/asr.c            |    8 ++++----
 sys/dev/buslogic/bt.c        |    4 ++--
 sys/dev/ciss/ciss.c          |   15 ++++++++-------
 sys/dev/dpt/dpt_scsi.c       |    2 +-
 sys/dev/firewire/sbp.c       |   10 ++++++----
 sys/dev/hptrr/hptrr_os_bsd.c |    3 ++-
 sys/dev/iir/iir.c            |    2 +-
 sys/dev/mpt/mpt_cam.c        |    4 ++--
 sys/dev/mvs/mvs.c            |    8 +++++---
 sys/dev/siis/siis.c          |    5 +++--
 sys/dev/sym/sym_hipd.c       |    5 +++--
 sys/dev/trm/trm.c            |    3 ++-
 sys/dev/mps/mps_sas.c        |    2 +-
 23 files changed, 66 insertions(+), 41 deletions(-)

diff --git sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index ed2a890..991f50c 100644
--- sys/cam/cam_ccb.h
+++ sys/cam/cam_ccb.h
@@ -320,6 +320,10 @@ struct ccb_hdr {
 	struct		callout_handle timeout_ch;
 };
 
+/* Converts ccb_hdr.timeout to ticks */
+#define	CAM_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 sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 013c415..3feadca 100644
--- sys/cam/cam_xpt.c
+++ sys/cam/cam_xpt.c
@@ -2832,7 +2832,7 @@ xpt_action_default(union ccb *start_ccb)
 			}
 
 			callout_reset(&dev->callout,
-			    (crs->release_timeout * hz) / 1000,
+			    CAM_TIMEOUT_TO_TICKS(crs->release_timeout),
 			    xpt_release_devq_timeout, dev);
 
 			dev->flags |= CAM_DEV_REL_TIMEOUT_PENDING;
@@ -4611,7 +4611,8 @@ xpt_config(void *arg)
 	periphdriver_init(1);
 	xpt_hold_boot();
 	callout_init(&xsoftc.boot_callout, 1);
-	callout_reset(&xsoftc.boot_callout, hz * xsoftc.boot_delay / 1000,
+	callout_reset(&xsoftc.boot_callout,
+	    CAM_TIMEOUT_TO_TICKS(xsoftc.boot_delay),
 	    xpt_boot_delay, NULL);
 	/* Fire up rescan thread. */
 	if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
diff --git sys/dev/advansys/advansys.c b/sys/dev/advansys/advansys.c
index cc18f18..fca9c6d 100644
--- sys/dev/advansys/advansys.c
+++ sys/dev/advansys/advansys.c
@@ -166,7 +166,7 @@ adv_clear_state_really(struct adv_softc *adv, union ccb* ccb)
 			while (ccb_h != NULL) {
 				ccb_h->timeout_ch =
 				    timeout(adv_timeout, (caddr_t)ccb_h,
-					    (ccb_h->timeout * hz) / 1000);
+					    CAM_TIMEOUT_TO_TICKS(ccb_h->timeout));
 				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 			}
 			adv->state &= ~ADV_IN_TIMEOUT;
@@ -628,8 +628,8 @@ adv_execute_ccb(void *arg, bus_dma_segment_t *dm_segs,
 	ccb_h->status |= CAM_SIM_QUEUED;
 	LIST_INSERT_HEAD(&adv->pending_ccbs, ccb_h, sim_links.le);
 	/* Schedule our timeout */
-	ccb_h->timeout_ch =
-	    timeout(adv_timeout, csio, (ccb_h->timeout * hz)/1000);
+	ccb_h->timeout_ch = timeout(adv_timeout, csio,
+	    CAM_TIMEOUT_TO_TICKS(ccb_h->timeout));
 	splx(s);
 }
 
diff --git sys/dev/advansys/adwcam.c b/sys/dev/advansys/adwcam.c
index fdee3fd..8ea932a 100644
--- sys/dev/advansys/adwcam.c
+++ sys/dev/advansys/adwcam.c
@@ -335,7 +335,7 @@ adwexecuteacb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	LIST_INSERT_HEAD(&adw->pending_ccbs, &ccb->ccb_h, sim_links.le);
 	ccb->ccb_h.timeout_ch =
 	    timeout(adwtimeout, (caddr_t)acb,
-		    (ccb->ccb_h.timeout * hz) / 1000);
+		    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 
 	adw_send_acb(adw, acb, acbvtob(adw, acb));
 
diff --git sys/dev/aha/aha.c b/sys/dev/aha/aha.c
index ace7d25..87e4793 100644
--- sys/dev/aha/aha.c
+++ sys/dev/aha/aha.c
@@ -1097,7 +1097,7 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le);
 
 	ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb,
-	    (ccb->ccb_h.timeout * hz) / 1000);
+	    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 
 	/* Tell the adapter about this command */
 	if (aha->cur_outbox->action_code != AMBO_FREE) {
@@ -1222,7 +1222,7 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
 			} else {
 				ccb_h->timeout_ch = timeout(ahatimeout,
 				    (caddr_t)pending_accb,
-				    (ccb_h->timeout * hz) / 1000);
+				    CAM_TIMEOUT_TO_TICKS(ccb_h->timeout));
 				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 			}
 		}
diff --git sys/dev/ahb/ahb.c b/sys/dev/ahb/ahb.c
index 10ecd6d..3109b40 100644
--- sys/dev/ahb/ahb.c
+++ sys/dev/ahb/ahb.c
@@ -624,7 +624,7 @@ ahbhandleimmed(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat)
 			/* Re-instate timeout */
 			ccb->ccb_h.timeout_ch =
 			    timeout(ahbtimeout, (caddr_t)pending_ecb,
-				    (ccb->ccb_h.timeout * hz) / 1000);
+				    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 		}
 	}
 
@@ -985,7 +985,7 @@ ahbexecuteecb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id);
 
 	ccb->ccb_h.timeout_ch = timeout(ahbtimeout, (caddr_t)ecb,
-					(ccb->ccb_h.timeout * hz) / 1000);
+					CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 	splx(s);
 }
 
diff --git sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index ccb4bc08..5beb76e 100644
--- sys/dev/ahci/ahci.c
+++ 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,
+	    CAM_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,
+    	    	    CAM_TIMEOUT_TO_TICKS(slot->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,
+	    	    CAM_TIMEOUT_TO_TICKS(slot->ccb->ccb_h.timeout)/2,
 		    (timeout_t*)ahci_timeout, slot);
 		return;
 	}
diff --git sys/dev/aic/aic.c b/sys/dev/aic/aic.c
index 4d5b5c3..237e994 100644
--- sys/dev/aic/aic.c
+++ sys/dev/aic/aic.c
@@ -327,7 +327,7 @@ aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
 
 	ccb->ccb_h.timeout_ch = timeout(aic_timeout, (caddr_t)scb,
-		(ccb->ccb_h.timeout * hz) / 1000);
+		CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 
 	aic_start(aic);
 	splx(s);
@@ -1085,7 +1085,7 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
 			} else {
 				ccb_h->timeout_ch =
 				    timeout(aic_timeout, (caddr_t)pending_scb,
-					(ccb_h->timeout * hz) / 1000);
+					CAM_TIMEOUT_TO_TICKS(ccb_h->timeout));
 				ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
 			}
 		}
@@ -1104,7 +1104,7 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
 			} else {
 				ccb_h->timeout_ch =
 				    timeout(aic_timeout, (caddr_t)nexus_scb,
-					(ccb_h->timeout * hz) / 1000);
+					CAM_TIMEOUT_TO_TICKS(ccb_h->timeout));
 				ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
 			}
 		}
diff --git sys/dev/amd/amd.c b/sys/dev/amd/amd.c
index f4b3d80..c70b576 100644
--- sys/dev/amd/amd.c
+++ sys/dev/amd/amd.c
@@ -385,7 +385,7 @@ amdexecutesrb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	/* XXX Need a timeout handler */
 	ccb->ccb_h.timeout_ch =
 	    timeout(amdtimeout, (caddr_t)srb,
-		    (ccb->ccb_h.timeout * hz) / 1000);
+		    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 #endif
 	TAILQ_INSERT_TAIL(&amd->waiting_srbs, srb, links);
 	amdrunwaiting(amd);
diff --git sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index 962f6b8..c1116f9 100644
--- sys/dev/arcmsr/arcmsr.c
+++ sys/dev/arcmsr/arcmsr.c
@@ -2377,7 +2377,9 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
 	if (pccb->ccb_h.timeout != CAM_TIME_INFINITY)
 	{
 		arcmsr_callout_init(&srb->ccb_callout);
-		callout_reset(&srb->ccb_callout, (pccb->ccb_h.timeout * hz ) / 1000, arcmsr_srb_timeout, srb);
+		callout_reset(&srb->ccb_callout,
+		    CAM_TIMEOUT_TO_TICKS(pccb->ccb_h.timeout),
+		    arcmsr_srb_timeout, srb);
 		srb->srb_flags |= SRB_FLAG_TIMER_START;
 	}
 	return;
diff --git sys/dev/asr/asr.c b/sys/dev/asr/asr.c
index ad41431..f81c625 100644
--- sys/dev/asr/asr.c
+++ sys/dev/asr/asr.c
@@ -797,7 +797,7 @@ ASR_ccbAdd(Asr_softc_t *sc, union asr_ccb *ccb)
 			ccb->ccb_h.timeout = 6 * 60 * 1000;
 		}
 		ccb->ccb_h.timeout_ch = timeout(asr_timeout, (caddr_t)ccb,
-		  (ccb->ccb_h.timeout * hz) / 1000);
+		  CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 	}
 	splx(s);
 } /* ASR_ccbAdd */
@@ -1323,7 +1323,7 @@ asr_timeout(void *arg)
 			/* Try again later */
 			ccb->ccb_h.timeout_ch = timeout(asr_timeout,
 			  (caddr_t)ccb,
-			  (ccb->ccb_h.timeout * hz) / 1000);
+			  CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 		}
 		return;
 	}
@@ -1339,7 +1339,7 @@ asr_timeout(void *arg)
 		if (ASR_reset (sc) == ENXIO) {
 			ccb->ccb_h.timeout_ch = timeout(asr_timeout,
 			  (caddr_t)ccb,
-			  (ccb->ccb_h.timeout * hz) / 1000);
+			  CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 		}
 		splx(s);
 		return;
@@ -1349,7 +1349,7 @@ asr_timeout(void *arg)
 	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 	ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
 	ccb->ccb_h.timeout_ch = timeout(asr_timeout, (caddr_t)ccb,
-	  (ccb->ccb_h.timeout * hz) / 1000);
+	  CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 	ASR_resetBus (sc, cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)));
 	xpt_async (AC_BUS_RESET, ccb->ccb_h.path, NULL);
 	splx(s);
diff --git sys/dev/buslogic/bt.c b/sys/dev/buslogic/bt.c
index 88d152f..351175d 100644
--- sys/dev/buslogic/bt.c
+++ sys/dev/buslogic/bt.c
@@ -1505,7 +1505,7 @@ btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 
 	ccb->ccb_h.timeout_ch =
 	    timeout(bttimeout, (caddr_t)bccb,
-		    (ccb->ccb_h.timeout * hz) / 1000);
+		    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 
 	/* Tell the adapter about this command */
 	bt->cur_outbox->ccb_addr = btccbvtop(bt, bccb);
@@ -1631,7 +1631,7 @@ btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code)
 			} else {
 				ccb_h->timeout_ch =
 				    timeout(bttimeout, (caddr_t)pending_bccb,
-					    (ccb_h->timeout * hz) / 1000);
+					    CAM_TIMEOUT_TO_TICKS(ccb_h->timeout));
 				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 			}
 		}
diff --git sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index e892e50..389c141 100644
--- sys/dev/ciss/ciss.c
+++ sys/dev/ciss/ciss.c
@@ -146,9 +146,9 @@ static void	ciss_perf_intr(void *arg);
 static void	ciss_perf_msi_intr(void *arg);
 static void	ciss_complete(struct ciss_softc *sc, cr_qhead_t *qh);
 static int	_ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_status, const char *func);
-static int	ciss_synch_request(struct ciss_request *cr, int timeout);
-static int	ciss_poll_request(struct ciss_request *cr, int timeout);
-static int	ciss_wait_request(struct ciss_request *cr, int timeout);
+static int	ciss_synch_request(struct ciss_request *cr, u_int32_t timeout);
+static int	ciss_poll_request(struct ciss_request *cr, u_int32_t timeout);
+static int	ciss_wait_request(struct ciss_request *cr, u_int32_t timeout);
 #if 0
 static int	ciss_abort_request(struct ciss_request *cr);
 #endif
@@ -2299,7 +2299,7 @@ _ciss_report_request(struct ciss_request *cr, int *command_status, int *scsi_sta
  * completion.
  */
 static int
-ciss_synch_request(struct ciss_request *cr, int timeout)
+ciss_synch_request(struct ciss_request *cr, u_int32_t timeout)
 {
     if (cr->cr_sc->ciss_flags & CISS_FLAG_RUNNING) {
 	return(ciss_wait_request(cr, timeout));
@@ -2314,7 +2314,7 @@ ciss_synch_request(struct ciss_request *cr, int timeout)
  * Timeout in milliseconds.
  */
 static int
-ciss_poll_request(struct ciss_request *cr, int timeout)
+ciss_poll_request(struct ciss_request *cr, u_int32_t timeout)
 {
     cr_qhead_t qh;
     struct ciss_softc *sc;
@@ -2348,7 +2348,7 @@ ciss_poll_request(struct ciss_request *cr, int timeout)
  * the timeout.
  */
 static int
-ciss_wait_request(struct ciss_request *cr, int timeout)
+ciss_wait_request(struct ciss_request *cr, u_int32_t timeout)
 {
     int		error;
 
@@ -2359,7 +2359,8 @@ ciss_wait_request(struct ciss_request *cr, int timeout)
 	return(error);
 
     while ((cr->cr_flags & CISS_REQ_SLEEP) && (error != EWOULDBLOCK)) {
-	error = msleep(cr, &cr->cr_sc->ciss_mtx, PRIBIO, "cissREQ", (timeout * hz) / 1000);
+	error = msleep(cr, &cr->cr_sc->ciss_mtx, PRIBIO, "cissREQ",
+	    CAM_TIMEOUT_TO_TICKS(timeout));
     }
     return(error);
 }
diff --git sys/dev/dpt/dpt_scsi.c b/sys/dev/dpt/dpt_scsi.c
index 2f72407..3b165e6 100644
--- sys/dev/dpt/dpt_scsi.c
+++ sys/dev/dpt/dpt_scsi.c
@@ -807,7 +807,7 @@ dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le);
 	ccb->ccb_h.timeout_ch =
 	    timeout(dpttimeout, (caddr_t)dccb,
-		    (ccb->ccb_h.timeout * hz) / 1000);
+		    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 	if (dpt_send_eata_command(dpt, &dccb->eata_ccb,
 				  dccb->eata_ccb.cp_busaddr,
 				  EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) {
diff --git sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c
index 0ac7d14..fefbdeb 100644
--- sys/dev/firewire/sbp.c
+++ sys/dev/firewire/sbp.c
@@ -1064,8 +1064,9 @@ static __inline void
 sbp_scan_dev(struct sbp_dev *sdev)
 {
 	sdev->status = SBP_DEV_PROBE;
-	callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
-			sbp_cam_scan_target, (void *)sdev->target);
+	callout_reset(&sdev->target->scan_callout,
+	    CAM_TIMEOUT_TO_TICKS(scan_delay),
+	    sbp_cam_scan_target, (void *)sdev->target);
 }
 
 static void
@@ -2843,8 +2844,9 @@ END_DEBUG
 	STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
 
 	if (ocb->ccb != NULL)
-		ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb,
-					(ocb->ccb->ccb_h.timeout * hz) / 1000);
+		ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout,
+		    (caddr_t)ocb,
+		    CAM_TIMEOUT_TO_TICKS(ocb->ccb->ccb_h.timeout));
 
 	if (use_doorbell && prev == NULL)
 		prev2 = sdev->last_ocb;
diff --git sys/dev/hptrr/hptrr_os_bsd.c b/sys/dev/hptrr/hptrr_os_bsd.c
index 81a3829..6053560 100644
--- sys/dev/hptrr/hptrr_os_bsd.c
+++ sys/dev/hptrr/hptrr_os_bsd.c
@@ -222,7 +222,8 @@ void  os_request_timer(void * osext, HPT_U32 interval)
 	HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS);
 	
 	untimeout(os_timer_for_ldm, vbus_ext, vbus_ext->timer);
-	vbus_ext->timer = timeout(os_timer_for_ldm, vbus_ext, interval * hz / 1000000);
+	vbus_ext->timer = timeout(os_timer_for_ldm, vbus_ext,
+	    CAM_TIMEOUT_TO_TICKS(interval) / 1000);
 }
 
 HPT_TIME os_query_time(void)
diff --git sys/dev/iir/iir.c b/sys/dev/iir/iir.c
index b0915c2..3cc020a 100644
--- sys/dev/iir/iir.c
+++ sys/dev/iir/iir.c
@@ -1310,7 +1310,7 @@ gdtexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
     /* timeout handling */
     ccb->ccb_h.timeout_ch =
         timeout(iir_timeout, (caddr_t)gccb,
-                (ccb->ccb_h.timeout * hz) / 1000);
+                CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 
     gdt->sc_copy_cmd(gdt, gccb);
     splx(lock);
diff --git sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c
index 1085672..a44562f 100644
--- sys/dev/mpt/mpt_cam.c
+++ sys/dev/mpt/mpt_cam.c
@@ -1644,7 +1644,7 @@ out:
 
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 	if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
-		mpt_req_timeout(req, (ccb->ccb_h.timeout * hz) / 1000,
+		mpt_req_timeout(req, CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
 		    mpt_timeout, ccb);
 	}
 	if (mpt->verbose > MPT_PRT_DEBUG) {
@@ -2039,7 +2039,7 @@ out:
 
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 	if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
-		mpt_req_timeout(req, (ccb->ccb_h.timeout * hz) / 1000,
+		mpt_req_timeout(req, CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
 		    mpt_timeout, ccb);
 	}
 	if (mpt->verbose > MPT_PRT_DEBUG) {
diff --git sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index 54808c5..cdd07e1 100644
--- sys/dev/mvs/mvs.c
+++ sys/dev/mvs/mvs.c
@@ -1415,7 +1415,8 @@ mvs_legacy_execute_transaction(struct mvs_slot *slot)
 		}
 	}
 	/* Start command execution timeout */
-	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
+	callout_reset(&slot->timeout,
+	    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
 	    (timeout_t*)mvs_timeout, slot);
 }
 
@@ -1529,7 +1530,8 @@ mvs_execute_transaction(struct mvs_slot *slot)
 	ATA_OUTL(ch->r_mem, EDMA_REQQIP,
 	    ch->dma.workrq_bus + MVS_CRQB_OFFSET + (MVS_CRQB_SIZE * ch->out_idx));
 	/* Start command execution timeout */
-	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
+	callout_reset(&slot->timeout,
+	    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
 	    (timeout_t*)mvs_timeout, slot);
 	return;
 }
@@ -1568,7 +1570,7 @@ mvs_rearm_timeout(device_t dev)
 		if ((ch->toslots & (1 << i)) == 0)
 			continue;
 		callout_reset(&slot->timeout,
-		    (int)slot->ccb->ccb_h.timeout * hz / 2000,
+		    CAM_TIMEOUT_TO_TICKS(slot->ccb->ccb_h.timeout)/2,
 		    (timeout_t*)mvs_timeout, slot);
 	}
 }
diff --git sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index a7b018a..55a886d 100644
--- sys/dev/siis/siis.c
+++ sys/dev/siis/siis.c
@@ -1124,7 +1124,8 @@ siis_execute_transaction(struct siis_slot *slot)
 	ATA_OUTL(ch->r_mem, SIIS_P_CACTL(slot->slot), prb_bus);
 	ATA_OUTL(ch->r_mem, SIIS_P_CACTH(slot->slot), prb_bus >> 32);
 	/* Start command execution timeout */
-	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
+	callout_reset(&slot->timeout,
+	    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
 	    (timeout_t*)siis_timeout, slot);
 	return;
 }
@@ -1167,7 +1168,7 @@ siis_rearm_timeout(device_t dev)
 		if ((ch->toslots & (1 << i)) == 0)
 			continue;
 		callout_reset(&slot->timeout,
-		    (int)slot->ccb->ccb_h.timeout * hz / 1000,
+		    CAM_TIMEOUT_TO_TICKS(slot->ccb->ccb_h.timeout),
 		    (timeout_t*)siis_timeout, slot);
 	}
 }
diff --git sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index bc1ddcc..682e2c4 100644
--- sys/dev/sym/sym_hipd.c
+++ sys/dev/sym/sym_hipd.c
@@ -2353,8 +2353,9 @@ static void sym_enqueue_cam_ccb(ccb_p cp)
 	assert(!(ccb->ccb_h.status & CAM_SIM_QUEUED));
 	ccb->ccb_h.status = CAM_REQ_INPROG;
 
-	callout_reset(&cp->ch, ccb->ccb_h.timeout * hz / 1000, sym_callout,
-			(caddr_t) ccb);
+	callout_reset(&cp->ch,
+	    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
+	    sym_callout, (caddr_t) ccb);
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 	ccb->ccb_h.sym_hcb_ptr = np;
 
diff --git sys/dev/trm/trm.c b/sys/dev/trm/trm.c
index e7d5aad..9966326 100644
--- sys/dev/trm/trm.c
+++ sys/dev/trm/trm.c
@@ -475,7 +475,8 @@ trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 #if 0
 	/* XXX Need a timeout handler */
-	ccb->ccb_h.timeout_ch = timeout(trmtimeout, (caddr_t)srb, (ccb->ccb_h.timeout * hz) / 1000);
+	ccb->ccb_h.timeout_ch = timeout(trmtimeout, (caddr_t)srb,
+	    CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout));
 #endif
 	trm_SendSRB(pACB, pSRB);
 	splx(flags);
--- sys/dev/mps/mps_sas.c.orig	2011-10-19 16:07:17.000000000 +0000
+++ sys/dev/mps/mps_sas.c	2011-10-19 16:08:09.000000000 +0000
@@ -1477,7 +1477,7 @@
 		sc->io_cmds_highwater = sc->io_cmds_active;
 
 	TAILQ_INSERT_TAIL(&sc->io_list, cm, cm_link);
-	callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
+	callout_reset(&cm->cm_callout, CAM_TIMEOUT_TO_TICKS(ccb->ccb_h.timeout),
 	   mpssas_scsiio_timeout, cm);
 
 	mps_map_command(sc, cm);
-- 
1.7.6



>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110221404.p9ME4IWI085487>