Index: net/if_fwsubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_fwsubr.c,v retrieving revision 1.22 diff -u -r1.22 if_fwsubr.c --- net/if_fwsubr.c 22 Oct 2006 11:52:15 -0000 1.22 +++ net/if_fwsubr.c 1 May 2007 08:40:32 -0000 @@ -338,8 +338,6 @@ int fstart, fend, start, end, islast; uint32_t id; - GIANT_REQUIRED; - /* * Find an existing reassembly buffer or create a new one. */ @@ -502,8 +500,6 @@ union fw_encap *enc; int type, isr; - GIANT_REQUIRED; - /* * The caller has already stripped off the packet header * (stream or wreqb) and marked the mbuf's M_BCAST flag Index: dev/firewire/firewire.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/firewire.c,v retrieving revision 1.93 diff -u -r1.93 firewire.c --- dev/firewire/firewire.c 21 May 2007 02:18:49 -0000 1.93 +++ dev/firewire/firewire.c 21 May 2007 02:20:05 -0000 @@ -95,6 +95,7 @@ static int firewire_attach (device_t); static int firewire_detach (device_t); static int firewire_resume (device_t); +static void firewire_xfer_timeout(void *, int); #if 0 static int firewire_shutdown (device_t); #endif @@ -178,9 +179,11 @@ int s; s = splfw(); + FW_GLOCK(fc); STAILQ_FOREACH(fwdev, &fc->devices, link) if (FW_EUI64_EQUAL(fwdev->eui, *eui)) break; + FW_GUNLOCK(fc); splx(s); if(fwdev == NULL) return NULL; @@ -201,6 +204,7 @@ int tcode; struct tcode_info *info; + if(xfer == NULL) return EINVAL; if(xfer->hand == NULL){ printf("hand == NULL\n"); @@ -242,7 +246,7 @@ if(!(xferq->queued < xferq->maxq)){ device_printf(fc->bdev, "Discard a packet (queued=%d)\n", xferq->queued); - return EINVAL; + return EAGAIN; } if (info->flag & FWTI_TLABEL) { @@ -276,6 +280,8 @@ { struct firewire_comm *fc = xfer->fc; int s; + + #if 0 /* XXX allow bus explore packets only after bus rest */ if (fc->status < FWBUSEXPLORE) { xfer->resp = EAGAIN; @@ -285,11 +291,16 @@ return; } #endif - microtime(&xfer->tv); s = splfw(); + /* Protect from interrupt/timeout */ + FW_GLOCK(fc); + microtime(&xfer->tv); xfer->state = FWXF_INQ; STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link); +#if 0 xfer->q->queued ++; +#endif + FW_GUNLOCK(fc); splx(s); /* XXX just queue for mbuf */ if (xfer->mbuf == NULL) @@ -311,8 +322,9 @@ } static void -firewire_xfer_timeout(struct firewire_comm *fc) +firewire_xfer_timeout(void *arg, int pending) { + struct firewire_comm *fc = (struct firewire_comm *)arg; struct fw_xfer *xfer; struct timeval tv; struct timeval split_timeout; @@ -341,14 +353,15 @@ } } splx(s); + fc->timeout(fc); } -#define WATCHDOC_HZ 10 +#define WATCHDOG_HZ 10 static void firewire_watchdog(void *arg) { struct firewire_comm *fc; - static int watchdoc_clock = 0; + static int watchdog_clock = 0; fc = (struct firewire_comm *)arg; @@ -357,14 +370,19 @@ * We encounter a timeout easily. To avoid this, * ignore clock interrupt for a while. */ - if (watchdoc_clock > WATCHDOC_HZ * 15) { + if (watchdog_clock > WATCHDOG_HZ * 15) { +#if 0 firewire_xfer_timeout(fc); - fc->timeout(fc); +#else + taskqueue_enqueue(taskqueue_swi, &fc->task_timeout); +#endif } else - watchdoc_clock ++; + watchdog_clock ++; - callout_reset(&fc->timeout_callout, hz / WATCHDOC_HZ, +#if 0 + callout_reset(&fc->timeout_callout, hz / WATCHDOG_HZ, (void *)firewire_watchdog, (void *)fc); +#endif } /* @@ -388,9 +406,10 @@ fwdev_makedev(sc); - CALLOUT_INIT(&sc->fc->timeout_callout); - CALLOUT_INIT(&sc->fc->bmr_callout); - CALLOUT_INIT(&sc->fc->busprobe_callout); + CALLOUT_INIT(&fc->timeout_callout); + CALLOUT_INIT(&fc->bmr_callout); + CALLOUT_INIT(&fc->busprobe_callout); + TASK_INIT(&fc->task_timeout, 0, firewire_xfer_timeout, (void *)fc); callout_reset(&sc->fc->timeout_callout, hz, (void *)firewire_watchdog, (void *)sc->fc); @@ -501,7 +520,9 @@ while ((xfer = STAILQ_FIRST(&xferq->q)) != NULL) { STAILQ_REMOVE_HEAD(&xferq->q, link); +#if 0 xferq->queued --; +#endif xfer->resp = EAGAIN; xfer->state = FWXF_SENTERR; fw_xfer_done(xfer); @@ -513,10 +534,12 @@ { int i; + FW_GLOCK(fc); fw_xferq_drain(fc->atq); fw_xferq_drain(fc->ats); for(i = 0; i < fc->nisodma; i++) fw_xferq_drain(fc->it[i]); + FW_GUNLOCK(fc); } static void @@ -802,13 +825,18 @@ fw_bindlookup(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo) { u_int64_t addr; - struct fw_bind *tfw; + struct fw_bind *tfw, *r = NULL; + addr = ((u_int64_t)dest_hi << 32) | dest_lo; + FW_GLOCK(fc); STAILQ_FOREACH(tfw, &fc->binds, fclist) - if (BIND_CMP(addr, tfw) == 0) - return(tfw); - return(NULL); + if (BIND_CMP(addr, tfw) == 0) { + r = tfw; + break; + } + FW_GUNLOCK(fc); + return(r); } /* @@ -818,28 +846,29 @@ fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb) { struct fw_bind *tfw, *prev = NULL; + int r = 0; if (fwb->start > fwb->end) { printf("%s: invalid range\n", __func__); return EINVAL; } + FW_GLOCK(fc); STAILQ_FOREACH(tfw, &fc->binds, fclist) { if (fwb->end < tfw->start) break; prev = tfw; } - if (prev == NULL) { + if (prev == NULL) STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist); - return (0); - } - if (prev->end < fwb->start) { + else if (prev->end < fwb->start) STAILQ_INSERT_AFTER(&fc->binds, prev, fwb, fclist); - return (0); + else { + printf("%s: bind failed\n", __func__); + r = EBUSY; } - - printf("%s: bind failed\n", __func__); - return (EBUSY); + FW_GUNLOCK(fc); + return (r); } /* @@ -854,7 +883,9 @@ struct fw_bind *tfw; int s; + s = splfw(); + FW_GLOCK(fc); STAILQ_FOREACH(tfw, &fc->binds, fclist) if (tfw == fwb) { STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist); @@ -862,6 +893,7 @@ } printf("%s: no such binding\n", __func__); + FW_GUNLOCK(fc); splx(s); return (1); found: @@ -873,6 +905,7 @@ } STAILQ_INIT(&fwb->xferlist); #endif + FW_GUNLOCK(fc); splx(s); return 0; @@ -925,6 +958,7 @@ return; s = splfw(); + FW_GLOCK(fc); #if 1 /* make sure the label is allocated */ STAILQ_FOREACH(txfer, &fc->tlabels[xfer->tl], tlabel) if(txfer == xfer) @@ -932,12 +966,14 @@ if (txfer == NULL) { printf("%s: the xfer is not in the tlabel(%d)\n", __FUNCTION__, xfer->tl); + FW_GUNLOCK(fc); splx(s); return; } #endif STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel); + FW_GUNLOCK(fc); splx(s); return; } @@ -951,15 +987,18 @@ struct fw_xfer *xfer; int s = splfw(); + FW_GLOCK(fc); STAILQ_FOREACH(xfer, &fc->tlabels[tlabel], tlabel) if(xfer->send.hdr.mode.hdr.dst == node) { splx(s); if (firewire_debug > 2) printf("fw_tl2xfer: found tl=%d\n", tlabel); + FW_GUNLOCK(fc); return(xfer); } if (firewire_debug > 1) printf("fw_tl2xfer: not found tl=%d\n", tlabel); + FW_GUNLOCK(fc); splx(s); return(NULL); } @@ -1037,8 +1076,12 @@ if(xfer->state == FWXF_INQ){ printf("fw_xfer_free FWXF_INQ\n"); s = splfw(); + FW_GLOCK(xfer->fc); STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link); +#if 0 xfer->q->queued --; +#endif + FW_GUNLOCK(xfer->fc); splx(s); } if (xfer->fc != NULL) { @@ -1603,7 +1646,9 @@ int s; static uint32_t label = 0; + s = splfw(); + FW_GLOCK(fc); for( i = 0 ; i < 0x40 ; i ++){ label = (label + 1) & 0x3f; STAILQ_FOREACH(txfer, &fc->tlabels[label], tlabel) @@ -1612,6 +1657,7 @@ break; if(txfer == NULL) { STAILQ_INSERT_TAIL(&fc->tlabels[label], xfer, tlabel); + FW_GUNLOCK(fc); splx(s); if (firewire_debug > 1) printf("fw_get_tlabel: dst=%d tl=%d\n", @@ -1619,6 +1665,7 @@ return(label); } } + FW_GUNLOCK(fc); splx(s); if (firewire_debug > 1) @@ -2097,6 +2144,34 @@ return 0; } +int +fw_open_isodma(struct firewire_comm *fc, int tx) +{ + struct fw_xferq **xferqa; + struct fw_xferq *xferq; + int i; + + if (tx) + xferqa = &fc->it[0]; + else + xferqa = &fc->ir[0]; + + FW_GLOCK(fc); + for (i = 0; i < fc->nisodma; i ++) { + xferq = xferqa[i]; + if ((xferq->flag & FWXFERQ_OPEN) == 0) { + xferq->flag |= FWXFERQ_OPEN; + break; + } + } + if (i == fc->nisodma) { + printf("no free dma channel (tx=%d)\n", tx); + i = -1; + } + FW_GUNLOCK(fc); + return (i); +} + static int fw_modevent(module_t mode, int type, void *data) { Index: dev/firewire/firewirereg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/firewirereg.h,v retrieving revision 1.46 diff -u -r1.46 firewirereg.h --- dev/firewire/firewirereg.h 21 May 2007 02:18:50 -0000 1.46 +++ dev/firewire/firewirereg.h 21 May 2007 02:20:32 -0000 @@ -47,6 +47,8 @@ #endif #include +#include +#include #define splfw splimp @@ -145,6 +147,7 @@ struct callout busprobe_callout; struct callout bmr_callout; struct callout timeout_callout; + struct task task_timeout; uint32_t (*cyctimer) (struct firewire_comm *); void (*ibr) (struct firewire_comm *); uint32_t (*set_bmr) (struct firewire_comm *, uint32_t); @@ -160,9 +163,15 @@ void (*itx_post) (struct firewire_comm *, uint32_t *); struct tcode_info *tcode; bus_dma_tag_t dmat; + struct mtx mtx; }; #define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4]) +#define FW_GMTX(fc) (&(fc)->mtx) +#define FW_GLOCK(fc) mtx_lock(FW_GMTX(fc)) +#define FW_GUNLOCK(fc) mtx_unlock(FW_GMTX(fc)) +#define FW_GLOCK_ASSERT(fc) mtx_assert(FW_GMTX(fc), MA_OWNED) + struct fw_xferq { int flag; #define FWXFERQ_CHTAGMASK 0xff @@ -279,6 +288,7 @@ int fwdev_makedev (struct firewire_softc *); int fwdev_destroydev (struct firewire_softc *); void fwdev_clone (void *, struct ucred *, char *, int, struct cdev **); +int fw_open_isodma(struct firewire_comm *, int); extern int firewire_debug; extern devclass_t firewire_devclass; @@ -292,7 +302,7 @@ #if defined(__DragonFly__) || __FreeBSD_version < 500000 #define CALLOUT_INIT(x) callout_init(x) #else -#define CALLOUT_INIT(x) callout_init(x, 0 /* mpsafe */) +#define CALLOUT_INIT(x) callout_init(x, 1 /* mpsafe */) #endif #if defined(__DragonFly__) || __FreeBSD_version < 500000 Index: dev/firewire/fwdev.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/fwdev.c,v retrieving revision 1.51 diff -u -r1.51 fwdev.c --- dev/firewire/fwdev.c 30 Apr 2007 13:41:40 -0000 1.51 +++ dev/firewire/fwdev.c 8 May 2007 05:22:52 -0000 @@ -98,7 +98,7 @@ .d_mmap = fw_mmap, .d_strategy = fw_strategy, .d_name = "fw", - .d_flags = D_MEM | D_NEEDGIANT + .d_flags = D_MEM #else #define CDEV_MAJOR 127 fw_open, fw_close, fw_read, fw_write, fw_ioctl, @@ -191,8 +191,22 @@ if (DEV_FWMEM(dev)) return fwmem_open(dev, flags, fmt, td); - if (dev->si_drv1 != NULL) + sc = devclass_get_softc(firewire_devclass, unit); + if (sc == NULL) + return (ENXIO); + + FW_GLOCK(sc->fc); + if (dev->si_drv1 != NULL) { + FW_GUNLOCK(sc->fc); return (EBUSY); + } + /* set dummy value for allocation */ + dev->si_drv1 = (void *)-1; + FW_GUNLOCK(sc->fc); + + dev->si_drv1 = malloc(sizeof(struct fw_drv1), M_FW, M_WAITOK | M_ZERO); + if (dev->si_drv1 == NULL) + return (ENOMEM); #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 if ((dev->si_flags & SI_NAMED) == 0) { @@ -204,13 +218,7 @@ "fw%d.%d", unit, sub); } #endif - - dev->si_drv1 = malloc(sizeof(struct fw_drv1), M_FW, M_WAITOK | M_ZERO); - if (dev->si_drv1 == NULL) - return (ENOMEM); - d = (struct fw_drv1 *)dev->si_drv1; - sc = devclass_get_softc(firewire_devclass, unit); d->fc = sc->fc; STAILQ_INIT(&d->binds); STAILQ_INIT(&d->rq); @@ -296,14 +304,18 @@ struct fw_pkt *fp; struct tcode_info *tinfo; + FW_GLOCK(d->fc); while ((xfer = STAILQ_FIRST(&d->rq)) == NULL && err == 0) - err = tsleep(&d->rq, FWPRI, "fwra", 0); + err = msleep(&d->rq, FW_GMTX(d->fc), FWPRI, "fwra", 0); - if (err != 0) + if (err != 0) { + FW_GUNLOCK(d->fc); return (err); + } s = splfw(); STAILQ_REMOVE_HEAD(&d->rq, link); + FW_GUNLOCK(xfer->fc); splx(s); fp = &xfer->recv.hdr; #if 0 /* for GASP ?? */ @@ -321,7 +333,9 @@ fwb = (struct fw_bind *)xfer->sc; fw_xfer_unload(xfer); xfer->recv.pay_len = PAGE_SIZE; + FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&fwb->xferlist, xfer, link); + FW_GUNLOCK(xfer->fc); return (err); } @@ -338,19 +352,22 @@ struct fw_pkt *fp; if (DEV_FWMEM(dev)) - return physio(dev, uio, ioflag); - + return (physio(dev, uio, ioflag)); d = (struct fw_drv1 *)dev->si_drv1; fc = d->fc; ir = d->ir; - if (ir == NULL) - return (fw_read_async(d, uio, ioflag)); - - if (ir->buf == NULL) - return (EIO); + if (ir == NULL) { + err = fw_read_async(d, uio, ioflag); + goto out; + } + if (ir->buf == NULL) { + err = EIO; + goto out; + } + FW_GLOCK(fc); readloop: if (ir->stproc == NULL) { /* iso bulkxfer */ @@ -367,22 +384,24 @@ if (slept == 0) { slept = 1; ir->flag |= FWXFERQ_WAKEUP; - err = tsleep(ir, FWPRI, "fw_read", hz); + err = msleep(ir, FW_GMTX(fc), FWPRI, "fw_read", hz); ir->flag &= ~FWXFERQ_WAKEUP; if (err == 0) goto readloop; } else if (slept == 1) err = EIO; - return err; + FW_GUNLOCK(fc); + goto out; } else if(ir->stproc != NULL) { /* iso bulkxfer */ + FW_GUNLOCK(fc); fp = (struct fw_pkt *)fwdma_v_addr(ir->buf, ir->stproc->poffset + ir->queued); if(fc->irx_post != NULL) fc->irx_post(fc, fp->mode.ld); if(fp->mode.stream.len == 0){ err = EIO; - return err; + goto out; } err = uiomove((caddr_t)fp, fp->mode.stream.len + sizeof(uint32_t), uio); @@ -396,9 +415,11 @@ } if (uio->uio_resid >= ir->psize) { slept = -1; + FW_GLOCK(fc); goto readloop; } } +out: return err; } @@ -438,7 +459,7 @@ if ((err = fw_asyreq(xfer->fc, -1, xfer))) goto out; - if ((err = tsleep(xfer, FWPRI, "fwwa", 0))) + if ((err = tsleep(xfer, FWPRI, "fwwa", hz))) goto out; if (xfer->resp != 0) { @@ -447,7 +468,9 @@ } if (xfer->state == FWXF_RCVD) { + FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&d->rq, xfer, link); + FW_GUNLOCK(xfer->fc); return (0); } @@ -467,17 +490,22 @@ struct fw_xferq *it; if (DEV_FWMEM(dev)) - return physio(dev, uio, ioflag); + return (physio(dev, uio, ioflag)); d = (struct fw_drv1 *)dev->si_drv1; fc = d->fc; it = d->it; - if (it == NULL) - return (fw_write_async(d, uio, ioflag)); + if (it == NULL) { + err = fw_write_async(d, uio, ioflag); + goto out; + } + if (it->buf == NULL) { + err = EIO; + goto out; + } - if (it->buf == NULL) - return (EIO); + FW_GLOCK(fc); isoloop: if (it->stproc == NULL) { it->stproc = STAILQ_FIRST(&it->stfree); @@ -488,18 +516,20 @@ it->queued = 0; } else if (slept == 0) { slept = 1; +#if 0 err = fc->itx_enable(fc, it->dmach); if (err) - return err; - err = tsleep(it, FWPRI, "fw_write", hz); - if (err) - return err; - goto isoloop; - } else { + goto out; +#endif + err = msleep(it, FW_GMTX(fc), FWPRI, "fw_write", hz); + if (err == 0) + goto isoloop; + } else err = EIO; - return err; - } + FW_GUNLOCK(fc); + goto out; } + FW_GUNLOCK(fc); fp = (struct fw_pkt *)fwdma_v_addr(it->buf, it->stproc->poffset + it->queued); err = uiomove((caddr_t)fp, sizeof(struct fw_isohdr), uio); @@ -515,8 +545,11 @@ } if (uio->uio_resid >= sizeof(struct fw_isohdr)) { slept = 0; + FW_GLOCK(fc); goto isoloop; } + +out: return err; } @@ -528,7 +561,9 @@ fwb = (struct fw_bind *)xfer->sc; d = (struct fw_drv1 *)fwb->sc; + FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&d->rq, xfer, link); + FW_GUNLOCK(xfer->fc); wakeup(&d->rq); } @@ -570,19 +605,17 @@ switch (cmd) { case FW_STSTREAM: if (it == NULL) { - for (i = 0; i < fc->nisodma; i ++) { - it = fc->it[i]; - if ((it->flag & FWXFERQ_OPEN) == 0) - break; - } - if (i >= fc->nisodma) { + i = fw_open_isodma(fc, /* tx */1); + if (i < 0) { err = EBUSY; break; } + it = fc->it[i]; err = fwdev_allocbuf(fc, it, &d->bufreq.tx); - if (err) + if (err) { + it->flag &= ~FWXFERQ_OPEN; break; - it->flag |= FWXFERQ_OPEN; + } } it->flag &= ~0xff; it->flag |= (0x3f & ichreq->ch); @@ -598,19 +631,17 @@ break; case FW_SRSTREAM: if (ir == NULL) { - for (i = 0; i < fc->nisodma; i ++) { - ir = fc->ir[i]; - if ((ir->flag & FWXFERQ_OPEN) == 0) - break; - } - if (i >= fc->nisodma) { + i = fw_open_isodma(fc, /* tx */1); + if (i < 0) { err = EBUSY; break; } + ir = fc->ir[i]; err = fwdev_allocbuf(fc, ir, &d->bufreq.rx); - if (err) + if (err) { + ir->flag &= ~FWXFERQ_OPEN; break; - ir->flag |= FWXFERQ_OPEN; + } } ir->flag &= ~0xff; ir->flag |= (0x3f & ichreq->ch); @@ -654,8 +685,10 @@ pay_len = MAX(0, asyreq->req.len - tinfo->hdr_len); xfer = fw_xfer_alloc_buf(M_FWXFER, pay_len, PAGE_SIZE/*XXX*/); - if (xfer == NULL) - return (ENOMEM); + if (xfer == NULL) { + err = ENOMEM; + goto out2; + } switch (asyreq->req.type) { case FWASREQNODE: @@ -742,7 +775,7 @@ err = EINVAL; break; } - fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_NOWAIT); + fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_WAITOK); if(fwb == NULL){ err = ENOMEM; break; @@ -823,6 +856,7 @@ fc->ioctl (dev, cmd, data, flag, td); break; } +out2: return err; } int Index: dev/firewire/fwdma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/fwdma.c,v retrieving revision 1.8 diff -u -r1.8 fwdma.c --- dev/firewire/fwdma.c 16 Apr 2007 12:31:35 -0000 1.8 +++ dev/firewire/fwdma.c 30 Apr 2007 14:44:49 -0000 @@ -92,7 +92,7 @@ /*flags*/ BUS_DMA_ALLOCNOW, #if defined(__FreeBSD__) && __FreeBSD_version >= 501102 /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, + /*lockarg*/FW_GMTX(fc), #endif &dma->dma_tag); if (err) { @@ -190,7 +190,7 @@ /*flags*/ BUS_DMA_ALLOCNOW, #if defined(__FreeBSD__) && __FreeBSD_version >= 501102 /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, + /*lockarg*/FW_GMTX(fc), #endif &am->dma_tag)) { printf("fwdma_malloc_multiseg: tag_create failed\n"); Index: dev/firewire/fwmem.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/fwmem.c,v retrieving revision 1.33 diff -u -r1.33 fwmem.c --- dev/firewire/fwmem.c 16 Mar 2007 05:39:33 -0000 1.33 +++ dev/firewire/fwmem.c 10 May 2007 02:22:42 -0000 @@ -90,6 +90,7 @@ struct fwmem_softc { struct fw_eui64 eui; + struct firewire_softc *sc; int refcount; }; @@ -276,26 +277,39 @@ fwmem_open (struct cdev *dev, int flags, int fmt, fw_proc *td) { struct fwmem_softc *fms; + struct firewire_softc *sc; + int unit = DEV2UNIT(dev); + + sc = devclass_get_softc(firewire_devclass, unit); + if (sc == NULL) + return (ENXIO); + FW_GLOCK(sc->fc); if (dev->si_drv1 != NULL) { - if ((flags & FWRITE) != 0) - return (EBUSY); + if ((flags & FWRITE) != 0) { + FW_GUNLOCK(sc->fc); + return(EBUSY); + } + FW_GUNLOCK(sc->fc); fms = (struct fwmem_softc *)dev->si_drv1; fms->refcount ++; } else { - fms = (struct fwmem_softc *)malloc(sizeof(struct fwmem_softc), - M_FWMEM, M_WAITOK); - if (fms == NULL) - return ENOMEM; - bcopy(&fwmem_eui64, &fms->eui, sizeof(struct fw_eui64)); - dev->si_drv1 = (void *)fms; + dev->si_drv1 = (void *)-1; + FW_GUNLOCK(sc->fc); + dev->si_drv1 = malloc(sizeof(struct fwmem_softc), + M_FWMEM, M_WAITOK); + if (dev->si_drv1 == NULL) + return(ENOMEM); dev->si_iosize_max = DFLTPHYS; + fms = (struct fwmem_softc *)dev->si_drv1; + bcopy(&fwmem_eui64, &fms->eui, sizeof(struct fw_eui64)); + fms->sc = sc; fms->refcount = 1; } if (fwmem_debug) printf("%s: refcount=%d\n", __func__, fms->refcount); - return (0); + return(0); } int @@ -304,7 +318,10 @@ struct fwmem_softc *fms; fms = (struct fwmem_softc *)dev->si_drv1; + + FW_GLOCK(fms->sc->fc); fms->refcount --; + FW_GUNLOCK(fms->sc->fc); if (fwmem_debug) printf("%s: refcount=%d\n", __func__, fms->refcount); if (fms->refcount < 1) { @@ -338,22 +355,21 @@ void fwmem_strategy(struct bio *bp) { - struct firewire_softc *sc; + struct firewire_comm *fc; struct fwmem_softc *fms; struct fw_device *fwdev; struct fw_xfer *xfer; struct cdev *dev; - int unit, err=0, s, iolen; + int err=0, s, iolen; dev = bp->bio_dev; /* XXX check request length */ - unit = DEV2UNIT(dev); - sc = devclass_get_softc(firewire_devclass, unit); - s = splfw(); fms = (struct fwmem_softc *)dev->si_drv1; - fwdev = fw_noderesolve_eui64(sc->fc, &fms->eui); + fc = fms->sc->fc; + + fwdev = fw_noderesolve_eui64(fc, &fms->eui); if (fwdev == NULL) { if (fwmem_debug) printf("fwmem: no such device ID:%08x%08x\n", @@ -411,6 +427,7 @@ int err = 0; fms = (struct fwmem_softc *)dev->si_drv1; + switch (cmd) { case FW_SDEUI64: bcopy(data, &fms->eui, sizeof(struct fw_eui64)); @@ -421,6 +438,7 @@ default: err = EINVAL; } + return(err); } int Index: dev/firewire/fwohci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/fwohci.c,v retrieving revision 1.89 diff -u -r1.89 fwohci.c --- dev/firewire/fwohci.c 30 Apr 2007 14:06:30 -0000 1.89 +++ dev/firewire/fwohci.c 11 May 2007 01:28:13 -0000 @@ -264,6 +264,7 @@ /* * Communication with PHY device */ +/* XXX need lock for phy access */ static uint32_t fwphy_wrdata( struct fwohci_softc *sc, uint32_t addr, uint32_t data) { @@ -561,6 +562,7 @@ /* Force to start async RX DMA */ sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING; sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING; + fwohci_rx_enable(sc, &sc->arrq); fwohci_rx_enable(sc, &sc->arrs); @@ -860,6 +862,8 @@ struct tcode_info *info; static int maxdesc=0; + FW_GLOCK_ASSERT(&sc->fc); + if(&sc->atrq == dbch){ off = OHCI_ATQOFF; }else if(&sc->atrs == dbch){ @@ -878,9 +882,11 @@ if(xfer == NULL){ goto kick; } +#if 0 if(dbch->xferq.queued == 0 ){ device_printf(sc->fc.dev, "TX queue empty\n"); } +#endif STAILQ_REMOVE_HEAD(&dbch->xferq.q, link); db_tr->xfer = xfer; xfer->state = FWXF_START; @@ -993,6 +999,7 @@ LAST_DB(dbch->pdb_tr, db); FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt); } + dbch->xferq.queued ++; dbch->pdb_tr = db_tr; db_tr = STAILQ_NEXT(db_tr, link); if(db_tr != dbch->bottom){ @@ -1026,7 +1033,9 @@ fwohci_start_atq(struct firewire_comm *fc) { struct fwohci_softc *sc = (struct fwohci_softc *)fc; + FW_GLOCK(&sc->fc); fwohci_start( sc, &(sc->atrq)); + FW_GUNLOCK(&sc->fc); return; } @@ -1034,7 +1043,9 @@ fwohci_start_ats(struct firewire_comm *fc) { struct fwohci_softc *sc = (struct fwohci_softc *)fc; + FW_GLOCK(&sc->fc); fwohci_start( sc, &(sc->atrs)); + FW_GUNLOCK(&sc->fc); return; } @@ -1150,7 +1161,9 @@ } else { printf("this shouldn't happen\n"); } + FW_GLOCK(fc); dbch->xferq.queued --; + FW_GUNLOCK(fc); tr->xfer = NULL; packets ++; @@ -1167,7 +1180,9 @@ if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) { printf("make free slot\n"); dbch->flags &= ~FWOHCI_DBCH_FULL; + FW_GLOCK(fc); fwohci_start(sc, dbch); + FW_GUNLOCK(fc); } splx(s); } @@ -1221,7 +1236,7 @@ /*flags*/ 0, #if defined(__FreeBSD__) && __FreeBSD_version >= 501102 /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, + /*lockarg*/FW_GMTX(&sc->fc), #endif &dbch->dmat)) return; @@ -1508,6 +1523,7 @@ fwohci_db_init(sc, dbch); if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) return ENOMEM; + err = fwohci_tx_enable(sc, dbch); } if(err) @@ -1515,6 +1531,7 @@ ldesc = dbch->ndesc - 1; s = splfw(); + FW_GLOCK(fc); prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link); while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) { struct fwohcidb *db; @@ -1541,6 +1558,7 @@ STAILQ_INSERT_TAIL(&it->stdma, chunk, link); prev = chunk; } + FW_GUNLOCK(fc); fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE); fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD); splx(s); @@ -1642,6 +1660,7 @@ ldesc = dbch->ndesc - 1; s = splfw(); + FW_GLOCK(fc); prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link); while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) { struct fwohcidb *db; @@ -1669,6 +1688,7 @@ STAILQ_INSERT_TAIL(&ir->stdma, chunk, link); prev = chunk; } + FW_GUNLOCK(fc); fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE); fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD); splx(s); @@ -2074,7 +2094,7 @@ atomic_set_int(&sc->intstat, stat); /* XXX mask bus reset intr. during bus reset phase */ if (stat) - taskqueue_enqueue(taskqueue_swi_giant, &sc->fwohci_task_complete); + taskqueue_enqueue(taskqueue_swi, &sc->fwohci_task_complete); #else /* We cannot clear bus reset event during bus reset phase */ if ((stat & ~bus_reset) == 0) @@ -2141,6 +2161,7 @@ it = fc->it[dmach]; ldesc = sc->it[dmach].ndesc - 1; s = splfw(); /* unnecessary ? */ + FW_GLOCK(fc); fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD); if (firewire_debug) dump_db(sc, ITX_CH + dmach); @@ -2169,6 +2190,7 @@ STAILQ_INSERT_TAIL(&it->stfree, chunk, link); w++; } + FW_GUNLOCK(fc); splx(s); if (w) wakeup(it); @@ -2190,6 +2212,7 @@ dump_db(sc, dmach); #endif s = splfw(); + FW_GLOCK(fc); fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD); while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) { db_tr = (struct fwohcidb_tr *)chunk->end; @@ -2224,6 +2247,7 @@ } w++; } + FW_GUNLOCK(fc); splx(s); if (w) { if (ir->flag & FWXFERQ_HANDLER) @@ -2487,6 +2511,8 @@ unsigned short chtag; int idb; + FW_GLOCK_ASSERT(&sc->fc); + dbch = &sc->it[dmach]; chtag = sc->it[dmach].xferq.flag & 0xff; Index: dev/firewire/fwohci_pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/fwohci_pci.c,v retrieving revision 1.59 diff -u -r1.59 fwohci_pci.c --- dev/firewire/fwohci_pci.c 30 Mar 2007 22:25:26 -0000 1.59 +++ dev/firewire/fwohci_pci.c 11 May 2007 01:52:56 -0000 @@ -302,6 +302,7 @@ firewire_debug = bootverbose; #endif + mtx_init(FW_GMTX(&sc->fc), "firewire", NULL, MTX_DEF); fwohci_pci_init(self); rid = PCI_CBMEM; @@ -376,7 +377,7 @@ /*flags*/BUS_DMA_ALLOCNOW, #if defined(__FreeBSD__) && __FreeBSD_version >= 501102 /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, + /*lockarg*/FW_GMTX(&sc->fc), #endif &sc->fc.dmat); if (err != 0) { @@ -409,9 +410,10 @@ s = splfw(); +#if 1 if (sc->bsr) fwohci_stop(sc, self); - +#endif bus_generic_detach(self); if (sc->fc.bdev) { device_delete_child(self, sc->fc.bdev); @@ -448,6 +450,7 @@ } fwohci_detach(sc, self); + mtx_destroy(FW_GMTX(&sc->fc)); splx(s); return 0; Index: dev/firewire/if_fwe.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/if_fwe.c,v retrieving revision 1.43 diff -u -r1.43 if_fwe.c --- dev/firewire/if_fwe.c 16 Mar 2007 05:39:33 -0000 1.43 +++ dev/firewire/if_fwe.c 11 May 2007 01:28:45 -0000 @@ -74,6 +74,9 @@ /* network interface */ static void fwe_start (struct ifnet *); +#if 0 +static void fwe_start_locked (struct ifnet *); +#endif static int fwe_ioctl (struct ifnet *, u_long, caddr_t); static void fwe_init (void *); @@ -157,6 +160,7 @@ unit = device_get_unit(dev); bzero(fwe, sizeof(struct fwe_softc)); + mtx_init(&fwe->mtx, "fwe", NULL, MTX_DEF); /* XXX */ fwe->stream_ch = stream_ch; fwe->dma_ch = -1; @@ -213,8 +217,7 @@ ifp->if_start = fwe_start; ifp->if_ioctl = fwe_ioctl; ifp->if_mtu = ETHERMTU; - ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST| - IFF_NEEDSGIANT); + ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE; s = splimp(); @@ -305,6 +308,7 @@ #endif splx(s); + mtx_destroy(&fwe->mtx); return 0; } @@ -325,22 +329,15 @@ ifp->if_flags |= IFF_PROMISC; fc = fwe->fd.fc; -#define START 0 if (fwe->dma_ch < 0) { - for (i = START; i < fc->nisodma; i ++) { - xferq = fc->ir[i]; - if ((xferq->flag & FWXFERQ_OPEN) == 0) - goto found; - } - printf("no free dma channel\n"); - return; -found: - fwe->dma_ch = i; + fwe->dma_ch = fw_open_isodma(fc, /* tx */0); + if (fwe->dma_ch < 0) + return; + xferq = fc->ir[fwe->dma_ch]; + xferq->flag |= FWXFERQ_EXTBUF | + FWXFERQ_HANDLER | FWXFERQ_STREAM; fwe->stream_ch = stream_ch; fwe->pkt_hdr.mode.stream.chtag = fwe->stream_ch; - /* allocate DMA channel and init packet mode */ - xferq->flag |= FWXFERQ_OPEN | FWXFERQ_EXTBUF | - FWXFERQ_HANDLER | FWXFERQ_STREAM; xferq->flag &= ~0xff; xferq->flag |= fwe->stream_ch & 0xff; /* register fwe_input handler */ @@ -520,7 +517,9 @@ fw_xfer_unload(xfer); s = splimp(); + FWE_LOCK(fwe); STAILQ_INSERT_TAIL(&fwe->xferlist, xfer, link); + FWE_UNLOCK(fwe); splx(s); /* for queue full */ @@ -534,8 +533,6 @@ struct fwe_softc *fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe; int s; - GIANT_REQUIRED; - FWEDEBUG(ifp, "starting\n"); if (fwe->dma_ch < 0) { @@ -590,15 +587,18 @@ xfer = NULL; xferq = fwe->fd.fc->atq; while (xferq->queued < xferq->maxq - 1) { + IF_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + FWE_LOCK(fwe); xfer = STAILQ_FIRST(&fwe->xferlist); if (xfer == NULL) { printf("if_fwe: lack of xfer\n"); + FWE_UNLOCK(fwe); return; } - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; STAILQ_REMOVE_HEAD(&fwe->xferlist, link); + FWE_UNLOCK(fwe); #if defined(__DragonFly__) || __FreeBSD_version < 500000 if (ifp->if_bpf != NULL) bpf_mtap(ifp, m); @@ -649,6 +649,7 @@ fwe = (struct fwe_softc *)xferq->sc; ifp = fwe->eth_softc.ifp; + /* We do not need a lock here because the bottom half is serialized */ while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) { STAILQ_REMOVE_HEAD(&xferq->stvalid, link); fp = mtod(sxfer->mbuf, struct fw_pkt *); Index: dev/firewire/if_fwevar.h =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/if_fwevar.h,v retrieving revision 1.5 diff -u -r1.5 if_fwevar.h --- dev/firewire/if_fwevar.h 10 Jun 2005 16:49:08 -0000 1.5 +++ dev/firewire/if_fwevar.h 8 May 2007 00:57:22 -0000 @@ -38,7 +38,7 @@ #define _NET_IF_FWEVAR_H_ struct fwe_softc { - /* XXX this must be first for fd.post_explore() */ + /* XXX this must be the first for fd.post_explore() */ struct firewire_dev_comm fd; short stream_ch; short dma_ch; @@ -48,5 +48,8 @@ struct ifnet *ifp; struct fwe_softc *fwe; } eth_softc; + struct mtx mtx; }; +#define FWE_LOCK(fwe) mtx_lock(&(fwe)->mtx) +#define FWE_UNLOCK(fwe) mtx_unlock(&(fwe)->mtx) #endif /* !_NET_IF_FWEVAR_H_ */ Index: dev/firewire/if_fwip.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/if_fwip.c,v retrieving revision 1.15 diff -u -r1.15 if_fwip.c --- dev/firewire/if_fwip.c 30 Apr 2007 13:41:40 -0000 1.15 +++ dev/firewire/if_fwip.c 15 May 2007 14:40:51 -0000 @@ -161,6 +161,7 @@ if (ifp == NULL) return (ENOSPC); + mtx_init(&fwip->mtx, "fwip", NULL, MTX_DEF); /* XXX */ fwip->dma_ch = -1; @@ -197,8 +198,7 @@ ifp->if_init = fwip_init; ifp->if_start = fwip_start; ifp->if_ioctl = fwip_ioctl; - ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST| - IFF_NEEDSGIANT); + ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE; #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; @@ -282,6 +282,7 @@ fwip_stop(fwip); firewire_ifdetach(ifp); if_free(ifp); + mtx_destroy(&fwip->mtx); splx(s); return 0; @@ -303,17 +304,11 @@ fc = fwip->fd.fc; #define START 0 if (fwip->dma_ch < 0) { - for (i = START; i < fc->nisodma; i ++) { - xferq = fc->ir[i]; - if ((xferq->flag & FWXFERQ_OPEN) == 0) - goto found; - } - printf("no free dma channel\n"); - return; -found: - fwip->dma_ch = i; - /* allocate DMA channel and init packet mode */ - xferq->flag |= FWXFERQ_OPEN | FWXFERQ_EXTBUF | + fwip->dma_ch = fw_open_isodma(fc, /* tx */0); + if (fwip->dma_ch < 0) + return; + xferq = fc->ir[fwip->dma_ch]; + xferq->flag |= FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_STREAM; xferq->flag &= ~0xff; xferq->flag |= broadcast_channel & 0xff; @@ -390,8 +385,9 @@ fwip->last_dest.lo = 0; /* start dma */ - if ((xferq->flag & FWXFERQ_RUNNING) == 0) + if ((xferq->flag & FWXFERQ_RUNNING) == 0) { fc->irx_enable(fc, fwip->dma_ch); + } #if defined(__FreeBSD__) ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -522,8 +518,6 @@ struct ifnet *ifp; int s; - GIANT_REQUIRED; - fwip = (struct fwip_softc *)xfer->sc; ifp = fwip->fw_softc.fwip_ifp; /* XXX error check */ @@ -535,12 +529,15 @@ fw_xfer_unload(xfer); s = splimp(); + FWIP_LOCK(fwip); STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link); + FWIP_UNLOCK(fwip); splx(s); /* for queue full */ - if (ifp->if_snd.ifq_head != NULL) + if (ifp->if_snd.ifq_head != NULL) { fwip_start(ifp); + } } static void @@ -549,8 +546,6 @@ struct fwip_softc *fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip; int s; - GIANT_REQUIRED; - FWIPDEBUG(ifp, "starting\n"); if (fwip->dma_ch < 0) { @@ -571,20 +566,8 @@ } s = splimp(); -#if defined(__FreeBSD__) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; -#else - ifp->if_flags |= IFF_OACTIVE; -#endif - if (ifp->if_snd.ifq_len != 0) fwip_async_output(fwip, ifp); - -#if defined(__FreeBSD__) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -#else - ifp->if_flags &= ~IFF_OACTIVE; -#endif splx(s); } @@ -603,19 +586,23 @@ int error; int i = 0; - GIANT_REQUIRED; - xfer = NULL; - xferq = fwip->fd.fc->atq; + xferq = fc->atq; while (xferq->queued < xferq->maxq - 1) { + FWIP_LOCK(fwip); xfer = STAILQ_FIRST(&fwip->xferlist); if (xfer == NULL) { + FWIP_UNLOCK(fwip); printf("if_fwip: lack of xfer\n"); - return; + break; } IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) + if (m == NULL) { + FWIP_UNLOCK(fwip); break; + } + STAILQ_REMOVE_HEAD(&fwip->xferlist, link); + FWIP_UNLOCK(fwip); /* * Dig out the link-level address which @@ -629,7 +616,6 @@ else destfw = (struct fw_hwaddr *) (mtag + 1); - STAILQ_REMOVE_HEAD(&fwip->xferlist, link); /* * We don't do any bpf stuff here - the generic code @@ -741,13 +727,12 @@ if (i > 1) printf("%d queued\n", i); #endif - if (i > 0) { + if (i > 0) #if 1 xferq->start(fc); #else taskqueue_enqueue(taskqueue_swi_giant, &fwip->start_send); #endif - } } static void @@ -755,7 +740,6 @@ { struct fwip_softc *fwip = arg; - GIANT_REQUIRED; fwip->fd.fc->atq->start(fwip->fd.fc); } @@ -772,7 +756,6 @@ uint16_t src; uint32_t *p; - GIANT_REQUIRED; fwip = (struct fwip_softc *)xferq->sc; ifp = fwip->fw_softc.fwip_ifp; @@ -874,8 +857,6 @@ { struct mbuf *m; - GIANT_REQUIRED; - /* * We have finished with a unicast xfer. Allocate a new * cluster and stick it on the back of the input queue. @@ -900,8 +881,6 @@ //struct fw_pkt *sfp; int rtcode; - GIANT_REQUIRED; - fwip = (struct fwip_softc *)xfer->sc; ifp = fwip->fw_softc.fwip_ifp; m = xfer->mbuf; Index: dev/firewire/if_fwipvar.h =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/if_fwipvar.h,v retrieving revision 1.4 diff -u -r1.4 if_fwipvar.h --- dev/firewire/if_fwipvar.h 10 Jun 2005 16:49:08 -0000 1.4 +++ dev/firewire/if_fwipvar.h 11 May 2007 01:39:13 -0000 @@ -58,5 +58,8 @@ struct ifnet *fwip_ifp; struct fwip_softc *fwip; } fw_softc; + struct mtx mtx; }; +#define FWIP_LOCK(fwip) mtx_lock(&(fwip)->mtx) +#define FWIP_UNLOCK(fwip) mtx_unlock(&(fwip)->mtx) #endif /* !_NET_IF_FWIPVAR_H_ */ Index: dev/firewire/sbp.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/sbp.c,v retrieving revision 1.91 diff -u -r1.91 sbp.c --- dev/firewire/sbp.c 30 Apr 2007 13:41:40 -0000 1.91 +++ dev/firewire/sbp.c 8 May 2007 13:43:30 -0000 @@ -245,7 +245,10 @@ struct timeval last_busreset; #define SIMQ_FREEZED 1 int flags; + struct mtx mtx; }; +#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx) +#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx) static void sbp_post_explore (void *); static void sbp_recv (struct fw_xfer *); @@ -736,8 +739,10 @@ 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_DEBUG(0) @@ -769,8 +774,10 @@ printf("lost target\n"); 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_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET); @@ -798,8 +805,10 @@ printf("sbp_post_busreset\n"); END_DEBUG 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); } @@ -870,8 +879,10 @@ 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); } #if NEED_RESPONSE @@ -901,7 +912,9 @@ sdev = (struct sbp_dev *)xfer->sc; fw_xfer_unload(xfer); s = splfw(); + SBP_LOCK(sdev->target->sbp); STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link); + SBP_UNLOCK(sdev->target->sbp); splx(s); } @@ -1008,9 +1021,11 @@ /* reuse ccb */ xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI); ccb->ccb_h.ccb_sdev_ptr = sdev; + SBP_LOCK(target->sbp); xpt_action(ccb); xpt_release_devq(sdev->path, sdev->freeze, TRUE); sdev->freeze = 1; + SBP_UNLOCK(target->sbp); } static void @@ -1043,9 +1058,11 @@ 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 @@ -1108,8 +1125,10 @@ 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); } } @@ -1738,8 +1757,10 @@ /* we have to reset the fetch agent if it's dead */ if (sbp_status->dead) { if (sdev->path) { + SBP_LOCK(sdev->target->sbp); xpt_freeze_devq(sdev->path, 1); sdev->freeze ++; + SBP_UNLOCK(sdev->target->sbp); } reset_agent = 1; } @@ -1910,6 +1931,7 @@ { struct sbp_softc *sbp; struct cam_devq *devq; + struct firewire_comm *fc; int i, s, error; if (DFLTPHYS > SBP_MAXPHYS) @@ -1926,12 +1948,13 @@ sbp = ((struct sbp_softc *)device_get_softc(dev)); bzero(sbp, sizeof(struct sbp_softc)); sbp->fd.dev = dev; - sbp->fd.fc = device_get_ivars(dev); + sbp->fd.fc = fc = device_get_ivars(dev); + mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF); if (max_speed < 0) - max_speed = sbp->fd.fc->speed; + max_speed = fc->speed; - error = bus_dma_tag_create(/*parent*/sbp->fd.fc->dmat, + error = bus_dma_tag_create(/*parent*/fc->dmat, /* XXX shoud be 4 for sane backend? */ /*alignment*/1, /*boundary*/0, @@ -1943,7 +1966,7 @@ /*flags*/BUS_DMA_ALLOCNOW, #if defined(__FreeBSD__) && __FreeBSD_version >= 501102 /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, + /*lockarg*/&sbp->mtx, #endif &sbp->dmat); if (error != 0) { @@ -1963,7 +1986,7 @@ sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp, device_get_unit(dev), - &Giant, + &sbp->mtx, /*untagged*/ 1, /*tagged*/ SBP_QUEUE_LEN - 1, devq); @@ -1973,7 +1996,7 @@ return (ENXIO); } - + SBP_LOCK(sbp); if (xpt_bus_register(sbp->sim, /*bus*/0) != CAM_SUCCESS) goto fail; @@ -1982,6 +2005,7 @@ xpt_bus_deregister(cam_sim_path(sbp->sim)); goto fail; } + SBP_UNLOCK(sbp); /* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */ sbp->fwb.start = ((u_int64_t)SBP_BIND_HI << 32) | SBP_DEV2ADDR(0, 0); @@ -1990,22 +2014,26 @@ STAILQ_INIT(&sbp->fwb.xferlist); fw_xferlist_add(&sbp->fwb.xferlist, M_SBP, /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2, - sbp->fd.fc, (void *)sbp, sbp_recv); - fw_bindadd(sbp->fd.fc, &sbp->fwb); + fc, (void *)sbp, sbp_recv); + + fw_bindadd(fc, &sbp->fwb); sbp->fd.post_busreset = sbp_post_busreset; sbp->fd.post_explore = sbp_post_explore; - if (sbp->fd.fc->status != -1) { + 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); + SBP_UNLOCK(sbp); return (0); fail: + SBP_UNLOCK(sbp); cam_sim_free(sbp->sim, /*free_devq*/TRUE); return (ENXIO); } @@ -2100,10 +2128,13 @@ 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); @@ -2117,6 +2148,7 @@ fw_xferlist_remove(&sbp->fwb.xferlist); bus_dma_tag_destroy(sbp->dmat); + mtx_destroy(&sbp->mtx); return (0); } @@ -2131,12 +2163,14 @@ if (sdev->status == SBP_DEV_RESET) return; 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); } sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE); } @@ -2171,8 +2205,10 @@ 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; @@ -2227,8 +2263,10 @@ 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; @@ -2332,6 +2370,7 @@ void *cdb; csio = &ccb->csio; + mtx_assert(sim->mtx, MA_OWNED); SBP_DEBUG(2) printf("%s:%d:%d XPT_SCSI_IO: " @@ -2375,8 +2414,10 @@ if ((ocb = sbp_get_ocb(sdev)) == NULL) { ccb->ccb_h.status = CAM_REQUEUE_REQ; 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; @@ -2681,6 +2722,7 @@ #endif __func__, 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); flags = ocb->flags; @@ -2728,6 +2770,7 @@ } else order ++; } + SBP_UNLOCK(sdev->target->sbp); splx(s); SBP_DEBUG(0) if (ocb && order > 0) { @@ -2808,9 +2851,11 @@ int count; sdev->flags &= ~ORB_SHORTAGE; + SBP_LOCK(sdev->target->sbp); count = sdev->freeze; sdev->freeze = 0; xpt_release_devq(sdev->path, count, TRUE); + SBP_UNLOCK(sdev->target->sbp); } } Index: dev/firewire/sbp_targ.c =================================================================== RCS file: /home/ncvs/src/sys/dev/firewire/sbp_targ.c,v retrieving revision 1.13 diff -u -r1.13 sbp_targ.c --- dev/firewire/sbp_targ.c 11 May 2007 14:51:13 -0000 1.13 +++ dev/firewire/sbp_targ.c 14 May 2007 04:53:20 -0000 @@ -140,7 +140,10 @@ struct sbp_targ_lstate *lstate[MAX_LUN]; struct sbp_targ_lstate *black_hole; struct sbp_targ_login *logins[MAX_LOGINS]; + struct mtx mtx; }; +#define SBP_LOCK(sc) mtx_lock(&(sc)->mtx) +#define SBP_UNLOCK(sc) mtx_unlock(&(sc)->mtx) struct corb4 { #if BYTE_ORDER == BIG_ENDIAN @@ -289,8 +292,10 @@ unit = &sc->unit; if ((sc->flags & F_FREEZED) == 0) { + SBP_LOCK(sc); sc->flags |= F_FREEZED; xpt_freeze_simq(sc->sim, /*count*/1); + SBP_UNLOCK(sc); } else { printf("%s: already freezed\n", __func__); } @@ -336,8 +341,10 @@ struct sbp_targ_softc *sc; sc = (struct sbp_targ_softc *)arg; + SBP_LOCK(sc); sc->flags &= ~F_FREEZED; xpt_release_simq(sc->sim, /*run queue*/TRUE); + SBP_UNLOCK(sc); return; } @@ -484,10 +491,19 @@ #endif } + +static __inline void +sbp_targ_remove_orb_info_locked(struct sbp_targ_login *login, struct orb_info *orbi) +{ + STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); +} + static __inline void sbp_targ_remove_orb_info(struct sbp_targ_login *login, struct orb_info *orbi) { + SBP_LOCK(orbi->sc); STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); + SBP_UNLOCK(orbi->sc); } /* @@ -518,17 +534,19 @@ STAILQ_FOREACH(orbi, &login->orbs, link) if (orbi->orb_lo == tag_id) goto found; - printf("%s: orb not found tag_id=0x%08x\n", __func__, tag_id); + printf("%s: orb not found tag_id=0x%08x init_id=%d\n", + __func__, tag_id, init_id); return (NULL); found: return (orbi); } static void -sbp_targ_abort(struct orb_info *orbi) +sbp_targ_abort(struct sbp_targ_softc *sc, struct orb_info *orbi) { struct orb_info *norbi; + SBP_LOCK(sc); for (; orbi != NULL; orbi = norbi) { printf("%s: status=%d\n", __func__, orbi->state); norbi = STAILQ_NEXT(orbi, link); @@ -539,12 +557,13 @@ orbi->ccb = NULL; } if (orbi->state <= ORBI_STATUS_ATIO) { - sbp_targ_remove_orb_info(orbi->login, orbi); + sbp_targ_remove_orb_info_locked(orbi->login, orbi); free(orbi, M_SBP_TARG); } else orbi->state = ORBI_STATUS_ABORTED; } } + SBP_UNLOCK(sc); } static void @@ -614,7 +633,7 @@ sbp_cmd_status->status = ccb->csio.scsi_status; sense = &ccb->csio.sense_data; - sbp_targ_abort(STAILQ_NEXT(orbi, link)); + sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); if ((sense->error_code & SSD_ERRCODE) == SSD_CURRENT_ERROR) sbp_cmd_status->sfmt = SBP_SFMT_CURR; @@ -677,7 +696,7 @@ orbi->status.resp = SBP_TRANS_FAIL; orbi->status.status = OBJ_DATA | SBE_TIMEOUT/*XXX*/; orbi->status.dead = 1; - sbp_targ_abort(STAILQ_NEXT(orbi, link)); + sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); } orbi->refcount --; @@ -695,14 +714,18 @@ if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) sbp_targ_send_status(orbi, ccb); ccb->ccb_h.status = CAM_REQ_CMP; + SBP_LOCK(orbi->sc); xpt_done(ccb); + SBP_UNLOCK(orbi->sc); } else { orbi->status.len = 1; sbp_targ_status_FIFO(orbi, orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); ccb->ccb_h.status = CAM_REQ_ABORTED; + SBP_LOCK(orbi->sc); xpt_done(ccb); + SBP_UNLOCK(orbi->sc); } } @@ -823,7 +846,7 @@ orbi->status.status = OBJ_PT | SBE_TIMEOUT/*XXX*/; orbi->status.dead = 1; orbi->status.len = 1; - sbp_targ_abort(STAILQ_NEXT(orbi, link)); + sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); sbp_targ_status_FIFO(orbi, orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); @@ -901,7 +924,8 @@ struct orb_info *orbi; if (debug) - printf("%s: XPT_CONT_TARGET_IO\n", __func__); + printf("%s: XPT_CONT_TARGET_IO (0x%08x)\n", + __func__, ccb->csio.tag_id); if (status != CAM_REQ_CMP) { ccb->ccb_h.status = status; @@ -966,8 +990,12 @@ sbp_targ_cam_done); if (ccb_dir == CAM_DIR_NONE) { - if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) + if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { + /* XXX */ + SBP_UNLOCK(sc); sbp_targ_send_status(orbi, ccb); + SBP_LOCK(sc); + } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); } @@ -1106,7 +1134,7 @@ orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; orbi->status.dead = 1; orbi->status.len = 1; - sbp_targ_abort(STAILQ_NEXT(orbi, link)); + sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); sbp_targ_status_FIFO(orbi, orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); @@ -1145,8 +1173,8 @@ atio->ccb_h.flags = CAM_TAG_ACTION_VALID; bytes = (char *)&orb[5]; if (debug) - printf("%s: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - __func__, + printf("%s: %p %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + __func__, (void *)atio, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]); switch (bytes[0] >> 5) { @@ -1191,7 +1219,9 @@ orbi->data_lo = orb[3]; orbi->orb4 = *orb4; + SBP_LOCK(orbi->sc); xpt_done((union ccb*)atio); + SBP_UNLOCK(orbi->sc); done0: fw_xfer_free(xfer); return; @@ -1256,7 +1286,7 @@ orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; orbi->status.dead = 1; orbi->status.len = 1; - sbp_targ_abort(STAILQ_NEXT(orbi, link)); + sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); sbp_targ_status_FIFO(orbi, orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/0); @@ -1309,6 +1339,7 @@ orbi->status.len = 1; break; } + printf("%s: login id=%d\n", __func__, login->id); login->fifo_hi = orb[6]; login->fifo_lo = orb[7]; @@ -1318,10 +1349,10 @@ login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id)); login->loginres.recon_hold = htons(login->hold_sec); + STAILQ_INSERT_TAIL(&lstate->logins, login, link); fwmem_write_block(orbi->fwdev, NULL, /*spd*/2, orb[2], orb[3], sizeof(struct sbp_login_res), (void *)&login->loginres, fw_asy_callback_free); - STAILQ_INSERT_TAIL(&lstate->logins, login, link); /* XXX return status after loginres is successfully written */ break; } @@ -1418,9 +1449,11 @@ login->last_lo = orb_lo; login->flags |= F_LINK_ACTIVE; /* dequeue */ + SBP_LOCK(sc); orbi->atio = (struct ccb_accept_tio *) SLIST_FIRST(&login->lstate->accept_tios); if (orbi->atio == NULL) { + SBP_UNLOCK(sc); printf("%s: no free atio\n", __func__); login->lstate->flags |= F_ATIO_STARVED; login->flags |= F_ATIO_STARVED; @@ -1431,10 +1464,11 @@ break; } SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle); + STAILQ_INSERT_TAIL(&login->orbs, orbi, link); + SBP_UNLOCK(sc); fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, sizeof(uint32_t) * 8, &orbi->orb[0], sbp_targ_cmd_handler); - STAILQ_INSERT_TAIL(&login->orbs, orbi, link); break; case FETCH_POINTER: orbi->state = ORBI_STATUS_POINTER; @@ -1489,7 +1523,7 @@ switch (reg) { case 0x08: /* ORB_POINTER */ if (debug) - printf("%s: ORB_POINTER\n", __func__); + printf("%s: ORB_POINTER(%d)\n", __func__, login_id); if ((login->flags & F_LINK_ACTIVE) != 0) { if (debug) printf("link active (ORB_POINTER)\n"); @@ -1502,14 +1536,14 @@ break; case 0x04: /* AGENT_RESET */ if (debug) - printf("%s: AGENT RESET\n", __func__); + printf("%s: AGENT RESET(%d)\n", __func__, login_id); login->last_hi = 0xffff; login->last_lo = 0xffffffff; - sbp_targ_abort(STAILQ_FIRST(&login->orbs)); + sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs)); break; case 0x10: /* DOORBELL */ if (debug) - printf("%s: DOORBELL\n", __func__); + printf("%s: DOORBELL(%d)\n", __func__, login_id); if (login->last_hi == 0xffff && login->last_lo == 0xffffffff) { printf("%s: no previous pointer(DOORBELL)\n", @@ -1526,13 +1560,15 @@ login, FETCH_POINTER); break; case 0x00: /* AGENT_STATE */ - printf("%s: AGENT_STATE (ignore)\n", __func__); + printf("%s: AGENT_STATE (%d:ignore)\n", __func__, login_id); break; case 0x14: /* UNSOLICITED_STATE_ENABLE */ - printf("%s: UNSOLICITED_STATE_ENABLE (ignore)\n", __func__); + printf("%s: UNSOLICITED_STATE_ENABLE (%d:ignore)\n", + __func__, login_id); break; default: - printf("%s: invalid register %d\n", __func__, reg); + printf("%s: invalid register %d(%d)\n", + __func__, reg, login_id); rtcode = RESP_ADDRESS_ERROR; } @@ -1561,7 +1597,6 @@ return(0); } - static void sbp_targ_recv(struct fw_xfer *xfer) { @@ -1582,6 +1617,7 @@ goto done; } lo = fp->mode.wreqb.dest_lo; + if (lo == SBP_TARG_BIND_LO(-1)) rtcode = sbp_targ_mgm(xfer, fwdev); else if (lo >= SBP_TARG_BIND_LO(0)) @@ -1611,11 +1647,13 @@ { struct sbp_targ_softc *sc; struct cam_devq *devq; + struct firewire_comm *fc; sc = (struct sbp_targ_softc *) device_get_softc(dev); bzero((void *)sc, sizeof(struct sbp_targ_softc)); - sc->fd.fc = device_get_ivars(dev); + mtx_init(&sc->mtx, "sbp_targ", NULL, MTX_DEF); + sc->fd.fc = fc = device_get_ivars(dev); sc->fd.dev = dev; sc->fd.post_explore = (void *) sbp_targ_post_explore; sc->fd.post_busreset = (void *) sbp_targ_post_busreset; @@ -1625,13 +1663,14 @@ return (ENXIO); sc->sim = cam_sim_alloc(sbp_targ_action, sbp_targ_poll, - "sbp_targ", sc, device_get_unit(dev), &Giant, + "sbp_targ", sc, device_get_unit(dev), &sc->mtx, /*untagged*/ 1, /*tagged*/ 1, devq); if (sc->sim == NULL) { cam_simq_free(devq); return (ENXIO); } + SBP_LOCK(sc); if (xpt_bus_register(sc->sim, /*bus*/0) != CAM_SUCCESS) goto fail; @@ -1640,6 +1679,7 @@ xpt_bus_deregister(cam_sim_path(sc->sim)); goto fail; } + SBP_UNLOCK(sc); sc->fwb.start = SBP_TARG_BIND_START; sc->fwb.end = SBP_TARG_BIND_END; @@ -1648,11 +1688,12 @@ STAILQ_INIT(&sc->fwb.xferlist); fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG, /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, - sc->fd.fc, (void *)sc, sbp_targ_recv); - fw_bindadd(sc->fd.fc, &sc->fwb); + fc, (void *)sc, sbp_targ_recv); + fw_bindadd(fc, &sc->fwb); return 0; fail: + SBP_UNLOCK(sc); cam_sim_free(sc->sim, /*free_devq*/TRUE); return (ENXIO); } @@ -1667,8 +1708,10 @@ sc = (struct sbp_targ_softc *)device_get_softc(dev); sc->fd.post_busreset = NULL; + SBP_LOCK(sc); xpt_free_path(sc->path); xpt_bus_deregister(cam_sim_path(sc->sim)); + SBP_UNLOCK(sc); cam_sim_free(sc->sim, /*free_devq*/TRUE); for (i = 0; i < MAX_LUN; i ++) { @@ -1686,6 +1729,8 @@ fw_bindremove(sc->fd.fc, &sc->fwb); fw_xferlist_remove(&sc->fwb.xferlist); + mtx_destroy(&sc->mtx); + return 0; } Index: cam/cam_xpt.c =================================================================== RCS file: /home/ncvs/src/sys/cam/cam_xpt.c,v retrieving revision 1.183 diff -u -r1.183 cam_xpt.c --- cam/cam_xpt.c 27 Apr 2007 14:23:05 -0000 1.183 +++ cam/cam_xpt.c 11 May 2007 10:15:27 -0000 @@ -548,6 +548,7 @@ }, CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/0 }, +#if 0 { /* * Maxtor Personal Storage 3000XT (Firewire) @@ -557,8 +558,9 @@ T_DIRECT, SIP_MEDIA_FIXED, "Maxtor", "1394 storage", "*" }, - CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/0 + CAM_QUIRK_NOSERIAL, /*mintags*/2, /*maxtags*/255 }, +#endif { /* * Would repond to all LUNs if asked for. @@ -4139,7 +4141,9 @@ void xpt_print_path(struct cam_path *path) { +#if 0 mtx_assert(path->bus->sim->mtx, MA_OWNED); +#endif if (path == NULL) printf("(nopath): "); Index: cam/scsi/scsi_target.c =================================================================== RCS file: /home/ncvs/src/sys/cam/scsi/scsi_target.c,v retrieving revision 1.73 diff -u -r1.73 scsi_target.c --- cam/scsi/scsi_target.c 15 Apr 2007 08:49:11 -0000 1.73 +++ cam/scsi/scsi_target.c 11 May 2007 02:19:16 -0000 @@ -372,10 +372,14 @@ int retval; softc = (struct targ_softc *)kn->kn_hook; +#if 0 cam_periph_lock(softc->periph); +#endif retval = !TAILQ_EMPTY(&softc->user_ccb_queue) || !TAILQ_EMPTY(&softc->abort_queue); +#if 0 cam_periph_unlock(softc->periph); +#endif return (retval); } @@ -585,12 +589,12 @@ cam_periph_unlock(softc->periph); break; default: - cam_periph_lock(softc->periph); if ((func_code & XPT_FC_QUEUED) != 0) { CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("Sending queued ccb %#x (%p)\n", func_code, user_ccb)); descr = targgetdescr(softc); + cam_periph_lock(softc->periph); descr->user_ccb = user_ccb; descr->priority = priority; descr->func_code = func_code; @@ -601,6 +605,7 @@ CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("Sending inline ccb %#x (%p)\n", func_code, user_ccb)); + cam_periph_lock(softc->periph); ccb = targgetccb(softc, func_code, priority); descr = (struct targ_cmd_descr *) ccb->ccb_h.targ_descr; @@ -762,7 +767,9 @@ && ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE)) || (ccb_h->func_code == XPT_DEV_MATCH))) { + cam_periph_unlock(softc->periph); error = cam_periph_mapmem(ccb, mapinfo); + cam_periph_lock(softc->periph); /* * cam_periph_mapmem returned an error, we can't continue. @@ -966,13 +973,16 @@ int ccb_len; ccb_len = targccblen(type); + /* XXX */ + cam_periph_unlock(softc->periph); MALLOC(ccb, union ccb *, ccb_len, M_TARG, M_WAITOK); + ccb->ccb_h.targ_descr = targgetdescr(softc); + cam_periph_lock(softc->periph); CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("getccb %p\n", ccb)); xpt_setup_ccb(&ccb->ccb_h, softc->path, priority); ccb->ccb_h.func_code = type; ccb->ccb_h.cbfcnp = targdone; - ccb->ccb_h.targ_descr = targgetdescr(softc); return (ccb); } @@ -1099,6 +1109,7 @@ static void notify_user(struct targ_softc *softc) { + mtx_assert(softc->periph->sim->mtx, MA_OWNED); /* * Notify users sleeping via poll(), kqueue(), and * blocking read().