Implementation of the AGENT_STATE Register
Sean Bruno
sbruno at miralink.com
Wed Feb 6 12:45:47 PST 2008
Ok, perhaps I should _READ_ the code before I start writing! :)
Please throw away my previous message.
I have updated the function sbp_targ_send_agent_state(). The custom
delete function is gone(just use fw_xfer_free_buf() ). I think this is
much closer. Or, I just don't understand what I am doing(very likely!).
Also, I pass the xfer struct into the function, not the login struct. I
believe this is more correct?
static void
sbp_targ_send_agent_state(struct fw_xfer *xfer)
{
struct agent_state *current_state;
struct fw_pkt *rfp;
xfer->send_buf = malloc(sizeof(struct agent_state), M_SBP_TARG,
M_NOWAIT | M_ZERO);
xfer->send_len = ntohs(sizeof(struct agent_state));
current_state = (struct agent_state *)xfer->send_buf;
current_state->fetch_agent_state = AGENT_STATE_ACTIVE;
rfp = &xfer->recv.hdr;
rfp->mode.rresb.payload = current_state;
rfp->mode.rresb.tcode = FWTCODE_RRESB;
rfp->mode.rresb.rtcode = 0;
rfp->mode.rresb.extcode = 0;
xfer->dst = ntohs(rfp->mode.hdr.src);
xfer->hand = fw_xfer_free_buf;
rfp->mode.hdr.pri = 0;
fw_asyreq(xfer->fc, -1, xfer);
}
Sean Bruno wrote:
> 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
> _______________________________________________
> freebsd-firewire at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-firewire
> To unsubscribe, send any mail to
> "freebsd-firewire-unsubscribe at freebsd.org"
More information about the freebsd-firewire
mailing list