DragonFly kernel List (threaded) for 2007-12
DragonFly BSD
DragonFly kernel List (threaded) for 2007-12
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

ahc/ahd locking


From: Peter Avalos <pavalos@xxxxxxxxxxxx>
Date: Sun, 30 Dec 2007 21:43:45 -0500

I've attempted to bring in some locking for the ahc and ahd drivers from
FreeBSD.  This is my first attempt with locking mechanisms, and I'd
appreciate some input on the attached patch.

Doing this brought along some questions:

1.  When should you use spinlocks instead of lockmgr locks?  Would this
code be better with spinlocks?  If so, are there any gotchas I need to
know about?

2.  tsleep->msleep.  Did I do that right, or can only spinlocks be used?

Thanks,
Peter

The patch can also be found at:
http://www.theshell.com/~pavalos/wip/aic7xxx-locking.patch
commit f40ed99bd885ad0c6ca868dd08b86530e8064870
Author: Peter Avalos <pavalos@theshell.com>
Date:   Sun Dec 30 21:36:58 2007 -0500

    Bring in locking from FreeBSD using lockmgr locks instead of mutexes.

diff --git a/sys/dev/disk/aic7xxx/aic7770.c b/sys/dev/disk/aic7xxx/aic7770.c
index fcef375..ad91898 100644
--- a/sys/dev/disk/aic7xxx/aic7770.c
+++ b/sys/dev/disk/aic7xxx/aic7770.c
@@ -254,6 +254,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
 	if (error != 0)
 		return (error);
 
+	ahc_lock(ahc);
 	/*
 	 * Link this softc in with all other ahc instances.
 	 */
@@ -264,6 +265,8 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
 	 */
 	ahc_outb(ahc, BCTL, ENABLE);
 
+	ahc_unlock(ahc);
+
 	return (0);
 }
 
diff --git a/sys/dev/disk/aic7xxx/aic79xx.c b/sys/dev/disk/aic7xxx/aic79xx.c
index 834fcf4..bcfbec6 100644
--- a/sys/dev/disk/aic7xxx/aic79xx.c
+++ b/sys/dev/disk/aic7xxx/aic79xx.c
@@ -5251,6 +5251,7 @@ ahd_alloc(void *platform_arg, char *name)
 		ahd_free(ahd);
 		ahd = NULL;
 	}
+	ahd_lockinit(ahd);
 #ifdef AHD_DEBUG
 	if ((ahd_debug & AHD_SHOW_MEMORY) != 0) {
 		kprintf("%s: scb size = 0x%x, hscb size = 0x%x\n",
@@ -5322,22 +5323,6 @@ ahd_softc_insert(struct ahd_softc *ahd)
 	ahd->init_level++;
 }
 
-/*
- * Verify that the passed in softc pointer is for a
- * controller that is still configured.
- */
-struct ahd_softc *
-ahd_find_softc(struct ahd_softc *ahd)
-{
-	struct ahd_softc *list_ahd;
-
-	TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
-		if (list_ahd == ahd)
-			return (ahd);
-	}
-	return (NULL);
-}
-
 void
 ahd_set_unit(struct ahd_softc *ahd, int unit)
 {
@@ -6179,6 +6164,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
 		next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
 		if (next_scb->col_scb != NULL)
 			next_scb->col_scb->col_scb = next_scb;
+		aic_timer_init(&next_scb->io_timer);
 		ahd_free_scb(ahd, next_scb);
 		hscb++;
 		hscb_busaddr += sizeof(*hscb);
@@ -8024,15 +8010,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
 static void
 ahd_reset_poll(void *arg)
 {
-	struct	ahd_softc *ahd;
+	struct	ahd_softc *ahd = (struct ahd_softc *)arg;
 	u_int	scsiseq1;
 	
-	ahd = ahd_find_softc((struct ahd_softc *)arg);
-	if (ahd == NULL) {
-		kprintf("ahd_reset_poll: Instance %p no longer exists\n", arg);
-		return;
-	}
-	ahd_lock();
+	ahd_lock(ahd);
 	ahd_pause(ahd);
 	ahd_update_modes(ahd);
 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
@@ -8041,7 +8022,7 @@ ahd_reset_poll(void *arg)
 		aic_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_MS,
 				ahd_reset_poll, ahd);
 		ahd_unpause(ahd);
-		ahd_unlock();
+		ahd_unlock(ahd);
 		return;
 	}
 
@@ -8051,24 +8032,18 @@ ahd_reset_poll(void *arg)
 	ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP));
 	ahd_unpause(ahd);
 	ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
-	ahd_unlock();
 	aic_release_simq(ahd);
+	ahd_unlock(ahd);
 }
 
 /**************************** Statistics Processing ***************************/
 static void
 ahd_stat_timer(void *arg)
 {
-	struct	ahd_softc *ahd;
+	struct	ahd_softc *ahd = (struct ahd_softc *)arg;
 	int	enint_coal;
 	
-	ahd = ahd_find_softc((struct ahd_softc *)arg);
-	if (ahd == NULL) {
-		kprintf("ahd_stat_timer: Instance %p no longer exists\n", arg);
-		return;
-	}
-	ahd_lock();
-
+	ahd_lock(ahd);
 	enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
 	if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
 		enint_coal |= ENINT_COALESCE;
@@ -8092,7 +8067,7 @@ ahd_stat_timer(void *arg)
 	ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
 	aic_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_MS,
 			ahd_stat_timer, ahd);
-	ahd_unlock();
+	ahd_unlock(ahd);
 }
 
 /****************************** Status Processing *****************************/
@@ -9255,8 +9230,6 @@ ahd_recover_commands(struct ahd_softc *ahd)
 	u_int	active_scbptr;
 	u_int	last_phase;
 
-	ahd_lock();
-
 	/*
 	 * Pause the controller and manually flush any
 	 * commands that have just completed but that our
@@ -9282,7 +9255,6 @@ ahd_recover_commands(struct ahd_softc *ahd)
 		kprintf("%s: Timedout SCBs already complete. "
 		       "Interrupts may not be functioning.\n", ahd_name(ahd));
 		ahd_unpause(ahd);
-		ahd_unlock();
 		return;
 	}
 
@@ -9473,7 +9445,6 @@ bus_reset:
 	}
 
 	ahd_unpause(ahd);
-	ahd_unlock();
 }
 
 /*
@@ -9889,13 +9860,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 	 */
 	if ((ahd->flags & AHD_TARGETROLE) == 0
 	 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
-		u_long	s;
-
 		kprintf("Configuring Target Mode\n");
-		ahd_lock();
 		if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
 			ccb->ccb_h.status = CAM_BUSY;
-			ahd_unlock();
 			return;
 		}
 		ahd->flags |= AHD_TARGETROLE;
@@ -9904,7 +9871,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 		ahd_pause(ahd);
 		ahd_loadseq(ahd);
 		ahd_restart(ahd);
-		ahd_unlock();
 	}
 	cel = &ccb->cel;
 	target = ccb->ccb_h.target_id;
@@ -9963,7 +9929,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 		}
 		SLIST_INIT(&lstate->accept_tios);
 		SLIST_INIT(&lstate->immed_notifies);
-		ahd_lock();
 		ahd_pause(ahd);
 		if (target != CAM_TARGET_WILDCARD) {
 			tstate->enabled_luns[lun] = lstate;
@@ -10022,7 +9987,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 			ahd_outb(ahd, SCSISEQ1, scsiseq1);
 		}
 		ahd_unpause(ahd);
-		ahd_unlock();
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_print_path(ccb->ccb_h.path);
 		kprintf("Lun now enabled for target mode\n");
@@ -10035,8 +9999,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 			return;
 		}
 
-		ahd_lock();
-		
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
 			struct ccb_hdr *ccbh;
@@ -10046,7 +10008,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 			 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
 				kprintf("CTIO pending\n");
 				ccb->ccb_h.status = CAM_REQ_INVALID;
-				ahd_unlock();
 				return;
 			}
 		}
@@ -10062,7 +10023,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 		}
 
 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
-			ahd_unlock();
 			return;
 		}
 
@@ -10129,7 +10089,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
 			}
 		}
 		ahd_unpause(ahd);
-		ahd_unlock();
 	}
 #endif
 }
diff --git a/sys/dev/disk/aic7xxx/aic79xx.h b/sys/dev/disk/aic7xxx/aic79xx.h
index f4e5bf3..847ae9d 100644
--- a/sys/dev/disk/aic7xxx/aic79xx.h
+++ b/sys/dev/disk/aic7xxx/aic79xx.h
@@ -640,6 +640,7 @@ struct scb {
 	u_int			  sg_count;/* How full ahd_dma_seg is */
 #define	AHD_MAX_LQ_CRC_ERRORS 5
 	u_int			  crc_retry_count;
+	aic_timer_t		  io_timer;
 };
 
 TAILQ_HEAD(scb_tailq, scb);
@@ -1395,7 +1396,6 @@ void			 ahd_pause_and_flushwork(struct ahd_softc *ahd);
 int			 ahd_suspend(struct ahd_softc *ahd); 
 int			 ahd_resume(struct ahd_softc *ahd);
 void			 ahd_softc_insert(struct ahd_softc *);
-struct ahd_softc	*ahd_find_softc(struct ahd_softc *ahd);
 void			 ahd_set_unit(struct ahd_softc *, int);
 void			 ahd_set_name(struct ahd_softc *, char *);
 struct scb		*ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
diff --git a/sys/dev/disk/aic7xxx/aic79xx_osm.c b/sys/dev/disk/aic7xxx/aic79xx_osm.c
index 360dea5..d20e643 100644
--- a/sys/dev/disk/aic7xxx/aic79xx_osm.c
+++ b/sys/dev/disk/aic7xxx/aic79xx_osm.c
@@ -126,7 +126,7 @@ ahd_attach(struct ahd_softc *ahd)
 
 	ahd_controller_info(ahd, ahd_info);
 	kprintf("%s\n", ahd_info);
-	ahd_lock();
+	ahd_lock(ahd);
 
 	/*
 	 * Construct our SIM entry
@@ -163,6 +163,7 @@ ahd_attach(struct ahd_softc *ahd)
 fail:
 	ahd->platform_data->sim = sim;
 	ahd->platform_data->path = path;
+	ahd_unlock(ahd);
 	if (count != 0) {
 		/* We have to wait until after any system dumps... */
 		ahd->platform_data->eh =
@@ -171,8 +172,6 @@ fail:
 		ahd_intr_enable(ahd, TRUE);
 	}
 
