Merge tag 'firewire-updates-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394
Merge commit. Changes below are compared with the first parent: a31980db.
Changes
7 files changed · +266 −226
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| drivers/firewire/core-card.c | modified | +2 | −2 | View file |
| drivers/firewire/core-cdev.c | modified | +26 | −45 | View file |
| drivers/firewire/core-iso.c | modified | +55 | −47 | View file |
| drivers/firewire/core.h | modified | +12 | −2 | View file |
| drivers/firewire/ohci.c | modified | +132 | −102 | View file |
| include/linux/firewire.h | modified | +30 | −6 | View file |
| sound/firewire/amdtp-stream.c | modified | +9 | −22 | View file |
Only the first 600 diff lines are shown. Download the complete patch.
drivers/firewire/core-card.c
View filediff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index 0462d7b..a754c63 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -704,8 +704,8 @@ static int dummy_enable_phys_dma(struct fw_card *card,
return -ENODEV;
}
-static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card,
- int type, int channel, size_t header_size)
+static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card, int type,
+ int channel, size_t header_size, size_t header_storage_size)
{
return ERR_PTR(-ENODEV);
}
drivers/firewire/core-cdev.c
View filediff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 49dc161..9e964fd 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -63,10 +63,10 @@ struct client {
u64 bus_reset_closure;
struct fw_iso_context *iso_context;
+ struct mutex iso_context_mutex;
u64 iso_closure;
struct fw_iso_buffer buffer;
unsigned long vm_start;
- bool buffer_is_mapped;
struct list_head phy_receiver_link;
u64 phy_receiver_closure;
@@ -306,6 +306,7 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
INIT_LIST_HEAD(&client->phy_receiver_link);
INIT_LIST_HEAD(&client->link);
kref_init(&client->kref);
+ mutex_init(&client->iso_context_mutex);
file->private_data = client;
@@ -1025,25 +1026,10 @@ static enum dma_data_direction iso_dma_direction(struct fw_iso_context *context)
return DMA_FROM_DEVICE;
}
-static struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card,
- fw_iso_mc_callback_t callback,
- void *callback_data)
-{
- struct fw_iso_context *ctx;
-
- ctx = fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL,
- 0, 0, 0, NULL, callback_data);
- if (!IS_ERR(ctx))
- ctx->callback.mc = callback;
-
- return ctx;
-}
-
static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
{
struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
struct fw_iso_context *context;
- union fw_iso_callback cb;
int ret;
BUILD_BUG_ON(FW_CDEV_ISO_CONTEXT_TRANSMIT != FW_ISO_CONTEXT_TRANSMIT ||
@@ -1055,20 +1041,15 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
case FW_ISO_CONTEXT_TRANSMIT:
if (a->speed > SCODE_3200 || a->channel > 63)
return -EINVAL;
-
- cb.sc = iso_callback;
break;
case FW_ISO_CONTEXT_RECEIVE:
if (a->header_size < 4 || (a->header_size & 3) ||
a->channel > 63)
return -EINVAL;
-
- cb.sc = iso_callback;
break;
case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
- cb.mc = iso_mc_callback;
break;
default:
@@ -1076,38 +1057,36 @@ static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
}
if (a->type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL)
- context = fw_iso_mc_context_create(client->device->card, cb.mc,
- client);
+ context = fw_iso_mc_context_create(client->device->card, iso_mc_callback, client);
else
- context = fw_iso_context_create(client->device->card, a->type,
- a->channel, a->speed,
- a->header_size, cb.sc, client);
+ context = fw_iso_context_create(client->device->card, a->type, a->channel, a->speed,
+ a->header_size, iso_callback, client);
if (IS_ERR(context))
return PTR_ERR(context);
if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)
- context->drop_overflow_headers = true;
+ context->flags |= FW_ISO_CONTEXT_FLAG_DROP_OVERFLOW_HEADERS;
// We only support one context at this time.
- guard(spinlock_irq)(&client->lock);
-
- if (client->iso_context != NULL) {
- fw_iso_context_destroy(context);
-
- return -EBUSY;
- }
- if (!client->buffer_is_mapped) {
- ret = fw_iso_buffer_map_dma(&client->buffer,
- client->device->card,
- iso_dma_direction(context));
- if (ret < 0) {
+ scoped_guard(mutex, &client->iso_context_mutex) {
+ if (client->iso_context != NULL) {
fw_iso_context_destroy(context);
- return ret;
+ return -EBUSY;
+ }
+ // The DMA mapping operation is available if the buffer is already allocated by
+ // mmap(2) system call. If not, it is delegated to the system call.
+ if (client->buffer.pages && !client->buffer.dma_addrs) {
+ ret = fw_iso_buffer_map_dma(&client->buffer, client->device->card,
+ iso_dma_direction(context));
+ if (ret < 0) {
+ fw_iso_context_destroy(context);
+
+ return ret;
+ }
}
- client->buffer_is_mapped = true;
+ client->iso_closure = a->closure;
+ client->iso_context = context;
}
- client->iso_closure = a->closure;
- client->iso_context = context;
a->handle = 0;
@@ -1826,13 +1805,14 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
if (ret < 0)
return ret;
- scoped_guard(spinlock_irq, &client->lock) {
+ scoped_guard(mutex, &client->iso_context_mutex) {
+ // The direction of DMA can be determined if the isochronous context is already
+ // allocated. If not, the DMA mapping operation is postponed after the allocation.
if (client->iso_context) {
ret = fw_iso_buffer_map_dma(&client->buffer, client->device->card,
iso_dma_direction(client->iso_context));
if (ret < 0)
goto fail;
- client->buffer_is_mapped = true;
}
}
@@ -1879,6 +1859,7 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
if (client->iso_context)
fw_iso_context_destroy(client->iso_context);
+ mutex_destroy(&client->iso_context_mutex);
if (client->buffer.pages)
fw_iso_buffer_destroy(&client->buffer, client->device->card);
drivers/firewire/core-iso.c
View filediff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index a674938..3190b2c 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -30,48 +30,57 @@
int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count)
{
- int i;
+ struct page **page_array __free(kfree) = kcalloc(page_count, sizeof(page_array[0]), GFP_KERNEL);
- buffer->page_count = 0;
- buffer->page_count_mapped = 0;
- buffer->pages = kmalloc_array(page_count, sizeof(buffer->pages[0]),
- GFP_KERNEL);
- if (buffer->pages == NULL)
+ if (!page_array)
return -ENOMEM;
- for (i = 0; i < page_count; i++) {
- buffer->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
- if (buffer->pages[i] == NULL)
- break;
- }
- buffer->page_count = i;
- if (i < page_count) {
- fw_iso_buffer_destroy(buffer, NULL);
+ // Retrieve noncontiguous pages. The descriptors for 1394 OHCI isochronous DMA contexts
+ // have a set of address and length per each, while the reason to use pages is the
+ // convenience to map them into virtual address space of user process.
+ unsigned long nr_populated = alloc_pages_bulk(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO,
+ page_count, page_array);
+ if (nr_populated != page_count) {
+ // Assuming the above call fills page_array sequentially from the beginning.
+ release_pages(page_array, nr_populated);
return -ENOMEM;
}
+ buffer->page_count = page_count;
+ buffer->pages = no_free_ptr(page_array);
+
return 0;
}
int fw_iso_buffer_map_dma(struct fw_iso_buffer *buffer, struct fw_card *card,
enum dma_data_direction direction)
{
- dma_addr_t address;
+ dma_addr_t *dma_addrs __free(kfree) = kcalloc(buffer->page_count, sizeof(dma_addrs[0]),
+ GFP_KERNEL);
int i;
- buffer->direction = direction;
+ if (!dma_addrs)
+ return -ENOMEM;
+ // Retrieve DMA mapping addresses for the pages. They are not contiguous. Maintain the cache
+ // coherency for the pages by hand.
for (i = 0; i < buffer->page_count; i++) {
- address = dma_map_page(card->device, buffer->pages[i],
- 0, PAGE_SIZE, direction);
- if (dma_mapping_error(card->device, address))
+ // The dma_map_phys() with a physical address per page is available here, instead.
+ dma_addr_t dma_addr = dma_map_page(card->device, buffer->pages[i], 0, PAGE_SIZE,
+ direction);
+ if (dma_mapping_error(card->device, dma_addr))
break;
- set_page_private(buffer->pages[i], address);
+ dma_addrs[i] = dma_addr;
}
- buffer->page_count_mapped = i;
- if (i < buffer->page_count)
+ if (i < buffer->page_count) {
+ while (i-- > 0)
+ dma_unmap_page(card->device, dma_addrs[i], PAGE_SIZE, buffer->direction);
return -ENOMEM;
+ }
+
+ buffer->direction = direction;
+ buffer->dma_addrs = no_free_ptr(dma_addrs);
return 0;
}
@@ -96,34 +105,31 @@ EXPORT_SYMBOL(fw_iso_buffer_init);
void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer,
struct fw_card *card)
{
- int i;
- dma_addr_t address;
+ if (buffer->dma_addrs) {
+ for (int i = 0; i < buffer->page_count; ++i) {
+ dma_addr_t dma_addr = buffer->dma_addrs[i];
+ dma_unmap_page(card->device, dma_addr, PAGE_SIZE, buffer->direction);
+ }
+ kfree(buffer->dma_addrs);
+ buffer->dma_addrs = NULL;
+ }
- for (i = 0; i < buffer->page_count_mapped; i++) {
- address = page_private(buffer->pages[i]);
- dma_unmap_page(card->device, address,
- PAGE_SIZE, buffer->direction);
+ if (buffer->pages) {
+ release_pages(buffer->pages, buffer->page_count);
+ kfree(buffer->pages);
+ buffer->pages = NULL;
}
- for (i = 0; i < buffer->page_count; i++)
- __free_page(buffer->pages[i]);
- kfree(buffer->pages);
- buffer->pages = NULL;
buffer->page_count = 0;
- buffer->page_count_mapped = 0;
}
EXPORT_SYMBOL(fw_iso_buffer_destroy);
/* Convert DMA address to offset into virtually contiguous buffer. */
size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed)
{
- size_t i;
- dma_addr_t address;
- ssize_t offset;
-
- for (i = 0; i < buffer->page_count; i++) {
- address = page_private(buffer->pages[i]);
- offset = (ssize_t)completed - (ssize_t)address;
+ for (int i = 0; i < buffer->page_count; i++) {
+ dma_addr_t dma_addr = buffer->dma_addrs[i];
+ ssize_t offset = (ssize_t)completed - (ssize_t)dma_addr;
if (offset > 0 && offset <= PAGE_SIZE)
return (i << PAGE_SHIFT) + offset;
}
@@ -131,14 +137,14 @@ size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed)
return 0;
}
-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)
+struct fw_iso_context *__fw_iso_context_create(struct fw_card *card, int type, int channel,
+ int speed, size_t header_size, size_t header_storage_size,
+ union fw_iso_callback callback, void *callback_data)
{
struct fw_iso_context *ctx;
- ctx = card->driver->allocate_iso_context(card,
- type, channel, header_size);
+ ctx = card->driver->allocate_iso_context(card, type, channel, header_size,
+ header_storage_size);
if (IS_ERR(ctx))
return ctx;
@@ -146,8 +152,10 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
ctx->type = type;
ctx->channel = channel;
ctx->speed = speed;
+ ctx->flags = 0;
ctx->header_size = header_size;
- ctx->callback.sc = callback;
+ ctx->header_storage_size = header_storage_size;
+ ctx->callback = callback;
ctx->callback_data = callback_data;
trace_isoc_outbound_allocate(ctx, channel, speed);
@@ -156,7 +164,7 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
return ctx;
}
-EXPORT_SYMBOL(fw_iso_context_create);
+EXPORT_SYMBOL(__fw_iso_context_create);
void fw_iso_context_destroy(struct fw_iso_context *ctx)
{
drivers/firewire/core.h
View filediff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 41fb39d..8b49d74 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -100,8 +100,8 @@ struct fw_card_driver {
void (*write_csr)(struct fw_card *card, int csr_offset, u32 value);
struct fw_iso_context *
- (*allocate_iso_context)(struct fw_card *card,
- int type, int channel, size_t header_size);
+ (*allocate_iso_context)(struct fw_card *card, int type, int channel, size_t header_size,
+ size_t header_storage_size);
void (*free_iso_context)(struct fw_iso_context *ctx);
int (*start_iso)(struct fw_iso_context *ctx,
@@ -166,12 +166,22 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event);
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);
+size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed);
static inline void fw_iso_context_init_work(struct fw_iso_context *ctx, work_func_t func)
{
INIT_WORK(&ctx->work, func);
}
+static inline struct fw_iso_context *fw_iso_mc_context_create(struct fw_card *card,
+ fw_iso_mc_callback_t callback, void *callback_data)
+{
+ union fw_iso_callback cb = { .mc = callback };
+
+ return __fw_iso_context_create(card, FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL, 0, 0, 0, 0, cb,
+ callback_data);
+}
+
/* -topology */
drivers/firewire/ohci.c
View filediff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index e3e78dc..1c868c1 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -86,7 +86,7 @@ struct descriptor {
#define AR_BUFFER_SIZE (32*1024)
#define AR_BUFFERS_MIN DIV_ROUND_UP(AR_BUFFER_SIZE, PAGE_SIZE)
/* we need at least two pages for proper list management */
-#define AR_BUFFERS (AR_BUFFERS_MIN >= 2 ? AR_BUFFERS_MIN : 2)
+#define AR_BUFFERS MAX(2, AR_BUFFERS_MIN)
#define MAX_ASYNC_PAYLOAD 4096
#define MAX_AR_PACKET_SIZE (16 + MAX_ASYNC_PAYLOAD + 4)
@@ -96,6 +96,7 @@ struct ar_context {
struct fw_ohci *ohci;
struct page *pages[AR_BUFFERS];
void *buffer;
+ dma_addr_t dma_addrs[AR_BUFFERS];
struct descriptor *descriptors;
dma_addr_t descriptors_bus;
void *pointer;
@@ -167,14 +168,20 @@ struct at_context {
struct iso_context {
struct fw_iso_context base;
struct context context;
- void *header;
- size_t header_length;
unsigned long flushing_completions;
- u32 mc_buffer_bus;
- u16 mc_completed;
- u16 last_timestamp;
u8 sync;
u8 tags;
+ union {
+ struct {
+ u16 last_timestamp;
+ size_t header_length;
+ void *header;
+ } sc;
+ struct {
+ u32 buffer_bus;
+ u16 completed;
+ } mc;
+ };
};
#define CONFIG_ROM_SIZE (CSR_CONFIG_ROM_END - CSR_CONFIG_ROM)
@@ -513,11 +520,6 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr,
return update_phy_reg(ohci, addr, clear_bits, set_bits);
}
-static inline dma_addr_t ar_buffer_bus(struct ar_context *ctx, unsigned int i)
-{
- return page_private(ctx->pages[i]);
-}
-
static void ar_context_link_page(struct ar_context *ctx, unsigned int index)
{
struct descriptor *d;
@@ -539,18 +541,22 @@ static void ar_context_link_page(struct ar_context *ctx, unsigned int index)
static void ar_context_release(struct ar_context *ctx)
{
struct device *dev = ctx->ohci->card.device;
- unsigned int i;
if (!ctx->buffer)
return;
+ for (int i = 0; i < AR_BUFFERS; ++i) {
+ dma_addr_t dma_addr = ctx->dma_addrs[i];
+ if (dma_addr)
+ dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
+ }
+ memset(ctx->dma_addrs, 0, sizeof(ctx->dma_addrs));
+
vunmap(ctx->buffer);
+ ctx->buffer = NULL;
- for (i = 0; i < AR_BUFFERS; i++) {
- if (ctx->pages[i])
- dma_free_pages(dev, PAGE_SIZE, ctx->pages[i],
- ar_buffer_bus(ctx, i), DMA_FROM_DEVICE);
- }
+ release_pages(ctx->pages, AR_BUFFERS);
+ memset(ctx->pages, 0, sizeof(ctx->pages));
}
static void ar_context_abort(struct ar_context *ctx, const char *error_msg)
@@ -643,14 +649,12 @@ static void ar_sync_buffers_for_cpu(struct ar_context *ctx,
i = ar_first_buffer_index(ctx);
while (i != end_buffer_index) {
- dma_sync_single_for_cpu(ctx->ohci->card.device,
- ar_buffer_bus(ctx, i),
- PAGE_SIZE, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(ctx->ohci->card.device, ctx->dma_addrs[i], PAGE_SIZE,
+ DMA_FROM_DEVICE);
i = ar_next_buffer_index(i);
}
if (end_buffer_offset > 0)
- dma_sync_single_for_cpu(ctx->ohci->card.device,
- ar_buffer_bus(ctx, i),
+ dma_sync_single_for_cpu(ctx->ohci->card.device, ctx->dma_addrs[i],
end_buffer_offset, DMA_FROM_DEVICE);
}
@@ -791,9 +795,8 @@ static void ar_recycle_buffers(struct ar_context *ctx, unsigned int end_buffer)
i = ar_first_buffer_index(ctx);
while (i != end_buffer) {
- dma_sync_single_for_device(ctx->ohci->card.device,
- ar_buffer_bus(ctx, i),
- PAGE_SIZE, DMA_FROM_DEVICE);
+ dma_sync_single_for_device(ctx->ohci->card.device, ctx->dma_addrs[i], PAGE_SIZE,
+ DMA_FROM_DEVICE);
ar_context_link_page(ctx, i);
i = ar_next_buffer_index(i);
}
@@ -845,31 +848,57 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
{
struct device *dev = ohci->card.device;
unsigned int i;
- dma_addr_t dma_addr;
struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES];
+ dma_addr_t dma_addrs[AR_BUFFERS];
+ void *vaddr;
struct descriptor *d;
ctx->regs = regs;
ctx->ohci = ohci;
INIT_WORK(&ctx->work, ohci_ar_context_work);
- for (i = 0; i < AR_BUFFERS; i++) {
- ctx->pages[i] = dma_alloc_pages(dev, PAGE_SIZE, &dma_addr,
- DMA_FROM_DEVICE, GFP_KERNEL);
- if (!ctx->pages[i])
- goto out_of_memory;
- set_page_private(ctx->pages[i], dma_addr);
- dma_sync_single_for_device(dev, dma_addr, PAGE_SIZE,
- DMA_FROM_DEVICE);
+ // Retrieve noncontiguous pages. The descriptors for 1394 OHCI AR DMA contexts have a set
+ // of address and length per each. The reason to use pages is to construct contiguous
+ // address range in kernel virtual address space.
+ unsigned long nr_populated = alloc_pages_bulk(GFP_KERNEL | GFP_DMA32, AR_BUFFERS, pages);
+
+ if (nr_populated != AR_BUFFERS) {
+ release_pages(pages, nr_populated);
+ return -ENOMEM;
}
- for (i = 0; i < AR_BUFFERS; i++)
- pages[i] = ctx->pages[i];
+ // Map the pages into contiguous kernel virtual addresses so that the packet data
+ // across the pages can be referred as being contiguous, especially across the last
+ // and first pages.
for (i = 0; i < AR_WRAPAROUND_PAGES; i++)
- pages[AR_BUFFERS + i] = ctx->pages[i];
- ctx->buffer = vmap(pages, ARRAY_SIZE(pages), VM_MAP, PAGE_KERNEL);
- if (!ctx->buffer)
- goto out_of_memory;
+ pages[AR_BUFFERS + i] = pages[i];
+ vaddr = vmap(pages, ARRAY_SIZE(pages), VM_MAP, PAGE_KERNEL);
+ if (!vaddr) {
+ release_pages(pages, nr_populated);
+ return -ENOMEM;
+ }
+
+ // Retrieve DMA mapping addresses for the pages. They are not contiguous. Maintain the cache
+ // coherency for the pages by hand.
+ for (i = 0; i < AR_BUFFERS; i++) {
+ // The dma_map_phys() with a physical address per page is available here, instead.
+ dma_addr_t dma_addr = dma_map_page(dev, pages[i], 0, PAGE_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dev, dma_addr))
+ break;
+ dma_addrs[i] = dma_addr;
+ dma_sync_single_for_device(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
+ }
+ if (i < AR_BUFFERS) {
+ while (i-- > 0)
+ dma_unmap_page(dev, dma_addrs[i], PAGE_SIZE, DMA_FROM_DEVICE);
+ vunmap(vaddr);
+ release_pages(pages, nr_populated);
+ return -ENOMEM;
+ }
+
+ memcpy(ctx->dma_addrs, dma_addrs, sizeof(ctx->dma_addrs));
+ ctx->buffer = vaddr;
+ memcpy(ctx->pages, pages, sizeof(ctx->pages));
ctx->descriptors = ohci->misc_buffer + descriptors_offset;
ctx->descriptors_bus = ohci->misc_buffer_bus + descriptors_offset;
@@ -880,17 +909,12 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
DESCRIPTOR_STATUS |
DESCRIPTOR_BRANCH_ALWAYS);
- d->data_address = cpu_to_le32(ar_buffer_bus(ctx, i));
+ d->data_address = cpu_to_le32(ctx->dma_addrs[i]);
d->branch_address = cpu_to_le32(ctx->descriptors_bus +
ar_next_buffer_index(i) * sizeof(struct descriptor));
}
return 0;
-
-out_of_memory:
- ar_context_release(ctx);
-
- return -ENOMEM;
}
static void ar_context_run(struct ar_context *ctx)
@@ -2717,29 +2741,28 @@ static void ohci_write_csr(struct fw_card *card, int csr_offset, u32 value)
static void flush_iso_completions(struct iso_context *ctx, enum fw_iso_context_completions_cause cause)
{
- trace_isoc_inbound_single_completions(&ctx->base, ctx->last_timestamp, cause, ctx->header,
- ctx->header_length);
- trace_isoc_outbound_completions(&ctx->base, ctx->last_timestamp, cause, ctx->header,
This diff is incomplete. Download the complete patch.
include/linux/firewire.h
View fileThis diff is incomplete. Download the complete patch.
sound/firewire/amdtp-stream.c
View fileThis diff is incomplete. Download the complete patch.