Re: Binding sbp_targ to another address

Sean Bruno <[email protected]>
Newsgroups gmane.os.freebsd.devel.firewire
Message-ID <[email protected]>
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 <[email protected]> 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;
>>
>>
>>
>>     
>
>
>
>   

_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-firewire
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.