+ Sync to FreeBSD.
firewire.c Rev.1.101 firewire.h Rev.1.21 firewirereg.h Rev.1.50 fwdev.c Rev.1.52 fwdma.c Rev.1.9 fwmem.c Rev.1.34 fwohci.c Rev.1.93 fwohcireg.h Rev.1.23 fwohcivar.h Rev.1.16 if_fwip.c Rev.1.16 if_fwipvar.h Rev.1.5 sbp.c Rev.1.92 + Cleanup macros in fw_port.h. + Fix the occurrence of the error at the resume. Don't set the buffer again.
This commit is contained in:
parent
02aa4d6c73
commit
c33e2714c5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: firewire.c,v 1.15 2007/10/19 12:00:12 ad Exp $ */
|
||||
/* $NetBSD: firewire.c,v 1.16 2007/11/05 19:08:56 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi Shimokawa
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
|
@ -32,7 +32,7 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/firewire.c,v 1.86 2007/03/30 15:43:56 simokawa Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.101 2007/10/20 23:23:14 julian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
|||
#include <sys/sysctl.h>
|
||||
#include <sys/kthread.h>
|
||||
|
||||
#include <sys/kdb.h>
|
||||
|
||||
#if defined(__DragonFly__) || __FreeBSD_version < 500000
|
||||
#include <machine/clock.h> /* for DELAY() */
|
||||
#endif
|
||||
|
@ -195,19 +197,21 @@ int firewirematch (struct device *, struct cfdata *, void *);
|
|||
void firewireattach (struct device *, struct device *, void *);
|
||||
int firewiredetach (struct device *, int);
|
||||
int firewire_print (void *, const char *);
|
||||
int firewire_resume(struct firewire_comm *);
|
||||
#endif
|
||||
static void firewire_xfer_timeout(void *, int);
|
||||
static void fw_try_bmr (void *);
|
||||
static void fw_try_bmr_callback (struct fw_xfer *);
|
||||
static void fw_asystart (struct fw_xfer *);
|
||||
static int fw_get_tlabel (struct firewire_comm *, struct fw_xfer *);
|
||||
static void fw_bus_probe (struct firewire_comm *);
|
||||
static void fw_kthread_create0 (void *);
|
||||
static void fw_attach_dev (struct firewire_comm *);
|
||||
static void fw_bus_probe_thread(void *);
|
||||
#ifdef FW_VMACCESS
|
||||
static void fw_vmaccess (struct fw_xfer *);
|
||||
#endif
|
||||
static int fw_bmr (struct firewire_comm *);
|
||||
static void fw_dump_hdr(struct fw_pkt *, const char *);
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static device_method_t firewire_methods[] = {
|
||||
|
@ -265,9 +269,11 @@ fw_noderesolve_nodeid(struct firewire_comm *fc, int dst)
|
|||
int s;
|
||||
|
||||
s = splfw();
|
||||
FW_GLOCK(fc);
|
||||
STAILQ_FOREACH(fwdev, &fc->devices, link)
|
||||
if (fwdev->dst == dst && fwdev->status != FWDEVINVAL)
|
||||
break;
|
||||
FW_GUNLOCK(fc);
|
||||
splx(s);
|
||||
|
||||
return fwdev;
|
||||
|
@ -301,7 +307,7 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
|
|||
{
|
||||
int err = 0;
|
||||
struct fw_xferq *xferq;
|
||||
int tl = -1, len;
|
||||
int len;
|
||||
struct fw_pkt *fp;
|
||||
int tcode;
|
||||
const struct tcode_info *info;
|
||||
|
@ -319,6 +325,17 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
|
|||
printf("invalid tcode=%x\n", tcode);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* XXX allow bus explore packets only after bus rest */
|
||||
if ((fc->status < FWBUSEXPLORE) &&
|
||||
((tcode != FWTCODE_RREQQ) || (fp->mode.rreqq.dest_hi != 0xffff) ||
|
||||
(fp->mode.rreqq.dest_lo < 0xf0000000) ||
|
||||
(fp->mode.rreqq.dest_lo >= 0xf0001000))) {
|
||||
xfer->resp = EAGAIN;
|
||||
xfer->flag = FWXF_BUSY;
|
||||
return (EAGAIN);
|
||||
}
|
||||
|
||||
if (info->flag & FWTI_REQ)
|
||||
xferq = fc->atq;
|
||||
else
|
||||
|
@ -345,18 +362,17 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
|
|||
return EINVAL;
|
||||
}
|
||||
if(!(xferq->queued < xferq->maxq)){
|
||||
device_printf(fc->bdev, "Discard a packet (queued=%d)\n",
|
||||
fw_printf(fc->bdev, "Discard a packet (queued=%d)\n",
|
||||
xferq->queued);
|
||||
return EINVAL;
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
xfer->tl = -1;
|
||||
if (info->flag & FWTI_TLABEL) {
|
||||
if ((tl = fw_get_tlabel(fc, xfer)) == -1)
|
||||
if (fw_get_tlabel(fc, xfer) < 0)
|
||||
return EAGAIN;
|
||||
fp->mode.hdr.tlrt = tl << 2;
|
||||
}
|
||||
|
||||
xfer->tl = tl;
|
||||
xfer->resp = 0;
|
||||
xfer->fc = fc;
|
||||
xfer->q = xferq;
|
||||
|
@ -368,11 +384,32 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
|
|||
* Wakeup blocked process.
|
||||
*/
|
||||
void
|
||||
fw_asy_callback(struct fw_xfer *xfer){
|
||||
fw_xferwake(struct fw_xfer *xfer)
|
||||
{
|
||||
fw_mtx_t lock = &xfer->fc->wait_lock;
|
||||
|
||||
fw_mtx_lock(lock);
|
||||
xfer->flag |= FWXF_WAKE;
|
||||
fw_mtx_unlock(lock);
|
||||
|
||||
wakeup(xfer);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
fw_xferwait(struct fw_xfer *xfer)
|
||||
{
|
||||
fw_mtx_t lock = &xfer->fc->wait_lock;
|
||||
int err = 0;
|
||||
|
||||
fw_mtx_lock(lock);
|
||||
if ((xfer->flag & FWXF_WAKE) == 0)
|
||||
err = fw_msleep((void *)xfer, lock, PWAIT|PCATCH, "fw_xferwait", 0);
|
||||
fw_mtx_unlock(lock);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Async. request with given xfer structure.
|
||||
*/
|
||||
|
@ -381,20 +418,15 @@ fw_asystart(struct fw_xfer *xfer)
|
|||
{
|
||||
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;
|
||||
xfer->state = FWXF_BUSY;
|
||||
if (xfer->hand != NULL)
|
||||
xfer->hand(xfer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
microtime(&xfer->tv);
|
||||
s = splfw();
|
||||
xfer->state = FWXF_INQ;
|
||||
/* Protect from interrupt/timeout */
|
||||
FW_GLOCK(fc);
|
||||
xfer->flag = 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)
|
||||
|
@ -429,44 +461,55 @@ firewirematch(struct device *parent, struct cfdata *cf,
|
|||
#endif
|
||||
|
||||
static void
|
||||
firewire_xfer_timeout(struct firewire_comm *fc)
|
||||
firewire_xfer_timeout(void *arg, int pending)
|
||||
{
|
||||
struct fw_xfer *xfer;
|
||||
struct firewire_comm *fc = (struct firewire_comm *)arg;
|
||||
struct fw_xfer *xfer, *txfer;
|
||||
struct timeval tv;
|
||||
struct timeval split_timeout;
|
||||
STAILQ_HEAD(, fw_xfer) xfer_timeout;
|
||||
int i, s;
|
||||
|
||||
split_timeout.tv_sec = 0;
|
||||
split_timeout.tv_usec = 200 * 1000; /* 200 msec */
|
||||
|
||||
microtime(&tv);
|
||||
timevalsub(&tv, &split_timeout);
|
||||
fw_timevalsub(&tv, &split_timeout);
|
||||
STAILQ_INIT(&xfer_timeout);
|
||||
|
||||
s = splfw();
|
||||
fw_mtx_lock(&fc->tlabel_lock);
|
||||
for (i = 0; i < 0x40; i ++) {
|
||||
while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
|
||||
if (timevalcmp(&xfer->tv, &tv, >))
|
||||
/* the rests are newer than this */
|
||||
break;
|
||||
if (xfer->state == FWXF_START)
|
||||
if ((xfer->flag & FWXF_SENT) == 0)
|
||||
/* not sent yet */
|
||||
break;
|
||||
device_printf(fc->bdev,
|
||||
"split transaction timeout dst=0x%x tl=0x%x state=%d\n",
|
||||
xfer->send.hdr.mode.hdr.dst, i, xfer->state);
|
||||
if (fw_timevalcmp(&xfer->tv, &tv, >))
|
||||
/* the rests are newer than this */
|
||||
break;
|
||||
fw_printf(fc->bdev,
|
||||
"split transaction timeout: "
|
||||
"tl=0x%x flag=0x%02x\n", i, xfer->flag);
|
||||
fw_dump_hdr(&xfer->send.hdr, "send");
|
||||
xfer->resp = ETIMEDOUT;
|
||||
fw_xfer_done(xfer);
|
||||
STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
|
||||
STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel);
|
||||
}
|
||||
}
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
splx(s);
|
||||
fc->timeout(fc);
|
||||
|
||||
STAILQ_FOREACH_SAFE(xfer, &xfer_timeout, tlabel, txfer)
|
||||
xfer->hand(xfer);
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -475,13 +518,12 @@ firewire_watchdog(void *arg)
|
|||
* We encounter a timeout easily. To avoid this,
|
||||
* ignore clock interrupt for a while.
|
||||
*/
|
||||
if (watchdoc_clock > WATCHDOC_HZ * 15) {
|
||||
firewire_xfer_timeout(fc);
|
||||
fc->timeout(fc);
|
||||
} else
|
||||
watchdoc_clock ++;
|
||||
if (watchdog_clock > WATCHDOG_HZ * 15)
|
||||
fw_taskqueue_enqueue(fc->taskqueue, &fc->task_timeout);
|
||||
else
|
||||
watchdog_clock ++;
|
||||
|
||||
callout_reset(&fc->timeout_callout, hz / WATCHDOC_HZ,
|
||||
fw_callout_reset(&fc->timeout_callout, hz / WATCHDOG_HZ,
|
||||
(void *)firewire_watchdog, (void *)fc);
|
||||
}
|
||||
|
||||
|
@ -500,19 +542,25 @@ FW_ATTACH(firewire)
|
|||
|
||||
FWDEV_MAKEDEV(sc);
|
||||
|
||||
CALLOUT_INIT(&sc->fc->timeout_callout);
|
||||
CALLOUT_INIT(&sc->fc->bmr_callout);
|
||||
CALLOUT_INIT(&sc->fc->busprobe_callout);
|
||||
fw_mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF);
|
||||
fw_mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF);
|
||||
fw_callout_init(&fc->timeout_callout);
|
||||
fw_callout_init(&fc->bmr_callout);
|
||||
fw_callout_init(&fc->busprobe_callout);
|
||||
FW_TASK_INIT(&fc->task_timeout, 0, firewire_xfer_timeout, (void *)fc);
|
||||
|
||||
callout_reset(&sc->fc->timeout_callout, hz,
|
||||
fw_callout_reset(&sc->fc->timeout_callout, hz,
|
||||
(void *)firewire_watchdog, (void *)sc->fc);
|
||||
|
||||
fw_kthread_create(fw_kthread_create0, fc);
|
||||
/* create thread */
|
||||
fw_kthread_create(fw_bus_probe_thread, (void *)fc, &fc->probe_thread,
|
||||
"fw%d_probe", fw_get_unit(fc->bdev));
|
||||
fw_config_pending_incr();
|
||||
|
||||
FIREWIRE_GENERIC_ATTACH;
|
||||
|
||||
/* bus_reset */
|
||||
fw_busreset(fc);
|
||||
fw_busreset(fc, FWBUSNOTREADY);
|
||||
fc->ibr(fc);
|
||||
|
||||
FW_ATTACH_RETURN(0);
|
||||
|
@ -566,14 +614,20 @@ FW_DETACH(firewire)
|
|||
struct fw_device *fwdev, *fwdev_next;
|
||||
|
||||
fc = sc->fc;
|
||||
fw_mtx_lock(&fc->wait_lock);
|
||||
fc->status = FWBUSDETACH;
|
||||
wakeup(fc);
|
||||
if (fw_msleep(fc->probe_thread,
|
||||
&fc->wait_lock, PWAIT, "fwthr", hz * 60))
|
||||
printf("firewire probe thread didn't die\n");
|
||||
fw_mtx_unlock(&fc->wait_lock);
|
||||
|
||||
FWDEV_DESTROYDEV(sc);
|
||||
FIREWIRE_GENERIC_DETACH;
|
||||
|
||||
callout_stop(&fc->timeout_callout);
|
||||
callout_stop(&fc->bmr_callout);
|
||||
callout_stop(&fc->busprobe_callout);
|
||||
fw_callout_stop(&fc->timeout_callout);
|
||||
fw_callout_stop(&fc->bmr_callout);
|
||||
fw_callout_stop(&fc->busprobe_callout);
|
||||
|
||||
/* XXX xfree_free and untimeout on all xfers */
|
||||
for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL;
|
||||
|
@ -585,10 +639,8 @@ FW_DETACH(firewire)
|
|||
free(fc->speed_map, M_FW);
|
||||
free(fc->crom_src_buf, M_FW);
|
||||
|
||||
wakeup(fc);
|
||||
if (tsleep(fc, PWAIT, "fwthr", hz * 60))
|
||||
printf("firewire task thread didn't die\n");
|
||||
|
||||
fw_mtx_destroy(&fc->wait_lock);
|
||||
fw_mtx_destroy(&fc->tlabel_lock);
|
||||
return(0);
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -610,6 +662,14 @@ firewire_print(void *aux, const char *pnp)
|
|||
|
||||
return UNCONF;
|
||||
}
|
||||
|
||||
int
|
||||
firewire_resume(struct firewire_comm *fc)
|
||||
{
|
||||
|
||||
fc->status = FWBUSNOTREADY;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
|
@ -619,9 +679,11 @@ fw_xferq_drain(struct fw_xferq *xferq)
|
|||
|
||||
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;
|
||||
xfer->flag = FWXF_SENTERR;
|
||||
fw_xfer_done(xfer);
|
||||
}
|
||||
}
|
||||
|
@ -629,12 +691,32 @@ fw_xferq_drain(struct fw_xferq *xferq)
|
|||
void
|
||||
fw_drain_txq(struct firewire_comm *fc)
|
||||
{
|
||||
struct fw_xfer *xfer, *txfer;
|
||||
STAILQ_HEAD(, fw_xfer) xfer_drain;
|
||||
int i;
|
||||
|
||||
STAILQ_INIT(&xfer_drain);
|
||||
|
||||
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);
|
||||
|
||||
fw_mtx_lock(&fc->tlabel_lock);
|
||||
for (i = 0; i < 0x40; i ++)
|
||||
while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
|
||||
if (firewire_debug)
|
||||
printf("tl=%d flag=%d\n", i, xfer->flag);
|
||||
xfer->resp = EAGAIN;
|
||||
STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
|
||||
STAILQ_INSERT_TAIL(&xfer_drain, xfer, tlabel);
|
||||
}
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
|
||||
STAILQ_FOREACH_SAFE(xfer, &xfer_drain, tlabel, txfer)
|
||||
xfer->hand(xfer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -750,7 +832,7 @@ fw_reset_crom(struct firewire_comm *fc)
|
|||
* Called after bus reset.
|
||||
*/
|
||||
void
|
||||
fw_busreset(struct firewire_comm *fc)
|
||||
fw_busreset(struct firewire_comm *fc, uint32_t new_status)
|
||||
{
|
||||
struct firewire_dev_comm *fdc;
|
||||
struct crom_src *src;
|
||||
|
@ -758,12 +840,12 @@ fw_busreset(struct firewire_comm *fc)
|
|||
|
||||
switch(fc->status){
|
||||
case FWBUSMGRELECT:
|
||||
callout_stop(&fc->bmr_callout);
|
||||
fw_callout_stop(&fc->bmr_callout);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fc->status = FWBUSRESET;
|
||||
fc->status = new_status;
|
||||
fw_reset_csr(fc);
|
||||
fw_reset_crom(fc);
|
||||
|
||||
|
@ -905,13 +987,17 @@ struct fw_bind *
|
|||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -921,28 +1007,29 @@ int
|
|||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -958,6 +1045,7 @@ fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
|
|||
int s;
|
||||
|
||||
s = splfw();
|
||||
FW_GLOCK(fc);
|
||||
STAILQ_FOREACH(tfw, &fc->binds, fclist)
|
||||
if (tfw == fwb) {
|
||||
STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
|
||||
|
@ -965,6 +1053,7 @@ fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
|
|||
}
|
||||
|
||||
printf("%s: no such binding\n", __func__);
|
||||
FW_GUNLOCK(fc);
|
||||
splx(s);
|
||||
return (1);
|
||||
found:
|
||||
|
@ -976,6 +1065,7 @@ found:
|
|||
}
|
||||
STAILQ_INIT(&fwb->xferlist);
|
||||
#endif
|
||||
FW_GUNLOCK(fc);
|
||||
|
||||
splx(s);
|
||||
return 0;
|
||||
|
@ -1015,6 +1105,20 @@ fw_xferlist_remove(struct fw_xferlist *q)
|
|||
STAILQ_INIT(q);
|
||||
}
|
||||
|
||||
/*
|
||||
* dump packet header
|
||||
*/
|
||||
static void
|
||||
fw_dump_hdr(struct fw_pkt *fp, const char *prefix)
|
||||
{
|
||||
printf("%s: dst=0x%02x tl=0x%02x rt=%d tcode=0x%x pri=0x%x "
|
||||
"src=0x%03x\n", prefix,
|
||||
fp->mode.hdr.dst & 0x3f,
|
||||
fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tlrt & 3,
|
||||
fp->mode.hdr.tcode, fp->mode.hdr.pri,
|
||||
fp->mode.hdr.src);
|
||||
}
|
||||
|
||||
/*
|
||||
* To free transaction label.
|
||||
*/
|
||||
|
@ -1028,19 +1132,26 @@ fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
|
|||
return;
|
||||
|
||||
s = splfw();
|
||||
fw_mtx_lock(&fc->tlabel_lock);
|
||||
#if 1 /* make sure the label is allocated */
|
||||
STAILQ_FOREACH(txfer, &fc->tlabels[xfer->tl], tlabel)
|
||||
if(txfer == xfer)
|
||||
break;
|
||||
if (txfer == NULL) {
|
||||
printf("%s: the xfer is not in the tlabel(%d)\n",
|
||||
__FUNCTION__, xfer->tl);
|
||||
printf("%s: the xfer is not in the queue "
|
||||
"(tlabel=%d, flag=0x%x)\n",
|
||||
__FUNCTION__, xfer->tl, xfer->flag);
|
||||
fw_dump_hdr(&xfer->send.hdr, "send");
|
||||
fw_dump_hdr(&xfer->recv.hdr, "recv");
|
||||
kdb_backtrace();
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel);
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
@ -1049,18 +1160,33 @@ fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
|
|||
* To obtain XFER structure by transaction label.
|
||||
*/
|
||||
static struct fw_xfer *
|
||||
fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel)
|
||||
fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel, int tcode)
|
||||
{
|
||||
struct fw_xfer *xfer;
|
||||
int s = splfw();
|
||||
int req;
|
||||
|
||||
fw_mtx_lock(&fc->tlabel_lock);
|
||||
STAILQ_FOREACH(xfer, &fc->tlabels[tlabel], tlabel)
|
||||
if(xfer->send.hdr.mode.hdr.dst == node) {
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
splx(s);
|
||||
FW_KASSERT(xfer->tl == tlabel,
|
||||
("xfer->tl 0x%x != 0x%x", xfer->tl, tlabel));
|
||||
/* extra sanity check */
|
||||
req = xfer->send.hdr.mode.hdr.tcode;
|
||||
if (xfer->fc->tcode[req].valid_res != tcode) {
|
||||
printf("%s: invalid response tcode "
|
||||
"(0x%x for 0x%x)\n", __FUNCTION__,
|
||||
tcode, req);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (firewire_debug > 2)
|
||||
printf("fw_tl2xfer: found tl=%d\n", tlabel);
|
||||
return(xfer);
|
||||
}
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
if (firewire_debug > 1)
|
||||
printf("fw_tl2xfer: not found tl=%d\n", tlabel);
|
||||
splx(s);
|
||||
|
@ -1137,16 +1263,20 @@ fw_xfer_unload(struct fw_xfer* xfer)
|
|||
int s;
|
||||
|
||||
if(xfer == NULL ) return;
|
||||
if(xfer->state == FWXF_INQ){
|
||||
if(xfer->flag & 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) {
|
||||
#if 1
|
||||
if(xfer->state == FWXF_START)
|
||||
if(xfer->flag == FWXF_START)
|
||||
/*
|
||||
* This could happen if:
|
||||
* 1. We call fwohci_arcv() before fwohci_txd().
|
||||
|
@ -1155,7 +1285,7 @@ fw_xfer_unload(struct fw_xfer* xfer)
|
|||
printf("fw_xfer_free FWXF_START\n");
|
||||
#endif
|
||||
}
|
||||
xfer->state = FWXF_INIT;
|
||||
xfer->flag = FWXF_INIT;
|
||||
xfer->resp = 0;
|
||||
}
|
||||
/*
|
||||
|
@ -1193,8 +1323,8 @@ void
|
|||
fw_asy_callback_free(struct fw_xfer *xfer)
|
||||
{
|
||||
#if 0
|
||||
printf("asyreq done state=%d resp=%d\n",
|
||||
xfer->state, xfer->resp);
|
||||
printf("asyreq done flag=%d resp=%d\n",
|
||||
xfer->flag, xfer->resp);
|
||||
#endif
|
||||
fw_xfer_free(xfer);
|
||||
}
|
||||
|
@ -1260,7 +1390,6 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
|||
u_int i, j, node, c_port = 0, i_branch = 0;
|
||||
|
||||
fc->sid_cnt = len /(sizeof(uint32_t) * 2);
|
||||
fc->status = FWBUSINIT;
|
||||
fc->max_node = fc->nodeid & 0x3f;
|
||||
CSRARC(fc, NODE_IDS) = ((uint32_t)fc->nodeid) << 16;
|
||||
fc->status = FWBUSCYMELECT;
|
||||
|
@ -1319,7 +1448,7 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
|||
self_id++;
|
||||
fc->topology_map->self_id_count ++;
|
||||
}
|
||||
device_printf(fc->bdev, "%d nodes", fc->max_node + 1);
|
||||
fw_printf(fc->bdev, "%d nodes", fc->max_node + 1);
|
||||
/* CRC */
|
||||
fc->topology_map->crc = fw_crc16(
|
||||
(uint32_t *)&fc->topology_map->generation,
|
||||
|
@ -1356,13 +1485,13 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
|
|||
fw_bmr(fc);
|
||||
} else {
|
||||
fc->status = FWBUSMGRELECT;
|
||||
callout_reset(&fc->bmr_callout, hz/8,
|
||||
fw_callout_reset(&fc->bmr_callout, hz/8,
|
||||
(void *)fw_try_bmr, (void *)fc);
|
||||
}
|
||||
} else
|
||||
fc->status = FWBUSMGRDONE;
|
||||
|
||||
callout_reset(&fc->busprobe_callout, hz/4,
|
||||
fw_callout_reset(&fc->busprobe_callout, hz/4,
|
||||
(void *)fw_bus_probe, (void *)fc);
|
||||
}
|
||||
|
||||
|
@ -1401,10 +1530,10 @@ fw_explore_read_quads(struct fw_device *fwdev, int offset,
|
|||
for (i = 0; i < n; i ++, offset += sizeof(uint32_t)) {
|
||||
xfer = fwmem_read_quad(fwdev, NULL, -1,
|
||||
0xffff, 0xf0000000 | offset, (void *)&tmp,
|
||||
fw_asy_callback);
|
||||
fw_xferwake);
|
||||
if (xfer == NULL)
|
||||
return (-1);
|
||||
tsleep((void *)xfer, FWPRI, "rquad", 0);
|
||||
fw_xferwait(xfer);
|
||||
|
||||
if (xfer->resp == 0)
|
||||
quad[i] = ntohl(tmp);
|
||||
|
@ -1449,9 +1578,9 @@ fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur)
|
|||
return (0);
|
||||
|
||||
for (i = 0; i < dir->crc_len; i ++, offset += sizeof(uint32_t)) {
|
||||
if (reg[i].key == CROM_UDIR)
|
||||
if ((reg[i].key & CSRTYPE_MASK) == CSRTYPE_D)
|
||||
recur = 1;
|
||||
else if (reg[i].key == CROM_TEXTLEAF)
|
||||
else if ((reg[i].key & CSRTYPE_MASK) == CSRTYPE_L)
|
||||
recur = 0;
|
||||
else
|
||||
continue;
|
||||
|
@ -1468,22 +1597,6 @@ fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
fw_kthread_create0(void *arg)
|
||||
{
|
||||
struct firewire_comm *fc = (struct firewire_comm *)arg;
|
||||
|
||||
config_pending_incr();
|
||||
|
||||
/* create thread */
|
||||
if (THREAD_CREATE(fw_bus_probe_thread,
|
||||
(void *)fc, NULL, "fw%d_probe", device_get_unit(fc->bdev))) {
|
||||
|
||||
device_printf(fc->bdev, "unable to create thread");
|
||||
panic("fw_kthread_create");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
fw_explore_node(struct fw_device *dfwdev)
|
||||
{
|
||||
|
@ -1551,7 +1664,7 @@ fw_explore_node(struct fw_device *dfwdev)
|
|||
else
|
||||
STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link);
|
||||
|
||||
device_printf(fc->bdev, "New %s device ID:%08x%08x\n",
|
||||
fw_printf(fc->bdev, "New %s device ID:%08x%08x\n",
|
||||
fw_linkspeed[spd],
|
||||
fwdev->eui.hi, fwdev->eui.lo);
|
||||
|
||||
|
@ -1608,6 +1721,7 @@ fw_explore(struct firewire_comm *fc)
|
|||
int node, err, s, i, todo, todo2, trys;
|
||||
char nodes[63];
|
||||
struct fw_device *dfwdev;
|
||||
union fw_self_id *fwsid;
|
||||
|
||||
todo = 0;
|
||||
dfwdev = malloc(sizeof(*dfwdev), M_TEMP, M_NOWAIT);
|
||||
|
@ -1623,7 +1737,8 @@ fw_explore(struct firewire_comm *fc)
|
|||
/* We don't probe myself and linkdown nodes */
|
||||
if (node == fc->nodeid)
|
||||
continue;
|
||||
if (!fw_find_self_id(fc, node)->p0.link_active) {
|
||||
fwsid = fw_find_self_id(fc, node);
|
||||
if (!fwsid || !fwsid->p0.link_active) {
|
||||
if (firewire_debug)
|
||||
printf("node%d: link down\n", node);
|
||||
continue;
|
||||
|
@ -1656,23 +1771,23 @@ fw_bus_probe_thread(void *arg)
|
|||
|
||||
fc = (struct firewire_comm *)arg;
|
||||
|
||||
config_pending_decr();
|
||||
fw_config_pending_decr();
|
||||
|
||||
FW_LOCK;
|
||||
while (1) {
|
||||
fw_mtx_lock(&fc->wait_lock);
|
||||
while (fc->status != FWBUSDETACH) {
|
||||
if (fc->status == FWBUSEXPLORE) {
|
||||
fw_mtx_unlock(&fc->wait_lock);
|
||||
fw_explore(fc);
|
||||
fc->status = FWBUSEXPDONE;
|
||||
if (firewire_debug)
|
||||
printf("bus_explore done\n");
|
||||
fw_attach_dev(fc);
|
||||
} else if (fc->status == FWBUSDETACH)
|
||||
break;
|
||||
tsleep((void *)fc, FWPRI, "fwprobe", 0);
|
||||
fw_mtx_lock(&fc->wait_lock);
|
||||
}
|
||||
fw_msleep((void *)fc, &fc->wait_lock, PWAIT|PCATCH, "-", 0);
|
||||
}
|
||||
FW_UNLOCK;
|
||||
wakeup(fc);
|
||||
THREAD_EXIT(0);
|
||||
fw_mtx_unlock(&fc->wait_lock);
|
||||
fw_kthread_exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1734,32 +1849,34 @@ fw_attach_dev(struct firewire_comm *fc)
|
|||
static int
|
||||
fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
|
||||
{
|
||||
u_int i;
|
||||
u_int dst, new_tlabel;
|
||||
struct fw_xfer *txfer;
|
||||
int s;
|
||||
static uint32_t label = 0;
|
||||
|
||||
dst = xfer->send.hdr.mode.hdr.dst & 0x3f;
|
||||
s = splfw();
|
||||
for( i = 0 ; i < 0x40 ; i ++){
|
||||
label = (label + 1) & 0x3f;
|
||||
STAILQ_FOREACH(txfer, &fc->tlabels[label], tlabel)
|
||||
if (txfer->send.hdr.mode.hdr.dst ==
|
||||
xfer->send.hdr.mode.hdr.dst)
|
||||
break;
|
||||
if(txfer == NULL) {
|
||||
STAILQ_INSERT_TAIL(&fc->tlabels[label], xfer, tlabel);
|
||||
splx(s);
|
||||
if (firewire_debug > 1)
|
||||
printf("fw_get_tlabel: dst=%d tl=%d\n",
|
||||
xfer->send.hdr.mode.hdr.dst, label);
|
||||
return(label);
|
||||
}
|
||||
fw_mtx_lock(&fc->tlabel_lock);
|
||||
new_tlabel = (fc->last_tlabel[dst] + 1) & 0x3f;
|
||||
STAILQ_FOREACH(txfer, &fc->tlabels[new_tlabel], tlabel)
|
||||
if ((txfer->send.hdr.mode.hdr.dst & 0x3f) == dst)
|
||||
break;
|
||||
if(txfer == NULL) {
|
||||
fc->last_tlabel[dst] = new_tlabel;
|
||||
STAILQ_INSERT_TAIL(&fc->tlabels[new_tlabel], xfer, tlabel);
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
splx(s);
|
||||
xfer->tl = new_tlabel;
|
||||
xfer->send.hdr.mode.hdr.tlrt = new_tlabel << 2;
|
||||
if (firewire_debug > 1)
|
||||
printf("fw_get_tlabel: dst=%d tl=%d\n", dst, new_tlabel);
|
||||
return (new_tlabel);
|
||||
}
|
||||
fw_mtx_unlock(&fc->tlabel_lock);
|
||||
splx(s);
|
||||
|
||||
if (firewire_debug > 1)
|
||||
printf("fw_get_tlabel: no free tlabel\n");
|
||||
return(-1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1849,7 +1966,7 @@ fw_rcv(struct fw_rcv_buf *rb)
|
|||
case FWTCODE_RRESB:
|
||||
case FWTCODE_LRES:
|
||||
rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
|
||||
fp->mode.hdr.tlrt >> 2);
|
||||
fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tcode);
|
||||
if(rb->xfer == NULL) {
|
||||
printf("fw_rcv: unknown response "
|
||||
"%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
|
||||
|
@ -1858,7 +1975,7 @@ fw_rcv(struct fw_rcv_buf *rb)
|
|||
fp->mode.hdr.tlrt >> 2,
|
||||
fp->mode.hdr.tlrt & 3,
|
||||
fp->mode.rresq.data);
|
||||
#if 1
|
||||
#if 0
|
||||
printf("try ad-hoc work around!!\n");
|
||||
rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
|
||||
(fp->mode.hdr.tlrt >> 2)^3);
|
||||
|
@ -1876,8 +1993,8 @@ fw_rcv(struct fw_rcv_buf *rb)
|
|||
else
|
||||
rb->xfer->resp = 0;
|
||||
/* make sure the packet is drained in AT queue */
|
||||
oldstate = rb->xfer->state;
|
||||
rb->xfer->state = FWXF_RCVD;
|
||||
oldstate = rb->xfer->flag;
|
||||
rb->xfer->flag = FWXF_RCVD;
|
||||
switch (oldstate) {
|
||||
case FWXF_SENT:
|
||||
fw_xfer_done(rb->xfer);
|
||||
|
@ -1889,7 +2006,7 @@ fw_rcv(struct fw_rcv_buf *rb)
|
|||
#endif
|
||||
break;
|
||||
default:
|
||||
printf("unexpected state %d\n", rb->xfer->state);
|
||||
printf("unexpected flag 0x%02x\n", rb->xfer->flag);
|
||||
}
|
||||
return;
|
||||
case FWTCODE_WREQQ:
|
||||
|
@ -1912,7 +2029,7 @@ fw_rcv(struct fw_rcv_buf *rb)
|
|||
tcode_str[tcode], tcode,
|
||||
fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
|
||||
#endif
|
||||
if (rb->fc->status == FWBUSRESET) {
|
||||
if (rb->fc->status == FWBUSINIT) {
|
||||
printf("fw_rcv: cannot respond(bus reset)!\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1945,7 +2062,7 @@ fw_rcv(struct fw_rcv_buf *rb)
|
|||
resfp->mode.rresb.extcode = 0;
|
||||
resfp->mode.rresb.len = 0;
|
||||
/*
|
||||
rb->xfer->hand = fw_asy_callback;
|
||||
rb->xfer->hand = fw_xferwake;
|
||||
*/
|
||||
rb->xfer->hand = fw_xfer_free;
|
||||
if(fw_asyreq(rb->fc, -1, rb->xfer)){
|
||||
|
@ -2047,7 +2164,7 @@ fw_try_bmr_callback(struct fw_xfer *xfer)
|
|||
return;
|
||||
|
||||
error:
|
||||
device_printf(fc->bdev, "bus manager election failed\n");
|
||||
fw_printf(fc->bdev, "bus manager election failed\n");
|
||||
fw_xfer_free_buf(xfer);
|
||||
}
|
||||
|
||||
|
@ -2201,7 +2318,7 @@ fw_bmr(struct firewire_comm *fc)
|
|||
if (self_id->p0.link_active && self_id->p0.contender)
|
||||
cmstr = fc->max_node;
|
||||
else {
|
||||
device_printf(fc->bdev,
|
||||
fw_printf(fc->bdev,
|
||||
"root node is not cycle master capable\n");
|
||||
/* XXX shall we be the cycle master? */
|
||||
cmstr = fc->nodeid;
|
||||
|
@ -2210,7 +2327,7 @@ fw_bmr(struct firewire_comm *fc)
|
|||
} else
|
||||
cmstr = -1;
|
||||
|
||||
device_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
|
||||
fw_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
|
||||
if(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) {
|
||||
/* We are not the bus manager */
|
||||
printf("\n");
|
||||
|
@ -2239,6 +2356,34 @@ fw_bmr(struct firewire_comm *fc)
|
|||
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);
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static int
|
||||
fw_modevent(module_t mode, int type, void *data)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: firewire.h,v 1.3 2006/11/16 15:59:28 jdolecek Exp $ */
|
||||
/* $NetBSD: firewire.h,v 1.4 2007/11/05 19:08:56 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi Shimokawa
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
|
@ -32,7 +32,7 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/firewire.h,v 1.20 2005/01/06 01:42:41 imp Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/firewire.h,v 1.21 2007/04/24 12:15:05 simokawa Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -413,14 +413,14 @@ struct fw_crom_buf {
|
|||
#define FWMAXNDMA 0x100 /* 8 bits DMA channel id. in device No. */
|
||||
|
||||
#define MAKEMINOR(f, u, s) \
|
||||
unit2minor((f) | (((u) & 0xff) << 8) | (s & 0xff))
|
||||
#define DEV2UNIT(x) ((dev2unit(x) & 0xff00) >> 8)
|
||||
#define DEV2SUB(x) (dev2unit(x) & 0xff)
|
||||
fw_unit2minor((f) | (((u) & 0xff) << 8) | (s & 0xff))
|
||||
#define DEV2UNIT(x) ((fw_dev2unit(x) & 0xff00) >> 8)
|
||||
#define DEV2SUB(x) (fw_dev2unit(x) & 0xff)
|
||||
#define FW_UNITMASK MAKEMINOR(0, -1, 0)
|
||||
#define FW_UNIT(unit) MAKEMINOR(0, unit, 0)
|
||||
|
||||
#define FWMEM_FLAG 0x10000
|
||||
#define DEV_FWMEM(x) (dev2unit(x) & FWMEM_FLAG)
|
||||
#define DEV_FWMEM(x) (fw_dev2unit(x) & FWMEM_FLAG)
|
||||
|
||||
struct fw_attach_args {
|
||||
const char *name;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: firewirereg.h,v 1.6 2007/07/29 13:31:08 ad Exp $ */
|
||||
/* $NetBSD: firewirereg.h,v 1.7 2007/11/05 19:08:56 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi Shimokawa
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
|
@ -32,7 +32,7 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/firewirereg.h,v 1.41 2007/03/16 05:39:33 simokawa Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/firewirereg.h,v 1.50 2007/07/20 03:42:57 simokawa Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -64,7 +64,7 @@ struct fw_device{
|
|||
|
||||
struct firewire_softc {
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
DEV_T dev;
|
||||
fw_dev_t dev;
|
||||
device_t sbp_dev;
|
||||
#elif defined(__NetBSD__)
|
||||
struct device _dev;
|
||||
|
@ -105,6 +105,7 @@ struct tcode_info {
|
|||
#define FWTI_TLABEL (1 << 2)
|
||||
#define FWTI_BLOCK_STR (1 << 3)
|
||||
#define FWTI_BLOCK_ASY (1 << 4)
|
||||
u_char valid_res;
|
||||
};
|
||||
|
||||
struct firewire_comm{
|
||||
|
@ -140,6 +141,8 @@ struct firewire_comm{
|
|||
struct fw_xferq
|
||||
*arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH];
|
||||
struct fw_xferlist tlabels[0x40];
|
||||
u_char last_tlabel[0x40];
|
||||
fw_mtx_t tlabel_lock;
|
||||
STAILQ_HEAD(, fw_bind) binds;
|
||||
STAILQ_HEAD(, fw_device) devices;
|
||||
u_int sid_cnt;
|
||||
|
@ -155,10 +158,11 @@ struct firewire_comm{
|
|||
struct callout busprobe_callout;
|
||||
struct callout bmr_callout;
|
||||
struct callout timeout_callout;
|
||||
fw_task_t task_timeout;
|
||||
uint32_t (*cyctimer) (struct firewire_comm *);
|
||||
void (*ibr) (struct firewire_comm *);
|
||||
uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
|
||||
int (*ioctl) (DEV_T, u_long, void *, int, fw_proc *);
|
||||
int (*ioctl) (fw_dev_t, u_long, void *, int, fw_proc_t);
|
||||
int (*irx_enable) (struct firewire_comm *, int);
|
||||
int (*irx_disable) (struct firewire_comm *, int);
|
||||
int (*itx_enable) (struct firewire_comm *, int);
|
||||
|
@ -170,9 +174,18 @@ struct firewire_comm{
|
|||
void (*itx_post) (struct firewire_comm *, uint32_t *);
|
||||
const struct tcode_info *tcode;
|
||||
bus_dma_tag_t dmat;
|
||||
fw_mtx_t mtx;
|
||||
fw_mtx_t wait_lock;
|
||||
struct taskqueue *taskqueue;
|
||||
fw_proc_t probe_thread;
|
||||
};
|
||||
#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
|
||||
|
||||
#define FW_GMTX(fc) (&(fc)->mtx)
|
||||
#define FW_GLOCK(fc) fw_mtx_lock(FW_GMTX(fc))
|
||||
#define FW_GUNLOCK(fc) fw_mtx_unlock(FW_GMTX(fc))
|
||||
#define FW_GLOCK_ASSERT(fc) fw_mtx_assert(FW_GMTX(fc), MA_OWNED)
|
||||
|
||||
struct fw_xferq {
|
||||
int flag;
|
||||
#define FWXFERQ_CHTAGMASK 0xff
|
||||
|
@ -230,14 +243,16 @@ struct fw_xfer{
|
|||
struct fw_xferq *q;
|
||||
struct timeval tv;
|
||||
int8_t resp;
|
||||
#define FWXF_INIT 0
|
||||
#define FWXF_INQ 1
|
||||
#define FWXF_START 2
|
||||
#define FWXF_SENT 3
|
||||
#define FWXF_SENTERR 4
|
||||
#define FWXF_BUSY 8
|
||||
#define FWXF_RCVD 10
|
||||
uint8_t state;
|
||||
#define FWXF_INIT 0x00
|
||||
#define FWXF_INQ 0x01
|
||||
#define FWXF_START 0x02
|
||||
#define FWXF_SENT 0x04
|
||||
#define FWXF_SENTERR 0x08
|
||||
#define FWXF_BUSY 0x10
|
||||
#define FWXF_RCVD 0x20
|
||||
|
||||
#define FWXF_WAKE 0x80
|
||||
uint8_t flag;
|
||||
int8_t tl;
|
||||
void (*hand) (struct fw_xfer *);
|
||||
struct {
|
||||
|
@ -276,11 +291,12 @@ int fw_xferlist_add (struct fw_xferlist *, struct malloc_type *, int, int, int,
|
|||
struct firewire_comm *, void *, void (*)(struct fw_xfer *));
|
||||
void fw_xferlist_remove (struct fw_xferlist *);
|
||||
int fw_asyreq (struct firewire_comm *, int, struct fw_xfer*);
|
||||
void fw_busreset (struct firewire_comm *);
|
||||
void fw_busreset (struct firewire_comm *, uint32_t);
|
||||
uint16_t fw_crc16 (uint32_t *, uint32_t);
|
||||
void fw_xfer_timeout (void *);
|
||||
void fw_xfer_done (struct fw_xfer *);
|
||||
void fw_asy_callback (struct fw_xfer *);
|
||||
void fw_xferwake (struct fw_xfer *);
|
||||
int fw_xferwait (struct fw_xfer *);
|
||||
void fw_asy_callback_free (struct fw_xfer *);
|
||||
struct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int);
|
||||
struct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
|
||||
|
@ -289,8 +305,9 @@ void fw_drain_txq (struct firewire_comm *);
|
|||
int fwdev_makedev (struct firewire_softc *);
|
||||
int fwdev_destroydev (struct firewire_softc *);
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
void fwdev_clone (void *, struct ucred *, char *, int, DEV_T *);
|
||||
void fwdev_clone (void *, struct ucred *, char *, int, fw_dev_t *);
|
||||
#endif
|
||||
int fw_open_isodma(struct firewire_comm *, int);
|
||||
|
||||
extern int firewire_debug;
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -298,6 +315,7 @@ extern devclass_t firewire_devclass;
|
|||
#elif defined(__NetBSD__)
|
||||
extern struct cfdriver ieee1394if_cd;
|
||||
#endif
|
||||
extern int firewire_phydma_enable;
|
||||
|
||||
#ifdef __DragonFly__
|
||||
#define FWPRI PCATCH
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fwdev.c,v 1.12 2007/10/19 12:00:13 ad Exp $ */
|
||||
/* $NetBSD: fwdev.c,v 1.13 2007/11/05 19:08:56 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi Shimokawa
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
|
@ -32,7 +32,7 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwdev.c,v 1.49 2007/03/16 05:39:33 simokawa Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/fwdev.c,v 1.52 2007/06/06 14:31:36 simokawa Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -124,7 +124,7 @@ struct cdevsw firewire_cdevsw = {
|
|||
.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,
|
||||
|
@ -233,8 +233,18 @@ FW_OPEN(fw)
|
|||
|
||||
FWDEV_OPEN_START;
|
||||
|
||||
if (dev->si_drv1 != NULL)
|
||||
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) {
|
||||
|
@ -247,10 +257,6 @@ FW_OPEN(fw)
|
|||
}
|
||||
#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;
|
||||
d->fc = sc->fc;
|
||||
STAILQ_INIT(&d->binds);
|
||||
|
@ -336,14 +342,18 @@ fw_read_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
|
|||
struct fw_pkt *fp;
|
||||
const 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 = fw_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 ?? */
|
||||
|
@ -361,7 +371,9 @@ out:
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -389,6 +401,7 @@ FW_READ(fw)
|
|||
if (ir->buf == NULL)
|
||||
return (EIO);
|
||||
|
||||
FW_GLOCK(fc);
|
||||
readloop:
|
||||
if (ir->stproc == NULL) {
|
||||
/* iso bulkxfer */
|
||||
|
@ -405,15 +418,17 @@ readloop:
|
|||
if (slept == 0) {
|
||||
slept = 1;
|
||||
ir->flag |= FWXFERQ_WAKEUP;
|
||||
err = tsleep(ir, FWPRI, "fw_read", hz);
|
||||
err = fw_msleep(ir, FW_GMTX(fc), FWPRI, "fw_read", hz);
|
||||
ir->flag &= ~FWXFERQ_WAKEUP;
|
||||
if (err == 0)
|
||||
goto readloop;
|
||||
} else if (slept == 1)
|
||||
err = EIO;
|
||||
FW_GUNLOCK(fc);
|
||||
return err;
|
||||
} 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)
|
||||
|
@ -434,6 +449,7 @@ readloop:
|
|||
}
|
||||
if (uio->uio_resid >= ir->psize) {
|
||||
slept = -1;
|
||||
FW_GLOCK(fc);
|
||||
goto readloop;
|
||||
}
|
||||
}
|
||||
|
@ -470,13 +486,13 @@ fw_write_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
|
|||
|
||||
xfer->fc = d->fc;
|
||||
xfer->sc = NULL;
|
||||
xfer->hand = fw_asy_callback;
|
||||
xfer->hand = fw_xferwake;
|
||||
xfer->send.spd = 2 /* XXX */;
|
||||
|
||||
if ((err = fw_asyreq(xfer->fc, -1, xfer)))
|
||||
goto out;
|
||||
|
||||
if ((err = tsleep(xfer, FWPRI, "fwwa", 0)))
|
||||
if ((err = fw_xferwait(xfer)))
|
||||
goto out;
|
||||
|
||||
if (xfer->resp != 0) {
|
||||
|
@ -484,8 +500,10 @@ fw_write_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (xfer->state == FWXF_RCVD) {
|
||||
if (xfer->flag == FWXF_RCVD) {
|
||||
FW_GLOCK(xfer->fc);
|
||||
STAILQ_INSERT_TAIL(&d->rq, xfer, link);
|
||||
FW_GUNLOCK(xfer->fc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -514,6 +532,8 @@ FW_WRITE(fw)
|
|||
|
||||
if (it->buf == NULL)
|
||||
return (EIO);
|
||||
|
||||
FW_GLOCK(fc);
|
||||
isoloop:
|
||||
if (it->stproc == NULL) {
|
||||
it->stproc = STAILQ_FIRST(&it->stfree);
|
||||
|
@ -524,18 +544,21 @@ isoloop:
|
|||
it->queued = 0;
|
||||
} else if (slept == 0) {
|
||||
slept = 1;
|
||||
#if 0 /* XXX to avoid lock recursion */
|
||||
err = fc->itx_enable(fc, it->dmach);
|
||||
if (err)
|
||||
return err;
|
||||
err = tsleep(it, FWPRI, "fw_write", hz);
|
||||
goto out;
|
||||
#endif
|
||||
err = fw_msleep(it, FW_GMTX(fc), FWPRI, "fw_write", hz);
|
||||
if (err)
|
||||
return err;
|
||||
goto out;
|
||||
goto isoloop;
|
||||
} else {
|
||||
err = EIO;
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
FW_GUNLOCK(fc);
|
||||
fp = (struct fw_pkt *)fwdma_v_addr(it->buf,
|
||||
it->stproc->poffset + it->queued);
|
||||
err = uiomove((void *)fp, sizeof(struct fw_isohdr), uio);
|
||||
|
@ -551,9 +574,14 @@ isoloop:
|
|||
}
|
||||
if (uio->uio_resid >= sizeof(struct fw_isohdr)) {
|
||||
slept = 0;
|
||||
FW_GLOCK(fc);
|
||||
goto isoloop;
|
||||
}
|
||||
return err;
|
||||
|
||||
out:
|
||||
FW_GUNLOCK(fc);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -564,7 +592,9 @@ fw_hand(struct fw_xfer *xfer)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -605,19 +635,17 @@ FW_IOCTL(fw)
|
|||
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);
|
||||
|
@ -633,19 +661,17 @@ FW_IOCTL(fw)
|
|||
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 */0);
|
||||
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);
|
||||
|
@ -699,8 +725,7 @@ FW_IOCTL(fw)
|
|||
fwdev = fw_noderesolve_eui64(fc,
|
||||
&asyreq->req.dst.eui);
|
||||
if (fwdev == NULL) {
|
||||
device_printf(fc->bdev,
|
||||
"cannot find node\n");
|
||||
fw_printf(fc->bdev, "cannot find node\n");
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -719,11 +744,11 @@ FW_IOCTL(fw)
|
|||
bcopy((char *)fp + tinfo->hdr_len,
|
||||
(void *)xfer->send.payload, pay_len);
|
||||
xfer->send.spd = asyreq->req.sped;
|
||||
xfer->hand = fw_asy_callback;
|
||||
xfer->hand = fw_xferwake;
|
||||
|
||||
if ((err = fw_asyreq(fc, -1, xfer)) != 0)
|
||||
goto out;
|
||||
if ((err = tsleep(xfer, FWPRI, "asyreq", hz)) != 0)
|
||||
if ((err = fw_xferwait(xfer)) != 0)
|
||||
goto out;
|
||||
if (xfer->resp != 0) {
|
||||
err = EIO;
|
||||
|
@ -777,7 +802,7 @@ out:
|
|||
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;
|
||||
|
@ -918,15 +943,15 @@ fwdev_makedev(struct firewire_softc *sc)
|
|||
#if defined(__DragonFly__)
|
||||
int unit;
|
||||
|
||||
unit = device_get_unit(sc->fc->bdev);
|
||||
unit = fw_get_unit(sc->fc->bdev);
|
||||
cdevsw_add(&firewire_cdevsw, FW_UNITMASK, FW_UNIT(unit));
|
||||
#elif __FreeBSD_version < 500000
|
||||
cdevsw_add(&firewire_cdevsw);
|
||||
#else
|
||||
DEV_T d;
|
||||
fw_dev_t d;
|
||||
int unit;
|
||||
|
||||
unit = device_get_unit(sc->fc->bdev);
|
||||
unit = fw_get_unit(sc->fc->bdev);
|
||||
sc->dev = make_dev(&firewire_cdevsw, MAKEMINOR(0, unit, 0),
|
||||
UID_ROOT, GID_OPERATOR, 0660,
|
||||
"fw%d.%d", unit, 0);
|
||||
|
@ -950,7 +975,7 @@ fwdev_destroydev(struct firewire_softc *sc)
|
|||
#if defined(__DragonFly__)
|
||||
int unit;
|
||||
|
||||
unit = device_get_unit(sc->fc->bdev);
|
||||
unit = fw_get_unit(sc->fc->bdev);
|
||||
cdevsw_remove(&firewire_cdevsw, FW_UNITMASK, FW_UNIT(unit));
|
||||
#elif __FreeBSD_version < 500000
|
||||
cdevsw_remove(&firewire_cdevsw);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fwdma.c,v 1.9 2007/10/19 12:00:13 ad Exp $ */
|
||||
/* $NetBSD: fwdma.c,v 1.10 2007/11/05 19:08:56 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2003
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FBSDID
|
||||
__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwdma.c,v 1.7 2005/01/06 01:42:41 imp Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/firewire/fwdma.c,v 1.9 2007/06/06 14:31:36 simokawa Exp $");
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -111,7 +111,7 @@ fwdma_malloc(struct firewire_comm *fc, int alignment, bus_size_t size,
|
|||
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
|
||||
/*flags*/ BUS_DMA_ALLOCNOW,
|
||||
/*lockfunc*/busdma_lock_mutex,
|
||||
/*lockarg*/&Giant,
|
||||
/*lockarg*/FW_GMTX(fc),
|
||||
&dma->fw_dma_tag);
|
||||
if (err) {
|
||||
printf("fwdma_malloc: failed(1)\n");
|
||||
|
@ -219,7 +219,7 @@ fwdma_malloc_multiseg(struct firewire_comm *fc, int alignment,
|
|||
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
|
||||
/*flags*/ BUS_DMA_ALLOCNOW,
|
||||
/*lockfunc*/busdma_lock_mutex,
|
||||
/*lockarg*/&Giant,
|
||||
/*lockarg*/FW_GMTX(fc),
|
||||
&am->fw_dma_tag)) {
|
||||
printf("fwdma_malloc_multiseg: tag_create failed\n");
|
||||
free(am, M_FW);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fwmem.c,v 1.6 2007/10/19 12:00:13 ad Exp $ */
|
||||
/* $NetBSD: fwmem.c,v 1.7 2007/11/05 19:08:56 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2002-2003
|
||||
* Hidetoshi Shimokawa. All rights reserved.
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FBSDID
|
||||
__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwmem.c,v 1.32 2007/03/16 05:11:42 simokawa Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/firewire/fwmem.c,v 1.34 2007/06/06 14:31:36 simokawa Exp $");
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
@ -209,6 +209,7 @@ MALLOC_DEFINE(M_FWMEM, "fwmem", "fwmem/IEEE1394");
|
|||
|
||||
struct fwmem_softc {
|
||||
struct fw_eui64 eui;
|
||||
struct firewire_softc *sc;
|
||||
int refcount;
|
||||
STAILQ_HEAD(, fw_xfer) xferlist;
|
||||
};
|
||||
|
@ -399,18 +400,24 @@ FW_OPEN(fwmem)
|
|||
FW_OPEN_START;
|
||||
|
||||
if (dev->si_drv1 != NULL) {
|
||||
if ((flags & FWRITE) != 0)
|
||||
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)
|
||||
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;
|
||||
bcopy(&fwmem_eui64, &fms->eui, sizeof(struct fw_eui64));
|
||||
dev->si_drv1 = (void *)fms;
|
||||
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;
|
||||
STAILQ_INIT(&fms->xferlist);
|
||||
xfer = fw_xfer_alloc(M_FWMEM);
|
||||
|
@ -429,7 +436,10 @@ FW_CLOSE(fwmem)
|
|||
FW_CLOSE_START;
|
||||
|
||||
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) {
|
||||
|
@ -473,7 +483,7 @@ fwmem_strategy(struct bio *bp)
|
|||
struct fwmem_softc *fms;
|
||||
struct fw_device *fwdev;
|
||||
struct fw_xfer *xfer;
|
||||
int err=0, s, iolen;
|
||||
int err = 0, s, iolen;
|
||||
|
||||
CTR0(KTR_DEV, "strategy");
|
||||
|
||||
|
@ -481,7 +491,7 @@ fwmem_strategy(struct bio *bp)
|
|||
|
||||
s = splfw();
|
||||
fms = (struct fwmem_softc *)dev->si_drv1;
|
||||
fwdev = fw_noderesolve_eui64(sc->fc, &fms->eui);
|
||||
fwdev = fw_noderesolve_eui64(fms->sc->fc, &fms->eui);
|
||||
if (fwdev == NULL) {
|
||||
if (fwmem_debug)
|
||||
printf("fwmem: no such device ID:%08x%08x\n",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fwohcireg.h,v 1.16 2007/03/04 06:02:07 christos Exp $ */
|
||||
/* $NetBSD: fwohcireg.h,v 1.17 2007/11/05 19:08:57 kiyohara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi Shimokawa
|
||||
|
@ -33,7 +33,7 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwohcireg.h,v 1.22 2005/05/20 12:37:16 marius Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/fwohcireg.h,v 1.23 2007/04/30 14:06:30 simokawa Exp $
|
||||
*
|
||||
*/
|
||||
#define PCI_CBMEM PCIR_BAR(0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fwohcivar.h,v 1.26 2007/04/21 15:27:44 kiyohara Exp $ */
|
||||
/* $NetBSD: fwohcivar.h,v 1.27 2007/11/05 19:08:57 kiyohara Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi SHimokawa
|
||||
|
@ -33,19 +33,10 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwohcivar.h,v 1.15 2007/03/16 04:25:02 simokawa Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/fwohcivar.h,v 1.16 2007/06/06 14:31:36 simokawa Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__DragonFly__) || __FreeBSD_version < 500000 || defined(__NetBSD__)
|
||||
#define FWOHCI_TASKQUEUE 0
|
||||
#else
|
||||
#define FWOHCI_TASKQUEUE 1
|
||||
#endif
|
||||
#if FWOHCI_TASKQUEUE
|
||||
#include <sys/taskqueue.h>
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
MALLOC_DECLARE(M_FW);
|
||||
#endif
|
||||
|
@ -64,8 +55,6 @@ typedef struct fwohci_softc {
|
|||
struct resource *irq_res;
|
||||
#elif defined(__NetBSD__)
|
||||
bus_size_t bssize;
|
||||
void *sc_shutdownhook;
|
||||
void *sc_powerhook;
|
||||
#endif
|
||||
struct fwohci_dbch{
|
||||
u_int ndb;
|
||||
|
@ -89,17 +78,22 @@ typedef struct fwohci_softc {
|
|||
struct fwdma_alloc crom_dma;
|
||||
struct fwdma_alloc dummy_dma;
|
||||
uint32_t intmask, irstat, itstat;
|
||||
#if FWOHCI_TASKQUEUE
|
||||
uint32_t intstat;
|
||||
struct task fwohci_task_complete;
|
||||
#endif
|
||||
fw_task_t fwohci_task_busreset;
|
||||
fw_task_t fwohci_task_sid;
|
||||
fw_task_t fwohci_task_dma;
|
||||
int cycle_lost;
|
||||
} fwohci_softc_t;
|
||||
|
||||
FW_INTR(fwohci);
|
||||
void fwohci_intr (void *arg);
|
||||
int fwohci_filt (void *arg);
|
||||
int fwohci_init (struct fwohci_softc *, device_t);
|
||||
void fwohci_poll (struct firewire_comm *, int, int);
|
||||
void fwohci_reset (struct fwohci_softc *, device_t);
|
||||
FWOHCI_DETACH();
|
||||
#if defined(__FreeBSD__)
|
||||
int fwohci_detach(struct fwohci_softc *, device_t);
|
||||
#elif defined(__NetBSD__)
|
||||
int fwohci_detach(struct fwohci_softc *, int);
|
||||
#endif
|
||||
int fwohci_resume (struct fwohci_softc *, device_t);
|
||||
FWOHCI_STOP();
|
||||
int fwohci_stop (struct fwohci_softc *, device_t dev);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_fwip.c,v 1.9 2007/10/19 12:00:13 ad Exp $ */
|
||||
/* $NetBSD: if_fwip.c,v 1.10 2007/11/05 19:08:57 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004
|
||||
* Doug Rabson
|
||||
|
@ -34,7 +34,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/if_fwip.c,v 1.14 2007/03/16 05:39:33 simokawa Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/if_fwip.c,v 1.16 2007/06/06 14:31:36 simokawa Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
|
@ -106,10 +106,10 @@
|
|||
#if defined(__FreeBSD__)
|
||||
#define FWIPDEBUG if (fwipdebug) if_printf
|
||||
#elif defined(__NetBSD__)
|
||||
#define FWIPDEBUG(ifp, fmt, ...) \
|
||||
if (fwipdebug) {\
|
||||
aprint_normal("%s: ", (ifp)->if_xname); \
|
||||
aprint_normal((fmt) ,##__VA_ARGS__); \
|
||||
#define FWIPDEBUG(ifp, fmt, ...) \
|
||||
if (fwipdebug) { \
|
||||
printf("%s: ", (ifp)->if_xname);\
|
||||
printf((fmt) , ##__VA_ARGS__); \
|
||||
}
|
||||
#endif
|
||||
#define TX_MAX_QUEUE (FWMAXQUEUE - 1)
|
||||
|
@ -124,15 +124,18 @@ int fwipactivate (struct device *, enum devact);
|
|||
/* network interface */
|
||||
static void fwip_start (struct ifnet *);
|
||||
static int fwip_ioctl (struct ifnet *, u_long, void *);
|
||||
IF_INIT(fwip);
|
||||
IF_STOP(fwip);
|
||||
#if defined(__FreeBSD__)
|
||||
static void fwip_init(void *);
|
||||
static void fwip_stop(struct fwip_softc *);
|
||||
#elif defined(__NetBSD__)
|
||||
static int fwip_init(struct ifnet *);
|
||||
static void fwip_stop(struct ifnet *, int);
|
||||
#endif
|
||||
|
||||
static void fwip_post_busreset (void *);
|
||||
static void fwip_output_callback (struct fw_xfer *);
|
||||
static void fwip_async_output (struct fwip_softc *, struct ifnet *);
|
||||
#if defined(__FreeBSD__)
|
||||
static void fwip_start_send (void *, int);
|
||||
#endif
|
||||
static void fwip_stream_input (struct fw_xferq *);
|
||||
static void fwip_unicast_input(struct fw_xfer *);
|
||||
|
||||
|
@ -223,7 +226,7 @@ fwip_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
|||
static void
|
||||
fwip_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
BUS_ADD_CHILD(parent, 0, "fwip", device_get_unit(parent));
|
||||
BUS_ADD_CHILD(parent, 0, "fwip", fw_get_unit(parent));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -232,7 +235,7 @@ fwip_probe(device_t dev)
|
|||
device_t pa;
|
||||
|
||||
pa = device_get_parent(dev);
|
||||
if(device_get_unit(dev) != device_get_unit(pa)){
|
||||
if(fw_get_unit(dev) != fw_get_unit(pa)){
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
|
@ -264,6 +267,7 @@ FW_ATTACH(fwip)
|
|||
if (ifp == NULL)
|
||||
FW_ATTACH_RETURN(ENOSPC);
|
||||
|
||||
fw_mtx_init(&fwip->mtx, "fwip", NULL, MTX_DEF);
|
||||
/* XXX */
|
||||
fwip->dma_ch = -1;
|
||||
|
||||
|
@ -274,7 +278,7 @@ FW_ATTACH(fwip)
|
|||
fwip->fd.post_explore = NULL;
|
||||
fwip->fd.post_busreset = fwip_post_busreset;
|
||||
fwip->fw_softc.fwip = fwip;
|
||||
TASK_INIT(&fwip->start_send, 0, fwip_start_send, fwip);
|
||||
FW_TASK_INIT(&fwip->start_send, 0, fwip_start_send, fwip);
|
||||
|
||||
/*
|
||||
* Encode our hardware the way that arp likes it.
|
||||
|
@ -299,8 +303,7 @@ FW_ATTACH(fwip)
|
|||
IFQ_SET_READY(&ifp->if_snd);
|
||||
#endif
|
||||
SET_IFFUNC(ifp, fwip_start, fwip_ioctl, fwip_init, fwip_stop);
|
||||
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;
|
||||
|
@ -380,6 +383,7 @@ FW_DETACH(fwip)
|
|||
|
||||
FWIP_STOP(fwip);
|
||||
FIREWIRE_IFDETACH(ifp);
|
||||
fw_mtx_destroy(&fwip->mtx);
|
||||
|
||||
splx(s);
|
||||
return 0;
|
||||
|
@ -422,18 +426,12 @@ IF_INIT(fwip)
|
|||
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");
|
||||
IF_INIT_RETURN(ENXIO);
|
||||
found:
|
||||
fwip->dma_ch = i;
|
||||
/* allocate DMA channel and init packet mode */
|
||||
xferq->flag |= FWXFERQ_OPEN | FWXFERQ_EXTBUF |
|
||||
FWXFERQ_HANDLER | FWXFERQ_STREAM;
|
||||
fwip->dma_ch = fw_open_isodma(fc, /* tx */0);
|
||||
if (fwip->dma_ch < 0)
|
||||
IF_INIT_RETURN(ENXIO);
|
||||
xferq = fc->ir[fwip->dma_ch];
|
||||
xferq->flag |=
|
||||
FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_STREAM;
|
||||
xferq->flag &= ~0xff;
|
||||
xferq->flag |= broadcast_channel & 0xff;
|
||||
/* register fwip_input handler */
|
||||
|
@ -644,8 +642,6 @@ fwip_output_callback(struct fw_xfer *xfer)
|
|||
struct ifnet *ifp;
|
||||
int s;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
fwip = (struct fwip_softc *)xfer->sc;
|
||||
ifp = fwip->fw_softc.fwip_ifp;
|
||||
/* XXX error check */
|
||||
|
@ -657,12 +653,15 @@ fwip_output_callback(struct fw_xfer *xfer)
|
|||
fw_xfer_unload(xfer);
|
||||
|
||||
s = splfwnet();
|
||||
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
|
||||
|
@ -672,8 +671,6 @@ fwip_start(struct ifnet *ifp)
|
|||
((struct fwip_eth_softc *)ifp->if_softc)->fwip;
|
||||
int s;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
FWIPDEBUG(ifp, "starting\n");
|
||||
|
||||
if (fwip->dma_ch < 0) {
|
||||
|
@ -726,19 +723,29 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
|
|||
int error;
|
||||
int i = 0;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
xfer = NULL;
|
||||
xferq = fwip->fd.fc->atq;
|
||||
while (xferq->queued < xferq->maxq - 1) {
|
||||
xferq = fc->atq;
|
||||
while ((xferq->queued < xferq->maxq - 1) &&
|
||||
(ifp->if_snd.ifq_head != NULL)) {
|
||||
FWIP_LOCK(fwip);
|
||||
xfer = STAILQ_FIRST(&fwip->xferlist);
|
||||
if (xfer == NULL) {
|
||||
FWIP_UNLOCK(fwip);
|
||||
#if 0
|
||||
printf("if_fwip: lack of xfer\n");
|
||||
return;
|
||||
}
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL)
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&fwip->xferlist, link);
|
||||
FWIP_UNLOCK(fwip);
|
||||
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL) {
|
||||
FWIP_LOCK(fwip);
|
||||
STAILQ_INSERT_HEAD(&fwip->xferlist, xfer, link);
|
||||
FWIP_UNLOCK(fwip);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dig out the link-level address which
|
||||
|
@ -752,8 +759,6 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
|
|||
else
|
||||
destfw = (struct fw_hwaddr *) (mtag + 1);
|
||||
|
||||
STAILQ_REMOVE_HEAD(&fwip->xferlist, link);
|
||||
|
||||
/*
|
||||
* We don't do any bpf stuff here - the generic code
|
||||
* in firewire_output gives the packet to bpf before
|
||||
|
@ -845,7 +850,9 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
|
|||
* for later transmission.
|
||||
*/
|
||||
xfer->mbuf = 0;
|
||||
FWIP_LOCK(fwip);
|
||||
STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
|
||||
FWIP_UNLOCK(fwip);
|
||||
IF_PREPEND(&ifp->if_snd, m);
|
||||
break;
|
||||
}
|
||||
|
@ -864,25 +871,17 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
|
|||
if (i > 1)
|
||||
printf("%d queued\n", i);
|
||||
#endif
|
||||
if (i > 0) {
|
||||
#if 1
|
||||
if (i > 0)
|
||||
xferq->start(fc);
|
||||
#else
|
||||
taskqueue_enqueue(taskqueue_swi_giant, &fwip->start_send);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
static void
|
||||
fwip_start_send (void *arg, int count)
|
||||
{
|
||||
struct fwip_softc *fwip = arg;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
fwip->fd.fc->atq->start(fwip->fd.fc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Async. stream output */
|
||||
static void
|
||||
|
@ -897,8 +896,6 @@ fwip_stream_input(struct fw_xferq *xferq)
|
|||
uint16_t src;
|
||||
uint32_t *p;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
fwip = (struct fwip_softc *)xferq->sc;
|
||||
ifp = fwip->fw_softc.fwip_ifp;
|
||||
while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) {
|
||||
|
@ -998,8 +995,6 @@ fwip_unicast_input_recycle(struct fwip_softc *fwip, struct fw_xfer *xfer)
|
|||
{
|
||||
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.
|
||||
|
@ -1026,8 +1021,6 @@ fwip_unicast_input(struct fw_xfer *xfer)
|
|||
//struct fw_pkt *sfp;
|
||||
int rtcode;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
fwip = (struct fwip_softc *)xfer->sc;
|
||||
ifp = fwip->fw_softc.fwip_ifp;
|
||||
m = xfer->mbuf;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_fwipvar.h,v 1.3 2007/04/21 15:27:44 kiyohara Exp $ */
|
||||
/* $NetBSD: if_fwipvar.h,v 1.4 2007/11/05 19:08:57 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004
|
||||
* Doug Rabson
|
||||
|
@ -34,7 +34,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/if_fwipvar.h,v 1.4 2005/06/10 16:49:08 brooks Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/if_fwipvar.h,v 1.5 2007/06/06 14:31:36 simokawa Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_FWIPVAR_H_
|
||||
|
@ -47,9 +47,7 @@ struct fwip_softc {
|
|||
struct fw_bind fwb;
|
||||
struct fw_eui64 last_dest;
|
||||
struct fw_pkt last_hdr;
|
||||
#if defined(__FreeBSD__)
|
||||
struct task start_send;
|
||||
#endif
|
||||
fw_task_t start_send;
|
||||
STAILQ_HEAD(, fw_xfer) xferlist;
|
||||
struct crom_chunk unit4; /* unit directory for IPv4 */
|
||||
struct crom_chunk spec4; /* specifier description IPv4 */
|
||||
|
@ -64,5 +62,10 @@ struct fwip_softc {
|
|||
struct ifnet *fwip_ifp;
|
||||
struct fwip_softc *fwip;
|
||||
} fw_softc;
|
||||
fw_mtx_t mtx;
|
||||
};
|
||||
|
||||
#define FWIP_LOCK(fwip) fw_mtx_lock(&(fwip)->mtx)
|
||||
#define FWIP_UNLOCK(fwip) fw_mtx_unlock(&(fwip)->mtx)
|
||||
|
||||
#endif /* !_NET_IF_FWIPVAR_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sbp.c,v 1.18 2007/10/19 12:00:13 ad Exp $ */
|
||||
/* $NetBSD: sbp.c,v 1.19 2007/11/05 19:08:57 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2003 Hidetoshi Shimokawa
|
||||
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
|
||||
|
@ -32,7 +32,7 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/sbp.c,v 1.89 2007/03/16 05:39:33 simokawa Exp $
|
||||
* $FreeBSD: src/sys/dev/firewire/sbp.c,v 1.92 2007/06/06 14:31:36 simokawa Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -429,7 +429,10 @@ struct sbp_softc {
|
|||
struct timeval last_busreset;
|
||||
#define SIMQ_FREEZED 1
|
||||
int flags;
|
||||
fw_mtx_t mtx;
|
||||
};
|
||||
#define SBP_LOCK(sbp) fw_mtx_lock(&(sbp)->mtx)
|
||||
#define SBP_UNLOCK(sbp) fw_mtx_unlock(&(sbp)->mtx)
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
int sbpmatch (struct device *, struct cfdata *, void *);
|
||||
|
@ -480,7 +483,6 @@ static void sbp_cam_detach_target (struct sbp_target *);
|
|||
#define SBP_DETACH_TARGET(st) sbp_cam_detach_target((st))
|
||||
#elif defined(__NetBSD__)
|
||||
/* scsipi related functions */
|
||||
static void fw_kthread_create0(void *);
|
||||
static void sbp_scsipi_scan_target(void *);
|
||||
static void sbp_scsipi_detach_sdev(struct sbp_dev *);
|
||||
static void sbp_scsipi_detach_target (struct sbp_target *);
|
||||
|
@ -542,7 +544,7 @@ SBP_DEBUG(0)
|
|||
printf("sbp_identify\n");
|
||||
END_DEBUG
|
||||
|
||||
child = BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent));
|
||||
child = BUS_ADD_CHILD(parent, 0, "sbp", fw_get_unit(parent));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -559,7 +561,7 @@ SBP_DEBUG(0)
|
|||
END_DEBUG
|
||||
|
||||
pa = device_get_parent(dev);
|
||||
if(device_get_unit(dev) != device_get_unit(pa)){
|
||||
if(fw_get_unit(dev) != fw_get_unit(pa)){
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
|
@ -579,8 +581,8 @@ sbpmatch(struct device *parent, struct cfdata *cf, void *aux)
|
|||
struct fw_attach_args *fwa = aux;
|
||||
|
||||
if (strcmp(fwa->name, "sbp") == 0)
|
||||
return (1);
|
||||
return (0);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -590,7 +592,7 @@ sbp_show_sdev_info(struct sbp_dev *sdev, int new)
|
|||
struct fw_device *fwdev;
|
||||
|
||||
printf("%s:%d:%d ",
|
||||
device_get_nameunit(sdev->target->sbp->fd.dev),
|
||||
fw_get_nameunit(sdev->target->sbp->fd.dev),
|
||||
sdev->target->target_id,
|
||||
sdev->lun_id
|
||||
);
|
||||
|
@ -643,7 +645,7 @@ END_DEBUG
|
|||
}
|
||||
if (maxlun < 0)
|
||||
printf("%s:%d no LUN found\n",
|
||||
device_get_nameunit(target->sbp->fd.dev),
|
||||
fw_get_nameunit(target->sbp->fd.dev),
|
||||
target->target_id);
|
||||
|
||||
maxlun ++;
|
||||
|
@ -713,7 +715,7 @@ END_DEBUG
|
|||
sdev->lun_id = lun;
|
||||
sdev->target = target;
|
||||
STAILQ_INIT(&sdev->ocbs);
|
||||
CALLOUT_INIT(&sdev->login_callout);
|
||||
fw_callout_init(&sdev->login_callout);
|
||||
sdev->status = SBP_DEV_RESET;
|
||||
new = 1;
|
||||
SBP_DEVICE_PREATTACH();
|
||||
|
@ -802,8 +804,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);
|
||||
fw_callout_init(&target->mgm_ocb_timeout);
|
||||
fw_callout_init(&target->scan_callout);
|
||||
|
||||
target->luns = NULL;
|
||||
target->num_lun = 0;
|
||||
|
@ -858,17 +860,17 @@ sbp_login(struct sbp_dev *sdev)
|
|||
int ticks = 0;
|
||||
|
||||
microtime(&delta);
|
||||
timevalsub(&delta, &sdev->target->sbp->last_busreset);
|
||||
fw_timevalsub(&delta, &sdev->target->sbp->last_busreset);
|
||||
t.tv_sec = login_delay / 1000;
|
||||
t.tv_usec = (login_delay % 1000) * 1000;
|
||||
timevalsub(&t, &delta);
|
||||
fw_timevalsub(&t, &delta);
|
||||
if (t.tv_sec >= 0 && t.tv_usec > 0)
|
||||
ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
|
||||
SBP_DEBUG(0)
|
||||
printf("%s: sec = %jd usec = %ld ticks = %d\n", __func__,
|
||||
(intmax_t)t.tv_sec, t.tv_usec, ticks);
|
||||
END_DEBUG
|
||||
callout_reset(&sdev->login_callout, ticks,
|
||||
fw_callout_reset(&sdev->login_callout, ticks,
|
||||
sbp_login_callout, (void *)(sdev));
|
||||
}
|
||||
|
||||
|
@ -896,8 +898,10 @@ END_DEBUG
|
|||
continue;
|
||||
if (sdev->status != SBP_DEV_DEAD) {
|
||||
if (SBP_DEVICE(sdev) != NULL) {
|
||||
SBP_LOCK(sbp);
|
||||
SBP_DEVICE_FREEZE(sdev, 1);
|
||||
sdev->freeze ++;
|
||||
SBP_UNLOCK(sbp);
|
||||
}
|
||||
sbp_probe_lun(sdev);
|
||||
SBP_DEBUG(0)
|
||||
|
@ -929,8 +933,10 @@ SBP_DEBUG(0)
|
|||
printf("lost target\n");
|
||||
END_DEBUG
|
||||
if (SBP_DEVICE(sdev) != NULL) {
|
||||
SBP_LOCK(sbp);
|
||||
SBP_DEVICE_FREEZE(sdev, 1);
|
||||
sdev->freeze ++;
|
||||
SBP_UNLOCK(sbp);
|
||||
}
|
||||
sdev->status = SBP_DEV_RETRY;
|
||||
sbp_abort_all_ocbs(sdev, XS_SCSI_BUS_RESET);
|
||||
|
@ -970,7 +976,9 @@ END_DEBUG
|
|||
if (!alive)
|
||||
return;
|
||||
|
||||
SBP_LOCK(sbp);
|
||||
SBP_BUS_FREEZE(sbp);
|
||||
SBP_UNLOCK(sbp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1008,7 +1016,9 @@ END_DEBUG
|
|||
if (target->num_lun == 0)
|
||||
sbp_free_target(target);
|
||||
|
||||
SBP_LOCK(sbp);
|
||||
SBP_BUS_THAW(sbp);
|
||||
SBP_UNLOCK(sbp);
|
||||
}
|
||||
|
||||
#if NEED_RESPONSE
|
||||
|
@ -1038,7 +1048,9 @@ sbp_xfer_free(struct fw_xfer *xfer)
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -1181,34 +1193,21 @@ END_DEBUG
|
|||
sxfer->ccb_h.ccb_sdev_ptr = sdev;
|
||||
|
||||
/* The scan is in progress now. */
|
||||
SBP_LOCK(target->sbp);
|
||||
xpt_action(sxfer);
|
||||
xpt_release_devq(sdev->path, sdev->freeze, TRUE);
|
||||
sdev->freeze = 1;
|
||||
SBP_UNLOCK(target->sbp);
|
||||
}
|
||||
|
||||
static inline void
|
||||
sbp_scan_dev(struct sbp_dev *sdev)
|
||||
{
|
||||
sdev->status = SBP_DEV_PROBE;
|
||||
callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
|
||||
fw_callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
|
||||
sbp_cam_scan_target, (void *)sdev->target);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
fw_kthread_create0(void *arg)
|
||||
{
|
||||
struct sbp_softc *sbp = (struct sbp_softc *)arg;
|
||||
|
||||
/* create thread */
|
||||
if (kthread_create(PRI_NONE, 0, NULL, sbp_scsipi_scan_target,
|
||||
&sbp->target, &sbp->lwp, "sbp%d_attach",
|
||||
device_unit(sbp->fd.dev))) {
|
||||
|
||||
device_printf(sbp->fd.dev, "unable to create thread");
|
||||
panic("fw_kthread_create");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sbp_scsipi_scan_target(void *arg)
|
||||
{
|
||||
|
@ -1313,8 +1312,10 @@ END_DEBUG
|
|||
|
||||
sbp_xfer_free(xfer);
|
||||
if (SBP_DEVICE(sdev)) {
|
||||
SBP_LOCK(sdev->target->sbp);
|
||||
SBP_DEVICE_THAW(sdev, sdev->freeze);
|
||||
sdev->freeze = 0;
|
||||
SBP_UNLOCK(sdev->target->sbp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1542,7 +1543,6 @@ sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
|
|||
fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
|
||||
|
||||
return xfer;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1556,23 +1556,28 @@ sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
|
|||
|
||||
target = sdev->target;
|
||||
nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
|
||||
dv_unit = device_get_unit(target->sbp->fd.dev);
|
||||
dv_unit = fw_get_unit(target->sbp->fd.dev);
|
||||
|
||||
s = splfw();
|
||||
SBP_LOCK(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;
|
||||
|
||||
|
@ -1609,7 +1614,9 @@ 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;
|
||||
}
|
||||
|
@ -1617,7 +1624,7 @@ start:
|
|||
target->mgm_ocb_cur = ocb;
|
||||
splx(s);
|
||||
|
||||
callout_reset(&target->mgm_ocb_timeout, 5*hz,
|
||||
fw_callout_reset(&target->mgm_ocb_timeout, 5*hz,
|
||||
sbp_mgm_timeout, (void *)ocb);
|
||||
xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
|
||||
if(xfer == NULL){
|
||||
|
@ -1655,7 +1662,7 @@ sbp_print_scsi_cmd(struct sbp_ocb *ocb)
|
|||
"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
|
||||
", flags: 0x%02x, "
|
||||
"%db cmd/%db data/%db sense\n",
|
||||
device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
|
||||
fw_get_nameunit(ocb->sdev->target->sbp->fd.dev),
|
||||
SCSI_XFER_TARGET(ocb->sxfer), SCSI_XFER_LUN(ocb->sxfer),
|
||||
SCSI_XFER_10BCMD_DUMP(ocb->sxfer),
|
||||
SCSI_XFER_DIR(ocb->sxfer),
|
||||
|
@ -1841,7 +1848,7 @@ END_DEBUG
|
|||
target = &sbp->target;
|
||||
l = SBP_ADDR2LUN(addr);
|
||||
if (l >= target->num_lun || target->luns[l] == NULL) {
|
||||
device_printf(sbp->fd.dev,
|
||||
fw_printf(sbp->fd.dev,
|
||||
"sbp_recv1: invalid lun %d (target=%d)\n",
|
||||
l, target->target_id);
|
||||
goto done0;
|
||||
|
@ -1858,7 +1865,7 @@ END_DEBUG
|
|||
ocb = target->mgm_ocb_cur;
|
||||
if (ocb != NULL) {
|
||||
if (OCB_MATCH(ocb, sbp_status)) {
|
||||
callout_stop(&target->mgm_ocb_timeout);
|
||||
fw_callout_stop(&target->mgm_ocb_timeout);
|
||||
target->mgm_ocb_cur = NULL;
|
||||
break;
|
||||
}
|
||||
|
@ -1933,8 +1940,10 @@ END_DEBUG
|
|||
/* we have to reset the fetch agent if it's dead */
|
||||
if (sbp_status->dead) {
|
||||
if (SBP_DEVICE(sdev) != NULL) {
|
||||
SBP_LOCK(sbp);
|
||||
SBP_DEVICE_FREEZE(sdev, 1);
|
||||
sdev->freeze ++;
|
||||
SBP_UNLOCK(sbp);
|
||||
}
|
||||
reset_agent = 1;
|
||||
}
|
||||
|
@ -2046,7 +2055,9 @@ printf("len %d\n", sbp_status->len);
|
|||
/* fix up inq data */
|
||||
if (SCSI_XFER_OPECODE(sxfer) == INQUIRY)
|
||||
sbp_fix_inq_data(ocb);
|
||||
SBP_LOCK(sbp);
|
||||
SCSI_TRANSFER_DONE(sxfer);
|
||||
SBP_UNLOCK(sbp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -2108,10 +2119,11 @@ FW_ATTACH(sbp)
|
|||
{
|
||||
FW_ATTACH_START(sbp, sbp, fwa);
|
||||
int dv_unit, error, s;
|
||||
struct firewire_comm *fc;
|
||||
SBP_ATTACH_START;
|
||||
|
||||
if (DFLTPHYS > SBP_MAXPHYS)
|
||||
device_printf(sbp->fd.dev,
|
||||
fw_printf(sbp->fd.dev,
|
||||
"Warning, DFLTPHYS(%dKB) is larger than "
|
||||
"SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
|
||||
SBP_MAXPHYS / 1024);
|
||||
|
@ -2121,12 +2133,13 @@ END_DEBUG
|
|||
|
||||
if (cold)
|
||||
sbp_cold ++;
|
||||
sbp->fd.fc = fwa->fc;
|
||||
sbp->fd.fc = fc = fwa->fc;
|
||||
fw_mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
|
||||
|
||||
if (max_speed < 0)
|
||||
max_speed = sbp->fd.fc->speed;
|
||||
max_speed = fc->speed;
|
||||
|
||||
error = fw_bus_dma_tag_create(/*parent*/sbp->fd.fc->dmat,
|
||||
error = fw_bus_dma_tag_create(/*parent*/fc->dmat,
|
||||
/* XXX shoud be 4 for sane backend? */
|
||||
/*alignment*/1,
|
||||
/*boundary*/0,
|
||||
|
@ -2137,7 +2150,7 @@ END_DEBUG
|
|||
/*maxsegsz*/SBP_SEG_MAX,
|
||||
/*flags*/BUS_DMA_ALLOCNOW,
|
||||
/*lockfunc*/busdma_lock_mutex,
|
||||
/*lockarg*/&Giant,
|
||||
/*lockarg*/&sbp->mtx,
|
||||
&sbp->dmat);
|
||||
if (error != 0) {
|
||||
printf("sbp_attach: Could not allocate DMA tag "
|
||||
|
@ -2160,20 +2173,20 @@ END_DEBUG
|
|||
SBP_SCSIBUS_ATTACH;
|
||||
|
||||
/* We reserve 16 bit space (4 bytes X 64 unit X 256 luns) */
|
||||
dv_unit = device_get_unit(sbp->fd.dev);
|
||||
dv_unit = fw_get_unit(sbp->fd.dev);
|
||||
sbp->fwb.start = SBP_DEV2ADDR(dv_unit, 0);
|
||||
sbp->fwb.end = SBP_DEV2ADDR(dv_unit, -1);
|
||||
/* pre-allocate xfer */
|
||||
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 != FWBUSNOTREADY) {
|
||||
if (fc->status != FWBUSNOTREADY) {
|
||||
s = splfw();
|
||||
sbp_post_busreset((void *)sbp);
|
||||
sbp_post_explore((void *)sbp);
|
||||
|
@ -2183,6 +2196,7 @@ END_DEBUG
|
|||
FW_ATTACH_RETURN(0);
|
||||
#if defined(__FreeBSD__)
|
||||
fail:
|
||||
SBP_UNLOCK(sbp);
|
||||
cam_sim_free(sbp->sim, /*free_devq*/TRUE);
|
||||
return (ENXIO);
|
||||
#endif
|
||||
|
@ -2204,7 +2218,7 @@ END_DEBUG
|
|||
sdev = target->luns[i];
|
||||
if (sdev == NULL)
|
||||
continue;
|
||||
callout_stop(&sdev->login_callout);
|
||||
fw_callout_stop(&sdev->login_callout);
|
||||
if (sdev->status >= SBP_DEV_TOATTACH &&
|
||||
sdev->status <= SBP_DEV_ATTACHED)
|
||||
sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
|
||||
|
@ -2247,7 +2261,7 @@ sbp_free_target(struct sbp_target *target)
|
|||
|
||||
if (target->luns == NULL)
|
||||
return;
|
||||
callout_stop(&target->mgm_ocb_timeout);
|
||||
fw_callout_stop(&target->mgm_ocb_timeout);
|
||||
sbp = target->sbp;
|
||||
for (i = 0; i < target->num_lun; i++)
|
||||
sbp_free_sdev(target->luns[i]);
|
||||
|
@ -2276,10 +2290,12 @@ END_DEBUG
|
|||
|
||||
SBP_DETACH_TARGET(&sbp->target);
|
||||
#if defined(__FreeBSD__)
|
||||
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);
|
||||
#endif
|
||||
|
||||
sbp_logout_all(sbp);
|
||||
|
@ -2293,6 +2309,7 @@ END_DEBUG
|
|||
fw_xferlist_remove(&sbp->fwb.xferlist);
|
||||
|
||||
fw_bus_dma_tag_destroy(sbp->dmat);
|
||||
fw_mtx_destroy(&sbp->mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -2307,15 +2324,17 @@ sbp_cam_detach_sdev(struct sbp_dev *sdev)
|
|||
return;
|
||||
if (sdev->status == SBP_DEV_RESET)
|
||||
return;
|
||||
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);
|
||||
}
|
||||
sbp_abort_all_ocbs(sdev, XS_DEV_NOT_THERE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2327,7 +2346,7 @@ sbp_cam_detach_target(struct sbp_target *target)
|
|||
SBP_DEBUG(0)
|
||||
printf("sbp_detach_target %d\n", target->target_id);
|
||||
END_DEBUG
|
||||
callout_stop(&target->scan_callout);
|
||||
fw_callout_stop(&target->scan_callout);
|
||||
for (i = 0; i < target->num_lun; i++)
|
||||
sbp_cam_detach_sdev(target->luns[i]);
|
||||
}
|
||||
|
@ -2376,11 +2395,11 @@ sbp_scsipi_detach_target(struct sbp_target *target)
|
|||
SBP_DEBUG(0)
|
||||
printf("sbp_detach_target %d\n", target->target_id);
|
||||
END_DEBUG
|
||||
callout_stop(&target->scan_callout);
|
||||
fw_callout_stop(&target->scan_callout);
|
||||
for (i = 0; i < target->num_lun; i++)
|
||||
sbp_scsipi_detach_sdev(target->luns[i]);
|
||||
if (config_detach(sbp->sc_bus, DETACH_FORCE) != 0)
|
||||
device_printf(sbp->fd.dev, "%d detach failed\n",
|
||||
fw_printf(sbp->fd.dev, "%d detach failed\n",
|
||||
target->target_id);
|
||||
sbp->sc_bus = NULL;
|
||||
}
|
||||
|
@ -2402,8 +2421,10 @@ sbp_target_reset(struct sbp_dev *sdev, int method)
|
|||
continue;
|
||||
if (tsdev->status == SBP_DEV_RESET)
|
||||
continue;
|
||||
SBP_LOCK(target->sbp);
|
||||
SBP_DEVICE_FREEZE(tsdev, 1);
|
||||
tsdev->freeze ++;
|
||||
SBP_UNLOCK(target->sbp);
|
||||
sbp_abort_all_ocbs(tsdev, XS_CMD_TIMEOUT);
|
||||
if (method == 2)
|
||||
tsdev->status = SBP_DEV_LOGIN;
|
||||
|
@ -2458,8 +2479,10 @@ sbp_timeout(void *arg)
|
|||
switch(sdev->timeout) {
|
||||
case 1:
|
||||
printf("agent reset\n");
|
||||
SBP_LOCK(sdev->target->sbp);
|
||||
SBP_DEVICE_FREEZE(sdev, 1);
|
||||
sdev->freeze ++;
|
||||
SBP_UNLOCK(sdev->target->sbp);
|
||||
sbp_abort_all_ocbs(sdev, XS_CMD_TIMEOUT);
|
||||
sbp_agent_reset(sdev);
|
||||
break;
|
||||
|
@ -2518,7 +2541,7 @@ END_DEBUG
|
|||
SBP_DEBUG(1)
|
||||
printf("%s:%d:%d:func_code 0x%04x: "
|
||||
"Invalid target (target needed)\n",
|
||||
sbp ? device_get_nameunit(sbp->fd.dev) : "???",
|
||||
sbp ? fw_get_nameunit(sbp->fd.dev) : "???",
|
||||
SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer),
|
||||
SCSI_XFER_FUNCCODE(sxfer));
|
||||
END_DEBUG
|
||||
|
@ -2540,7 +2563,7 @@ END_DEBUG
|
|||
SBP_DEBUG(0)
|
||||
printf("%s:%d:%d func_code 0x%04x: "
|
||||
"Invalid target (no wildcard)\n",
|
||||
device_get_nameunit(sbp->fd.dev),
|
||||
fw_get_nameunit(sbp->fd.dev),
|
||||
sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun,
|
||||
sxfer->ccb_h.func_code);
|
||||
END_DEBUG
|
||||
|
@ -2561,13 +2584,14 @@ END_DEBUG
|
|||
struct sbp_ocb *ocb;
|
||||
int speed;
|
||||
void *cdb;
|
||||
fw_mtx_assert(sim->mtx, MA_OWNED);
|
||||
|
||||
SBP_DEBUG(2)
|
||||
printf("%s:%d:%d XPT_SCSI_IO: "
|
||||
"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
|
||||
", flags: 0x%02x, "
|
||||
"%db cmd/%db data/%db sense\n",
|
||||
device_get_nameunit(sbp->fd.dev),
|
||||
fw_get_nameunit(sbp->fd.dev),
|
||||
SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer),
|
||||
SCSI_XFER_10BCMD_DUMP(sxfer),
|
||||
SCSI_XFER_DIR(sxfer),
|
||||
|
@ -2595,8 +2619,10 @@ END_DEBUG
|
|||
if ((ocb = sbp_get_ocb(sdev)) == NULL) {
|
||||
SCSI_XFER_ERROR(sxfer) = XS_REQUEUE_REQ;
|
||||
if (sdev->freeze == 0) {
|
||||
SBP_LOCK(sdev->target->sbp);
|
||||
SBP_DEVICE_FREEZE(sdev, 1);
|
||||
sdev->freeze ++;
|
||||
SBP_UNLOCK(sdev->target->sbp);
|
||||
}
|
||||
SCSI_TRANSFER_DONE(sxfer);
|
||||
return;
|
||||
|
@ -2672,7 +2698,7 @@ SBP_DEBUG(1)
|
|||
#else
|
||||
"Volume size = %jd\n",
|
||||
#endif
|
||||
device_get_nameunit(sbp->fd.dev),
|
||||
fw_get_nameunit(sbp->fd.dev),
|
||||
cam_sim_path(sbp->sim),
|
||||
sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun,
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
|
||||
|
@ -2706,7 +2732,7 @@ END_DEBUG
|
|||
|
||||
SBP_DEBUG(1)
|
||||
printf("%s:%d:XPT_RESET_BUS: \n",
|
||||
device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
|
||||
fw_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
|
||||
END_DEBUG
|
||||
|
||||
SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
|
||||
|
@ -2720,7 +2746,7 @@ END_DEBUG
|
|||
|
||||
SBP_DEBUG(1)
|
||||
printf("%s:%d:%d XPT_PATH_INQ:.\n",
|
||||
device_get_nameunit(sbp->fd.dev),
|
||||
fw_get_nameunit(sbp->fd.dev),
|
||||
sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun);
|
||||
END_DEBUG
|
||||
cpi->version_num = 1; /* XXX??? */
|
||||
|
@ -2764,7 +2790,7 @@ END_DEBUG
|
|||
scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
|
||||
SBP_DEBUG(1)
|
||||
printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
|
||||
device_get_nameunit(sbp->fd.dev),
|
||||
fw_get_nameunit(sbp->fd.dev),
|
||||
sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun);
|
||||
END_DEBUG
|
||||
SCSI_XFER_ERROR(cts) = XS_REQ_CMP;
|
||||
|
@ -2910,6 +2936,7 @@ SBP_DEBUG(1)
|
|||
#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;
|
||||
|
@ -2918,7 +2945,7 @@ END_DEBUG
|
|||
STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
|
||||
if (ocb->sxfer != NULL)
|
||||
#if defined(__DragonFly__) || defined(__NetBSD__)
|
||||
callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
|
||||
fw_callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
|
||||
#else
|
||||
untimeout(sbp_timeout, (void *)ocb,
|
||||
SCSI_XFER_CALLOUT(ocb->sxfer));
|
||||
|
@ -2961,6 +2988,7 @@ END_DEBUG
|
|||
} else
|
||||
order ++;
|
||||
}
|
||||
SBP_UNLOCK(sdev->target->sbp);
|
||||
splx(s);
|
||||
SBP_DEBUG(0)
|
||||
if (ocb && order > 0) {
|
||||
|
@ -2991,7 +3019,7 @@ END_DEBUG
|
|||
|
||||
if (ocb->sxfer != NULL)
|
||||
#if defined(__DragonFly__) || defined(__NetBSD__)
|
||||
callout_reset(&SCSI_XFER_CALLOUT(ocb->sxfer),
|
||||
fw_callout_reset(&SCSI_XFER_CALLOUT(ocb->sxfer),
|
||||
mstohz(SCSI_XFER_TIMEOUT(ocb->sxfer)), sbp_timeout, ocb);
|
||||
#else
|
||||
SCSI_XFER_CALLOUT(ocb->sxfer) = timeout(sbp_timeout,
|
||||
|
@ -3025,6 +3053,8 @@ sbp_get_ocb(struct sbp_dev *sdev)
|
|||
{
|
||||
struct sbp_ocb *ocb;
|
||||
int s = splfw();
|
||||
|
||||
fw_mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
|
||||
ocb = STAILQ_FIRST(&sdev->free_ocbs);
|
||||
if (ocb == NULL) {
|
||||
sdev->flags |= ORB_SHORTAGE;
|
||||
|
@ -3043,6 +3073,8 @@ sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
|
|||
{
|
||||
ocb->flags = 0;
|
||||
ocb->sxfer = NULL;
|
||||
|
||||
SBP_LOCK(sdev->target->sbp);
|
||||
STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
|
||||
if ((sdev->flags & ORB_SHORTAGE) != 0) {
|
||||
int count;
|
||||
|
@ -3052,6 +3084,7 @@ sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
|
|||
sdev->freeze = 0;
|
||||
SBP_DEVICE_THAW(sdev, count);
|
||||
}
|
||||
SBP_UNLOCK(sdev->target->sbp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3081,13 +3114,15 @@ END_DEBUG
|
|||
}
|
||||
if (ocb->sxfer != NULL) {
|
||||
#if defined(__DragonFly__ ) || defined(__NetBSD__)
|
||||
callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
|
||||
fw_callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
|
||||
#else
|
||||
untimeout(sbp_timeout, (void *)ocb,
|
||||
SCSI_XFER_CALLOUT(ocb->sxfer));
|
||||
#endif
|
||||
SCSI_XFER_ERROR(ocb->sxfer) = status;
|
||||
SBP_LOCK(sdev->target->sbp);
|
||||
SCSI_TRANSFER_DONE(ocb->sxfer);
|
||||
SBP_UNLOCK(sdev->target->sbp);
|
||||
}
|
||||
sbp_free_ocb(sdev, ocb);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue