Date: Thu, 28 Feb 2008 12:42:06 -0800 From: Sean Bruno <sbruno@miralink.com> To: Hidetoshi Shimokawa <simokawa@FreeBSD.ORG> Cc: freebsd-firewire@freebsd.org Subject: Re: Binding sbp_targ to another address Message-ID: <47C71C9E.4070704@miralink.com> In-Reply-To: <626eb4530802281236q7b81ee9cn1a7067b149c04193@mail.gmail.com> References: <47C31B2A.2030701@miralink.com> <47C36A3E.1070701@miralink.com> <626eb4530802281236q7b81ee9cn1a7067b149c04193@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Hidetoshi Shimokawa wrote: > 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. > > Yes. It is not specific to SBP-2, but it is mandatory by SBP-2. Where do you think it should be bound? Sean > 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; >> >> >> >> > > > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47C71C9E.4070704>