Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Feb 2008 06:10:45 +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:  <626eb4530802281310h606f1382wfd617208aa1fb579@mail.gmail.com>
In-Reply-To: <47C71C9E.4070704@miralink.com>
References:  <47C31B2A.2030701@miralink.com> <47C36A3E.1070701@miralink.com> <626eb4530802281236q7b81ee9cn1a7067b149c04193@mail.gmail.com> <47C71C9E.4070704@miralink.com>

next in thread | previous in thread | raw e-mail | index | archive | help
I think we should have something like fwcsr.c to implement CSR and provide
a interface to initialize/manipulate those registers and sbp_targ should use
the interface.

On Fri, Feb 29, 2008 at 5:42 AM, Sean Bruno <sbruno@miralink.com> wrote:
> 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;
>  >>
>  >>
>  >>
>  >>
>  >
>  >
>  >
>  >
>
>



-- 
/\ Hidetoshi Shimokawa
\/  simokawa@FreeBSD.ORG



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?626eb4530802281310h606f1382wfd617208aa1fb579>