-	ahd_unlock();
-
 	return (count);
 }
 
@@ -185,7 +184,9 @@ ahd_platform_intr(void *arg)
 	struct	ahd_softc *ahd;
 
 	ahd = (struct ahd_softc *)arg; 
+	ahd_lock(ahd);
 	ahd_intr(ahd);
+	ahd_unlock(ahd);
 }
 
 /*
@@ -206,7 +207,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
 	if ((scb->flags & SCB_TIMEDOUT) != 0)
 		LIST_REMOVE(scb, timedout_links);
 
-	callout_stop(&ccb->ccb_h.timeout_ch);
+	callout_stop(&scb->io_timer);
 
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 		bus_dmasync_op_t op;
@@ -369,13 +370,11 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
 		}
 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
 
-			ahd_lock();
 			SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h,
 					  sim_links.sle);
 			ccb->ccb_h.status = CAM_REQ_INPROG;
 			if ((ahd->flags & AHD_TQINFIFO_BLOCKED) != 0)
 				ahd_run_tqinfifo(ahd, /*paused*/FALSE);
-			ahd_unlock();
 			break;
 		}
 
@@ -409,7 +408,6 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
 		/*
 		 * get an scb to use.
 		 */
-		ahd_lock();
 		tinfo = ahd_fetch_transinfo(ahd, 'A', our_id,
 					    target_id, &tstate);
 		if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0
@@ -424,12 +422,10 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
 	
 			xpt_freeze_simq(sim, /*count*/1);
 			ahd->flags |= AHD_RESOURCE_SHORTAGE;
-			ahd_unlock();
 			ccb->ccb_h.status = CAM_REQUEUE_REQ;
 			xpt_done(ccb);
 			return;
 		}
-		ahd_unlock();
 		
 		hscb = scb->hscb;
 		
@@ -517,20 +513,16 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
 	}
 	case XPT_SET_TRAN_SETTINGS:
 	{
-		ahd_lock();
 		ahd_set_tran_settings(ahd, SIM_SCSI_ID(ahd, sim),
 				      SIM_CHANNEL(ahd, sim), &ccb->cts);
-		ahd_unlock();
 		xpt_done(ccb);
 		break;
 	}
 	case XPT_GET_TRAN_SETTINGS:
 	/* Get default/user set transfer settings for the target */
 	{
-		ahd_lock();
 		ahd_get_tran_settings(ahd, SIM_SCSI_ID(ahd, sim),
 				      SIM_CHANNEL(ahd, sim), &ccb->cts);
-		ahd_unlock();
 		xpt_done(ccb);
 		break;
 	}
@@ -544,10 +536,8 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
 	{
 		int  found;
 		
-		ahd_lock();
 		found = ahd_reset_channel(ahd, SIM_CHANNEL(ahd, sim),
 					  /*initiate reset*/TRUE);
-		ahd_unlock();
 		if (bootverbose) {
 			xpt_print_path(SIM_PATH(ahd, sim));
 			kprintf("SCSI bus reset delivered. "
@@ -976,13 +966,11 @@ ahd_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
 		 * Revert to async/narrow transfers
 		 * for the next device.
 		 */
-		ahd_lock();
 		ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
 			      AHD_TRANS_GOAL|AHD_TRANS_CUR, /*paused*/FALSE);
 		ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
 				 /*ppr_options*/0, AHD_TRANS_GOAL|AHD_TRANS_CUR,
 				 /*paused*/FALSE);
-		ahd_unlock();
 		break;
 	}
 	default:
@@ -1012,9 +1000,7 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 			aic_set_transaction_status(scb, CAM_REQ_CMP_ERR);
 		if (nsegments != 0)
 			bus_dmamap_unload(ahd->buffer_dmat, scb->dmamap);
-		ahd_lock();
 		ahd_free_scb(ahd, scb);
-		ahd_unlock();
 		xpt_done(ccb);
 		return;
 	}
@@ -1052,8 +1038,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 		}
 	}
 
-	ahd_lock();
-
 	/*
 	 * Last time we need to check if this SCB needs to
 	 * be aborted.
@@ -1063,7 +1047,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 			bus_dmamap_unload(ahd->buffer_dmat,
 					  scb->dmamap);
 		ahd_free_scb(ahd, scb);
-		ahd_unlock();
 		xpt_done(ccb);
 		return;
 	}
@@ -1112,8 +1095,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 	} else {
 		ahd_queue_scb(ahd, scb);
 	}
-
-	ahd_unlock();
 }
 
 static void
@@ -1140,6 +1121,7 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
 
 			if (hscb->cdb_len > MAX_CDB_LEN
 			 && (ccb_h->flags & CAM_CDB_PHYS) == 0) {
+
 				/*
 				 * Should CAM start to support CDB sizes
 				 * greater than 16 bytes, we could use
@@ -1147,9 +1129,7 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
 				 */
 				aic_set_transaction_status(scb,
 							   CAM_REQ_INVALID);
-				ahd_lock();
 				ahd_free_scb(ahd, scb);
-				ahd_unlock();
 				xpt_done((union ccb *)csio);
 				return;
 			}
