firewire: cdev: code refactoring to dispatch event for phy packet
In 1394 OHCI, both Asynchronous Transmit (AT) and Asynchronous Receive (AR) contexts are used to deliver the phy packet of IEEE 1394. The time stamp is available as well as the usual asynchronous transaction. This commit is a preparation for future commit to handle the time stamp. Link: https://lore.kernel.org/r/20230529113406.986289-11-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
This commit is contained in:
parent
d8527cab6c
commit
1ef147710b
@ -204,12 +204,16 @@ struct outbound_phy_packet_event {
|
|||||||
struct event event;
|
struct event event;
|
||||||
struct client *client;
|
struct client *client;
|
||||||
struct fw_packet p;
|
struct fw_packet p;
|
||||||
struct fw_cdev_event_phy_packet phy_packet;
|
union {
|
||||||
|
struct fw_cdev_event_phy_packet without_tstamp;
|
||||||
|
} phy_packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct inbound_phy_packet_event {
|
struct inbound_phy_packet_event {
|
||||||
struct event event;
|
struct event event;
|
||||||
struct fw_cdev_event_phy_packet phy_packet;
|
union {
|
||||||
|
struct fw_cdev_event_phy_packet without_tstamp;
|
||||||
|
} phy_packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
@ -1549,26 +1553,41 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
|
|||||||
{
|
{
|
||||||
struct outbound_phy_packet_event *e =
|
struct outbound_phy_packet_event *e =
|
||||||
container_of(packet, struct outbound_phy_packet_event, p);
|
container_of(packet, struct outbound_phy_packet_event, p);
|
||||||
struct client *e_client;
|
struct client *e_client = e->client;
|
||||||
|
u32 rcode;
|
||||||
|
struct fw_cdev_event_phy_packet *pp;
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
/* expected: */
|
// expected:
|
||||||
case ACK_COMPLETE: e->phy_packet.rcode = RCODE_COMPLETE; break;
|
case ACK_COMPLETE:
|
||||||
/* should never happen with PHY packets: */
|
rcode = RCODE_COMPLETE;
|
||||||
case ACK_PENDING: e->phy_packet.rcode = RCODE_COMPLETE; break;
|
break;
|
||||||
|
// should never happen with PHY packets:
|
||||||
|
case ACK_PENDING:
|
||||||
|
rcode = RCODE_COMPLETE;
|
||||||
|
break;
|
||||||
case ACK_BUSY_X:
|
case ACK_BUSY_X:
|
||||||
case ACK_BUSY_A:
|
case ACK_BUSY_A:
|
||||||
case ACK_BUSY_B: e->phy_packet.rcode = RCODE_BUSY; break;
|
case ACK_BUSY_B:
|
||||||
case ACK_DATA_ERROR: e->phy_packet.rcode = RCODE_DATA_ERROR; break;
|
rcode = RCODE_BUSY;
|
||||||
case ACK_TYPE_ERROR: e->phy_packet.rcode = RCODE_TYPE_ERROR; break;
|
break;
|
||||||
/* stale generation; cancelled; on certain controllers: no ack */
|
case ACK_DATA_ERROR:
|
||||||
default: e->phy_packet.rcode = status; break;
|
rcode = RCODE_DATA_ERROR;
|
||||||
|
break;
|
||||||
|
case ACK_TYPE_ERROR:
|
||||||
|
rcode = RCODE_TYPE_ERROR;
|
||||||
|
break;
|
||||||
|
// stale generation; cancelled; on certain controllers: no ack
|
||||||
|
default:
|
||||||
|
rcode = status;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
e->phy_packet.data[0] = packet->timestamp;
|
|
||||||
|
|
||||||
e_client = e->client;
|
pp = &e->phy_packet.without_tstamp;
|
||||||
queue_event(e->client, &e->event, &e->phy_packet,
|
pp->rcode = rcode;
|
||||||
sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0);
|
pp->data[0] = packet->timestamp;
|
||||||
|
queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, NULL, 0);
|
||||||
|
|
||||||
client_put(e_client);
|
client_put(e_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1577,6 +1596,7 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
|
|||||||
struct fw_cdev_send_phy_packet *a = &arg->send_phy_packet;
|
struct fw_cdev_send_phy_packet *a = &arg->send_phy_packet;
|
||||||
struct fw_card *card = client->device->card;
|
struct fw_card *card = client->device->card;
|
||||||
struct outbound_phy_packet_event *e;
|
struct outbound_phy_packet_event *e;
|
||||||
|
struct fw_cdev_event_phy_packet *pp;
|
||||||
|
|
||||||
/* Access policy: Allow this ioctl only on local nodes' device files. */
|
/* Access policy: Allow this ioctl only on local nodes' device files. */
|
||||||
if (!client->device->is_local)
|
if (!client->device->is_local)
|
||||||
@ -1595,10 +1615,12 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
|
|||||||
e->p.header[2] = a->data[1];
|
e->p.header[2] = a->data[1];
|
||||||
e->p.header_length = 12;
|
e->p.header_length = 12;
|
||||||
e->p.callback = outbound_phy_packet_callback;
|
e->p.callback = outbound_phy_packet_callback;
|
||||||
e->phy_packet.closure = a->closure;
|
|
||||||
e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT;
|
pp = &e->phy_packet.without_tstamp;
|
||||||
|
pp->closure = a->closure;
|
||||||
|
pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT;
|
||||||
if (is_ping_packet(a->data))
|
if (is_ping_packet(a->data))
|
||||||
e->phy_packet.length = 4;
|
pp->length = 4;
|
||||||
|
|
||||||
card->driver->send_request(card, &e->p);
|
card->driver->send_request(card, &e->p);
|
||||||
|
|
||||||
@ -1633,18 +1655,20 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p)
|
|||||||
spin_lock_irqsave(&card->lock, flags);
|
spin_lock_irqsave(&card->lock, flags);
|
||||||
|
|
||||||
list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) {
|
list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) {
|
||||||
|
struct fw_cdev_event_phy_packet *pp;
|
||||||
|
|
||||||
e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC);
|
e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC);
|
||||||
if (e == NULL)
|
if (e == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
e->phy_packet.closure = client->phy_receiver_closure;
|
pp = &e->phy_packet.without_tstamp;
|
||||||
e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED;
|
pp->closure = client->phy_receiver_closure;
|
||||||
e->phy_packet.rcode = RCODE_COMPLETE;
|
pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED;
|
||||||
e->phy_packet.length = 8;
|
pp->rcode = RCODE_COMPLETE;
|
||||||
e->phy_packet.data[0] = p->header[1];
|
pp->length = 8;
|
||||||
e->phy_packet.data[1] = p->header[2];
|
pp->data[0] = p->header[1];
|
||||||
queue_event(client, &e->event,
|
pp->data[1] = p->header[2];
|
||||||
&e->phy_packet, sizeof(e->phy_packet) + 8, NULL, 0);
|
queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&card->lock, flags);
|
spin_unlock_irqrestore(&card->lock, flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user