Commit 054286b1 authored by Stefan Richter's avatar Stefan Richter Committed by Mauro Carvalho Chehab

V4L/DVB (13398): firedtv: reform lock transaction backend call

Preparation for the port of firedtv to the firewire-core kernel API:
The fdtv->backend->lock() hook and thus the CMP code is slightly changed
to better fit with the new API.
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 56411f49
...@@ -87,10 +87,15 @@ static inline struct node_entry *node_of(struct firedtv *fdtv) ...@@ -87,10 +87,15 @@ static inline struct node_entry *node_of(struct firedtv *fdtv)
return container_of(fdtv->device, struct unit_directory, device)->ne; return container_of(fdtv->device, struct unit_directory, device)->ne;
} }
static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
{ {
return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, int ret;
(__force quadlet_t)arg);
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];
return ret;
} }
static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
......
...@@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) ...@@ -1251,14 +1251,14 @@ static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
return ret; return ret;
} }
static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
{ {
int ret; int ret;
if (mutex_lock_interruptible(&fdtv->avc_mutex)) if (mutex_lock_interruptible(&fdtv->avc_mutex))
return -EINTR; return -EINTR;
ret = fdtv->backend->lock(fdtv, addr, data, arg); ret = fdtv->backend->lock(fdtv, addr, data);
if (ret < 0) if (ret < 0)
dev_err(fdtv->device, "CMP: lock I/O error\n"); dev_err(fdtv->device, "CMP: lock I/O error\n");
...@@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) ...@@ -1288,25 +1288,25 @@ static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
{ {
__be32 old_opcr, opcr; __be32 old_opcr, opcr[2];
u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
int attempts = 0; int attempts = 0;
int ret; int ret;
ret = cmp_read(fdtv, &opcr, opcr_address, 4); ret = cmp_read(fdtv, opcr, opcr_address, 4);
if (ret < 0) if (ret < 0)
return ret; return ret;
repeat: repeat:
if (!get_opcr_online(opcr)) { if (!get_opcr_online(*opcr)) {
dev_err(fdtv->device, "CMP: output offline\n"); dev_err(fdtv->device, "CMP: output offline\n");
return -EBUSY; return -EBUSY;
} }
old_opcr = opcr; old_opcr = *opcr;
if (get_opcr_p2p_connections(opcr)) { if (get_opcr_p2p_connections(*opcr)) {
if (get_opcr_channel(opcr) != channel) { if (get_opcr_channel(*opcr) != channel) {
dev_err(fdtv->device, "CMP: cannot change channel\n"); dev_err(fdtv->device, "CMP: cannot change channel\n");
return -EBUSY; return -EBUSY;
} }
...@@ -1314,11 +1314,11 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) ...@@ -1314,11 +1314,11 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
/* We don't allocate isochronous resources. */ /* We don't allocate isochronous resources. */
} else { } else {
set_opcr_channel(&opcr, channel); set_opcr_channel(opcr, channel);
set_opcr_data_rate(&opcr, 2); /* S400 */ set_opcr_data_rate(opcr, 2); /* S400 */
/* FIXME: this is for the worst case - optimize */ /* FIXME: this is for the worst case - optimize */
set_opcr_overhead_id(&opcr, 0); set_opcr_overhead_id(opcr, 0);
/* /*
* FIXME: allocate isochronous channel and bandwidth at IRM * FIXME: allocate isochronous channel and bandwidth at IRM
...@@ -1326,13 +1326,16 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) ...@@ -1326,13 +1326,16 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
*/ */
} }
set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); opcr[1] = *opcr;
opcr[0] = old_opcr;
ret = cmp_lock(fdtv, opcr_address, opcr);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (old_opcr != opcr) { if (old_opcr != *opcr) {
/* /*
* FIXME: if old_opcr.P2P_Connections > 0, * FIXME: if old_opcr.P2P_Connections > 0,
* deallocate isochronous channel and bandwidth at IRM * deallocate isochronous channel and bandwidth at IRM
...@@ -1350,27 +1353,30 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) ...@@ -1350,27 +1353,30 @@ int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
{ {
__be32 old_opcr, opcr; __be32 old_opcr, opcr[2];
u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
int attempts = 0; int attempts = 0;
if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) if (cmp_read(fdtv, opcr, opcr_address, 4) < 0)
return; return;
repeat: repeat:
if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
get_opcr_channel(opcr) != channel) { get_opcr_channel(*opcr) != channel) {
dev_err(fdtv->device, "CMP: no connection to break\n"); dev_err(fdtv->device, "CMP: no connection to break\n");
return; return;
} }
old_opcr = opcr; old_opcr = *opcr;
set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);
opcr[1] = *opcr;
opcr[0] = old_opcr;
if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) if (cmp_lock(fdtv, opcr_address, opcr) < 0)
return; return;
if (old_opcr != opcr) { if (old_opcr != *opcr) {
/* /*
* FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
* owner, deallocate isochronous channel and bandwidth at IRM * owner, deallocate isochronous channel and bandwidth at IRM
......
...@@ -72,7 +72,7 @@ struct input_dev; ...@@ -72,7 +72,7 @@ struct input_dev;
struct firedtv; struct firedtv;
struct firedtv_backend { struct firedtv_backend {
int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]);
int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
int (*start_iso)(struct firedtv *fdtv); int (*start_iso)(struct firedtv *fdtv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment