firewire: core: replace local macros with common inline functions for asynchronous packet header
This commit uses common inline functions to serialize and deserialize header of asynchronous packet. Link: https://lore.kernel.org/r/20240428071347.409202-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
This commit is contained in:
parent
75527d8d9e
commit
e8cd3e4f27
@ -29,29 +29,13 @@
|
|||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "packet-header-definitions.h"
|
||||||
|
|
||||||
#define HEADER_PRI(pri) ((pri) << 0)
|
|
||||||
#define HEADER_TCODE(tcode) ((tcode) << 4)
|
#define HEADER_TCODE(tcode) ((tcode) << 4)
|
||||||
#define HEADER_RETRY(retry) ((retry) << 8)
|
|
||||||
#define HEADER_TLABEL(tlabel) ((tlabel) << 10)
|
|
||||||
#define HEADER_DESTINATION(destination) ((destination) << 16)
|
|
||||||
#define HEADER_SOURCE(source) ((source) << 16)
|
|
||||||
#define HEADER_RCODE(rcode) ((rcode) << 12)
|
|
||||||
#define HEADER_OFFSET_HIGH(offset_high) ((offset_high) << 0)
|
|
||||||
#define HEADER_DATA_LENGTH(length) ((length) << 16)
|
#define HEADER_DATA_LENGTH(length) ((length) << 16)
|
||||||
#define HEADER_EXTENDED_TCODE(tcode) ((tcode) << 0)
|
|
||||||
|
|
||||||
#define HEADER_GET_TCODE(q) (((q) >> 4) & 0x0f)
|
#define HEADER_DESTINATION_IS_BROADCAST(header) \
|
||||||
#define HEADER_GET_TLABEL(q) (((q) >> 10) & 0x3f)
|
((async_header_get_destination(header) & 0x3f) == 0x3f)
|
||||||
#define HEADER_GET_RCODE(q) (((q) >> 12) & 0x0f)
|
|
||||||
#define HEADER_GET_DESTINATION(q) (((q) >> 16) & 0xffff)
|
|
||||||
#define HEADER_GET_SOURCE(q) (((q) >> 16) & 0xffff)
|
|
||||||
#define HEADER_GET_OFFSET_HIGH(q) (((q) >> 0) & 0xffff)
|
|
||||||
#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
|
|
||||||
#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)
|
|
||||||
|
|
||||||
#define HEADER_DESTINATION_IS_BROADCAST(q) \
|
|
||||||
(((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f))
|
|
||||||
|
|
||||||
#define PHY_PACKET_CONFIG 0x0
|
#define PHY_PACKET_CONFIG 0x0
|
||||||
#define PHY_PACKET_LINK_ON 0x1
|
#define PHY_PACKET_LINK_ON 0x1
|
||||||
@ -248,28 +232,24 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
|
|||||||
} else
|
} else
|
||||||
ext_tcode = 0;
|
ext_tcode = 0;
|
||||||
|
|
||||||
packet->header[0] =
|
async_header_set_retry(packet->header, RETRY_X);
|
||||||
HEADER_RETRY(RETRY_X) |
|
async_header_set_tlabel(packet->header, tlabel);
|
||||||
HEADER_TLABEL(tlabel) |
|
async_header_set_tcode(packet->header, tcode);
|
||||||
HEADER_TCODE(tcode) |
|
async_header_set_destination(packet->header, destination_id);
|
||||||
HEADER_DESTINATION(destination_id);
|
async_header_set_source(packet->header, source_id);
|
||||||
packet->header[1] =
|
async_header_set_offset(packet->header, offset);
|
||||||
HEADER_OFFSET_HIGH(offset >> 32) | HEADER_SOURCE(source_id);
|
|
||||||
packet->header[2] =
|
|
||||||
offset;
|
|
||||||
|
|
||||||
switch (tcode) {
|
switch (tcode) {
|
||||||
case TCODE_WRITE_QUADLET_REQUEST:
|
case TCODE_WRITE_QUADLET_REQUEST:
|
||||||
packet->header[3] = *(u32 *)payload;
|
async_header_set_quadlet_data(packet->header, *(u32 *)payload);
|
||||||
packet->header_length = 16;
|
packet->header_length = 16;
|
||||||
packet->payload_length = 0;
|
packet->payload_length = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCODE_LOCK_REQUEST:
|
case TCODE_LOCK_REQUEST:
|
||||||
case TCODE_WRITE_BLOCK_REQUEST:
|
case TCODE_WRITE_BLOCK_REQUEST:
|
||||||
packet->header[3] =
|
async_header_set_data_length(packet->header, length);
|
||||||
HEADER_DATA_LENGTH(length) |
|
async_header_set_extended_tcode(packet->header, ext_tcode);
|
||||||
HEADER_EXTENDED_TCODE(ext_tcode);
|
|
||||||
packet->header_length = 16;
|
packet->header_length = 16;
|
||||||
packet->payload = payload;
|
packet->payload = payload;
|
||||||
packet->payload_length = length;
|
packet->payload_length = length;
|
||||||
@ -281,9 +261,8 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TCODE_READ_BLOCK_REQUEST:
|
case TCODE_READ_BLOCK_REQUEST:
|
||||||
packet->header[3] =
|
async_header_set_data_length(packet->header, length);
|
||||||
HEADER_DATA_LENGTH(length) |
|
async_header_set_extended_tcode(packet->header, ext_tcode);
|
||||||
HEADER_EXTENDED_TCODE(ext_tcode);
|
|
||||||
packet->header_length = 16;
|
packet->header_length = 16;
|
||||||
packet->payload_length = 0;
|
packet->payload_length = 0;
|
||||||
break;
|
break;
|
||||||
@ -655,7 +634,7 @@ EXPORT_SYMBOL(fw_core_remove_address_handler);
|
|||||||
struct fw_request {
|
struct fw_request {
|
||||||
struct kref kref;
|
struct kref kref;
|
||||||
struct fw_packet response;
|
struct fw_packet response;
|
||||||
u32 request_header[4];
|
u32 request_header[ASYNC_HEADER_QUADLET_COUNT];
|
||||||
int ack;
|
int ack;
|
||||||
u32 timestamp;
|
u32 timestamp;
|
||||||
u32 length;
|
u32 length;
|
||||||
@ -695,7 +674,7 @@ int fw_get_response_length(struct fw_request *r)
|
|||||||
{
|
{
|
||||||
int tcode, ext_tcode, data_length;
|
int tcode, ext_tcode, data_length;
|
||||||
|
|
||||||
tcode = HEADER_GET_TCODE(r->request_header[0]);
|
tcode = async_header_get_tcode(r->request_header);
|
||||||
|
|
||||||
switch (tcode) {
|
switch (tcode) {
|
||||||
case TCODE_WRITE_QUADLET_REQUEST:
|
case TCODE_WRITE_QUADLET_REQUEST:
|
||||||
@ -706,12 +685,12 @@ int fw_get_response_length(struct fw_request *r)
|
|||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case TCODE_READ_BLOCK_REQUEST:
|
case TCODE_READ_BLOCK_REQUEST:
|
||||||
data_length = HEADER_GET_DATA_LENGTH(r->request_header[3]);
|
data_length = async_header_get_data_length(r->request_header);
|
||||||
return data_length;
|
return data_length;
|
||||||
|
|
||||||
case TCODE_LOCK_REQUEST:
|
case TCODE_LOCK_REQUEST:
|
||||||
ext_tcode = HEADER_GET_EXTENDED_TCODE(r->request_header[3]);
|
ext_tcode = async_header_get_extended_tcode(r->request_header);
|
||||||
data_length = HEADER_GET_DATA_LENGTH(r->request_header[3]);
|
data_length = async_header_get_data_length(r->request_header);
|
||||||
switch (ext_tcode) {
|
switch (ext_tcode) {
|
||||||
case EXTCODE_FETCH_ADD:
|
case EXTCODE_FETCH_ADD:
|
||||||
case EXTCODE_LITTLE_ADD:
|
case EXTCODE_LITTLE_ADD:
|
||||||
@ -731,46 +710,42 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
|
|||||||
{
|
{
|
||||||
int tcode, tlabel, extended_tcode, source, destination;
|
int tcode, tlabel, extended_tcode, source, destination;
|
||||||
|
|
||||||
tcode = HEADER_GET_TCODE(request_header[0]);
|
tcode = async_header_get_tcode(request_header);
|
||||||
tlabel = HEADER_GET_TLABEL(request_header[0]);
|
tlabel = async_header_get_tlabel(request_header);
|
||||||
source = HEADER_GET_DESTINATION(request_header[0]);
|
source = async_header_get_destination(request_header); // Exchange.
|
||||||
destination = HEADER_GET_SOURCE(request_header[1]);
|
destination = async_header_get_source(request_header); // Exchange.
|
||||||
extended_tcode = HEADER_GET_EXTENDED_TCODE(request_header[3]);
|
extended_tcode = async_header_get_extended_tcode(request_header);
|
||||||
|
|
||||||
response->header[0] =
|
async_header_set_retry(response->header, RETRY_1);
|
||||||
HEADER_RETRY(RETRY_1) |
|
async_header_set_tlabel(response->header, tlabel);
|
||||||
HEADER_TLABEL(tlabel) |
|
async_header_set_destination(response->header, destination);
|
||||||
HEADER_DESTINATION(destination);
|
async_header_set_source(response->header, source);
|
||||||
response->header[1] =
|
async_header_set_rcode(response->header, rcode);
|
||||||
HEADER_SOURCE(source) |
|
response->header[2] = 0; // The field is reserved.
|
||||||
HEADER_RCODE(rcode);
|
|
||||||
response->header[2] = 0;
|
|
||||||
|
|
||||||
switch (tcode) {
|
switch (tcode) {
|
||||||
case TCODE_WRITE_QUADLET_REQUEST:
|
case TCODE_WRITE_QUADLET_REQUEST:
|
||||||
case TCODE_WRITE_BLOCK_REQUEST:
|
case TCODE_WRITE_BLOCK_REQUEST:
|
||||||
response->header[0] |= HEADER_TCODE(TCODE_WRITE_RESPONSE);
|
async_header_set_tcode(response->header, TCODE_WRITE_RESPONSE);
|
||||||
response->header_length = 12;
|
response->header_length = 12;
|
||||||
response->payload_length = 0;
|
response->payload_length = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCODE_READ_QUADLET_REQUEST:
|
case TCODE_READ_QUADLET_REQUEST:
|
||||||
response->header[0] |=
|
async_header_set_tcode(response->header, TCODE_READ_QUADLET_RESPONSE);
|
||||||
HEADER_TCODE(TCODE_READ_QUADLET_RESPONSE);
|
|
||||||
if (payload != NULL)
|
if (payload != NULL)
|
||||||
response->header[3] = *(u32 *)payload;
|
async_header_set_quadlet_data(response->header, *(u32 *)payload);
|
||||||
else
|
else
|
||||||
response->header[3] = 0;
|
async_header_set_quadlet_data(response->header, 0);
|
||||||
response->header_length = 16;
|
response->header_length = 16;
|
||||||
response->payload_length = 0;
|
response->payload_length = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCODE_READ_BLOCK_REQUEST:
|
case TCODE_READ_BLOCK_REQUEST:
|
||||||
case TCODE_LOCK_REQUEST:
|
case TCODE_LOCK_REQUEST:
|
||||||
response->header[0] |= HEADER_TCODE(tcode + 2);
|
async_header_set_tcode(response->header, tcode + 2);
|
||||||
response->header[3] =
|
async_header_set_data_length(response->header, length);
|
||||||
HEADER_DATA_LENGTH(length) |
|
async_header_set_extended_tcode(response->header, extended_tcode);
|
||||||
HEADER_EXTENDED_TCODE(extended_tcode);
|
|
||||||
response->header_length = 16;
|
response->header_length = 16;
|
||||||
response->payload = payload;
|
response->payload = payload;
|
||||||
response->payload_length = length;
|
response->payload_length = length;
|
||||||
@ -807,7 +782,7 @@ static struct fw_request *allocate_request(struct fw_card *card,
|
|||||||
u32 *data, length;
|
u32 *data, length;
|
||||||
int request_tcode;
|
int request_tcode;
|
||||||
|
|
||||||
request_tcode = HEADER_GET_TCODE(p->header[0]);
|
request_tcode = async_header_get_tcode(p->header);
|
||||||
switch (request_tcode) {
|
switch (request_tcode) {
|
||||||
case TCODE_WRITE_QUADLET_REQUEST:
|
case TCODE_WRITE_QUADLET_REQUEST:
|
||||||
data = &p->header[3];
|
data = &p->header[3];
|
||||||
@ -817,7 +792,7 @@ static struct fw_request *allocate_request(struct fw_card *card,
|
|||||||
case TCODE_WRITE_BLOCK_REQUEST:
|
case TCODE_WRITE_BLOCK_REQUEST:
|
||||||
case TCODE_LOCK_REQUEST:
|
case TCODE_LOCK_REQUEST:
|
||||||
data = p->payload;
|
data = p->payload;
|
||||||
length = HEADER_GET_DATA_LENGTH(p->header[3]);
|
length = async_header_get_data_length(p->header);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCODE_READ_QUADLET_REQUEST:
|
case TCODE_READ_QUADLET_REQUEST:
|
||||||
@ -827,7 +802,7 @@ static struct fw_request *allocate_request(struct fw_card *card,
|
|||||||
|
|
||||||
case TCODE_READ_BLOCK_REQUEST:
|
case TCODE_READ_BLOCK_REQUEST:
|
||||||
data = NULL;
|
data = NULL;
|
||||||
length = HEADER_GET_DATA_LENGTH(p->header[3]);
|
length = async_header_get_data_length(p->header);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -872,7 +847,7 @@ void fw_send_response(struct fw_card *card,
|
|||||||
{
|
{
|
||||||
/* unified transaction or broadcast transaction: don't respond */
|
/* unified transaction or broadcast transaction: don't respond */
|
||||||
if (request->ack != ACK_PENDING ||
|
if (request->ack != ACK_PENDING ||
|
||||||
HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
|
HEADER_DESTINATION_IS_BROADCAST(request->request_header)) {
|
||||||
fw_request_put(request);
|
fw_request_put(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -926,11 +901,11 @@ static void handle_exclusive_region_request(struct fw_card *card,
|
|||||||
struct fw_address_handler *handler;
|
struct fw_address_handler *handler;
|
||||||
int tcode, destination, source;
|
int tcode, destination, source;
|
||||||
|
|
||||||
destination = HEADER_GET_DESTINATION(p->header[0]);
|
destination = async_header_get_destination(p->header);
|
||||||
source = HEADER_GET_SOURCE(p->header[1]);
|
source = async_header_get_source(p->header);
|
||||||
tcode = HEADER_GET_TCODE(p->header[0]);
|
tcode = async_header_get_tcode(p->header);
|
||||||
if (tcode == TCODE_LOCK_REQUEST)
|
if (tcode == TCODE_LOCK_REQUEST)
|
||||||
tcode = 0x10 + HEADER_GET_EXTENDED_TCODE(p->header[3]);
|
tcode = 0x10 + async_header_get_extended_tcode(p->header);
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
handler = lookup_enclosing_address_handler(&address_handler_list,
|
handler = lookup_enclosing_address_handler(&address_handler_list,
|
||||||
@ -963,9 +938,9 @@ static void handle_fcp_region_request(struct fw_card *card,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcode = HEADER_GET_TCODE(p->header[0]);
|
tcode = async_header_get_tcode(p->header);
|
||||||
destination = HEADER_GET_DESTINATION(p->header[0]);
|
destination = async_header_get_destination(p->header);
|
||||||
source = HEADER_GET_SOURCE(p->header[1]);
|
source = async_header_get_source(p->header);
|
||||||
|
|
||||||
if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
|
if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
|
||||||
tcode != TCODE_WRITE_BLOCK_REQUEST) {
|
tcode != TCODE_WRITE_BLOCK_REQUEST) {
|
||||||
@ -997,7 +972,7 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
|
|||||||
if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
|
if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TCODE_IS_LINK_INTERNAL(HEADER_GET_TCODE(p->header[0]))) {
|
if (TCODE_IS_LINK_INTERNAL(async_header_get_tcode(p->header))) {
|
||||||
fw_cdev_handle_phy_packet(card, p);
|
fw_cdev_handle_phy_packet(card, p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1008,8 +983,7 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = ((u64)HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) |
|
offset = async_header_get_offset(p->header);
|
||||||
p->header[2];
|
|
||||||
|
|
||||||
if (!is_in_fcp_region(offset, request->length))
|
if (!is_in_fcp_region(offset, request->length))
|
||||||
handle_exclusive_region_request(card, p, request, offset);
|
handle_exclusive_region_request(card, p, request, offset);
|
||||||
@ -1027,10 +1001,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
|
|||||||
size_t data_length;
|
size_t data_length;
|
||||||
int tcode, tlabel, source, rcode;
|
int tcode, tlabel, source, rcode;
|
||||||
|
|
||||||
tcode = HEADER_GET_TCODE(p->header[0]);
|
tcode = async_header_get_tcode(p->header);
|
||||||
tlabel = HEADER_GET_TLABEL(p->header[0]);
|
tlabel = async_header_get_tlabel(p->header);
|
||||||
source = HEADER_GET_SOURCE(p->header[1]);
|
source = async_header_get_source(p->header);
|
||||||
rcode = HEADER_GET_RCODE(p->header[1]);
|
rcode = async_header_get_rcode(p->header);
|
||||||
|
|
||||||
spin_lock_irqsave(&card->lock, flags);
|
spin_lock_irqsave(&card->lock, flags);
|
||||||
list_for_each_entry(iter, &card->transaction_list, link) {
|
list_for_each_entry(iter, &card->transaction_list, link) {
|
||||||
@ -1073,7 +1047,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
|
|||||||
case TCODE_READ_BLOCK_RESPONSE:
|
case TCODE_READ_BLOCK_RESPONSE:
|
||||||
case TCODE_LOCK_RESPONSE:
|
case TCODE_LOCK_RESPONSE:
|
||||||
data = p->payload;
|
data = p->payload;
|
||||||
data_length = HEADER_GET_DATA_LENGTH(p->header[3]);
|
data_length = async_header_get_data_length(p->header);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user