Skip to content

Commit

Permalink
firewire: cdev: add PHY pinging
Browse files Browse the repository at this point in the history
This extends the FW_CDEV_IOC_SEND_PHY_PACKET ioctl() for /dev/fw* to be
useful for ping time measurements.  One application for it would be gap
count optimization in userspace that is based on ping times rather than
hop count.  (The latter is implemented in firewire-core itself but is
not applicable to beta PHYs that act as repeater.)

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
  • Loading branch information
Stefan Richter committed Jul 23, 2010
1 parent bf54e14 commit cc55021
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 4 deletions.
9 changes: 6 additions & 3 deletions drivers/firewire/core-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1423,9 +1423,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
/* stale generation; cancelled; on certain controllers: no ack */
default: e->phy_packet.rcode = status; break;
}
e->phy_packet.data[0] = packet->timestamp;

queue_event(e->client, &e->event,
&e->phy_packet, sizeof(e->phy_packet), NULL, 0);
queue_event(e->client, &e->event, &e->phy_packet,
sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0);
client_put(e->client);
}

Expand All @@ -1439,7 +1440,7 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
if (!client->device->is_local)
return -ENOSYS;

e = kzalloc(sizeof(*e), GFP_KERNEL);
e = kzalloc(sizeof(*e) + 4, GFP_KERNEL);
if (e == NULL)
return -ENOMEM;

Expand All @@ -1453,6 +1454,8 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
e->p.callback = outbound_phy_packet_callback;
e->phy_packet.closure = a->closure;
e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT;
if (is_ping_packet(a->data))
e->phy_packet.length = 4;

card->driver->send_request(card, &e->p);

Expand Down
5 changes: 5 additions & 0 deletions drivers/firewire/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,9 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
void fw_send_phy_config(struct fw_card *card,
int node_id, int generation, int gap_count);

static inline bool is_ping_packet(u32 *data)
{
return (data[0] & 0xc0ffffff) == 0 && ~data[0] == data[1];
}

#endif /* _FIREWIRE_CORE_H */
3 changes: 3 additions & 0 deletions drivers/firewire/ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,9 @@ static int at_context_queue_packet(struct context *ctx,
header[1] = cpu_to_le32(packet->header[0]);
header[2] = cpu_to_le32(packet->header[1]);
d[0].req_count = cpu_to_le16(12);

if (is_ping_packet(packet->header))
d[0].control |= cpu_to_le16(DESCRIPTOR_PING);
break;

case 4:
Expand Down
5 changes: 4 additions & 1 deletion include/linux/firewire-cdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,10 @@ struct fw_cdev_event_iso_resource {
* @length: Data length in bytes
* @data: Incoming data
*
* If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT, @length is 0 and @data empty.
* If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT, @length is 0 and @data empty,
* except in case of a ping packet: Then, @length is 4, and @data[0] is the
* ping time in 49.152MHz clocks if @rcode is %RCODE_COMPLETE.
*
* If @type is %FW_CDEV_EVENT_PHY_PACKET_RECEIVED, @length is 8 and @data
* consists of the two PHY packet quadlets, in host byte order.
*/
Expand Down

0 comments on commit cc55021

Please sign in to comment.