|
List Info
Thread: Re: Binding sbp_targ to another address
|
|
| Re: Binding sbp_targ to another address |
  United States |
2008-02-25 19:24:14 |
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[] = ;
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 = %dn", __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: %sn", __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 orbn",
__func__);
+ abort_hi = orb4->off_hi;
+ aborted_orb = (abort_hi << 32) + (orb4->off_lo
>> 2);
+ printf("%s: Abort Task recieved for orb %dn",
__func__, aborted_orb);
+ sbp_targ_abort((struct orb_info *)aborted_orb);
break;
case ORB_FUN_ATS: /* TODO */
printf("%s: Abort Task Set recieved for
orbn",__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 heren",__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=%dn",
__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 = %dn", __func__, rtcode);
+ printf("%s: rtcode = %d lo == 0x%xn",
__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=%dn",
+ __func__, fp->mode.wreqb.src & 0x3f);
+ rtcode = RESP_TYPE_ERROR; /* XXX */
+ } else {
+ printf("%s: BUSY_TIMEOUT Recievedn",
__func__);
+ rtcode = 0;
+ }
+ if (rtcode != 0)
+ printf("%s: rtcode = %d lo == 0x%xn",
__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;
_______________________________________________
freebsd-firewire freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-fire
wire
To unsubscribe, send any mail to
"freebsd-firewire-unsubscribe freebsd.org"
|
|
| Re: Binding sbp_targ to another address |

|
2008-02-28 14:36:21 |
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 =
%dn", __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: %sn", __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 orbn", __func__);
> + abort_hi = orb4->off_hi;
> + aborted_orb = (abort_hi << 32) +
(orb4->off_lo >> 2);
> + printf("%s: Abort Task recieved
for orb %dn", __func__, aborted_orb);
> + sbp_targ_abort((struct orb_info
*)aborted_orb);
> break;
> case ORB_FUN_ATS: /* TODO */
> printf("%s: Abort Task Set
recieved for orbn",__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
heren",__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=%dn",
> __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 = %dn",
__func__, rtcode);
> + printf("%s: rtcode = %d lo ==
0x%xn", __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=%dn",
> + __func__, fp->mode.wreqb.src
& 0x3f);
> + rtcode = RESP_TYPE_ERROR; /* XXX */
> + } else {
> + printf("%s: BUSY_TIMEOUT
Recievedn", __func__);
> + rtcode = 0;
> + }
> + if (rtcode != 0)
> + printf("%s: rtcode = %d lo ==
0x%xn", __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
_______________________________________________
freebsd-firewire freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-fire
wire
To unsubscribe, send any mail to
"freebsd-firewire-unsubscribe freebsd.org"
|
|
[1-2]
|
|