// SPDX-License-Identifier: GPL-2.0-or-later /* * Isochronous I/O functionality: * - Isochronous DMA context management * - Isochronous bus resource management (channels, bandwidth), client side * * Copyright (C) 2006 Kristian Hoegsberg <[email protected]> */ #include <linux/dma-mapping.h> #include <linux/errno.h> #include <linux/firewire.h> #include <linux/firewire-constants.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/vmalloc.h> #include <linux/export.h> #include <asm/byteorder.h> #include "core.h" #include <trace/events/firewire.h> /* * Isochronous DMA context management */ int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count) { … } int fw_iso_buffer_map_dma(struct fw_iso_buffer *buffer, struct fw_card *card, enum dma_data_direction direction) { … } int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, int page_count, enum dma_data_direction direction) { … } EXPORT_SYMBOL(…); void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card) { … } EXPORT_SYMBOL(…); /* Convert DMA address to offset into virtually contiguous buffer. */ size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed) { … } struct fw_iso_context *fw_iso_context_create(struct fw_card *card, int type, int channel, int speed, size_t header_size, fw_iso_callback_t callback, void *callback_data) { … } EXPORT_SYMBOL(…); void fw_iso_context_destroy(struct fw_iso_context *ctx) { … } EXPORT_SYMBOL(…); int fw_iso_context_start(struct fw_iso_context *ctx, int cycle, int sync, int tags) { … } EXPORT_SYMBOL(…); int fw_iso_context_set_channels(struct fw_iso_context *ctx, u64 *channels) { … } int fw_iso_context_queue(struct fw_iso_context *ctx, struct fw_iso_packet *packet, struct fw_iso_buffer *buffer, unsigned long payload) { … } EXPORT_SYMBOL(…); void fw_iso_context_queue_flush(struct fw_iso_context *ctx) { … } EXPORT_SYMBOL(…); /** * fw_iso_context_flush_completions() - process isochronous context in current process context. * @ctx: the isochronous context * * Process the isochronous context in the current process context. The registered callback function * is called when a queued packet buffer with the interrupt flag is completed, either after * transmission in the IT context or after being filled in the IR context. Additionally, the * callback function is also called for the packet buffer completed at last. Furthermore, the * callback function is called as well when the header buffer in the context becomes full. If it is * required to process the context asynchronously, fw_iso_context_schedule_flush_completions() is * available instead. * * Context: Process context. May sleep due to disable_work_sync(). */ int fw_iso_context_flush_completions(struct fw_iso_context *ctx) { … } EXPORT_SYMBOL(…); int fw_iso_context_stop(struct fw_iso_context *ctx) { … } EXPORT_SYMBOL(…); /* * Isochronous bus resource management (channels, bandwidth), client side */ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, int bandwidth, bool allocate) { … } static int manage_channel(struct fw_card *card, int irm_id, int generation, u32 channels_mask, u64 offset, bool allocate) { … } static void deallocate_channel(struct fw_card *card, int irm_id, int generation, int channel) { … } /** * fw_iso_resource_manage() - Allocate or deallocate a channel and/or bandwidth * @card: card interface for this action * @generation: bus generation * @channels_mask: bitmask for channel allocation * @channel: pointer for returning channel allocation result * @bandwidth: pointer for returning bandwidth allocation result * @allocate: whether to allocate (true) or deallocate (false) * * In parameters: card, generation, channels_mask, bandwidth, allocate * Out parameters: channel, bandwidth * * This function blocks (sleeps) during communication with the IRM. * * Allocates or deallocates at most one channel out of channels_mask. * channels_mask is a bitfield with MSB for channel 63 and LSB for channel 0. * (Note, the IRM's CHANNELS_AVAILABLE is a big-endian bitfield with MSB for * channel 0 and LSB for channel 63.) * Allocates or deallocates as many bandwidth allocation units as specified. * * Returns channel < 0 if no channel was allocated or deallocated. * Returns bandwidth = 0 if no bandwidth was allocated or deallocated. * * If generation is stale, deallocations succeed but allocations fail with * channel = -EAGAIN. * * If channel allocation fails, no bandwidth will be allocated either. * If bandwidth allocation fails, no channel will be allocated either. * But deallocations of channel and bandwidth are tried independently * of each other's success. */ void fw_iso_resource_manage(struct fw_card *card, int generation, u64 channels_mask, int *channel, int *bandwidth, bool allocate) { … } EXPORT_SYMBOL(…);