@@ -1166,11 +1146,10 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
 			}
 		} else {
 			if (hscb->cdb_len > MAX_CDB_LEN) {
+
 				aic_set_transaction_status(scb,
 							   CAM_REQ_INVALID);
-				ahd_lock();
 				ahd_free_scb(ahd, scb);
-				ahd_unlock();
 				xpt_done((union ccb *)csio);
 				return;
 			}
@@ -1448,16 +1427,11 @@ ahd_detach(device_t dev)
 
 	device_printf(dev, "detaching device\n");
 	ahd = device_get_softc(dev);
-	ahd = ahd_find_softc(ahd);
-	if (ahd == NULL) {
-		device_printf(dev, "aic7xxx already detached\n");
-		return (ENOENT);
-	}
+	ahd_lock(ahd);
 	TAILQ_REMOVE(&ahd_tailq, ahd, links);
-	ahd_lock();
 	ahd_intr_enable(ahd, FALSE);
 	bus_teardown_intr(dev, ahd->platform_data->irq, ahd->platform_data->ih);
-	ahd_unlock();
+	ahd_unlock(ahd);
 	ahd_free(ahd);
 	return (0);
 }
@@ -1494,6 +1468,7 @@ static int
 ahd_modevent(module_t mod, int type, void *data)
 {
 	/* XXX Deal with busy status on unload. */
+	/* XXX Deal with unknown events */
 	return 0;
 }
   
diff --git a/sys/dev/disk/aic7xxx/aic79xx_osm.h b/sys/dev/disk/aic7xxx/aic79xx_osm.h
index 1e4b4fe..4b74997 100644
--- a/sys/dev/disk/aic7xxx/aic79xx_osm.h
+++ b/sys/dev/disk/aic7xxx/aic79xx_osm.h
@@ -116,6 +116,17 @@
 #define AHD_TARGET_MODE 1
 #endif
 
+/***************************** Core Includes **********************************/
+#ifdef AHD_REG_PRETTY_PRINT
+#define AIC_DEBUG_REGISTERS 1
+#else
+#define AIC_DEBUG_REGISTERS 0
+#endif
+#define	AIC_CORE_INCLUDE "aic79xx.h"
+#define	AIC_LIB_PREFIX ahd
+#define	AIC_CONST_PREFIX AHD
+#include "aic_osm_lib.h"
+
 /************************** Softc/SCB Platform Data ***************************/
 struct ahd_platform_data {
 	/*
@@ -132,22 +143,12 @@ struct ahd_platform_data {
 	void			*ih;
 	eventhandler_tag	 eh;
 	struct thread		*recovery_thread;
+	struct lock		 lock;
 };
 
 struct scb_platform_data {
 };
 
-/***************************** Core Includes **********************************/
-#ifdef AHD_REG_PRETTY_PRINT
-#define AIC_DEBUG_REGISTERS 1
-#else
-#define AIC_DEBUG_REGISTERS 0
-#endif
-#define	AIC_CORE_INCLUDE "aic79xx.h"
-#define	AIC_LIB_PREFIX ahd
-#define	AIC_CONST_PREFIX AHD
-#include "aic_osm_lib.h"
-
 /*************************** Device Access ************************************/
 #define ahd_inb(ahd, port)					\
 	bus_space_read_1((ahd)->tags[(port) >> 8],		\
@@ -187,19 +188,26 @@ ahd_flush_device_writes(struct ahd_softc *ahd)
 
 /**************************** Locking Primitives ******************************/
 /* Lock protecting internal data structures */
-static __inline void ahd_lock(void);
-static __inline void ahd_unlock(void);
+static __inline void ahd_lockinit(struct ahd_softc *);
+static __inline void ahd_lock(struct ahd_softc *);
+static __inline void ahd_unlock(struct ahd_softc *);
+
+static __inline void
+ahd_lockinit(struct ahd_softc *ahd)
+{
+	lockinit(&ahd->platform_data->lock, "ahd_lock", 0, LK_EXCLUSIVE|LK_CANRECURSE);
+}
 
 static __inline void
-ahd_lock(void)
+ahd_lock(struct ahd_softc *ahd)
 {
-	crit_enter();
+	lockmgr(&ahd->platform_data->lock, LK_EXCLUSIVE);
 }
 
 static __inline void
-ahd_unlock(void)
+ahd_unlock(struct ahd_softc *ahd)
 {
-	crit_exit();
+	lockmgr(&ahd->platform_data->lock, LK_RELEASE);
 }
 
 /********************************** PCI ***************************************/
diff --git a/sys/dev/disk/aic7xxx/aic79xx_pci.c b/sys/dev/disk/aic7xxx/aic79xx_pci.c
index 07e27cf..ee67102 100644
--- a/sys/dev/disk/aic7xxx/aic79xx_pci.c
+++ b/sys/dev/disk/aic7xxx/aic79xx_pci.c
@@ -416,10 +416,12 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
 	if (error != 0)
 		return (error);
 
+	ahd_lock(ahd);
 	/*
 	 * Link this softc in with all other ahd instances.
 	 */
 	ahd_softc_insert(ahd);
+	ahd_unlock(ahd);
 	return (0);
 }
 
diff --git a/sys/dev/disk/aic7xxx/aic7xxx.c b/sys/dev/disk/aic7xxx/aic7xxx.c
index add0b68..24a279a 100644
--- a/sys/dev/disk/aic7xxx/aic7xxx.c
+++ b/sys/dev/disk/aic7xxx/aic7xxx.c
@@ -3928,6 +3928,7 @@ ahc_alloc(void *platform_arg, char *name)
 		ahc_free(ahc);
 		ahc = NULL;
 	}
