Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3fb80ef3 authored by Stefan Richter's avatar Stefan Richter Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: firedtv: do not DMA-map stack addresses



This is a portability fix and reduces stack usage.

The DMA mapping API cannot map on-stack addresses, as explained in
Documentation/DMA-mapping.txt.  Convert the two cases of on-stack packet
payload buffers in firedtv (payload of write requests in avc_write and
of lock requests in cmp_lock) to slab-allocated memory.

We use the 512 bytes sized FCP frame buffer in struct firedtv for this
purpose.  Previously it held only incoming FCP responses, now it holds
pending FCP requests and is then overwriten by an FCP response from the
tuner subunit.  Ditto for CMP lock requests and responses.  Accesses to
the payload buffer are serialized by fdtv->avc_mutex.

As a welcome side effect, stack usage of the AV/C transaction functions
is reduced by 512 bytes.

Alas, avc_register_remote_control() is a special case:  It previously
did not wait for a response.  To fit better in with the other FCP
transactions, let it wait for an interim response.

Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 9420048c
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -90,13 +90,14 @@ static inline struct node_entry *node_of(struct firedtv *fdtv)
	return container_of(fdtv->device, struct unit_directory, device)->ne;
}

static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
{
	quadlet_t *d = data;
	int ret;

	ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP,
		(__force quadlet_t *)&data[1], (__force quadlet_t)data[0]);
	data[0] = data[1];
	ret = hpsb_node_lock(node_of(fdtv), addr,
			     EXTCODE_COMPARE_SWAP, &d[1], d[0]);
	d[0] = d[1];

	return ret;
}
+255 −182

File changed.

Preview size limit exceeded, changes collapsed.

+0 −1
Original line number Diff line number Diff line
@@ -277,7 +277,6 @@ struct firedtv *fdtv_alloc(struct device *dev,

	mutex_init(&fdtv->avc_mutex);
	init_waitqueue_head(&fdtv->avc_wait);
	fdtv->avc_reply_received = true;
	mutex_init(&fdtv->demux_mutex);
	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);

+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
	return rcode != RCODE_COMPLETE ? -EIO : 0;
}

static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
{
	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
}
+3 −3
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ struct input_dev;
struct firedtv;

struct firedtv_backend {
	int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
	int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
	int (*read)(struct firedtv *fdtv, u64 addr, void *data);
	int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
	int (*start_iso)(struct firedtv *fdtv);
@@ -114,8 +114,8 @@ struct firedtv {
	unsigned long		channel_active;
	u16			channel_pid[16];

	size_t			response_length;
	u8			response[512];
	int			avc_data_length;
	u8			avc_data[512];
};

/* firedtv-1394.c */