linux/drivers/firewire/core-transaction.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Core IEEE1394 transaction logic
 *
 * Copyright (C) 2004-2006 Kristian Hoegsberg <[email protected]>
 */

#include <linux/bug.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/rculist.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include <asm/byteorder.h>

#include "core.h"
#include "packet-header-definitions.h"
#include "phy-packet-definitions.h"
#include <trace/events/firewire.h>

#define HEADER_DESTINATION_IS_BROADCAST(header)

/* returns 0 if the split timeout handler is already running */
static int try_cancel_split_timeout(struct fw_transaction *t)
{}

static int close_transaction(struct fw_transaction *transaction, struct fw_card *card, int rcode,
			     u32 response_tstamp)
{}

/*
 * Only valid for transactions that are potentially pending (ie have
 * been sent).
 */
int fw_cancel_transaction(struct fw_card *card,
			  struct fw_transaction *transaction)
{}
EXPORT_SYMBOL();

static void split_transaction_timeout_callback(struct timer_list *timer)
{}

static void start_split_transaction_timeout(struct fw_transaction *t,
					    struct fw_card *card)
{}

static u32 compute_split_timeout_timestamp(struct fw_card *card, u32 request_timestamp);

static void transmit_complete_callback(struct fw_packet *packet,
				       struct fw_card *card, int status)
{}

static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
		int destination_id, int source_id, int generation, int speed,
		unsigned long long offset, void *payload, size_t length)
{}

static int allocate_tlabel(struct fw_card *card)
{}

/**
 * __fw_send_request() - submit a request packet for transmission to generate callback for response
 *			 subaction with or without time stamp.
 * @card:		interface to send the request at
 * @t:			transaction instance to which the request belongs
 * @tcode:		transaction code
 * @destination_id:	destination node ID, consisting of bus_ID and phy_ID
 * @generation:		bus generation in which request and response are valid
 * @speed:		transmission speed
 * @offset:		48bit wide offset into destination's address space
 * @payload:		data payload for the request subaction
 * @length:		length of the payload, in bytes
 * @callback:		union of two functions whether to receive time stamp or not for response
 *			subaction.
 * @with_tstamp:	Whether to receive time stamp or not for response subaction.
 * @callback_data:	data to be passed to the transaction completion callback
 *
 * Submit a request packet into the asynchronous request transmission queue.
 * Can be called from atomic context.  If you prefer a blocking API, use
 * fw_run_transaction() in a context that can sleep.
 *
 * In case of lock requests, specify one of the firewire-core specific %TCODE_
 * constants instead of %TCODE_LOCK_REQUEST in @tcode.
 *
 * Make sure that the value in @destination_id is not older than the one in
 * @generation.  Otherwise the request is in danger to be sent to a wrong node.
 *
 * In case of asynchronous stream packets i.e. %TCODE_STREAM_DATA, the caller
 * needs to synthesize @destination_id with fw_stream_packet_destination_id().
 * It will contain tag, channel, and sy data instead of a node ID then.
 *
 * The payload buffer at @data is going to be DMA-mapped except in case of
 * @length <= 8 or of local (loopback) requests.  Hence make sure that the
 * buffer complies with the restrictions of the streaming DMA mapping API.
 * @payload must not be freed before the @callback is called.
 *
 * In case of request types without payload, @data is NULL and @length is 0.
 *
 * After the transaction is completed successfully or unsuccessfully, the
 * @callback will be called.  Among its parameters is the response code which
 * is either one of the rcodes per IEEE 1394 or, in case of internal errors,
 * the firewire-core specific %RCODE_SEND_ERROR.  The other firewire-core
 * specific rcodes (%RCODE_CANCELLED, %RCODE_BUSY, %RCODE_GENERATION,
 * %RCODE_NO_ACK) denote transaction timeout, busy responder, stale request
 * generation, or missing ACK respectively.
 *
 * Note some timing corner cases:  fw_send_request() may complete much earlier
 * than when the request packet actually hits the wire.  On the other hand,
 * transaction completion and hence execution of @callback may happen even
 * before fw_send_request() returns.
 */
void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
		int destination_id, int generation, int speed, unsigned long long offset,
		void *payload, size_t length, union fw_transaction_callback callback,
		bool with_tstamp, void *callback_data)
{}
EXPORT_SYMBOL_GPL();

struct transaction_callback_data {};

static void transaction_callback(struct fw_card *card, int rcode,
				 void *payload, size_t length, void *data)
{}

/**
 * fw_run_transaction() - send request and sleep until transaction is completed
 * @card:		card interface for this request
 * @tcode:		transaction code
 * @destination_id:	destination node ID, consisting of bus_ID and phy_ID
 * @generation:		bus generation in which request and response are valid
 * @speed:		transmission speed
 * @offset:		48bit wide offset into destination's address space
 * @payload:		data payload for the request subaction
 * @length:		length of the payload, in bytes
 *
 * Returns the RCODE.  See fw_send_request() for parameter documentation.
 * Unlike fw_send_request(), @data points to the payload of the request or/and
 * to the payload of the response.  DMA mapping restrictions apply to outbound
 * request payloads of >= 8 bytes but not to inbound response payloads.
 */
int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
		       int generation, int speed, unsigned long long offset,
		       void *payload, size_t length)
{}
EXPORT_SYMBOL();

static DEFINE_MUTEX(phy_config_mutex);
static DECLARE_COMPLETION(phy_config_done);

static void transmit_phy_packet_callback(struct fw_packet *packet,
					 struct fw_card *card, int status)
{}

static struct fw_packet phy_config_packet =;

void fw_send_phy_config(struct fw_card *card,
			int node_id, int generation, int gap_count)
{}

static struct fw_address_handler *lookup_overlapping_address_handler(
	struct list_head *list, unsigned long long offset, size_t length)
{}

static bool is_enclosing_handler(struct fw_address_handler *handler,
				 unsigned long long offset, size_t length)
{}

static struct fw_address_handler *lookup_enclosing_address_handler(
	struct list_head *list, unsigned long long offset, size_t length)
{}

static DEFINE_SPINLOCK(address_handler_list_lock);
static LIST_HEAD(address_handler_list);

const struct fw_address_region fw_high_memory_region =;
EXPORT_SYMBOL();

static const struct fw_address_region low_memory_region =;

#if 0
const struct fw_address_region fw_private_region =
	{ .start = 0xffffe0000000ULL, .end = 0xfffff0000000ULL,  };
const struct fw_address_region fw_csr_region =
	{ .start = CSR_REGISTER_BASE,
	  .end   = CSR_REGISTER_BASE | CSR_CONFIG_ROM_END,  };
const struct fw_address_region fw_unit_space_region =
	{ .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
#endif  /*  0  */

/**
 * fw_core_add_address_handler() - register for incoming requests
 * @handler:	callback
 * @region:	region in the IEEE 1212 node space address range
 *
 * region->start, ->end, and handler->length have to be quadlet-aligned.
 *
 * When a request is received that falls within the specified address range,
 * the specified callback is invoked.  The parameters passed to the callback
 * give the details of the particular request.
 *
 * To be called in process context.
 * Return value:  0 on success, non-zero otherwise.
 *
 * The start offset of the handler's address region is determined by
 * fw_core_add_address_handler() and is returned in handler->offset.
 *
 * Address allocations are exclusive, except for the FCP registers.
 */
int fw_core_add_address_handler(struct fw_address_handler *handler,
				const struct fw_address_region *region)
{}
EXPORT_SYMBOL();

/**
 * fw_core_remove_address_handler() - unregister an address handler
 * @handler: callback
 *
 * To be called in process context.
 *
 * When fw_core_remove_address_handler() returns, @handler->callback() is
 * guaranteed to not run on any CPU anymore.
 */
void fw_core_remove_address_handler(struct fw_address_handler *handler)
{}
EXPORT_SYMBOL();

struct fw_request {};

void fw_request_get(struct fw_request *request)
{}

static void release_request(struct kref *kref)
{}

void fw_request_put(struct fw_request *request)
{}

static void free_response_callback(struct fw_packet *packet,
				   struct fw_card *card, int status)
{}

int fw_get_response_length(struct fw_request *r)
{}

void fw_fill_response(struct fw_packet *response, u32 *request_header,
		      int rcode, void *payload, size_t length)
{}
EXPORT_SYMBOL();

static u32 compute_split_timeout_timestamp(struct fw_card *card,
					   u32 request_timestamp)
{}

static struct fw_request *allocate_request(struct fw_card *card,
					   struct fw_packet *p)
{}

/**
 * fw_send_response: - send response packet for asynchronous transaction.
 * @card:	interface to send the response at.
 * @request:	firewire request data for the transaction.
 * @rcode:	response code to send.
 *
 * Submit a response packet into the asynchronous response transmission queue. The @request
 * is going to be released when the transmission successfully finishes later.
 */
void fw_send_response(struct fw_card *card,
		      struct fw_request *request, int rcode)
{}
EXPORT_SYMBOL();

/**
 * fw_get_request_speed() - returns speed at which the @request was received
 * @request: firewire request data
 */
int fw_get_request_speed(struct fw_request *request)
{}
EXPORT_SYMBOL();

/**
 * fw_request_get_timestamp: Get timestamp of the request.
 * @request: The opaque pointer to request structure.
 *
 * Get timestamp when 1394 OHCI controller receives the asynchronous request subaction. The
 * timestamp consists of the low order 3 bits of second field and the full 13 bits of count
 * field of isochronous cycle time register.
 *
 * Returns: timestamp of the request.
 */
u32 fw_request_get_timestamp(const struct fw_request *request)
{}
EXPORT_SYMBOL_GPL();

static void handle_exclusive_region_request(struct fw_card *card,
					    struct fw_packet *p,
					    struct fw_request *request,
					    unsigned long long offset)
{}

static void handle_fcp_region_request(struct fw_card *card,
				      struct fw_packet *p,
				      struct fw_request *request,
				      unsigned long long offset)
{}

void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
{}
EXPORT_SYMBOL();

void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
{}
EXPORT_SYMBOL();

/**
 * fw_rcode_string - convert a firewire result code to an error description
 * @rcode: the result code
 */
const char *fw_rcode_string(int rcode)
{}
EXPORT_SYMBOL();

static const struct fw_address_region topology_map_region =;

static void handle_topology_map(struct fw_card *card, struct fw_request *request,
		int tcode, int destination, int source, int generation,
		unsigned long long offset, void *payload, size_t length,
		void *callback_data)
{}

static struct fw_address_handler topology_map =;

static const struct fw_address_region registers_region =;

static void update_split_timeout(struct fw_card *card)
{}

static void handle_registers(struct fw_card *card, struct fw_request *request,
		int tcode, int destination, int source, int generation,
		unsigned long long offset, void *payload, size_t length,
		void *callback_data)
{}

static struct fw_address_handler registers =;

static void handle_low_memory(struct fw_card *card, struct fw_request *request,
		int tcode, int destination, int source, int generation,
		unsigned long long offset, void *payload, size_t length,
		void *callback_data)
{}

static struct fw_address_handler low_memory =;

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

static const u32 vendor_textual_descriptor[] =;

static const u32 model_textual_descriptor[] =;

static struct fw_descriptor vendor_id_descriptor =;

static struct fw_descriptor model_id_descriptor =;

static int __init fw_core_init(void)
{}

static void __exit fw_core_cleanup(void)
{}

module_init();
module_exit(fw_core_cleanup);