aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-07-18 07:00:50 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-07-23 07:36:28 -0400
commitcc550216ae9a2993ef3973464714dc1a39ab1f86 (patch)
tree62ffde836c83fe44b7a9edc01d00bcb9ad4f4ad6 /drivers/firewire
parentbf54e1462b9192fdef7ea9e2bc44fdc16a4b87bc (diff)
firewire: cdev: add PHY pinging
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>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-cdev.c9
-rw-r--r--drivers/firewire/core.h5
-rw-r--r--drivers/firewire/ohci.c3
3 files changed, 14 insertions, 3 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 0425dd5dfcd3..31863cf8b6c4 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1423,9 +1423,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
1423 /* stale generation; cancelled; on certain controllers: no ack */ 1423 /* stale generation; cancelled; on certain controllers: no ack */
1424 default: e->phy_packet.rcode = status; break; 1424 default: e->phy_packet.rcode = status; break;
1425 } 1425 }
1426 e->phy_packet.data[0] = packet->timestamp;
1426 1427
1427 queue_event(e->client, &e->event, 1428 queue_event(e->client, &e->event, &e->phy_packet,
1428 &e->phy_packet, sizeof(e->phy_packet), NULL, 0); 1429 sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0);
1429 client_put(e->client); 1430 client_put(e->client);
1430} 1431}
1431 1432
@@ -1439,7 +1440,7 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
1439 if (!client->device->is_local) 1440 if (!client->device->is_local)
1440 return -ENOSYS; 1441 return -ENOSYS;
1441 1442
1442 e = kzalloc(sizeof(*e), GFP_KERNEL); 1443 e = kzalloc(sizeof(*e) + 4, GFP_KERNEL);
1443 if (e == NULL) 1444 if (e == NULL)
1444 return -ENOMEM; 1445 return -ENOMEM;
1445 1446
@@ -1453,6 +1454,8 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
1453 e->p.callback = outbound_phy_packet_callback; 1454 e->p.callback = outbound_phy_packet_callback;
1454 e->phy_packet.closure = a->closure; 1455 e->phy_packet.closure = a->closure;
1455 e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT; 1456 e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT;
1457 if (is_ping_packet(a->data))
1458 e->phy_packet.length = 4;
1456 1459
1457 card->driver->send_request(card, &e->p); 1460 card->driver->send_request(card, &e->p);
1458 1461
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 3102b6b63438..28621e44b111 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -234,4 +234,9 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
234void fw_send_phy_config(struct fw_card *card, 234void fw_send_phy_config(struct fw_card *card,
235 int node_id, int generation, int gap_count); 235 int node_id, int generation, int gap_count);
236 236
237static inline bool is_ping_packet(u32 *data)
238{
239 return (data[0] & 0xc0ffffff) == 0 && ~data[0] == data[1];
240}
241
237#endif /* _FIREWIRE_CORE_H */ 242#endif /* _FIREWIRE_CORE_H */
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 08afccc66333..5f6bb2c53808 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1068,6 +1068,9 @@ static int at_context_queue_packet(struct context *ctx,
1068 header[1] = cpu_to_le32(packet->header[0]); 1068 header[1] = cpu_to_le32(packet->header[0]);
1069 header[2] = cpu_to_le32(packet->header[1]); 1069 header[2] = cpu_to_le32(packet->header[1]);
1070 d[0].req_count = cpu_to_le16(12); 1070 d[0].req_count = cpu_to_le16(12);
1071
1072 if (is_ping_packet(packet->header))
1073 d[0].control |= cpu_to_le16(DESCRIPTOR_PING);
1071 break; 1074 break;
1072 1075
1073 case 4: 1076 case 4: