diff options
author | scottl <scottl@FreeBSD.org> | 2007-04-17 06:26:25 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-04-17 06:26:25 +0000 |
commit | 46e32eee32ff63f525942709fe5d7322352f1a9d (patch) | |
tree | 27921cfc4f9e8b58ec48c74db9e6854c5d538d81 /sys/dev/aic7xxx | |
parent | 5e201c93e8ef6977dfe347629109a48522c9ba42 (diff) | |
download | FreeBSD-src-46e32eee32ff63f525942709fe5d7322352f1a9d.zip FreeBSD-src-46e32eee32ff63f525942709fe5d7322352f1a9d.tar.gz |
Basic MPSAFE locking for the AHC and AHD drivers.
Diffstat (limited to 'sys/dev/aic7xxx')
-rw-r--r-- | sys/dev/aic7xxx/aic7770.c | 5 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx.c | 71 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx.h | 2 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx_osm.c | 57 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx_osm.h | 56 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic79xx_pci.c | 5 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.c | 38 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.h | 2 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_osm.c | 63 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_osm.h | 56 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_pci.c | 5 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic_osm_lib.c | 31 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic_osm_lib.h | 17 |
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); } } |