From owner-svn-src-head@FreeBSD.ORG Tue May 27 19:56:02 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7DB2CDD3; Tue, 27 May 2014 19:56:02 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6A8622F9B; Tue, 27 May 2014 19:56:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4RJu2Vv092181; Tue, 27 May 2014 19:56:02 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4RJu2Mg092180; Tue, 27 May 2014 19:56:02 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201405271956.s4RJu2Mg092180@svn.freebsd.org> From: John Baldwin Date: Tue, 27 May 2014 19:56:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266772 - head/sys/dev/firewire X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 May 2014 19:56:02 -0000 Author: jhb Date: Tue May 27 19:56:02 2014 New Revision: 266772 URL: http://svnweb.freebsd.org/changeset/base/266772 Log: Various cleanups and fixes: - Switch from timeout() to callout_*() for per-request timers. - Use device_find_child() in the identify routine. - Use device_printf() instead of passing device_get_nameunit() to printf(). - Expand the SBP_LOCK coverage simplifying the locking. - Uninline STAILQ_FOREACH_SAFE(). Tested by: sbruno Modified: head/sys/dev/firewire/sbp.c Modified: head/sys/dev/firewire/sbp.c ============================================================================== --- head/sys/dev/firewire/sbp.c Tue May 27 19:46:11 2014 (r266771) +++ head/sys/dev/firewire/sbp.c Tue May 27 19:56:02 2014 (r266772) @@ -177,7 +177,7 @@ struct sbp_ocb { struct sbp_dev *sdev; int flags; /* XXX should be removed */ bus_dmamap_t dmamap; - struct callout_handle timeout_ch; + struct callout timer; }; #define OCB_ACT_MGM 0 @@ -250,8 +250,9 @@ struct sbp_softc { int flags; struct mtx mtx; }; -#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx) -#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx) +#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx) +#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx) +#define SBP_LOCK_ASSERT(sbp) mtx_assert(&(sbp)->mtx, MA_OWNED) static void sbp_post_explore (void *); static void sbp_recv (struct fw_xfer *); @@ -265,7 +266,6 @@ static void sbp_execute_ocb (void *, bu static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *); static void sbp_abort_ocb (struct sbp_ocb *, int); static void sbp_abort_all_ocbs (struct sbp_dev *, int); -static struct fw_xfer * sbp_write_cmd_locked (struct sbp_dev *, int, int); static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int); static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *); static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *); @@ -337,7 +337,8 @@ SBP_DEBUG(0) printf("sbp_identify\n"); END_DEBUG - BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent)); + if (device_find_child(parent, "sbp", -1) == NULL) + BUS_ADD_CHILD(parent, 0, "sbp", -1); } /* @@ -346,17 +347,11 @@ END_DEBUG static int sbp_probe(device_t dev) { - device_t pa; SBP_DEBUG(0) printf("sbp_probe\n"); END_DEBUG - pa = device_get_parent(dev); - if(device_get_unit(dev) != device_get_unit(pa)){ - return(ENXIO); - } - device_set_desc(dev, "SBP-2/SCSI over FireWire"); #if 0 @@ -460,6 +455,7 @@ sbp_alloc_lun(struct sbp_target *target) int maxlun, lun, i; sbp = target->sbp; + SBP_LOCK_ASSERT(sbp); crom_init_context(&cc, target->fwdev->csrrom); /* XXX shoud parse appropriate unit directories only */ maxlun = -1; @@ -476,8 +472,7 @@ END_DEBUG crom_next(&cc); } if (maxlun < 0) - printf("%s:%d no LUN found\n", - device_get_nameunit(target->sbp->fd.dev), + device_printf(target->sbp->fd.dev, "%d no LUN found\n", target->target_id); maxlun ++; @@ -548,7 +543,7 @@ END_DEBUG sdev->lun_id = lun; sdev->target = target; STAILQ_INIT(&sdev->ocbs); - CALLOUT_INIT(&sdev->login_callout); + callout_init_mtx(&sdev->login_callout, &sbp->mtx, 0); sdev->status = SBP_DEV_RESET; new = 1; snprintf(sdev->bustgtlun, 32, "%s:%d:%d", @@ -592,7 +587,7 @@ END_DEBUG /* XXX */ goto next; } - callout_handle_init(&ocb->timeout_ch); + callout_init_mtx(&ocb->timer, &sbp->mtx, 0); sbp_free_ocb(sdev, ocb); } next: @@ -648,8 +643,8 @@ END_DEBUG STAILQ_INIT(&target->xferlist); target->n_xfer = 0; STAILQ_INIT(&target->mgm_ocb_queue); - CALLOUT_INIT(&target->mgm_ocb_timeout); - CALLOUT_INIT(&target->scan_callout); + callout_init_mtx(&target->mgm_ocb_timeout, &sbp->mtx, 0); + callout_init_mtx(&target->scan_callout, &sbp->mtx, 0); target->luns = NULL; target->num_lun = 0; @@ -693,6 +688,7 @@ static void sbp_login_callout(void *arg) { struct sbp_dev *sdev = (struct sbp_dev *)arg; + SBP_LOCK_ASSERT(sdev->target->sbp); sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL); } @@ -737,6 +733,7 @@ SBP_DEBUG(1) END_DEBUG sbp = target->sbp; + SBP_LOCK_ASSERT(sbp); sbp_alloc_lun(target); /* XXX untimeout mgm_ocb and dequeue */ @@ -746,10 +743,8 @@ END_DEBUG continue; if (alive && (sdev->status != SBP_DEV_DEAD)) { if (sdev->path != NULL) { - SBP_LOCK(sbp); xpt_freeze_devq(sdev->path, 1); sdev->freeze ++; - SBP_UNLOCK(sbp); } sbp_probe_lun(sdev); sbp_show_sdev_info(sdev); @@ -778,10 +773,8 @@ SBP_DEBUG(0) __func__); END_DEBUG if (sdev->path) { - SBP_LOCK(sbp); xpt_freeze_devq(sdev->path, 1); sdev->freeze ++; - SBP_UNLOCK(sbp); } sdev->status = SBP_DEV_RETRY; sbp_cam_detach_sdev(sdev); @@ -810,13 +803,13 @@ sbp_post_busreset(void *arg) SBP_DEBUG(0) printf("sbp_post_busreset\n"); END_DEBUG + SBP_LOCK(sbp); if ((sbp->sim->flags & SIMQ_FREEZED) == 0) { - SBP_LOCK(sbp); xpt_freeze_simq(sbp->sim, /*count*/1); sbp->sim->flags |= SIMQ_FREEZED; - SBP_UNLOCK(sbp); } microtime(&sbp->last_busreset); + SBP_UNLOCK(sbp); } static void @@ -837,6 +830,7 @@ END_DEBUG if (sbp_cold > 0) sbp_cold --; + SBP_LOCK(sbp); #if 0 /* * XXX don't let CAM the bus rest. @@ -887,7 +881,6 @@ END_DEBUG if (target->num_lun == 0) sbp_free_target(target); } - SBP_LOCK(sbp); xpt_release_simq(sbp->sim, /*run queue*/TRUE); sbp->sim->flags &= ~SIMQ_FREEZED; SBP_UNLOCK(sbp); @@ -896,16 +889,15 @@ END_DEBUG #if NEED_RESPONSE static void sbp_loginres_callback(struct fw_xfer *xfer){ - int s; struct sbp_dev *sdev; sdev = (struct sbp_dev *)xfer->sc; SBP_DEBUG(1) device_printf(sdev->target->sbp->fd.dev,"%s\n", __func__); END_DEBUG /* recycle */ - s = splfw(); + SBP_LOCK(sdev->target->sbp); STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link); - splx(s); + SBP_UNLOCK(sdev->target->sbp); return; } #endif @@ -914,15 +906,11 @@ static __inline void sbp_xfer_free(struct fw_xfer *xfer) { struct sbp_dev *sdev; - int s; sdev = (struct sbp_dev *)xfer->sc; fw_xfer_unload(xfer); - s = splfw(); - SBP_LOCK(sdev->target->sbp); + SBP_LOCK_ASSERT(sdev->target->sbp); STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link); - SBP_UNLOCK(sdev->target->sbp); - splx(s); } static void @@ -937,11 +925,13 @@ sbp_reset_start_callback(struct fw_xfer "%s: %s failed: resp=%d\n", __func__, sdev->bustgtlun, xfer->resp); } + SBP_LOCK(target->sbp); for (i = 0; i < target->num_lun; i++) { tsdev = target->luns[i]; if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN) sbp_login(tsdev); } + SBP_UNLOCK(target->sbp); } static void @@ -977,8 +967,9 @@ SBP_DEBUG(1) "%s:%s\n", __func__, sdev->bustgtlun); END_DEBUG resp = xfer->resp; + SBP_LOCK(sdev->target->sbp); sbp_xfer_free(xfer); - return; + SBP_UNLOCK(sdev->target->sbp); } static struct sbp_dev * @@ -1003,6 +994,7 @@ sbp_cam_scan_lun(struct cam_periph *peri sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr; target = sdev->target; + SBP_LOCK_ASSERT(target->sbp); SBP_DEBUG(0) device_printf(sdev->target->sbp->fd.dev, "%s:%s\n", __func__, sdev->bustgtlun); @@ -1033,6 +1025,7 @@ sbp_cam_scan_target(void *arg) struct sbp_dev *sdev; union ccb *ccb; + SBP_LOCK_ASSERT(target->sbp); sdev = sbp_next_dev(target, 0); if (sdev == NULL) { printf("sbp_cam_scan_target: nothing to do for target%d\n", @@ -1056,11 +1049,9 @@ END_DEBUG ccb->ccb_h.ccb_sdev_ptr = sdev; /* The scan is in progress now. */ - SBP_LOCK(target->sbp); xpt_action(ccb); xpt_release_devq(sdev->path, sdev->freeze, TRUE); sdev->freeze = 1; - SBP_UNLOCK(target->sbp); } static __inline void @@ -1081,6 +1072,7 @@ sbp_do_attach(struct fw_xfer *xfer) sdev = (struct sbp_dev *)xfer->sc; target = sdev->target; sbp = target->sbp; + SBP_LOCK(sbp); SBP_DEBUG(0) device_printf(sdev->target->sbp->fd.dev, "%s:%s\n", __func__, sdev->bustgtlun); @@ -1095,15 +1087,16 @@ END_DEBUG /* * Let CAM scan the bus if we are in the boot process. * XXX xpt_scan_bus cannot detect LUN larger than 0 - * if LUN 0 doesn't exists. + * if LUN 0 doesn't exist. */ if (sbp_cold > 0) { sdev->status = SBP_DEV_ATTACHED; + SBP_UNLOCK(sbp); return; } sbp_scan_dev(sdev); - return; + SBP_UNLOCK(sbp); } static void @@ -1121,13 +1114,13 @@ END_DEBUG "%s:%s resp=%d\n", __func__, sdev->bustgtlun, xfer->resp); } + SBP_LOCK(sdev->target->sbp); sbp_xfer_free(xfer); if (sdev->path) { - SBP_LOCK(sdev->target->sbp); xpt_release_devq(sdev->path, sdev->freeze, TRUE); sdev->freeze = 0; - SBP_UNLOCK(sdev->target->sbp); } + SBP_UNLOCK(sdev->target->sbp); } static void @@ -1136,6 +1129,7 @@ sbp_agent_reset(struct sbp_dev *sdev) struct fw_xfer *xfer; struct fw_pkt *fp; + SBP_LOCK_ASSERT(sdev->target->sbp); SBP_DEBUG(0) device_printf(sdev->target->sbp->fd.dev, "%s:%s\n", __func__, sdev->bustgtlun); @@ -1163,8 +1157,10 @@ SBP_DEBUG(1) device_printf(sdev->target->sbp->fd.dev, "%s:%s\n", __func__, sdev->bustgtlun); END_DEBUG + SBP_LOCK(sdev->target->sbp); sbp_xfer_free(xfer); sbp_agent_reset(sdev); + SBP_UNLOCK(sdev->target->sbp); } static void @@ -1200,9 +1196,9 @@ END_DEBUG /* XXX */ printf("%s: xfer->resp = %d\n", __func__, xfer->resp); } + SBP_LOCK(sdev->target->sbp); sbp_xfer_free(xfer); - SBP_LOCK(sdev->target->sbp); sdev->flags &= ~ORB_POINTER_ACTIVE; if ((sdev->flags & ORB_POINTER_NEED) != 0) { @@ -1229,7 +1225,7 @@ SBP_DEBUG(1) (uint32_t)ocb->bus_addr); END_DEBUG - mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); + SBP_LOCK_ASSERT(sdev->target->sbp); if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) { SBP_DEBUG(0) @@ -1240,7 +1236,7 @@ END_DEBUG } sdev->flags |= ORB_POINTER_ACTIVE; - xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQB, 0x08); + xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0x08); if (xfer == NULL) return; xfer->hand = sbp_orb_pointer_callback; @@ -1252,18 +1248,11 @@ END_DEBUG htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16)); xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr); - /* - * sbp_xfer_free() will attempt to acquire - * the SBP lock on entrance. Also, this removes - * a LOR between the firewire layer and sbp - */ - SBP_UNLOCK(sdev->target->sbp); - if(fw_asyreq(xfer->fc, -1, xfer) != 0){ - sbp_xfer_free(xfer); - ocb->ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ocb->ccb); + if (fw_asyreq(xfer->fc, -1, xfer) != 0) { + sbp_xfer_free(xfer); + ocb->ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ocb->ccb); } - SBP_LOCK(sdev->target->sbp); } static void @@ -1281,15 +1270,14 @@ END_DEBUG device_printf(sdev->target->sbp->fd.dev, "%s: xfer->resp = %d\n", __func__, xfer->resp); } + SBP_LOCK(sdev->target->sbp); sbp_xfer_free(xfer); sdev->flags &= ~ORB_DOORBELL_ACTIVE; if ((sdev->flags & ORB_DOORBELL_NEED) != 0) { sdev->flags &= ~ORB_DOORBELL_NEED; - SBP_LOCK(sdev->target->sbp); sbp_doorbell(sdev); - SBP_UNLOCK(sdev->target->sbp); } - return; + SBP_UNLOCK(sdev->target->sbp); } static void @@ -1307,7 +1295,7 @@ END_DEBUG return; } sdev->flags |= ORB_DOORBELL_ACTIVE; - xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQQ, 0x10); + xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x10); if (xfer == NULL) return; xfer->hand = sbp_doorbell_callback; @@ -1317,28 +1305,25 @@ END_DEBUG } static struct fw_xfer * -sbp_write_cmd_locked(struct sbp_dev *sdev, int tcode, int offset) +sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset) { struct fw_xfer *xfer; struct fw_pkt *fp; struct sbp_target *target; - int s, new = 0; + int new = 0; - mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); + SBP_LOCK_ASSERT(sdev->target->sbp); target = sdev->target; - s = splfw(); xfer = STAILQ_FIRST(&target->xferlist); if (xfer == NULL) { if (target->n_xfer > 5 /* XXX */) { printf("sbp: no more xfer for this target\n"); - splx(s); return(NULL); } xfer = fw_xfer_alloc_buf(M_SBP, 8, 0); if(xfer == NULL){ printf("sbp: fw_xfer_alloc_buf failed\n"); - splx(s); return NULL; } target->n_xfer ++; @@ -1348,7 +1333,6 @@ sbp_write_cmd_locked(struct sbp_dev *sde } else { STAILQ_REMOVE_HEAD(&target->xferlist, link); } - splx(s); if (new) { xfer->recv.pay_len = 0; @@ -1371,20 +1355,6 @@ sbp_write_cmd_locked(struct sbp_dev *sde fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst; return xfer; - -} - -static struct fw_xfer * -sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset) -{ - struct sbp_softc *sbp = sdev->target->sbp; - struct fw_xfer *xfer; - - SBP_LOCK(sbp); - xfer = sbp_write_cmd_locked(sdev, tcode, offset); - SBP_UNLOCK(sbp); - - return (xfer); } static void @@ -1394,31 +1364,24 @@ sbp_mgm_orb(struct sbp_dev *sdev, int fu struct fw_pkt *fp; struct sbp_ocb *ocb; struct sbp_target *target; - int s, nid; + int nid; target = sdev->target; nid = target->sbp->fd.fc->nodeid | FWLOCALBUS; - s = splfw(); - SBP_LOCK(target->sbp); + SBP_LOCK_ASSERT(target->sbp); if (func == ORB_FUN_RUNQUEUE) { ocb = STAILQ_FIRST(&target->mgm_ocb_queue); if (target->mgm_ocb_cur != NULL || ocb == NULL) { - SBP_UNLOCK(target->sbp); - splx(s); return; } STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb); - SBP_UNLOCK(target->sbp); goto start; } if ((ocb = sbp_get_ocb(sdev)) == NULL) { - SBP_UNLOCK(target->sbp); - splx(s); /* XXX */ return; } - SBP_UNLOCK(target->sbp); ocb->flags = OCB_ACT_MGM; ocb->sdev = sdev; @@ -1458,15 +1421,11 @@ END_DEBUG if (target->mgm_ocb_cur != NULL) { /* there is a standing ORB */ - SBP_LOCK(target->sbp); STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb); - SBP_UNLOCK(target->sbp); - splx(s); return; } start: target->mgm_ocb_cur = ocb; - splx(s); callout_reset(&target->mgm_ocb_timeout, 5*hz, sbp_mgm_timeout, (caddr_t)ocb); @@ -1677,6 +1636,7 @@ printf("sbp %08x %08x %08x %08x\n", ntoh printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11])); */ sbp = (struct sbp_softc *)xfer->sc; + SBP_LOCK_ASSERT(sbp); if (xfer->resp != 0){ printf("sbp_recv: xfer->resp = %d\n", xfer->resp); goto done0; @@ -1796,10 +1756,8 @@ END_DEBUG /* we have to reset the fetch agent if it's dead */ if (sbp_status->dead) { if (sdev->path) { - SBP_LOCK(sbp); xpt_freeze_devq(sdev->path, 1); sdev->freeze ++; - SBP_UNLOCK(sbp); } reset_agent = 1; } @@ -1904,9 +1862,7 @@ END_DEBUG /* fix up inq data */ if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY) sbp_fix_inq_data(ocb); - SBP_LOCK(sbp); xpt_done(ccb); - SBP_UNLOCK(sbp); } break; default: @@ -1945,22 +1901,19 @@ done0: fw_asyreq(xfer->fc, -1, xfer); #else /* recycle */ - /* we don't need a lock here because bottom half is serialized */ STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link); #endif - - return; - } static void sbp_recv(struct fw_xfer *xfer) { - int s; + struct sbp_softc *sbp; - s = splcam(); + sbp = (struct sbp_softc *)xfer->sc; + SBP_LOCK(sbp); sbp_recv1(xfer); - splx(s); + SBP_UNLOCK(sbp); } /* * sbp_attach() @@ -1971,7 +1924,7 @@ sbp_attach(device_t dev) struct sbp_softc *sbp; struct cam_devq *devq; struct firewire_comm *fc; - int i, s, error; + int i, error; if (DFLTPHYS > SBP_MAXPHYS) device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than " @@ -1987,8 +1940,7 @@ END_DEBUG if (cold) sbp_cold ++; - sbp = ((struct sbp_softc *)device_get_softc(dev)); - bzero(sbp, sizeof(struct sbp_softc)); + sbp = device_get_softc(dev); sbp->fd.dev = dev; sbp->fd.fc = fc = device_get_ivars(dev); mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF); @@ -2064,10 +2016,8 @@ END_DEBUG sbp->fd.post_explore = sbp_post_explore; if (fc->status != -1) { - s = splfw(); sbp_post_busreset((void *)sbp); sbp_post_explore((void *)sbp); - splx(s); } SBP_LOCK(sbp); xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL); @@ -2090,6 +2040,7 @@ sbp_logout_all(struct sbp_softc *sbp) SBP_DEBUG(0) printf("sbp_logout_all\n"); END_DEBUG + SBP_LOCK_ASSERT(sbp); for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) { target = &sbp->targets[i]; if (target->luns == NULL) @@ -2113,23 +2064,30 @@ sbp_shutdown(device_t dev) { struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev)); + SBP_LOCK(sbp); sbp_logout_all(sbp); + SBP_UNLOCK(sbp); return (0); } static void sbp_free_sdev(struct sbp_dev *sdev) { + struct sbp_softc *sbp; int i; if (sdev == NULL) return; - for (i = 0; i < SBP_QUEUE_LEN; i++) - bus_dmamap_destroy(sdev->target->sbp->dmat, - sdev->ocb[i].dmamap); - fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma); + sbp = sdev->target->sbp; + SBP_UNLOCK(sbp); + callout_drain(&sdev->login_callout); + for (i = 0; i < SBP_QUEUE_LEN; i++) { + callout_drain(&sdev->ocb[i].timer); + bus_dmamap_destroy(sbp->dmat, sdev->ocb[i].dmamap); + } + fwdma_free(sbp->fd.fc, &sdev->dma); free(sdev, M_SBP); - sdev = NULL; + SBP_LOCK(sbp); } static void @@ -2141,14 +2099,16 @@ sbp_free_target(struct sbp_target *targe if (target->luns == NULL) return; - callout_stop(&target->mgm_ocb_timeout); sbp = target->sbp; + SBP_LOCK_ASSERT(sbp); + SBP_UNLOCK(sbp); + callout_drain(&target->mgm_ocb_timeout); + callout_drain(&target->scan_callout); + SBP_LOCK(sbp); for (i = 0; i < target->num_lun; i++) sbp_free_sdev(target->luns[i]); - for (xfer = STAILQ_FIRST(&target->xferlist); - xfer != NULL; xfer = next) { - next = STAILQ_NEXT(xfer, link); + STAILQ_FOREACH_SAFE(xfer, &target->xferlist, link, next) { fw_xfer_free_buf(xfer); } STAILQ_INIT(&target->xferlist); @@ -2169,23 +2129,25 @@ SBP_DEBUG(0) printf("sbp_detach\n"); END_DEBUG + SBP_LOCK(sbp); for (i = 0; i < SBP_NUM_TARGETS; i ++) sbp_cam_detach_target(&sbp->targets[i]); - SBP_LOCK(sbp); xpt_async(AC_LOST_DEVICE, sbp->path, NULL); xpt_free_path(sbp->path); xpt_bus_deregister(cam_sim_path(sbp->sim)); cam_sim_free(sbp->sim, /*free_devq*/ TRUE); - SBP_UNLOCK(sbp); sbp_logout_all(sbp); + SBP_UNLOCK(sbp); /* XXX wait for logout completion */ pause("sbpdtc", hz/2); + SBP_LOCK(sbp); for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) sbp_free_target(&sbp->targets[i]); + SBP_UNLOCK(sbp); fw_bindremove(fc, &sbp->fwb); fw_xferlist_remove(&sbp->fwb.xferlist); @@ -2205,16 +2167,15 @@ sbp_cam_detach_sdev(struct sbp_dev *sdev return; if (sdev->status == SBP_DEV_RESET) return; + SBP_LOCK_ASSERT(sdev->target->sbp); sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE); if (sdev->path) { - SBP_LOCK(sdev->target->sbp); xpt_release_devq(sdev->path, sdev->freeze, TRUE); sdev->freeze = 0; xpt_async(AC_LOST_DEVICE, sdev->path, NULL); xpt_free_path(sdev->path); sdev->path = NULL; - SBP_UNLOCK(sdev->target->sbp); } } @@ -2223,6 +2184,7 @@ sbp_cam_detach_target(struct sbp_target { int i; + SBP_LOCK_ASSERT(target->sbp); if (target->luns != NULL) { SBP_DEBUG(0) printf("sbp_detach_target %d\n", target->target_id); @@ -2240,6 +2202,7 @@ sbp_target_reset(struct sbp_dev *sdev, i struct sbp_target *target = sdev->target; struct sbp_dev *tsdev; + SBP_LOCK_ASSERT(target->sbp); for (i = 0; i < target->num_lun; i++) { tsdev = target->luns[i]; if (tsdev == NULL) @@ -2248,10 +2211,8 @@ sbp_target_reset(struct sbp_dev *sdev, i continue; if (tsdev->status == SBP_DEV_RESET) continue; - SBP_LOCK(target->sbp); xpt_freeze_devq(tsdev->path, 1); tsdev->freeze ++; - SBP_UNLOCK(target->sbp); sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT); if (method == 2) tsdev->status = SBP_DEV_LOGIN; @@ -2276,6 +2237,7 @@ sbp_mgm_timeout(void *arg) struct sbp_dev *sdev = ocb->sdev; struct sbp_target *target = sdev->target; + SBP_LOCK_ASSERT(target->sbp); device_printf(sdev->target->sbp->fd.dev, "%s:%s request timeout(mgm orb:0x%08x)\n", __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr); @@ -2302,14 +2264,13 @@ sbp_timeout(void *arg) "%s:%s request timeout(cmd orb:0x%08x) ... ", __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr); + SBP_LOCK_ASSERT(sdev->target->sbp); sdev->timeout ++; switch(sdev->timeout) { case 1: printf("agent reset\n"); - SBP_LOCK(sdev->target->sbp); xpt_freeze_devq(sdev->path, 1); sdev->freeze ++; - SBP_UNLOCK(sdev->target->sbp); sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT); sbp_agent_reset(sdev); break; @@ -2331,13 +2292,15 @@ sbp_timeout(void *arg) } static void -sbp_action1(struct cam_sim *sim, union ccb *ccb) +sbp_action(struct cam_sim *sim, union ccb *ccb) { struct sbp_softc *sbp = (struct sbp_softc *)sim->softc; struct sbp_target *target = NULL; struct sbp_dev *sdev = NULL; + if (sbp != NULL) + SBP_LOCK_ASSERT(sbp); /* target:lun -> sdev mapping */ if (sbp != NULL && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD @@ -2459,10 +2422,8 @@ END_DEBUG if ((ocb = sbp_get_ocb(sdev)) == NULL) { ccb->ccb_h.status = CAM_RESRC_UNAVAIL; if (sdev->freeze == 0) { - SBP_LOCK(sdev->target->sbp); xpt_freeze_devq(sdev->path, 1); sdev->freeze ++; - SBP_UNLOCK(sdev->target->sbp); } xpt_done(ccb); return; @@ -2518,7 +2479,7 @@ printf("ORB %08x %08x %08x %08x\n", ntoh ccg = &ccb->ccg; if (ccg->block_size == 0) { - printf("sbp_action1: block_size is 0.\n"); + printf("sbp_action: block_size is 0.\n"); ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); break; @@ -2643,16 +2604,6 @@ END_DEBUG } static void -sbp_action(struct cam_sim *sim, union ccb *ccb) -{ - int s; - - s = splfw(); - sbp_action1(sim, ccb); - splx(s); -} - -static void sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error) { int i; @@ -2747,7 +2698,7 @@ sbp_dequeue_ocb(struct sbp_dev *sdev, st { struct sbp_ocb *ocb; struct sbp_ocb *next; - int s = splfw(), order = 0; + int order = 0; SBP_DEBUG(1) device_printf(sdev->target->sbp->fd.dev, @@ -2758,15 +2709,13 @@ SBP_DEBUG(1) #endif __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo), sbp_status->src); END_DEBUG - SBP_LOCK(sdev->target->sbp); - for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) { - next = STAILQ_NEXT(ocb, ocb); + SBP_LOCK_ASSERT(sdev->target->sbp); + STAILQ_FOREACH_SAFE(ocb, &sdev->ocbs, ocb, next) { if (OCB_MATCH(ocb, sbp_status)) { /* found */ STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb); if (ocb->ccb != NULL) - untimeout(sbp_timeout, (caddr_t)ocb, - ocb->timeout_ch); + callout_stop(&ocb->timer); if (ntohl(ocb->orb[4]) & 0xffff) { bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap, @@ -2795,9 +2744,7 @@ END_DEBUG * execution. */ if (sdev->last_ocb != NULL) { - SBP_UNLOCK(sdev->target->sbp); sbp_free_ocb(sdev, sdev->last_ocb); - SBP_LOCK(sdev->target->sbp); } sdev->last_ocb = ocb; if (next != NULL && @@ -2808,8 +2755,6 @@ END_DEBUG } else order ++; } - SBP_UNLOCK(sdev->target->sbp); - splx(s); SBP_DEBUG(0) if (ocb && order > 0) { device_printf(sdev->target->sbp->fd.dev, @@ -2823,10 +2768,9 @@ END_DEBUG static struct sbp_ocb * sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb) { - int s = splfw(); struct sbp_ocb *prev, *prev2; - mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); + SBP_LOCK_ASSERT(sdev->target->sbp); SBP_DEBUG(1) device_printf(sdev->target->sbp->fd.dev, #if defined(__DragonFly__) || __FreeBSD_version < 500000 @@ -2839,8 +2783,8 @@ END_DEBUG STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb); if (ocb->ccb != NULL) - ocb->timeout_ch = timeout(sbp_timeout, (caddr_t)ocb, - (ocb->ccb->ccb_h.timeout * hz) / 1000); + callout_reset(&ocb->timer, (ocb->ccb->ccb_h.timeout * hz) / 1000, + sbp_timeout, ocb); if (use_doorbell && prev == NULL) prev2 = sdev->last_ocb; @@ -2863,7 +2807,6 @@ END_DEBUG *(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr); *(volatile uint32_t *)&prev2->orb[0] = 0; } - splx(s); return prev; } @@ -2872,18 +2815,15 @@ static struct sbp_ocb * sbp_get_ocb(struct sbp_dev *sdev) { struct sbp_ocb *ocb; - int s = splfw(); - mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); + SBP_LOCK_ASSERT(sdev->target->sbp); ocb = STAILQ_FIRST(&sdev->free_ocbs); if (ocb == NULL) { sdev->flags |= ORB_SHORTAGE; printf("ocb shortage!!!\n"); - splx(s); return NULL; } STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb); - splx(s); ocb->ccb = NULL; return (ocb); } @@ -2894,7 +2834,7 @@ sbp_free_ocb(struct sbp_dev *sdev, struc ocb->flags = 0; ocb->ccb = NULL; - SBP_LOCK(sdev->target->sbp); + SBP_LOCK_ASSERT(sdev->target->sbp); STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb); if ((sdev->flags & ORB_SHORTAGE) != 0) { int count; @@ -2904,7 +2844,6 @@ sbp_free_ocb(struct sbp_dev *sdev, struc sdev->freeze = 0; xpt_release_devq(sdev->path, count, TRUE); } - SBP_UNLOCK(sdev->target->sbp); } static void @@ -2913,6 +2852,7 @@ sbp_abort_ocb(struct sbp_ocb *ocb, int s struct sbp_dev *sdev; sdev = ocb->sdev; + SBP_LOCK_ASSERT(sdev->target->sbp); SBP_DEBUG(0) device_printf(sdev->target->sbp->fd.dev, #if defined(__DragonFly__) || __FreeBSD_version < 500000 @@ -2932,12 +2872,9 @@ END_DEBUG bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap); } if (ocb->ccb != NULL) { - untimeout(sbp_timeout, (caddr_t)ocb, - ocb->timeout_ch); + callout_stop(&ocb->timer); ocb->ccb->ccb_h.status = status; - SBP_LOCK(sdev->target->sbp); xpt_done(ocb->ccb); - SBP_UNLOCK(sdev->target->sbp); } sbp_free_ocb(sdev, ocb); } @@ -2945,28 +2882,21 @@ END_DEBUG static void sbp_abort_all_ocbs(struct sbp_dev *sdev, int status) { - int s; struct sbp_ocb *ocb, *next; STAILQ_HEAD(, sbp_ocb) temp; - s = splfw(); - STAILQ_INIT(&temp); - SBP_LOCK(sdev->target->sbp); + SBP_LOCK_ASSERT(sdev->target->sbp); STAILQ_CONCAT(&temp, &sdev->ocbs); STAILQ_INIT(&sdev->ocbs); - SBP_UNLOCK(sdev->target->sbp); - for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) { - next = STAILQ_NEXT(ocb, ocb); + STAILQ_FOREACH_SAFE(ocb, &temp, ocb, next) { sbp_abort_ocb(ocb, status); } if (sdev->last_ocb != NULL) { sbp_free_ocb(sdev, sdev->last_ocb); sdev->last_ocb = NULL; } - - splx(s); } static devclass_t sbp_devclass;