MPSAFE locking for the ahc/ahd drivers using lockmgr locks.
authorPeter Avalos <pavalos@dragonflybsd.org>
Sat, 9 Feb 2008 18:13:13 +0000 (18:13 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sat, 9 Feb 2008 18:13:13 +0000 (18:13 +0000)
Obtained-from: FreeBSD

14 files changed:
sys/dev/disk/aic7xxx/ahc_isa.c
sys/dev/disk/aic7xxx/aic7770.c
sys/dev/disk/aic7xxx/aic79xx.c
sys/dev/disk/aic7xxx/aic79xx.h
sys/dev/disk/aic7xxx/aic79xx_osm.c
sys/dev/disk/aic7xxx/aic79xx_osm.h
sys/dev/disk/aic7xxx/aic79xx_pci.c
sys/dev/disk/aic7xxx/aic7xxx.c
sys/dev/disk/aic7xxx/aic7xxx.h
sys/dev/disk/aic7xxx/aic7xxx_osm.c
sys/dev/disk/aic7xxx/aic7xxx_osm.h
sys/dev/disk/aic7xxx/aic7xxx_pci.c
sys/dev/disk/aic7xxx/aic_osm_lib.c
sys/dev/disk/aic7xxx/aic_osm_lib.h

index c220eda..f269762 100644 (file)
@@ -35,7 +35,7 @@
  * $Id$
  *
  * $FreeBSD: src/sys/dev/aic7xxx/ahc_isa.c,v 1.5 2004/10/15 23:39:52 gibbs Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/ahc_isa.c,v 1.2 2007/07/18 21:48:34 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/ahc_isa.c,v 1.3 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #include "aic7xxx_osm.h"
@@ -242,9 +242,7 @@ ahc_isa_attach(device_t dev)
         * set it up for attachment by our
         * common detect routine.
         */
-       name = kmalloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT);
-       if (name == NULL)
-               return (ENOMEM);
+       name = kmalloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_WAITOK);
        strcpy(name, device_get_nameunit(dev));
        ahc = ahc_alloc(dev, name);
        if (ahc == NULL)
index fcef375..80abbbf 100644 (file)
@@ -40,7 +40,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#34 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.16 2003/12/17 00:02:09 gibbs Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic7770.c,v 1.8 2007/07/06 00:01:16 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic7770.c,v 1.9 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifdef __linux__
@@ -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);
 }
 
index 834fcf4..84d1b25 100644 (file)
@@ -40,7 +40,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#246 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx.c,v 1.40 2007/04/19 18:53:52 scottl Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx.c,v 1.29 2007/07/19 00:23:04 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx.c,v 1.30 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #include "aic79xx_osm.h"
@@ -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
 }
index f4e5bf3..290d20d 100644 (file)
@@ -40,7 +40,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#107 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx.h,v 1.27 2007/04/19 18:53:52 scottl Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx.h,v 1.13 2007/07/19 00:23:04 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx.h,v 1.14 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifndef _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);
index 360dea5..846f869 100644 (file)
@@ -32,7 +32,7 @@
  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#35 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_osm.c,v 1.23 2005/12/04 02:12:40 ru Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.c,v 1.21 2007/07/11 23:46:58 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.c,v 1.22 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #include "aic79xx_osm.h"
@@ -95,7 +95,7 @@ ahd_map_int(struct ahd_softc *ahd)
 
        /* Hook up our interrupt handler */
        error = bus_setup_intr(ahd->dev_softc, ahd->platform_data->irq,
-                              0, ahd_platform_intr, ahd,
+                              INTR_MPSAFE, ahd_platform_intr, ahd,
                               &ahd->platform_data->ih, NULL);
        if (error != 0)
                device_printf(ahd->dev_softc, "bus_setup_intr() failed: %d\n",
@@ -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;
 }
   
index 1e4b4fe..dcaadf8 100644 (file)
@@ -33,7 +33,7 @@
  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.h#23 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_osm.h,v 1.18 2005/12/06 11:19:36 ru Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.h,v 1.11 2007/07/07 01:12:01 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.h,v 1.12 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifndef _AIC79XX_FREEBSD_H_
 #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 ***************************************/
index 07e27cf..e9e7f06 100644 (file)
@@ -41,7 +41,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#88 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_pci.c,v 1.24 2005/12/04 02:12:40 ru Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_pci.c,v 1.15 2007/07/07 01:06:07 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_pci.c,v 1.16 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifdef __linux__
@@ -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);
 }
 
index add0b68..8a277b3 100644 (file)
@@ -40,7 +40,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#155 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.111 2007/04/19 18:53:52 scottl Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx.c,v 1.26 2007/07/19 00:23:04 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx.c,v 1.27 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #include "aic7xxx_osm.h"
@@ -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();
        }
 }
 
index 77cce33..0699bd6 100644 (file)
@@ -40,7 +40,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#85 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.56 2007/04/19 18:53:52 scottl Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx.h,v 1.6 2007/07/19 00:23:04 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx.h,v 1.7 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifndef _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);
index 8181836..c6c1069 100644 (file)
@@ -31,7 +31,7 @@
  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#20 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.c,v 1.45 2006/09/05 20:28:28 mjacob Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_osm.c,v 1.20 2007/07/11 23:46:58 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_osm.c,v 1.21 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #include "aic7xxx_osm.h"
@@ -107,7 +107,7 @@ ahc_map_int(struct ahc_softc *ahc)
 
        /* Hook up our interrupt handler */
        error = bus_setup_intr(ahc->dev_softc, ahc->platform_data->irq,
-                              0, ahc_platform_intr, ahc,
+                              INTR_MPSAFE, ahc_platform_intr, ahc,
                               &ahc->platform_data->ih, NULL);
 
        if (error != 0)
@@ -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);
                ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
                                 /*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;
 }
   
index 193bef0..4a39bc0 100644 (file)
@@ -32,7 +32,7 @@
  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.h#18 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.h,v 1.30 2005/12/05 11:58:32 ru Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_osm.h,v 1.12 2007/07/07 01:09:42 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_osm.h,v 1.13 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifndef _AIC7XXX_FREEBSD_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 ****************************/
index c4caf62..fc841db 100644 (file)
@@ -42,7 +42,7 @@
  * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#78 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_pci.c,v 1.35 2005/09/22 05:11:35 gibbs Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_pci.c,v 1.13 2007/08/04 21:42:15 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic7xxx_pci.c,v 1.14 2008/02/09 18:13:13 pavalos Exp $
  */
 
 #ifdef __linux__
@@ -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);
 }
 
index ff2568d..3ba2031 100644 (file)
@@ -32,7 +32,7 @@
  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic_osm_lib.c#5 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic_osm_lib.c,v 1.3 2004/08/17 00:14:31 gibbs Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic_osm_lib.c,v 1.2 2007/07/06 04:56:22 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic_osm_lib.c,v 1.3 2008/02/09 18:13:13 pavalos Exp $
  */
 
 static void    aic_recovery_thread(void *arg);
@@ -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,12 @@ aic_terminate_recovery_thread(struct aic_softc *aic)
         * Sleep on a slightly different location 
         * for this interlock just for added safety.
         */
+       crit_enter();
+       aic_lock(aic);
+       tsleep_interlock(aic->platform_data);
+       aic_unlock(aic);
        tsleep(aic->platform_data, 0, "thtrm", 0);
-       aic_unlock();
+       crit_exit();
 }
 
 static void
@@ -112,29 +114,27 @@ 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)
+                && (aic->flags & AIC_SHUTDOWN_RECOVERY) == 0) {
+                       crit_enter();
+                       tsleep_interlock(aic);
+                       aic_unlock(aic);
                        tsleep(aic, 0, "idle", 0);
+                       aic_lock(aic);
+                       crit_exit();
+               }
 
                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();
 }
index e402ba1..2b24385 100644 (file)
  * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic_osm_lib.h#5 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic_osm_lib.h,v 1.4 2004/11/18 20:22:31 gibbs Exp $
- * $DragonFly: src/sys/dev/disk/aic7xxx/aic_osm_lib.h,v 1.4 2007/07/06 05:58:26 pavalos Exp $
+ * $DragonFly: src/sys/dev/disk/aic7xxx/aic_osm_lib.h,v 1.5 2008/02/09 18:13:13 pavalos Exp $
  */
 
 /******************************** 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);
        }
 }