summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2007-04-17 06:26:25 +0000
committerscottl <scottl@FreeBSD.org>2007-04-17 06:26:25 +0000
commit46e32eee32ff63f525942709fe5d7322352f1a9d (patch)
tree27921cfc4f9e8b58ec48c74db9e6854c5d538d81 /sys/dev
parent5e201c93e8ef6977dfe347629109a48522c9ba42 (diff)
downloadFreeBSD-src-46e32eee32ff63f525942709fe5d7322352f1a9d.zip
FreeBSD-src-46e32eee32ff63f525942709fe5d7322352f1a9d.tar.gz
Basic MPSAFE locking for the AHC and AHD drivers.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/aic7xxx/aic7770.c5
-rw-r--r--sys/dev/aic7xxx/aic79xx.c71
-rw-r--r--sys/dev/aic7xxx/aic79xx.h2
-rw-r--r--sys/dev/aic7xxx/aic79xx_osm.c57
-rw-r--r--sys/dev/aic7xxx/aic79xx_osm.h56
-rw-r--r--sys/dev/aic7xxx/aic79xx_pci.c5
-rw-r--r--sys/dev/aic7xxx/aic7xxx.c38
-rw-r--r--sys/dev/aic7xxx/aic7xxx.h2
-rw-r--r--sys/dev/aic7xxx/aic7xxx_osm.c63
-rw-r--r--sys/dev/aic7xxx/aic7xxx_osm.h56
-rw-r--r--sys/dev/aic7xxx/aic7xxx_pci.c5
-rw-r--r--sys/dev/aic7xxx/aic_osm_lib.c31
-rw-r--r--sys/dev/aic7xxx/aic_osm_lib.h17
13 files changed, 72 insertions, 336 deletions
diff --git a/sys/dev/aic7xxx/aic7770.c b/sys/dev/aic7xxx/aic7770.c
index 1ce48f9..a5efb0b 100644
--- a/sys/dev/aic7xxx/aic7770.c
+++ b/sys/dev/aic7xxx/aic7770.c
@@ -126,7 +126,6 @@ aic7770_find_device(uint32_t id)
int
aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
{
- u_long l;
int error;
int have_seeprom;
u_int hostconf;
@@ -254,7 +253,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
if (error != 0)
return (error);
- ahc_list_lock(&l);
+ ahc_lock(ahc);
/*
* Link this softc in with all other ahc instances.
*/
@@ -265,7 +264,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
*/
ahc_outb(ahc, BCTL, ENABLE);
- ahc_list_unlock(&l);
+ ahc_unlock(ahc);
return (0);
}
diff --git a/sys/dev/aic7xxx/aic79xx.c b/sys/dev/aic7xxx/aic79xx.c
index b5a8b6c..d65c3a4 100644
--- a/sys/dev/aic7xxx/aic79xx.c
+++ b/sys/dev/aic7xxx/aic79xx.c
@@ -5271,6 +5271,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) {
printf("%s: scb size = 0x%x, hscb size = 0x%x\n",
@@ -5342,22 +5343,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)
{
@@ -6215,6 +6200,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);
@@ -8060,19 +8046,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;
- u_long l;
- u_long s;
- ahd_list_lock(&l);
- ahd = ahd_find_softc((struct ahd_softc *)arg);
- if (ahd == NULL) {
- printf("ahd_reset_poll: Instance %p no longer exists\n", arg);
- ahd_list_unlock(&l);
- return;
- }
- ahd_lock(ahd, &s);
+ ahd_lock(ahd);
ahd_pause(ahd);
ahd_update_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
@@ -8081,8 +8058,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, &s);
- ahd_list_unlock(&l);
+ ahd_unlock(ahd);
return;
}
@@ -8092,29 +8068,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(ahd, &s);
aic_release_simq(ahd);
- ahd_list_unlock(&l);
+ ahd_unlock(ahd);
}
/**************************** Statistics Processing ***************************/
static void
ahd_stat_timer(void *arg)
{
- struct ahd_softc *ahd;
- u_long l;
- u_long s;
+ struct ahd_softc *ahd = (struct ahd_softc *)arg;
int enint_coal;
- ahd_list_lock(&l);
- ahd = ahd_find_softc((struct ahd_softc *)arg);
- if (ahd == NULL) {
- printf("ahd_stat_timer: Instance %p no longer exists\n", arg);
- ahd_list_unlock(&l);
- return;
- }
- ahd_lock(ahd, &s);
-
+ ahd_lock(ahd);
enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
enint_coal |= ENINT_COALESCE;
@@ -8138,8 +8103,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, &s);
- ahd_list_unlock(&l);
+ ahd_unlock(ahd);
}
/****************************** Status Processing *****************************/
@@ -9300,14 +9264,11 @@ ahd_recover_commands(struct ahd_softc *ahd)
{
struct scb *scb;
struct scb *active_scb;
- long s;
int found;
int was_paused;
u_int active_scbptr;
u_int last_phase;
- ahd_lock(ahd, &s);
-
/*
* Pause the controller and manually flush any
* commands that have just completed but that our
@@ -9333,7 +9294,6 @@ ahd_recover_commands(struct ahd_softc *ahd)
printf("%s: Timedout SCBs already complete. "
"Interrupts may not be functioning.\n", ahd_name(ahd));
ahd_unpause(ahd);
- ahd_unlock(ahd, &s);
return;
}
@@ -9524,7 +9484,6 @@ bus_reset:
}
ahd_unpause(ahd);
- ahd_unlock(ahd, &s);
}
/*
@@ -9940,13 +9899,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;
-
printf("Configuring Target Mode\n");
- ahd_lock(ahd, &s);
if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
ccb->ccb_h.status = CAM_BUSY;
- ahd_unlock(ahd, &s);
return;
}
ahd->flags |= AHD_TARGETROLE;
@@ -9955,7 +9910,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(ahd, &s);
}
cel = &ccb->cel;
target = ccb->ccb_h.target_id;
@@ -10021,7 +9975,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, &s);
ahd_pause(ahd);
if (target != CAM_TARGET_WILDCARD) {
tstate->enabled_luns[lun] = lstate;
@@ -10080,7 +10033,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(ahd, &s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_print_path(ccb->ccb_h.path);
printf("Lun now enabled for target mode\n");
@@ -10093,8 +10045,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
return;
}
- ahd_lock(ahd, &s);
-
ccb->ccb_h.status = CAM_REQ_CMP;
LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
struct ccb_hdr *ccbh;
@@ -10104,7 +10054,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)){
printf("CTIO pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
- ahd_unlock(ahd, &s);
return;
}
}
@@ -10120,7 +10069,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(ahd, &s);
return;
}
@@ -10187,7 +10135,6 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
}
}
ahd_unpause(ahd);
- ahd_unlock(ahd, &s);
}
#endif
}
diff --git a/sys/dev/aic7xxx/aic79xx.h b/sys/dev/aic7xxx/aic79xx.h
index 2f63683..1703ab4 100644
--- a/sys/dev/aic7xxx/aic79xx.h
+++ b/sys/dev/aic7xxx/aic79xx.h
@@ -639,6 +639,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);
@@ -1397,7 +1398,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/aic7xxx/aic79xx_osm.c b/sys/dev/aic7xxx/aic79xx_osm.c
index aef520d..e6a1cad 100644
--- a/sys/dev/aic7xxx/aic79xx_osm.c
+++ b/sys/dev/aic7xxx/aic79xx_osm.c
@@ -95,8 +95,8 @@ ahd_map_int(struct ahd_softc *ahd)
/* Hook up our interrupt handler */
error = bus_setup_intr(ahd->dev_softc, ahd->platform_data->irq,
- INTR_TYPE_CAM, NULL, ahd_platform_intr, ahd,
- &ahd->platform_data->ih);
+ INTR_TYPE_CAM|INTR_MPSAFE, NULL,
+ ahd_platform_intr, ahd, &ahd->platform_data->ih);
if (error != 0)
device_printf(ahd->dev_softc, "bus_setup_intr() failed: %d\n",
error);
@@ -114,7 +114,6 @@ ahd_attach(struct ahd_softc *ahd)
struct cam_devq *devq;
struct cam_sim *sim;
struct cam_path *path;
- long s;
int count;
count = 0;
@@ -129,7 +128,7 @@ ahd_attach(struct ahd_softc *ahd)
ahd_controller_info(ahd, ahd_info);
printf("%s\n", ahd_info);
- ahd_lock(ahd, &s);
+ ahd_lock(ahd);
/*
* Create the device queue for our SIM(s).
@@ -143,7 +142,7 @@ ahd_attach(struct ahd_softc *ahd)
*/
sim = cam_sim_alloc(ahd_action, ahd_poll, "ahd", ahd,
device_get_unit(ahd->dev_softc),
- &Giant, 1, /*XXX*/256, devq);
+ &ahd->platform_data->mtx, 1, /*XXX*/256, devq);
if (sim == NULL) {
cam_simq_free(devq);
goto fail;
@@ -175,6 +174,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 =
@@ -183,7 +183,6 @@ fail:
ahd_intr_enable(ahd, TRUE);
}
- ahd_unlock(ahd, &s);
return (count);
}
@@ -197,7 +196,9 @@ ahd_platform_intr(void *arg)
struct ahd_softc *ahd;
ahd = (struct ahd_softc *)arg;
+ ahd_lock(ahd);
ahd_intr(ahd);
+ ahd_unlock(ahd);
}
/*
@@ -218,7 +219,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
if ((scb->flags & SCB_TIMEDOUT) != 0)
LIST_REMOVE(scb, timedout_links);
- untimeout(ahd_platform_timeout, (caddr_t)scb, 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;
@@ -348,7 +349,6 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
#endif
u_int target_id;
u_int our_id;
- long s;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahd_action\n"));
@@ -382,13 +382,11 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
}
if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
- ahd_lock(ahd, &s);
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(ahd, &s);
break;
}
@@ -422,7 +420,6 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
/*
* get an scb to use.
*/
- ahd_lock(ahd, &s);
tinfo = ahd_fetch_transinfo(ahd, 'A', our_id,
target_id, &tstate);
if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0
@@ -437,12 +434,10 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
xpt_freeze_simq(sim, /*count*/1);
ahd->flags |= AHD_RESOURCE_SHORTAGE;
- ahd_unlock(ahd, &s);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
return;
}
- ahd_unlock(ahd, &s);
hscb = scb->hscb;
@@ -530,20 +525,16 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
}
case XPT_SET_TRAN_SETTINGS:
{
- ahd_lock(ahd, &s);
ahd_set_tran_settings(ahd, SIM_SCSI_ID(ahd, sim),
SIM_CHANNEL(ahd, sim), &ccb->cts);
- ahd_unlock(ahd, &s);
xpt_done(ccb);
break;
}
case XPT_GET_TRAN_SETTINGS:
/* Get default/user set transfer settings for the target */
{
- ahd_lock(ahd, &s);
ahd_get_tran_settings(ahd, SIM_SCSI_ID(ahd, sim),
SIM_CHANNEL(ahd, sim), &ccb->cts);
- ahd_unlock(ahd, &s);
xpt_done(ccb);
break;
}
@@ -557,10 +548,8 @@ ahd_action(struct cam_sim *sim, union ccb *ccb)
{
int found;
- ahd_lock(ahd, &s);
found = ahd_reset_channel(ahd, SIM_CHANNEL(ahd, sim),
/*initiate reset*/TRUE);
- ahd_unlock(ahd, &s);
if (bootverbose) {
xpt_print_path(SIM_PATH(ahd, sim));
printf("SCSI bus reset delivered. "
@@ -817,7 +806,6 @@ ahd_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
case AC_LOST_DEVICE:
{
struct ahd_devinfo devinfo;
- long s;
ahd_compile_devinfo(&devinfo, SIM_SCSI_ID(ahd, sim),
xpt_path_target_id(path),
@@ -829,13 +817,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, &s);
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(ahd, &s);
break;
}
default:
@@ -853,7 +839,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
u_int mask;
- u_long s;
scb = (struct scb *)arg;
ccb = scb->io_ctx;
@@ -866,9 +851,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, &s);
ahd_free_scb(ahd, scb);
- ahd_unlock(ahd, &s);
xpt_done(ccb);
return;
}
@@ -906,8 +889,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
}
}
- ahd_lock(ahd, &s);
-
/*
* Last time we need to check if this SCB needs to
* be aborted.
@@ -917,7 +898,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(ahd, &s);
xpt_done(ccb);
return;
}
@@ -967,7 +947,6 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
ahd_queue_scb(ahd, scb);
}
- ahd_unlock(ahd, &s);
}
static void
@@ -994,7 +973,6 @@ 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) {
- u_long s;
/*
* Should CAM start to support CDB sizes
@@ -1003,9 +981,7 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
*/
aic_set_transaction_status(scb,
CAM_REQ_INVALID);
- ahd_lock(ahd, &s);
ahd_free_scb(ahd, scb);
- ahd_unlock(ahd, &s);
xpt_done((union ccb *)csio);
return;
}
@@ -1022,13 +998,10 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
}
} else {
if (hscb->cdb_len > MAX_CDB_LEN) {
- u_long s;
aic_set_transaction_status(scb,
CAM_REQ_INVALID);
- ahd_lock(ahd, &s);
ahd_free_scb(ahd, scb);
- ahd_unlock(ahd, &s);
xpt_done((union ccb *)csio);
return;
}
@@ -1292,24 +1265,14 @@ int
ahd_detach(device_t dev)
{
struct ahd_softc *ahd;
- u_long l;
- u_long s;
- ahd_list_lock(&l);
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");
- ahd_list_unlock(&l);
- return (ENOENT);
- }
+ ahd_lock(ahd);
TAILQ_REMOVE(&ahd_tailq, ahd, links);
- ahd_list_unlock(&l);
- ahd_lock(ahd, &s);
ahd_intr_enable(ahd, FALSE);
bus_teardown_intr(dev, ahd->platform_data->irq, ahd->platform_data->ih);
- ahd_unlock(ahd, &s);
+ ahd_unlock(ahd);
ahd_free(ahd);
return (0);
}
diff --git a/sys/dev/aic7xxx/aic79xx_osm.h b/sys/dev/aic7xxx/aic79xx_osm.h
index 6d4ac68..3c97a63 100644
--- a/sys/dev/aic7xxx/aic79xx_osm.h
+++ b/sys/dev/aic7xxx/aic79xx_osm.h
@@ -133,6 +133,7 @@ struct ahd_platform_data {
void *ih;
eventhandler_tag eh;
struct proc *recovery_thread;
+ struct mtx mtx;
};
struct scb_platform_data {
@@ -189,66 +190,25 @@ ahd_flush_device_writes(struct ahd_softc *ahd)
/**************************** Locking Primitives ******************************/
/* Lock protecting internal data structures */
static __inline void ahd_lockinit(struct ahd_softc *);
-static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags);
-static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags);
-
-/* Lock held during command compeletion to the upper layer */
-static __inline void ahd_done_lockinit(struct ahd_softc *);
-static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags);
-static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags);
-
-/* Lock held during ahd_list manipulation and ahd softc frees */
-static __inline void ahd_list_lockinit(void);
-static __inline void ahd_list_lock(unsigned long *flags);
-static __inline void ahd_list_unlock(unsigned long *flags);
+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)
{
+ mtx_init(&ahd->platform_data->mtx, "ahd_lock", NULL, MTX_DEF);
}
static __inline void
-ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
-{
- *flags = splcam();
-}
-
-static __inline void
-ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
-{
- splx(*flags);
-}
-
-/* Lock held during command compeletion to the upper layer */
-static __inline void
-ahd_done_lockinit(struct ahd_softc *ahd)
-{
-}
-
-static __inline void
-ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
-{
-}
-
-static __inline void
-ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
-{
-}
-
-/* Lock held during ahd_list manipulation and ahd softc frees */
-static __inline void
-ahd_list_lockinit(void)
-{
-}
-
-static __inline void
-ahd_list_lock(unsigned long *flags)
+ahd_lock(struct ahd_softc *ahd)
{
+ mtx_lock(&ahd->platform_data->mtx);
}
static __inline void
-ahd_list_unlock(unsigned long *flags)
+ahd_unlock(struct ahd_softc *ahd)
{
+ mtx_unlock(&ahd->platform_data->mtx);
}
/********************************** PCI ***************************************/
diff --git a/sys/dev/aic7xxx/aic79xx_pci.c b/sys/dev/aic7xxx/aic79xx_pci.c
index ec47c97..d19313a 100644
--- a/sys/dev/aic7xxx/aic79xx_pci.c
+++ b/sys/dev/aic7xxx/aic79xx_pci.c
@@ -314,7 +314,6 @@ int
ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
{
struct scb_data *shared_scb_data;
- u_long l;
u_int command;
uint32_t devconfig;
uint16_t device;
@@ -423,12 +422,12 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
if (error != 0)
return (error);
- ahd_list_lock(&l);
+ ahd_lock(ahd);
/*
* Link this softc in with all other ahd instances.
*/
ahd_softc_insert(ahd);
- ahd_list_unlock(&l);
+ ahd_unlock(ahd);
return (0);
}
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c
index 71714ab..a5883e2 100644
--- a/sys/dev/aic7xxx/aic7xxx.c
+++ b/sys/dev/aic7xxx/aic7xxx.c
@@ -3948,6 +3948,7 @@ ahc_alloc(void *platform_arg, char *name)
ahc_free(ahc);
ahc = NULL;
}
+ ahc_lockinit(ahc);
return (ahc);
}
@@ -4029,22 +4030,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)
{
@@ -4606,6 +4591,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;
@@ -6944,6 +6930,7 @@ ahc_timeout(struct scb *scb)
struct ahc_softc *ahc;
ahc = scb->ahc_softc;
+ ahc_lock(ahc);
if ((scb->flags & SCB_ACTIVE) != 0) {
if ((scb->flags & SCB_TIMEDOUT) == 0) {
LIST_INSERT_HEAD(&ahc->timedout_scbs, scb,
@@ -6952,6 +6939,7 @@ ahc_timeout(struct scb *scb)
}
ahc_wakeup_recovery_thread(ahc);
}
+ ahc_unlock(ahc);
}
/*
@@ -7017,13 +7005,10 @@ void
ahc_recover_commands(struct ahc_softc *ahc)
{
struct scb *scb;
- long s;
int found;
int restart_needed;
u_int last_phase;
- ahc_lock(ahc, &s);
-
/*
* Pause the controller and manually flush any
* commands that have just completed but that our
@@ -7043,7 +7028,6 @@ ahc_recover_commands(struct ahc_softc *ahc)
printf("%s: Timedout SCBs already complete. "
"Interrupts may not be functioning.\n", ahc_name(ahc));
ahc_unpause(ahc);
- ahc_unlock(ahc, &s);
return;
}
@@ -7296,7 +7280,6 @@ bus_reset:
ahc_restart(ahc);
else
ahc_unpause(ahc);
- ahc_unlock(ahc, &s);
}
/************************* Target Mode ****************************************/
@@ -7349,7 +7332,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
struct ahc_tmode_lstate *lstate;
struct ccb_en_lun *cel;
cam_status status;
- u_long s;
u_int target;
u_int lun;
u_int target_mask;
@@ -7431,14 +7413,11 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
*/
if ((ahc->flags & AHC_TARGETROLE) == 0
&& ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
- u_long s;
ahc_flag saved_flags;
printf("Configuring Target Mode\n");
- ahc_lock(ahc, &s);
if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
ccb->ccb_h.status = CAM_BUSY;
- ahc_unlock(ahc, &s);
return;
}
saved_flags = ahc->flags;
@@ -7459,12 +7438,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(ahc, &s);
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
return;
}
ahc_restart(ahc);
- ahc_unlock(ahc, &s);
}
cel = &ccb->cel;
target = ccb->ccb_h.target_id;
@@ -7530,7 +7507,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, &s);
ahc_pause(ahc);
if (target != CAM_TARGET_WILDCARD) {
tstate->enabled_luns[lun] = lstate;
@@ -7596,7 +7572,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(ahc, &s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_print_path(ccb->ccb_h.path);
printf("Lun now enabled for target mode\n");
@@ -7609,8 +7584,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
return;
}
- ahc_lock(ahc, &s);
-
ccb->ccb_h.status = CAM_REQ_CMP;
LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
struct ccb_hdr *ccbh;
@@ -7620,7 +7593,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)){
printf("CTIO pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
- ahc_unlock(ahc, &s);
return;
}
}
@@ -7636,7 +7608,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(ahc, &s);
return;
}
@@ -7711,7 +7682,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
}
}
ahc_unpause(ahc);
- ahc_unlock(ahc, &s);
}
}
diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h
index 0ac10be..ac0bde2 100644
--- a/sys/dev/aic7xxx/aic7xxx.h
+++ b/sys/dev/aic7xxx/aic7xxx.h
@@ -597,6 +597,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 {
@@ -1224,7 +1225,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 *);
void ahc_alloc_scbs(struct ahc_softc *ahc);
diff --git a/sys/dev/aic7xxx/aic7xxx_osm.c b/sys/dev/aic7xxx/aic7xxx_osm.c
index b53f96a..ff8106d 100644
--- a/sys/dev/aic7xxx/aic7xxx_osm.c
+++ b/sys/dev/aic7xxx/aic7xxx_osm.c
@@ -107,8 +107,8 @@ ahc_map_int(struct ahc_softc *ahc)
/* Hook up our interrupt handler */
error = bus_setup_intr(ahc->dev_softc, ahc->platform_data->irq,
- INTR_TYPE_CAM, NULL, ahc_platform_intr, ahc,
- &ahc->platform_data->ih);
+ INTR_TYPE_CAM|INTR_MPSAFE, NULL,
+ ahc_platform_intr, ahc, &ahc->platform_data->ih);
if (error != 0)
device_printf(ahc->dev_softc, "bus_setup_intr() failed: %d\n",
@@ -152,7 +152,6 @@ ahc_attach(struct ahc_softc *ahc)
struct cam_sim *sim2;
struct cam_path *path;
struct cam_path *path2;
- long s;
int count;
count = 0;
@@ -161,6 +160,7 @@ ahc_attach(struct ahc_softc *ahc)
path = NULL;
path2 = NULL;
+
/*
* Create a thread to perform all recovery.
*/
@@ -169,7 +169,7 @@ ahc_attach(struct ahc_softc *ahc)
ahc_controller_info(ahc, ahc_info);
printf("%s\n", ahc_info);
- ahc_lock(ahc, &s);
+ ahc_lock(ahc);
/*
* Attach secondary channel first if the user has
@@ -196,7 +196,7 @@ ahc_attach(struct ahc_softc *ahc)
*/
sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc,
device_get_unit(ahc->dev_softc),
- &Giant, 1, AHC_MAX_QUEUE, devq);
+ &ahc->platform_data->mtx, 1, AHC_MAX_QUEUE, devq);
if (sim == NULL) {
cam_simq_free(devq);
goto fail;
@@ -228,7 +228,7 @@ ahc_attach(struct ahc_softc *ahc)
if (ahc->features & AHC_TWIN) {
sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc",
ahc, device_get_unit(ahc->dev_softc),
- &Giant, 1,
+ &ahc->platform_data->mtx, 1,
AHC_MAX_QUEUE, devq);
if (sim2 == NULL) {
@@ -279,6 +279,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... */
@@ -288,7 +289,6 @@ fail:
ahc_intr_enable(ahc, TRUE);
}
- ahc_unlock(ahc, &s);
return (count);
}
@@ -301,7 +301,9 @@ ahc_platform_intr(void *arg)
struct ahc_softc *ahc;
ahc = (struct ahc_softc *)arg;
+ ahc_lock(ahc);
ahc_intr(ahc);
+ ahc_unlock(ahc);
}
/*
@@ -332,7 +334,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
ahc_run_untagged_queue(ahc, untagged_q);
}
- untimeout(ahc_platform_timeout, (caddr_t)scb, 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;
@@ -442,7 +444,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
struct ahc_tmode_lstate *lstate;
u_int target_id;
u_int our_id;
- long s;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n"));
@@ -475,13 +476,11 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
}
if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
- ahc_lock(ahc, &s);
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(ahc, &s);
break;
}
@@ -511,17 +510,14 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
/*
* get an scb to use.
*/
- ahc_lock(ahc, &s);
if ((scb = ahc_get_scb(ahc)) == NULL) {
xpt_freeze_simq(sim, /*count*/1);
ahc->flags |= AHC_RESOURCE_SHORTAGE;
- ahc_unlock(ahc, &s);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
return;
}
- ahc_unlock(ahc, &s);
hscb = scb->hscb;
@@ -651,8 +647,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
break;
}
- ahc_lock(ahc, &s);
-
if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
*discenable |= devinfo.target_mask;
@@ -728,7 +722,6 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
spi->ppr_options, update_type,
/*paused*/FALSE);
}
- ahc_unlock(ahc, &s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@@ -737,10 +730,8 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
/* Get default/user set transfer settings for the target */
{
- ahc_lock(ahc, &s);
ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim),
SIM_CHANNEL(ahc, sim), &ccb->cts);
- ahc_unlock(ahc, &s);
xpt_done(ccb);
break;
}
@@ -759,10 +750,8 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
{
int found;
- ahc_lock(ahc, &s);
found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim),
/*initiate reset*/TRUE);
- ahc_unlock(ahc, &s);
if (bootverbose) {
xpt_print_path(SIM_PATH(ahc, sim));
printf("SCSI bus reset delivered. "
@@ -910,7 +899,6 @@ ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
case AC_LOST_DEVICE:
{
struct ahc_devinfo devinfo;
- long s;
ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
xpt_path_target_id(path),
@@ -922,14 +910,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, &s);
ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE);
ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
/*period*/0, /*offset*/0, /*ppr_options*/0,
AHC_TRANS_GOAL|AHC_TRANS_CUR,
/*paused*/FALSE);
- ahc_unlock(ahc, &s);
break;
}
default:
@@ -947,7 +933,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
struct ahc_initiator_tinfo *tinfo;
struct ahc_tmode_tstate *tstate;
u_int mask;
- long s;
scb = (struct scb *)arg;
ccb = scb->io_ctx;
@@ -960,9 +945,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, &s);
ahc_free_scb(ahc, scb);
- ahc_unlock(ahc, &s);
xpt_done(ccb);
return;
}
@@ -1035,9 +1018,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, &s);
ahc_free_scb(ahc, scb);
- ahc_unlock(ahc, &s);
xpt_done(ccb);
return;
}
@@ -1060,8 +1041,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
scb->sg_count = nsegments;
- ahc_lock(ahc, &s);
-
/*
* Last time we need to check if this SCB needs to
* be aborted.
@@ -1070,7 +1049,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(ahc, &s);
xpt_done(ccb);
return;
}
@@ -1121,7 +1099,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(ahc, &s);
return;
}
}
@@ -1143,8 +1120,6 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
} else {
ahc_queue_scb(ahc, scb);
}
-
- ahc_unlock(ahc, &s);
}
static void
@@ -1174,13 +1149,9 @@ ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
if (hscb->cdb_len > sizeof(hscb->cdb32)
|| (ccb_h->flags & CAM_CDB_PHYS) != 0) {
- u_long s;
-
aic_set_transaction_status(scb,
CAM_REQ_INVALID);
- ahc_lock(ahc, &s);
ahc_free_scb(ahc, scb);
- ahc_unlock(ahc, &s);
xpt_done((union ccb *)csio);
return;
}
@@ -1462,24 +1433,14 @@ int
ahc_detach(device_t dev)
{
struct ahc_softc *ahc;
- u_long l;
- u_long s;
- ahc_list_lock(&l);
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");
- ahc_list_unlock(&l);
- return (ENOENT);
- }
+ ahc_lock(ahc);
TAILQ_REMOVE(&ahc_tailq, ahc, links);
- ahc_list_unlock(&l);
- ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE);
bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih);
- ahc_unlock(ahc, &s);
+ ahc_unlock(ahc);
ahc_free(ahc);
return (0);
}
diff --git a/sys/dev/aic7xxx/aic7xxx_osm.h b/sys/dev/aic7xxx/aic7xxx_osm.h
index b3c297e..d105971 100644
--- a/sys/dev/aic7xxx/aic7xxx_osm.h
+++ b/sys/dev/aic7xxx/aic7xxx_osm.h
@@ -146,6 +146,7 @@ struct ahc_platform_data {
void *ih;
eventhandler_tag eh;
struct proc *recovery_thread;
+ struct mtx mtx;
};
struct scb_platform_data {
@@ -187,66 +188,25 @@ ahc_flush_device_writes(struct ahc_softc *ahc)
/**************************** Locking Primitives ******************************/
/* Lock protecting internal data structures */
static __inline void ahc_lockinit(struct ahc_softc *);
-static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
-static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
-
-/* Lock held during command compeletion to the upper layer */
-static __inline void ahc_done_lockinit(struct ahc_softc *);
-static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
-static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
-
-/* Lock held during ahc_list manipulation and ahc softc frees */
-static __inline void ahc_list_lockinit(void);
-static __inline void ahc_list_lock(unsigned long *flags);
-static __inline void ahc_list_unlock(unsigned long *flags);
+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)
{
+ mtx_init(&ahc->platform_data->mtx, "ahc_lock", NULL, MTX_DEF);
}
static __inline void
-ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
-{
- *flags = splcam();
-}
-
-static __inline void
-ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
-{
- splx(*flags);
-}
-
-/* Lock held during command compeletion to the upper layer */
-static __inline void
-ahc_done_lockinit(struct ahc_softc *ahc)
-{
-}
-
-static __inline void
-ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
-{
-}
-
-static __inline void
-ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
-{
-}
-
-/* Lock held during ahc_list manipulation and ahc softc frees */
-static __inline void
-ahc_list_lockinit(void)
-{
-}
-
-static __inline void
-ahc_list_lock(unsigned long *flags)
+ahc_lock(struct ahc_softc *ahc)
{
+ mtx_lock(&ahc->platform_data->mtx);
}
static __inline void
-ahc_list_unlock(unsigned long *flags)
+ahc_unlock(struct ahc_softc *ahc)
{
+ mtx_unlock(&ahc->platform_data->mtx);
}
/************************* Initialization/Teardown ****************************/
diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c
index 25c24ea..2bf4927 100644
--- a/sys/dev/aic7xxx/aic7xxx_pci.c
+++ b/sys/dev/aic7xxx/aic7xxx_pci.c
@@ -785,7 +785,6 @@ ahc_find_pci_device(aic_dev_softc_t pci)
int
ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
{
- u_long l;
u_int command;
u_int our_id;
u_int sxfrctl1;
@@ -1045,12 +1044,12 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
if (error != 0)
return (error);
- ahc_list_lock(&l);
+ ahc_lock(ahc);
/*
* Link this softc in with all other ahc instances.
*/
ahc_softc_insert(ahc);
- ahc_list_unlock(&l);
+ ahc_unlock(ahc);
return (0);
}
diff --git a/sys/dev/aic7xxx/aic_osm_lib.c b/sys/dev/aic7xxx/aic_osm_lib.c
index 8919789..e4128ec 100644
--- a/sys/dev/aic7xxx/aic_osm_lib.c
+++ b/sys/dev/aic7xxx/aic_osm_lib.c
@@ -57,8 +57,7 @@ aic_set_recoveryscb(struct aic_softc *aic, struct scb *scb)
union ccb *ccb;
ccb = list_scb->io_ctx;
- untimeout(aic_platform_timeout, list_scb,
- ccb->ccb_h.timeout_ch);
+ callout_stop(&scb->io_timer);
}
}
}
@@ -67,12 +66,11 @@ void
aic_platform_timeout(void *arg)
{
struct scb *scb;
- u_long s;
scb = (struct scb *)arg;
- aic_lock(scb->aic_softc, &s);
+ aic_lock(scb->aic_softc);
aic_timeout(scb);
- aic_unlock(scb->aic_softc, &s);
+ aic_unlock(scb->aic_softc);
}
int
@@ -93,11 +91,8 @@ aic_spawn_recovery_thread(struct aic_softc *aic)
void
aic_terminate_recovery_thread(struct aic_softc *aic)
{
- u_long s;
- aic_lock(aic, &s);
if (aic->platform_data->recovery_thread == NULL) {
- aic_unlock(aic, &s);
return;
}
aic->flags |= AIC_SHUTDOWN_RECOVERY;
@@ -106,40 +101,32 @@ 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, PUSER, "thtrm", 0);
- aic_unlock(aic, &s);
+ msleep(aic->platform_data, &aic->platform_data->mtx, PUSER, "thtrm", 0);
}
static void
aic_recovery_thread(void *arg)
{
struct aic_softc *aic;
- u_long s;
-#if __FreeBSD_version >= 500000
- mtx_lock(&Giant);
-#endif
aic = (struct aic_softc *)arg;
- aic_lock(aic, &s);
+ aic_lock(aic);
for (;;) {
if (LIST_EMPTY(&aic->timedout_scbs) != 0
&& (aic->flags & AIC_SHUTDOWN_RECOVERY) == 0)
- tsleep(aic, PUSER, "idle", 0);
+ msleep(aic, &aic->platform_data->mtx, PUSER, "idle", 0);
if ((aic->flags & AIC_SHUTDOWN_RECOVERY) != 0)
break;
- aic_unlock(aic, &s);
+ aic_unlock(aic);
aic_recover_commands(aic);
- aic_lock(aic, &s);
+ aic_lock(aic);
}
aic->platform_data->recovery_thread = NULL;
wakeup(aic->platform_data);
- aic_unlock(aic, &s);
-#if __FreeBSD_version >= 500000
- mtx_unlock(&Giant);
-#endif
+ aic_unlock(aic);
kthread_exit(0);
}
diff --git a/sys/dev/aic7xxx/aic_osm_lib.h b/sys/dev/aic7xxx/aic_osm_lib.h
index 1c8678b..434acf3 100644
--- a/sys/dev/aic7xxx/aic_osm_lib.h
+++ b/sys/dev/aic7xxx/aic_osm_lib.h
@@ -143,7 +143,7 @@ aic_wakeup_recovery_thread(struct aic_softc *aic)
bus_dma_tag_create(parent_tag, alignment, boundary, \
lowaddr, highaddr, filter, filterarg, \
maxsize, nsegments, maxsegsz, flags, \
- busdma_lock_mutex, &Giant, \
+ busdma_lock_mutex, &aic->platform_data->mtx, \
dma_tagp)
#else
#define aic_dma_tag_create(aic, parent_tag, alignment, boundary, \
@@ -187,7 +187,7 @@ aic_wakeup_recovery_thread(struct aic_softc *aic)
/***************************** Timer Facilities *******************************/
#if __FreeBSD_version >= 500000
-#define aic_timer_init(timer) callout_init(timer, /*mpsafe*/0)
+#define aic_timer_init(timer) callout_init(timer, /*mpsafe*/1)
#else
#define aic_timer_init callout_init
#endif
@@ -223,10 +223,7 @@ aic_scb_timer_reset(struct scb *scb, u_int msec)
time = msec;
time *= hz;
time /= 1000;
- untimeout(aic_platform_timeout, (caddr_t)scb,
- scb->io_ctx->ccb_h.timeout_ch);
- scb->io_ctx->ccb_h.timeout_ch =
- timeout(aic_platform_timeout, scb, time);
+ callout_reset(&scb->io_timer, time, aic_platform_timeout, scb);
}
static __inline void
@@ -235,13 +232,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;
- scb->io_ctx->ccb_h.timeout_ch =
- timeout(aic_platform_timeout, scb, time);
+ aic_scb_timer_reset(scb, scb->io_ctx->ccb_h.timeout);
}
}
OpenPOWER on IntegriCloud