Skip site navigation (1)Skip section navigation (2)
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>