+	ahc_lockinit(ahc);
 	return (ahc);
 }
 
@@ -4006,22 +4007,6 @@ ahc_softc_insert(struct ahc_softc *ahc)
 	ahc->init_level++;
 }
 
-/*
- * Verify that the passed in softc pointer is for a
- * controller that is still configured.
- */
-struct ahc_softc *
-ahc_find_softc(struct ahc_softc *ahc)
-{
-	struct ahc_softc *list_ahc;
-
-	TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
-		if (list_ahc == ahc)
-			return (ahc);
-	}
-	return (NULL);
-}
-
 void
 ahc_set_unit(struct ahc_softc *ahc, int unit)
 {
@@ -4574,6 +4559,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
 #endif
 		next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
 		next_scb->hscb->tag = ahc->scb_data->numscbs;
+		aic_timer_init(&next_scb->io_timer);
 		SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
 				  next_scb, links.sle);
 		segs += AHC_NSEG;
@@ -6988,8 +6974,6 @@ ahc_recover_commands(struct ahc_softc *ahc)
 	int	restart_needed;
 	u_int	last_phase;
 
-	ahc_lock();
-
 	/*
 	 * Pause the controller and manually flush any
 	 * commands that have just completed but that our
@@ -7009,7 +6993,6 @@ ahc_recover_commands(struct ahc_softc *ahc)
 		kprintf("%s: Timedout SCBs already complete. "
 		       "Interrupts may not be functioning.\n", ahc_name(ahc));
 		ahc_unpause(ahc);
-		ahc_unlock();
 		return;
 	}
 
@@ -7262,7 +7245,6 @@ bus_reset:
 		ahc_restart(ahc);
 	else
 		ahc_unpause(ahc);
-	ahc_unlock();
 }
 
 /************************* Target Mode ****************************************/
@@ -7399,10 +7381,8 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 		ahc_flag saved_flags;
 
 		kprintf("Configuring Target Mode\n");
-		ahc_lock();
 		if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
 			ccb->ccb_h.status = CAM_BUSY;
-			ahc_unlock();
 			return;
 		}
 		saved_flags = ahc->flags;
@@ -7423,12 +7403,10 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 			ahc->flags = saved_flags;
 			(void)ahc_loadseq(ahc);
 			ahc_restart(ahc);
-			ahc_unlock();
 			ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 			return;
 		}
 		ahc_restart(ahc);
-		ahc_unlock();
 	}
 	cel = &ccb->cel;
 	target = ccb->ccb_h.target_id;
@@ -7487,7 +7465,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 		}
 		SLIST_INIT(&lstate->accept_tios);
 		SLIST_INIT(&lstate->immed_notifies);
-		ahc_lock();
 		ahc_pause(ahc);
 		if (target != CAM_TARGET_WILDCARD) {
 			tstate->enabled_luns[lun] = lstate;
@@ -7553,7 +7530,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 			ahc_outb(ahc, SCSISEQ, scsiseq);
 		}
 		ahc_unpause(ahc);
-		ahc_unlock();
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_print_path(ccb->ccb_h.path);
 		kprintf("Lun now enabled for target mode\n");
@@ -7566,8 +7542,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 			return;
 		}
 
-		ahc_lock();
-		
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
 			struct ccb_hdr *ccbh;
@@ -7577,7 +7551,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 			 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
 				kprintf("CTIO pending\n");
 				ccb->ccb_h.status = CAM_REQ_INVALID;
-				ahc_unlock();
 				return;
 			}
 		}
@@ -7593,7 +7566,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 		}
 
 		if (ccb->ccb_h.status != CAM_REQ_CMP) {
-			ahc_unlock();
 			return;
 		}
 
@@ -7668,7 +7640,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
 			}
 		}
 		ahc_unpause(ahc);
-		ahc_unlock();
 	}
 }
 
diff --git a/sys/dev/disk/aic7xxx/aic7xxx.h b/sys/dev/disk/aic7xxx/aic7xxx.h
index 77cce33..65a1cb0 100644
--- a/sys/dev/disk/aic7xxx/aic7xxx.h
+++ b/sys/dev/disk/aic7xxx/aic7xxx.h
@@ -598,6 +598,7 @@ struct scb {
 	struct ahc_dma_seg 	 *sg_list;
 	bus_addr_t		  sg_list_phys;
 	u_int			  sg_count;/* How full ahc_dma_seg is */
+	aic_timer_t		  io_timer;
 };
 
 struct scb_data {
@@ -1225,7 +1226,6 @@ void			 ahc_pause_and_flushwork(struct ahc_softc *ahc);
 int			 ahc_suspend(struct ahc_softc *ahc); 
 int			 ahc_resume(struct ahc_softc *ahc);
 void			 ahc_softc_insert(struct ahc_softc *);
-struct ahc_softc	*ahc_find_softc(struct ahc_softc *ahc);
 void			 ahc_set_unit(struct ahc_softc *, int);
 void			 ahc_set_name(struct ahc_softc *, char *);
 int			 ahc_alloc_scbs(struct ahc_softc *ahc);
diff --git a/sys/dev/disk/aic7xxx/aic7xxx_osm.c b/sys/dev/disk/aic7xxx/aic7xxx_osm.c
index 8181836..4201d65 100644
--- a/sys/dev/disk/aic7xxx/aic7xxx_osm.c
+++ b/sys/dev/disk/aic7xxx/aic7xxx_osm.c
@@ -167,7 +167,7 @@ ahc_attach(struct ahc_softc *ahc)
 
 	ahc_controller_info(ahc, ahc_info);
 	kprintf("%s\n", ahc_info);
-	ahc_lock();
+	ahc_lock(ahc);
 
 	/*
 	 * Attach secondary channel first if the user has
@@ -267,6 +267,7 @@ fail:
 		ahc->platform_data->sim_b = sim2;
 		ahc->platform_data->path_b = path2;
 	}
+	ahc_unlock(ahc);
 
 	if (count != 0) {
 		/* We have to wait until after any system dumps... */
@@ -276,7 +277,6 @@ fail:
 		ahc_intr_enable(ahc, TRUE);
 	}
 
-	ahc_unlock();
 	return (count);
 }
 
@@ -289,7 +289,9 @@ ahc_platform_intr(void *arg)
 	struct	ahc_softc *ahc;
 
 	ahc = (struct ahc_softc *)arg; 
+	ahc_lock(ahc);
 	ahc_intr(ahc);
+	ahc_unlock(ahc);
 }
 
 /*
@@ -320,7 +322,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
 		ahc_run_untagged_queue(ahc, untagged_q);
 	}
 
-	callout_stop(&ccb->ccb_h.timeout_ch);
+	callout_stop(&scb->io_timer);
 
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 		bus_dmasync_op_t op;
@@ -384,8 +386,8 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
 			 * so reinstate the timeouts for all other pending
 			 * commands.
 			 */
-			 LIST_FOREACH(list_scb, &ahc->pending_scbs,
-				      pending_links) {
+			LIST_FOREACH(list_scb, &ahc->pending_scbs,
+				     pending_links) {
 
 				aic_scb_timer_reset(list_scb,
 						    aic_get_timeout(scb));
@@ -462,13 +464,11 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 		}
 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
 
-			ahc_lock();
 			SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h,
 					  sim_links.sle);
 			ccb->ccb_h.status = CAM_REQ_INPROG;
 			if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0)
 				ahc_run_tqinfifo(ahc, /*paused*/FALSE);
-			ahc_unlock();
 			break;
 		}
 
@@ -498,17 +498,14 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 		/*
 		 * get an scb to use.
 		 */
-		ahc_lock();
 		if ((scb = ahc_get_scb(ahc)) == NULL) {
 	
 			xpt_freeze_simq(sim, /*count*/1);
 			ahc->flags |= AHC_RESOURCE_SHORTAGE;
-			ahc_unlock();
 			ccb->ccb_h.status = CAM_REQUEUE_REQ;
 			xpt_done(ccb);
 			return;
 		}
-		ahc_unlock();
 		
 		hscb = scb->hscb;
 		
@@ -639,8 +636,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 			break;
 		}
 		
-		ahc_lock();
-
 		if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
 			if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
 				*discenable |= devinfo.target_mask;
@@ -716,7 +711,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 					 spi->ppr_options, update_type,
 					 /*paused*/FALSE);
 		}
-		ahc_unlock();
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 #else
@@ -752,8 +746,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 			break;
 		}
 		
-		ahc_lock();
-
 		if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
 			if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
 				*discenable |= devinfo.target_mask;
@@ -834,7 +826,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 					 ppr_options, update_type,
 					 /*paused*/FALSE);
 		}
-		ahc_unlock();
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 #endif
@@ -844,10 +835,8 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 	/* Get default/user set transfer settings for the target */
 	{
 
-		ahc_lock();
 		ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim),
 				      SIM_CHANNEL(ahc, sim), &ccb->cts);
-		ahc_unlock();
 		xpt_done(ccb);
 		break;
 	}
@@ -866,10 +855,8 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
 	{
 		int  found;
 		
-		ahc_lock();
 		found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim),
 					  /*initiate reset*/TRUE);
-		ahc_unlock();
 		if (bootverbose) {
 			xpt_print_path(SIM_PATH(ahc, sim));
 			kprintf("SCSI bus reset delivered. "
@@ -1077,14 +1064,12 @@ ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
 		 * Revert to async/narrow transfers
 		 * for the next device.
 		 */
-		ahc_lock();
 		ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
 			      AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE);
 				 /*period*/0, /*offset*/0, /*ppr_options*/0,
 				 AHC_TRANS_GOAL|AHC_TRANS_CUR,
 				 /*paused*/FALSE);
-		ahc_unlock();
 		break;
 	}
 	default:
@@ -1114,9 +1099,7 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 			aic_set_transaction_status(scb, CAM_REQ_CMP_ERR);
 		if (nsegments != 0)
 			bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
-		ahc_lock();
 		ahc_free_scb(ahc, scb);
-		ahc_unlock();
 		xpt_done(ccb);
 		return;
 	}
@@ -1189,9 +1172,7 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 					    CAM_REQ_TOO_BIG);
 					bus_dmamap_unload(ahc->buffer_dmat,
 							  scb->dmamap);
-					ahc_lock();
 					ahc_free_scb(ahc, scb);
-					ahc_unlock();
 					xpt_done(ccb);
 					return;
 				}
@@ -1214,8 +1195,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 	
 	scb->sg_count = nsegments;
 
-	ahc_lock();
-
 	/*
 	 * Last time we need to check if this SCB needs to
 	 * be aborted.
@@ -1224,7 +1203,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 		if (nsegments != 0)
 			bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
 		ahc_free_scb(ahc, scb);
-		ahc_unlock();
 		xpt_done(ccb);
 		return;
 	}
@@ -1275,7 +1253,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 		TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
 		scb->flags |= SCB_UNTAGGEDQ;
 		if (TAILQ_FIRST(untagged_q) != scb) {
-			ahc_unlock();
 			return;
 		}
 	}
@@ -1297,8 +1274,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
 	} else {
 		ahc_queue_scb(ahc, scb);
 	}
-
-	ahc_unlock();
 }
 
 static void
@@ -1330,9 +1305,7 @@ ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
 			 || (ccb_h->flags & CAM_CDB_PHYS) != 0) {
 				aic_set_transaction_status(scb,
 							   CAM_REQ_INVALID);
-				ahc_lock();
 				ahc_free_scb(ahc, scb);
-				ahc_unlock();
 				xpt_done((union ccb *)csio);
 				return;
 			}
@@ -1628,16 +1601,11 @@ ahc_detach(device_t dev)
 
 	device_printf(dev, "detaching device\n");
 	ahc = device_get_softc(dev);
-	ahc = ahc_find_softc(ahc);
-	if (ahc == NULL) {
-		device_printf(dev, "aic7xxx already detached\n");
-		return (ENOENT);
-	}
+	ahc_lock(ahc);
 	TAILQ_REMOVE(&ahc_tailq, ahc, links);
-	ahc_lock();
 	ahc_intr_enable(ahc, FALSE);
 	bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih);
-	ahc_unlock();
+	ahc_unlock(ahc);
 	ahc_free(ahc);
 	return (0);
 }
@@ -1674,6 +1642,7 @@ static int
 ahc_modevent(module_t mod, int type, void *data)
 {
 	/* XXX Deal with busy status on unload. */
+	/* XXX Deal with unknown events */
 	return 0;
 }
   
diff --git a/sys/dev/disk/aic7xxx/aic7xxx_osm.h b/sys/dev/disk/aic7xxx/aic7xxx_osm.h
index 193bef0..d0c7a97 100644
--- a/sys/dev/disk/aic7xxx/aic7xxx_osm.h
+++ b/sys/dev/disk/aic7xxx/aic7xxx_osm.h
@@ -126,6 +126,17 @@ extern devclass_t ahc_devclass;
 /* This driver supports target mode */
 #define AHC_TARGET_MODE 1
 
+/***************************** Core Includes **********************************/
+#ifdef AHC_REG_PRETTY_PRINT
+#define AIC_DEBUG_REGISTERS 1
+#else
+#define AIC_DEBUG_REGISTERS 0
+#endif
+#define	AIC_CORE_INCLUDE "aic7xxx.h"
+#define	AIC_LIB_PREFIX ahc
+#define	AIC_CONST_PREFIX AHC
+#include "aic_osm_lib.h"
+
 /************************** Softc/SCB Platform Data ***************************/
 struct ahc_platform_data {
 	/*
@@ -144,22 +155,12 @@ struct ahc_platform_data {
 	void			*ih;
 	eventhandler_tag	 eh;
 	struct thread		*recovery_thread;
+	struct lock		 lock;
 };
 
 struct scb_platform_data {
 };
 
-/***************************** Core Includes **********************************/
-#ifdef AHC_REG_PRETTY_PRINT
-#define AIC_DEBUG_REGISTERS 1
-#else
-#define AIC_DEBUG_REGISTERS 0
-#endif
-#define	AIC_CORE_INCLUDE "aic7xxx.h"
-#define	AIC_LIB_PREFIX ahc
-#define	AIC_CONST_PREFIX AHC
-#include "aic_osm_lib.h"
-
 /*************************** Device Access ************************************/
 #define ahc_inb(ahc, port)				\
 	bus_space_read_1((ahc)->tag, (ahc)->bsh, port)
@@ -184,19 +185,26 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
 
 /**************************** Locking Primitives ******************************/
 /* Lock protecting internal data structures */
-static __inline void ahc_lock(void);
-static __inline void ahc_unlock(void);
+static __inline void ahc_lockinit(struct ahc_softc *);
+static __inline void ahc_lock(struct ahc_softc *);
+static __inline void ahc_unlock(struct ahc_softc *);
+
+static __inline void
+ahc_lockinit(struct ahc_softc *ahc)
+{
+	lockinit(&ahc->platform_data->lock, "ahc_lock", 0, LK_EXCLUSIVE|LK_CANRECURSE);
+}
 
 static __inline void
-ahc_lock(void)
+ahc_lock(struct ahc_softc *ahc)
 {
-	crit_enter_id("ahc");
+	lockmgr(&ahc->platform_data->lock, LK_EXCLUSIVE);
 }
 
 static __inline void
-ahc_unlock(void)
+ahc_unlock(struct ahc_softc *ahc)
 {
-	crit_exit_id("ahc");
+	lockmgr(&ahc->platform_data->lock, LK_RELEASE);
 }
 
 /************************* Initialization/Teardown ****************************/
diff --git a/sys/dev/disk/aic7xxx/aic7xxx_pci.c b/sys/dev/disk/aic7xxx/aic7xxx_pci.c
index c4caf62..2129843 100644
--- a/sys/dev/disk/aic7xxx/aic7xxx_pci.c
+++ b/sys/dev/disk/aic7xxx/aic7xxx_pci.c
@@ -1045,10 +1045,12 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
 	if (error != 0)
 		return (error);
 
+	ahc_lock(ahc);
 	/*
 	 * Link this softc in with all other ahc instances.
 	 */
 	ahc_softc_insert(ahc);
+	ahc_unlock(ahc);
 	return (0);
 }
 
