if (!card->broadcast_channel_allocated) {
fw_iso_resource_manage(card, generation, 1ULL << 31,
- &channel, &bandwidth, true,
- card->bm_transaction_data);
+ &channel, &bandwidth, true);
if (channel != 31) {
fw_notify("failed to allocate broadcast channel\n");
return;
bool root_device_is_cmc;
bool irm_is_1394_1995_only;
bool keep_this_irm;
+ __be32 transaction_data[2];
spin_lock_irq(&card->lock);
goto pick_me;
}
- card->bm_transaction_data[0] = cpu_to_be32(0x3f);
- card->bm_transaction_data[1] = cpu_to_be32(local_id);
+ transaction_data[0] = cpu_to_be32(0x3f);
+ transaction_data[1] = cpu_to_be32(local_id);
spin_unlock_irq(&card->lock);
rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
irm_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
- card->bm_transaction_data, 8);
+ transaction_data, 8);
if (rcode == RCODE_GENERATION)
/* Another bus reset, BM work has been rescheduled. */
goto out;
- bm_id = be32_to_cpu(card->bm_transaction_data[0]);
+ bm_id = be32_to_cpu(transaction_data[0]);
spin_lock_irq(&card->lock);
if (rcode == RCODE_COMPLETE && generation == card->generation)
/*
* Make sure that the cycle master sends cycle start packets.
*/
- card->bm_transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
+ transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
root_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_STATE_SET,
- card->bm_transaction_data, 4);
+ transaction_data, 4);
if (rcode == RCODE_GENERATION)
goto out;
}
int generation;
u64 channels;
s32 bandwidth;
- __be32 transaction_data[2];
struct iso_resource_event *e_alloc, *e_dealloc;
};
r->channels, &channel, &bandwidth,
todo == ISO_RES_ALLOC ||
todo == ISO_RES_REALLOC ||
- todo == ISO_RES_ALLOC_ONCE,
- r->transaction_data);
+ todo == ISO_RES_ALLOC_ONCE);
/*
* Is this generation outdated already? As long as this resource sticks
* in the idr, it will be scheduled again for a newer generation or at
*/
static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
- int bandwidth, bool allocate, __be32 data[2])
+ int bandwidth, bool allocate)
{
int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
+ __be32 data[2];
/*
* On a 1394a IRM with low contention, try < 1 is enough.
}
static int manage_channel(struct fw_card *card, int irm_id, int generation,
- u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
+ u32 channels_mask, u64 offset, bool allocate)
{
__be32 bit, all, old;
+ __be32 data[2];
int channel, ret = -EIO, retry = 5;
old = all = allocate ? cpu_to_be32(~0) : 0;
}
static void deallocate_channel(struct fw_card *card, int irm_id,
- int generation, int channel, __be32 buffer[2])
+ int generation, int channel)
{
u32 mask;
u64 offset;
offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
- manage_channel(card, irm_id, generation, mask, offset, false, buffer);
+ manage_channel(card, irm_id, generation, mask, offset, false);
}
/**
*/
void fw_iso_resource_manage(struct fw_card *card, int generation,
u64 channels_mask, int *channel, int *bandwidth,
- bool allocate, __be32 buffer[2])
+ bool allocate)
{
u32 channels_hi = channels_mask; /* channels 31...0 */
u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
if (channels_hi)
c = manage_channel(card, irm_id, generation, channels_hi,
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
- allocate, buffer);
+ allocate);
if (channels_lo && c < 0) {
c = manage_channel(card, irm_id, generation, channels_lo,
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
- allocate, buffer);
+ allocate);
if (c >= 0)
c += 32;
}
if (*bandwidth == 0)
return;
- ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
- allocate, buffer);
+ ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
if (ret < 0)
*bandwidth = 0;
if (allocate && ret < 0) {
if (c >= 0)
- deallocate_channel(card, irm_id, generation, c, buffer);
+ deallocate_channel(card, irm_id, generation, c);
*channel = ret;
}
}
* 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
- * quadlet-sized payload or of local (loopback) requests. Hence make sure that
- * the buffer complies with the restrictions for DMA-mapped memory. The
+ * @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.
*
* 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.
+ * 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,
{
int ret;
- mutex_lock(&fdtv->avc_mutex);
-
ret = fdtv_read(fdtv, addr, data);
if (ret < 0)
dev_err(fdtv->device, "CMP: read I/O error\n");
- mutex_unlock(&fdtv->avc_mutex);
-
return ret;
}
{
int ret;
- mutex_lock(&fdtv->avc_mutex);
-
- /* data[] is stack-allocated and should not be DMA-mapped. */
- memcpy(fdtv->avc_data, data, 8);
-
- ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
+ ret = fdtv_lock(fdtv, addr, data);
if (ret < 0)
dev_err(fdtv->device, "CMP: lock I/O error\n");
- else
- memcpy(data, fdtv->avc_data, 8);
-
- mutex_unlock(&fdtv->avc_mutex);
return ret;
}
struct delayed_work bm_work; /* bus manager job */
int bm_retries;
int bm_generation;
- __be32 bm_transaction_data[2];
int bm_node_id;
bool bm_abdicate;
void fw_iso_context_destroy(struct fw_iso_context *ctx);
void fw_iso_resource_manage(struct fw_card *card, int generation,
u64 channels_mask, int *channel, int *bandwidth,
- bool allocate, __be32 buffer[2]);
+ bool allocate);
#endif /* _LINUX_FIREWIRE_H */
enum bus_reset_handling bus_reset_handling)
{
struct fw_device *device = fw_parent_device(c->resources.unit);
- __be32 *buffer = c->resources.buffer;
int generation = c->resources.generation;
int rcode, errors = 0;
- __be32 old_arg;
+ __be32 old_arg, buffer[2];
int err;
buffer[0] = c->last_pcr_value;
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/sched.h>
-#include <linux/slab.h>
#include <linux/spinlock.h>
#include "iso-resources.h"
*/
int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
{
- r->buffer = kmalloc(2 * 4, GFP_KERNEL);
- if (!r->buffer)
- return -ENOMEM;
-
r->channels_mask = ~0uLL;
r->unit = fw_unit_get(unit);
mutex_init(&r->mutex);
void fw_iso_resources_destroy(struct fw_iso_resources *r)
{
WARN_ON(r->allocated);
- kfree(r->buffer);
mutex_destroy(&r->mutex);
fw_unit_put(r->unit);
}
bandwidth = r->bandwidth + r->bandwidth_overhead;
fw_iso_resource_manage(card, r->generation, r->channels_mask,
- &channel, &bandwidth, true, r->buffer);
+ &channel, &bandwidth, true);
if (channel == -EAGAIN) {
mutex_unlock(&r->mutex);
goto retry_after_bus_reset;
bandwidth = r->bandwidth + r->bandwidth_overhead;
fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
- &channel, &bandwidth, true, r->buffer);
+ &channel, &bandwidth, true);
/*
* When another bus reset happens, pretend that the allocation
* succeeded; we will try again for the new generation later.
if (r->allocated) {
bandwidth = r->bandwidth + r->bandwidth_overhead;
fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
- &channel, &bandwidth, false, r->buffer);
+ &channel, &bandwidth, false);
if (channel < 0)
dev_err(&r->unit->device,
"isochronous resource deallocation failed\n");
unsigned int bandwidth_overhead;
int generation; /* in which allocation is valid */
bool allocated;
- __be32 *buffer;
};
int fw_iso_resources_init(struct fw_iso_resources *r,