+ 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:
kiyohara 2007-11-05 19:08:56 +00:00
parent 02aa4d6c73
commit c33e2714c5
13 changed files with 1423 additions and 1113 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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_ */

View File

@ -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);
}