diff --git a/sys/dev/disk/aic7xxx/aic_osm_lib.c b/sys/dev/disk/aic7xxx/aic_osm_lib.c
index ff2568d..43e050c 100644
--- a/sys/dev/disk/aic7xxx/aic_osm_lib.c
+++ b/sys/dev/disk/aic7xxx/aic_osm_lib.c
@@ -57,7 +57,7 @@ aic_set_recoveryscb(struct aic_softc *aic, struct scb *scb)
 			union ccb *ccb;
 
 			ccb = list_scb->io_ctx;
-			callout_stop(&ccb->ccb_h.timeout_ch);
+			callout_stop(&scb->io_timer);
 		}
 	}
 }
@@ -68,9 +68,9 @@ aic_platform_timeout(void *arg)
 	struct	scb *scb;
 	
 	scb = (struct scb *)arg; 
-	aic_lock();
+	aic_lock(scb->aic_softc);
 	aic_timeout(scb);
-	aic_unlock();
+	aic_unlock(scb->aic_softc);
 }
 
 int
@@ -92,9 +92,7 @@ void
 aic_terminate_recovery_thread(struct aic_softc *aic)
 {
 
-	aic_lock();
 	if (aic->platform_data->recovery_thread == NULL) {
-		aic_unlock();
 		return;
 	}
 	aic->flags |= AIC_SHUTDOWN_RECOVERY;
@@ -103,8 +101,7 @@ aic_terminate_recovery_thread(struct aic_softc *aic)
 	 * Sleep on a slightly different location 
 	 * for this interlock just for added safety.
 	 */
-	tsleep(aic->platform_data, 0, "thtrm", 0);
-	aic_unlock();
+	msleep(aic->platform_data, &aic->platform_data->lock, 0, "thtrm", 0);
 }
 
 static void
@@ -112,29 +109,21 @@ aic_recovery_thread(void *arg)
 {
 	struct aic_softc *aic;
 
-#if __FreeBSD_version >= 500000
-	mtx_lock(&Giant);
-#endif
 	aic = (struct aic_softc *)arg;
-	aic_lock();
+	aic_lock(aic);
 	for (;;) {
 		
 		if (LIST_EMPTY(&aic->timedout_scbs) != 0
 		 && (aic->flags & AIC_SHUTDOWN_RECOVERY) == 0)
-			tsleep(aic, 0, "idle", 0);
+			msleep(aic, &aic->platform_data->lock, 0, "idle", 0);
 
 		if ((aic->flags & AIC_SHUTDOWN_RECOVERY) != 0)
 			break;
 
-		aic_unlock();
 		aic_recover_commands(aic);
-		aic_lock();
 	}
 	aic->platform_data->recovery_thread = NULL;
 	wakeup(aic->platform_data);
-	aic_unlock();
-#if __FreeBSD_version >= 500000
-	mtx_unlock(&Giant);
-#endif
+	aic_unlock(aic);
 	kthread_exit();
 }
diff --git a/sys/dev/disk/aic7xxx/aic_osm_lib.h b/sys/dev/disk/aic7xxx/aic_osm_lib.h
index e402ba1..8916fe0 100644
--- a/sys/dev/disk/aic7xxx/aic_osm_lib.h
+++ b/sys/dev/disk/aic7xxx/aic_osm_lib.h
@@ -39,6 +39,8 @@
 /******************************** OS Includes *********************************/
 #if __FreeBSD_version >= 500000
 #include <sys/mutex.h>
+#else
+#include <sys/lock.h>
 #endif
 
 /*************************** Library Symbol Mapping ***************************/
@@ -223,8 +225,7 @@ aic_scb_timer_reset(struct scb *scb, u_int msec)
 	time = msec;
 	time *= hz;
 	time /= 1000;
-	callout_reset(&scb->io_ctx->ccb_h.timeout_ch, time,
-		aic_platform_timeout, scb);
+	callout_reset(&scb->io_timer, time, aic_platform_timeout, scb);
 }
 
 static __inline void
@@ -233,13 +234,7 @@ aic_scb_timer_start(struct scb *scb)
 	
 	if (AIC_SCB_DATA(scb->aic_softc)->recovery_scbs == 0
 	 && scb->io_ctx->ccb_h.timeout != CAM_TIME_INFINITY) {
-		uint64_t time;
-
-		time = scb->io_ctx->ccb_h.timeout;
-		time *= hz;
-		time /= 1000;
-		callout_reset(&scb->io_ctx->ccb_h.timeout_ch, time,
-		    aic_platform_timeout, scb);
+		aic_scb_timer_reset(scb, scb->io_ctx->ccb_h.timeout);
 	}
 }
 

Attachment: pgp00004.pgp
Description: PGP signature



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]