Skip to content

Commit 141d9c6

Browse files
committed
Merge tag 'firewire-updates-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394
Pull firewire updates from Takashi Sakamoto: "This includes the series of changes related to device attributes, as well as slight code refactoring. Some old devices are recognized to have legacy layout of configuration ROM. They have an inconvenience that FireWire subsystem adds no attributes for vendor information to corresponding devices. The main purpose of this update is to rectify the inconvenience. We have a slight concern about regression. The update changes the value of modalias for the unit devices by populating its model field, which was previously left as zero in the case. I've assessed the potential impact of this change and anticipate it to have minimal concern for both the kernel and user lands. The change is enough acceptable" * tag 'firewire-updates-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: firewire: core: fill model field in modalias of unit device for legacy layout of configuration ROM firewire: core: detect model name for legacy layout of configuration ROM firewire: core: detect numeric model identifier for legacy layout of configuration ROM firewire: test: add test of device attributes for legacy AV/C device firewire: test: add test of device attributes for simple AV/C device firewire: test: add KUnit test for device attributes firewire: core: replace magic number with macro firewire: core: adds constant qualifier for local helper functions firewire: make fw_bus_type const
2 parents 645f910 + 986c20b commit 141d9c6

File tree

5 files changed

+370
-29
lines changed

5 files changed

+370
-29
lines changed

drivers/firewire/.kunitconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ CONFIG_KUNIT=y
22
CONFIG_PCI=y
33
CONFIG_FIREWIRE=y
44
CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y
5+
CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST=y

drivers/firewire/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ config FIREWIRE_KUNIT_UAPI_TEST
3434
For more information on KUnit and unit tests in general, refer
3535
to the KUnit documentation in Documentation/dev-tools/kunit/.
3636

37+
config FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST
38+
tristate "KUnit tests for device attributes" if !KUNIT_ALL_TESTS
39+
depends on FIREWIRE && KUNIT
40+
default KUNIT_ALL_TESTS
41+
help
42+
This builds the KUnit tests for device attribute for node and
43+
unit.
44+
45+
KUnit tests run during boot and output the results to the debug
46+
log in TAP format (https://testanything.org/). Only useful for
47+
kernel devs running KUnit test harness and are not for inclusion
48+
into a production build.
49+
50+
For more information on KUnit and unit tests in general, refer
51+
to the KUnit documentation in Documentation/dev-tools/kunit/.
52+
3753
config FIREWIRE_OHCI
3854
tristate "OHCI-1394 controllers"
3955
depends on PCI && FIREWIRE && MMU

drivers/firewire/core-device.c

Lines changed: 101 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
#include "core.h"
3333

34+
#define ROOT_DIR_OFFSET 5
35+
3436
void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p)
3537
{
3638
ci->p = p + 1;
@@ -47,6 +49,22 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value)
4749
}
4850
EXPORT_SYMBOL(fw_csr_iterator_next);
4951

52+
static const u32 *search_directory(const u32 *directory, int search_key)
53+
{
54+
struct fw_csr_iterator ci;
55+
int key, value;
56+
57+
search_key |= CSR_DIRECTORY;
58+
59+
fw_csr_iterator_init(&ci, directory);
60+
while (fw_csr_iterator_next(&ci, &key, &value)) {
61+
if (key == search_key)
62+
return ci.p - 1 + value;
63+
}
64+
65+
return NULL;
66+
}
67+
5068
static const u32 *search_leaf(const u32 *directory, int search_key)
5169
{
5270
struct fw_csr_iterator ci;
@@ -135,8 +153,25 @@ static void get_ids(const u32 *directory, int *id)
135153

136154
static void get_modalias_ids(const struct fw_unit *unit, int *id)
137155
{
138-
get_ids(&fw_parent_device(unit)->config_rom[5], id);
139-
get_ids(unit->directory, id);
156+
const u32 *root_directory = &fw_parent_device(unit)->config_rom[ROOT_DIR_OFFSET];
157+
const u32 *directories[] = {NULL, NULL, NULL};
158+
const u32 *vendor_directory;
159+
int i;
160+
161+
directories[0] = root_directory;
162+
163+
// Legacy layout of configuration ROM described in Annex 1 of 'Configuration ROM for AV/C
164+
// Devices 1.0 (December 12, 2000, 1394 Trading Association, TA Document 1999027)'.
165+
vendor_directory = search_directory(root_directory, CSR_VENDOR);
166+
if (!vendor_directory) {
167+
directories[1] = unit->directory;
168+
} else {
169+
directories[1] = vendor_directory;
170+
directories[2] = unit->directory;
171+
}
172+
173+
for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i)
174+
get_ids(directories[i], id);
140175
}
141176

142177
static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
@@ -171,7 +206,7 @@ static const struct ieee1394_device_id *unit_match(struct device *dev,
171206
return NULL;
172207
}
173208

174-
static bool is_fw_unit(struct device *dev);
209+
static bool is_fw_unit(const struct device *dev);
175210

176211
static int fw_unit_match(struct device *dev, struct device_driver *drv)
177212
{
@@ -219,7 +254,7 @@ static int fw_unit_uevent(const struct device *dev, struct kobj_uevent_env *env)
219254
return 0;
220255
}
221256

222-
struct bus_type fw_bus_type = {
257+
const struct bus_type fw_bus_type = {
223258
.name = "firewire",
224259
.match = fw_unit_match,
225260
.probe = fw_unit_probe,
@@ -251,27 +286,44 @@ static ssize_t show_immediate(struct device *dev,
251286
struct config_rom_attribute *attr =
252287
container_of(dattr, struct config_rom_attribute, attr);
253288
struct fw_csr_iterator ci;
254-
const u32 *dir;
255-
int key, value, ret = -ENOENT;
289+
const u32 *directories[] = {NULL, NULL};
290+
int i, value = -1;
256291

257292
down_read(&fw_device_rwsem);
258293

259-
if (is_fw_unit(dev))
260-
dir = fw_unit(dev)->directory;
261-
else
262-
dir = fw_device(dev)->config_rom + 5;
294+
if (is_fw_unit(dev)) {
295+
directories[0] = fw_unit(dev)->directory;
296+
} else {
297+
const u32 *root_directory = fw_device(dev)->config_rom + ROOT_DIR_OFFSET;
298+
const u32 *vendor_directory = search_directory(root_directory, CSR_VENDOR);
299+
300+
if (!vendor_directory) {
301+
directories[0] = root_directory;
302+
} else {
303+
// Legacy layout of configuration ROM described in Annex 1 of
304+
// 'Configuration ROM for AV/C Devices 1.0 (December 12, 2000, 1394 Trading
305+
// Association, TA Document 1999027)'.
306+
directories[0] = vendor_directory;
307+
directories[1] = root_directory;
308+
}
309+
}
263310

264-
fw_csr_iterator_init(&ci, dir);
265-
while (fw_csr_iterator_next(&ci, &key, &value))
266-
if (attr->key == key) {
267-
ret = snprintf(buf, buf ? PAGE_SIZE : 0,
268-
"0x%06x\n", value);
269-
break;
311+
for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) {
312+
int key, val;
313+
314+
fw_csr_iterator_init(&ci, directories[i]);
315+
while (fw_csr_iterator_next(&ci, &key, &val)) {
316+
if (attr->key == key)
317+
value = val;
270318
}
319+
}
271320

272321
up_read(&fw_device_rwsem);
273322

274-
return ret;
323+
if (value < 0)
324+
return -ENOENT;
325+
326+
return snprintf(buf, buf ? PAGE_SIZE : 0, "0x%06x\n", value);
275327
}
276328

277329
#define IMMEDIATE_ATTR(name, key) \
@@ -282,17 +334,29 @@ static ssize_t show_text_leaf(struct device *dev,
282334
{
283335
struct config_rom_attribute *attr =
284336
container_of(dattr, struct config_rom_attribute, attr);
285-
const u32 *dir;
337+
const u32 *directories[] = {NULL, NULL};
286338
size_t bufsize;
287339
char dummy_buf[2];
288-
int ret;
340+
int i, ret = -ENOENT;
289341

290342
down_read(&fw_device_rwsem);
291343

292-
if (is_fw_unit(dev))
293-
dir = fw_unit(dev)->directory;
294-
else
295-
dir = fw_device(dev)->config_rom + 5;
344+
if (is_fw_unit(dev)) {
345+
directories[0] = fw_unit(dev)->directory;
346+
} else {
347+
const u32 *root_directory = fw_device(dev)->config_rom + ROOT_DIR_OFFSET;
348+
const u32 *vendor_directory = search_directory(root_directory, CSR_VENDOR);
349+
350+
if (!vendor_directory) {
351+
directories[0] = root_directory;
352+
} else {
353+
// Legacy layout of configuration ROM described in Annex 1 of
354+
// 'Configuration ROM for AV/C Devices 1.0 (December 12, 2000, 1394
355+
// Trading Association, TA Document 1999027)'.
356+
directories[0] = root_directory;
357+
directories[1] = vendor_directory;
358+
}
359+
}
296360

297361
if (buf) {
298362
bufsize = PAGE_SIZE - 1;
@@ -301,7 +365,12 @@ static ssize_t show_text_leaf(struct device *dev,
301365
bufsize = 1;
302366
}
303367

304-
ret = fw_csr_string(dir, attr->key, buf, bufsize);
368+
for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) {
369+
int result = fw_csr_string(directories[i], attr->key, buf, bufsize);
370+
// Detected.
371+
if (result >= 0)
372+
ret = result;
373+
}
305374

306375
if (ret >= 0) {
307376
/* Strip trailing whitespace and add newline. */
@@ -446,7 +515,7 @@ static ssize_t units_show(struct device *dev,
446515
int key, value, i = 0;
447516

448517
down_read(&fw_device_rwsem);
449-
fw_csr_iterator_init(&ci, &device->config_rom[5]);
518+
fw_csr_iterator_init(&ci, &device->config_rom[ROOT_DIR_OFFSET]);
450519
while (fw_csr_iterator_next(&ci, &key, &value)) {
451520
if (key != (CSR_UNIT | CSR_DIRECTORY))
452521
continue;
@@ -679,7 +748,7 @@ static struct device_type fw_unit_type = {
679748
.release = fw_unit_release,
680749
};
681750

682-
static bool is_fw_unit(struct device *dev)
751+
static bool is_fw_unit(const struct device *dev)
683752
{
684753
return dev->type == &fw_unit_type;
685754
}
@@ -691,7 +760,7 @@ static void create_units(struct fw_device *device)
691760
int key, value, i;
692761

693762
i = 0;
694-
fw_csr_iterator_init(&ci, &device->config_rom[5]);
763+
fw_csr_iterator_init(&ci, &device->config_rom[ROOT_DIR_OFFSET]);
695764
while (fw_csr_iterator_next(&ci, &key, &value)) {
696765
if (key != (CSR_UNIT | CSR_DIRECTORY))
697766
continue;
@@ -835,7 +904,7 @@ static struct device_type fw_device_type = {
835904
.release = fw_device_release,
836905
};
837906

838-
static bool is_fw_device(struct device *dev)
907+
static bool is_fw_device(const struct device *dev)
839908
{
840909
return dev->type == &fw_device_type;
841910
}
@@ -1308,3 +1377,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
13081377
break;
13091378
}
13101379
}
1380+
1381+
#ifdef CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST
1382+
#include "device-attribute-test.c"
1383+
#endif

0 commit comments

Comments
 (0)