Implementation of the AGENT_STATE Register
Sean Bruno
sbruno at miralink.com
Wed Feb 6 12:09:33 PST 2008
Hidetoshi Shimokawa wrote:
> O.K. I checked the specification.
> AGENT_STATE is a register. So you have to respond with a read response packet
> rather than a write request packet.
> A response packet should be sent via fw_asyreq() with a tcode FWTCODE_RRES*.
>
>
Hmmm...This is what I have come up with.
First I have defined an AGENT_STATE Structure as per SBP-2 6.4.1:
struct agent_state {
uint32_t fetch_agent_state;
#define AGENT_STATE_RESET 0
#define AGENT_STATE_ACTIVE 1
#define AGENT_STATE_SUSPENDED 2
#define AGENT_STATE_DEAD 3
uint32_t bus_reset_command_reset_init_vals;
uint32_t read_vals;
uint32_t write_effects;
}
Second, I added a new function for the AGENT_STATE Register handler in
sbp_targ_cmd():
case 0x00: /* AGENT_STATE */
printf("%s: AGENT_STATE (%d:ignore)\n", __func__, login_id);
sbp_targ_send_agent_state(login);
break;
Third, I started coding sbp_targ_send_agent_state() to send the Read
Response packet in addition to a call back handler to cleanup the
malloc's after the read response is complete. I'm using code from
firewire.c::fw_vmaccess() to guide myself, but I do not quite understand
all of the pieces. Can you look at this code and tell me what it should
look like as I'm pretty sure that it's wrong.
static void
sbp_targ_send_agent_state(struct login *login)
{
struct agent_state *current_state;
struct fw_xfer *xfer;
struct fw_pkt *sfp;
struct fw_pkt *rfp;
xfer = fw_xfer_alloc(M_SBP_TARG);
current_state = malloc(sizeof(struct agent_state), M_SBP_TARG,
M_NOWAIT | M_ZERO);
current_state->fetch_agent_state = AGENT_STATE_ACTIVE;
xfer->send.buf = current_state;
xfer->send.len = sizeof(*current_state);
xfer->send.spd = FWSPD_S400;
sfp = (struct fw_pkt *)xfer->send.buf;
rfp = (struct fw_pkt *)xfer->recv.buf;
sfp->mode.rresq.data = *(uint32_t
*)(ntohl(rfp->mode.rreqq.dest_lo));
sfp->mode.wres.tcode = FWTCODE_RRESB;
sfp->mode.rresb.rtcode = 0;
sfp->mode.hdr.dst = rfp->mode.hdr.src;
xfer->dst = ntohs(rfp->mode.hdr.src);
xfer->hand = sbp_targ_free_agent_state;
sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
sfp->mode.hdr.pri = 0;
fw_asyreq(xfer->fc, -1, xfer);
}
static void
sbp_targ_free_agent_state(struct fw_xfer *xfer)
{
if(xfer != NULL){
fw_xfer_free(xfer);
}
}
Sean
More information about the freebsd-firewire
mailing list