Date: Fri, 29 Feb 2008 05:36:21 +0900 From: "Hidetoshi Shimokawa" <simokawa@FreeBSD.ORG> To: "Sean Bruno" <sbruno@miralink.com> Cc: freebsd-firewire@freebsd.org Subject: Re: Binding sbp_targ to another address Message-ID: <626eb4530802281236q7b81ee9cn1a7067b149c04193@mail.gmail.com> In-Reply-To: <47C36A3E.1070701@miralink.com> References: <47C31B2A.2030701@miralink.com> <47C36A3E.1070701@miralink.com>
next in thread | previous in thread | raw e-mail | index | archive | help
You are right about using fw_bindadd() but I'm afraid that you should not implement it in sbp_targ because it is not sbp specific as far as I remember. On Tue, Feb 26, 2008 at 10:24 AM, Sean Bruno <sbruno@miralink.com> wrote: > > Sean Bruno wrote: > > It looks like SBP-2 defines the BUSY_TIMEOUT as a CSR that sbp_targ > > needs to accept from a windows initiator. > > > > How do I bind sbp_targ to 0x210 so that I can accept that value? > > > > Sean > I came up with the attached diff, I think I got it right. > > Bind to the appropriate address and then setup a handler for that register: > > Index: /branches/miralink.FreeBSD.6/src/sys/dev/firewire/sbp_targ.c > =================================================================== > --- /branches/miralink.FreeBSD.6/src/sys/dev/firewire/sbp_targ.c (revision 5135) > +++ /branches/miralink.FreeBSD.6/src/sys/dev/firewire/sbp_targ.c (revision 5137) > @@ -72,13 +72,14 @@ > * management/command block agent registers > * > * BASE 0xffff f001 0000 management port > * BASE 0xffff f001 0020 command port for login id 0 > * BASE 0xffff f001 0040 command port for login id 1 > + * BASE 0xffff f001 (0x20 * [login_id + 1]) for login_id > * > */ > -#define SBP_TARG_MGM 0x10000 /* offset from 0xffff f000 000 */ > +#define SBP_TARG_MGM 0x10000 /* offset from 0xffff f000 0000 */ > #define SBP_TARG_BIND_HI 0xffff > #define SBP_TARG_BIND_LO(l) (0xf0000000 + SBP_TARG_MGM + 0x20 * ((l) + 1)) > #define SBP_TARG_BIND_START (((u_int64_t)SBP_TARG_BIND_HI << 32) | \ > SBP_TARG_BIND_LO(-1)) > #define SBP_TARG_BIND_END (((u_int64_t)SBP_TARG_BIND_HI << 32) | \ > @@ -136,10 +137,11 @@ > struct sbp_targ_softc { > struct firewire_dev_comm fd; > struct cam_sim *sim; > struct cam_path *path; > struct fw_bind fwb; > + struct fw_bind busy_timeout; > int ndevs; > int flags; > struct crom_chunk unit; > struct sbp_targ_lstate *lstate[MAX_LUN]; > struct sbp_targ_lstate *black_hole; > @@ -170,10 +172,14 @@ > #endif > }; > > struct morb4 { > #if BYTE_ORDER == BIG_ENDIAN > + uint16_t reserved; > + uint16_t off_hi; > + uint32_t off_lo; > + uint64_t reserved2; > uint32_t n:1, > rq_fmt:2, > :9, > fun:4, > id:16; > @@ -181,10 +187,14 @@ > uint32_t id:16, > fun:4, > :9, > rq_fmt:2, > n:1; > + uint64_t reserved2; > + uint32_t off_lo; > + uint16_t off_hi; > + uint16_t reserved; > #endif > }; > > /* > * Urestricted page table format > @@ -242,10 +252,11 @@ > static char *orb_fun_name[] = { > ORB_FUN_NAMES > }; > > static void sbp_targ_recv(struct fw_xfer *); > +static void sbp_targ_busy_timeout(struct fw_xfer *); > static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *, > uint16_t, uint32_t, struct sbp_targ_login *, int); > static void sbp_targ_xfer_pt(struct orb_info *); > static void sbp_targ_send_agent_state(struct fw_xfer *); > > @@ -629,21 +640,10 @@ > } else > orbi->state = ORBI_STATUS_ABORTED; > } > } > } > -#if 0 > -static void > -sbp_targ_abort_task(struct orb_info *orbi) > -{ > -} > - > -static void > -sbp_targ_abort_task_set(struct orb_info *orbi) > -{ > -} > -#endif > > static void > sbp_targ_free_orbi(struct fw_xfer *xfer) > { > struct orb_info *orbi; > @@ -1565,10 +1565,12 @@ > struct sbp_targ_login *login; > struct fw_pkt *fp; > uint32_t *orb; > struct morb4 *orb4; > struct orb_info *orbi; > + uint32_t aborted_orb; > + uint64_t abort_hi; > int i; > > orbi = (struct orb_info *)xfer->sc; > if (xfer->resp != 0) { > printf("%s: xfer->resp = %d\n", __func__, xfer->resp); > @@ -1588,11 +1590,11 @@ > orb = orbi->orb; > /* swap payload */ > for (i = 0; i < 8; i ++) { > orb[i] = ntohl(orb[i]); > } > - orb4 = (struct morb4 *)&orb[4]; > + orb4 = (struct morb4 *)&orb; > if (debug) > printf("%s: %s\n", __func__, orb_fun_name[orb4->fun]); > > orbi->status.src = SRC_NO_NEXT; > > @@ -1689,11 +1691,14 @@ > /* > * Find the orb to be aborted. > * If we haven't fetched, just drop it on the floor. > * If we have fetched, process normally and don't worry about it. > */ > - printf("%s: Abort Task recieved for orb\n", __func__); > + abort_hi = orb4->off_hi; > + aborted_orb = (abort_hi << 32) + (orb4->off_lo >> 2); > + printf("%s: Abort Task recieved for orb %d\n", __func__, aborted_orb); > + sbp_targ_abort((struct orb_info *)aborted_orb); > break; > case ORB_FUN_ATS: /* TODO */ > printf("%s: Abort Task Set recieved for orb\n",__func__ ); > break; > case ORB_FUN_LUR: /* TODO */ > @@ -1842,10 +1847,11 @@ > int rtcode = 0; > > if (login_id < 0 || login_id >= MAX_LOGINS) > return(RESP_ADDRESS_ERROR); > > + printf("%s: made it here\n",__func__); > sc = (struct sbp_targ_softc *)xfer->sc; > login = sc->logins[login_id]; > if (login == NULL) > return(RESP_ADDRESS_ERROR); > > @@ -1963,11 +1969,11 @@ > static void > sbp_targ_recv(struct fw_xfer *xfer) > { > struct fw_pkt *fp, *sfp; > struct fw_device *fwdev; > - uint32_t lo; > + uint32_t lo = 0; > int s, rtcode; > struct sbp_targ_softc *sc; > > s = splfw(); > sc = (struct sbp_targ_softc *)xfer->sc; > @@ -1975,24 +1981,23 @@ > fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f); > if (fwdev == NULL) { > printf("%s: cannot resolve nodeid=%d\n", > __func__, fp->mode.wreqb.src & 0x3f); > rtcode = RESP_TYPE_ERROR; /* XXX */ > - goto done; > - } > - lo = fp->mode.wreqb.dest_lo; > - if (lo == SBP_TARG_BIND_LO(-1)) > - rtcode = sbp_targ_mgm(xfer, fwdev); > - else if (lo >= SBP_TARG_BIND_LO(0)) > - rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo), > - lo % 0x20); > - else > - rtcode = RESP_ADDRESS_ERROR; > - > -done: > + } else { > + lo = fp->mode.wreqb.dest_lo; > + if (lo == SBP_TARG_BIND_LO(-1)) > + rtcode = sbp_targ_mgm(xfer, fwdev); > + else if (lo >= SBP_TARG_BIND_LO(0)) > + rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo), > + lo % 0x20); > + else > + rtcode = RESP_ADDRESS_ERROR; > + } > + > if (rtcode != 0) > - printf("%s: rtcode = %d\n", __func__, rtcode); > + printf("%s: rtcode = %d lo == 0x%x\n", __func__, rtcode, lo); > sfp = &xfer->send.hdr; > xfer->send.spd = FWSPD_S400; > xfer->hand = sbp_targ_resp_callback; > sfp->mode.wres.dst = fp->mode.wreqb.src; > sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt; > @@ -2002,10 +2007,47 @@ > > fw_asyreq(xfer->fc, -1, xfer); > splx(s); > } > > +static void > +sbp_targ_busy_timeout(struct fw_xfer *xfer) > +{ > + struct fw_pkt *fp, *sfp; > + struct fw_device *fwdev; > + uint32_t lo = 0; > + int s, rtcode; > + struct sbp_targ_softc *sc; > + > + s = splfw(); > + sc = (struct sbp_targ_softc *)xfer->sc; > + fp = &xfer->recv.hdr; > + fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f); > + if (fwdev == NULL) { > + printf("%s: cannot resolve nodeid=%d\n", > + __func__, fp->mode.wreqb.src & 0x3f); > + rtcode = RESP_TYPE_ERROR; /* XXX */ > + } else { > + printf("%s: BUSY_TIMEOUT Recieved\n", __func__); > + rtcode = 0; > + } > + if (rtcode != 0) > + printf("%s: rtcode = %d lo == 0x%x\n", __func__, rtcode, lo); > + > + sfp = &xfer->send.hdr; > + xfer->send.spd = FWSPD_S400; > + xfer->hand = sbp_targ_resp_callback; > + sfp->mode.wres.dst = fp->mode.wreqb.src; > + sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt; > + sfp->mode.wres.tcode = FWTCODE_WRES; > + sfp->mode.wres.rtcode = rtcode; > + sfp->mode.wres.pri = 0; > + > + fw_asyreq(xfer->fc, -1, xfer); > + splx(s); > +} > + > static int > sbp_targ_attach(device_t dev) > { > struct sbp_targ_softc *sc; > struct cam_devq *devq; > @@ -2048,10 +2090,21 @@ > STAILQ_INIT(&sc->fwb.xferlist); > fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG, > /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, > sc->fd.fc, (void *)sc, sbp_targ_recv); > fw_bindadd(sc->fd.fc, &sc->fwb); > + /* > + * setup CSR for BUSY_TIMEOUT from > + * initiator(0x210) > + */ > + sc->busy_timeout.start = 0xfffff0000000 | BUSY_TIMEOUT; > + sc->busy_timeout.end = 0xfffff0000000 | BUSY_TIMEOUT; > + STAILQ_INIT(&sc->busy_timeout.xferlist); > + fw_xferlist_add(&sc->busy_timeout.xferlist, M_SBP_TARG, > + /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, > + sc->fd.fc, (void *)sc, sbp_targ_busy_timeout); > + fw_bindadd(sc->fd.fc, &sc->busy_timeout); > return 0; > > fail: > cam_sim_free(sc->sim, /*free_devq*/TRUE); > return (ENXIO); > @@ -2089,10 +2142,11 @@ > sc->black_hole = NULL; > } > > fw_bindremove(sc->fd.fc, &sc->fwb); > fw_xferlist_remove(&sc->fwb.xferlist); > + fw_bindremove(sc->fd.fc, &sc->busy_timeout); > > return 0; > } > > static devclass_t sbp_targ_devclass; > > > -- /\ Hidetoshi Shimokawa \/ simokawa@FreeBSD.ORG
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?626eb4530802281236q7b81ee9cn1a7067b149c04193>