diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-12-24 05:59:57 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-12-29 13:58:17 -0500 |
commit | 1f8fef7b3388b5a976e80839679b5bae581a1091 (patch) | |
tree | 40ce4828cee287d6e54f627df787f8d993a21b1e /drivers/media | |
parent | 5d7db0499e5bb13381a7fbfdd0d913b966545e75 (diff) |
firewire: add fw_csr_string() helper function
The core (sysfs attributes), the firedtv driver, and possible future
drivers all read strings from some configuration ROM directory. Factor
out the generic code from show_text_leaf() into a new helper function,
modified slightly to handle arbitrary buffer sizes.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-fw.c | 39 |
1 files changed, 5 insertions, 34 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 6223bf01efe9..4253b7ab0097 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c | |||
@@ -239,47 +239,18 @@ static const struct fw_address_region fcp_region = { | |||
239 | }; | 239 | }; |
240 | 240 | ||
241 | /* Adjust the template string if models with longer names appear. */ | 241 | /* Adjust the template string if models with longer names appear. */ |
242 | #define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4)) | 242 | #define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") |
243 | |||
244 | static size_t model_name(u32 *directory, __be32 *buffer) | ||
245 | { | ||
246 | struct fw_csr_iterator ci; | ||
247 | int i, length, key, value, last_key = 0; | ||
248 | u32 *block = NULL; | ||
249 | |||
250 | fw_csr_iterator_init(&ci, directory); | ||
251 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
252 | if (last_key == CSR_MODEL && | ||
253 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | ||
254 | block = ci.p - 1 + value; | ||
255 | last_key = key; | ||
256 | } | ||
257 | |||
258 | if (block == NULL) | ||
259 | return 0; | ||
260 | |||
261 | length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN); | ||
262 | if (length <= 0) | ||
263 | return 0; | ||
264 | |||
265 | /* fast-forward to text string */ | ||
266 | block += 3; | ||
267 | |||
268 | for (i = 0; i < length; i++) | ||
269 | buffer[i] = cpu_to_be32(block[i]); | ||
270 | |||
271 | return length * 4; | ||
272 | } | ||
273 | 243 | ||
274 | static int node_probe(struct device *dev) | 244 | static int node_probe(struct device *dev) |
275 | { | 245 | { |
276 | struct firedtv *fdtv; | 246 | struct firedtv *fdtv; |
277 | __be32 name[MAX_MODEL_NAME_LEN]; | 247 | char name[MAX_MODEL_NAME_LEN]; |
278 | int name_len, err; | 248 | int name_len, err; |
279 | 249 | ||
280 | name_len = model_name(fw_unit(dev)->directory, name); | 250 | name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL, |
251 | name, sizeof(name)); | ||
281 | 252 | ||
282 | fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len); | 253 | fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); |
283 | if (!fdtv) | 254 | if (!fdtv) |
284 | return -ENOMEM; | 255 | return -ENOMEM; |
285 | 256 | ||