11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2e71d31daSStefan Richter /*
3e71d31daSStefan Richter * Device probing and sysfs code.
4e71d31daSStefan Richter *
5e71d31daSStefan Richter * Copyright (C) 2005-2006 Kristian Hoegsberg <[email protected]>
6e71d31daSStefan Richter */
7e71d31daSStefan Richter
8d54423c6SStefan Richter #include <linux/bug.h>
9e71d31daSStefan Richter #include <linux/ctype.h>
10e71d31daSStefan Richter #include <linux/delay.h>
11e71d31daSStefan Richter #include <linux/device.h>
12e71d31daSStefan Richter #include <linux/errno.h>
13e71d31daSStefan Richter #include <linux/firewire.h>
14e71d31daSStefan Richter #include <linux/firewire-constants.h>
15e71d31daSStefan Richter #include <linux/jiffies.h>
16e71d31daSStefan Richter #include <linux/kobject.h>
17e71d31daSStefan Richter #include <linux/list.h>
18e71d31daSStefan Richter #include <linux/mod_devicetable.h>
19e71d31daSStefan Richter #include <linux/module.h>
20e71d31daSStefan Richter #include <linux/mutex.h>
21badfcb24SClemens Ladisch #include <linux/random.h>
22e71d31daSStefan Richter #include <linux/rwsem.h>
235a0e3ad6STejun Heo #include <linux/slab.h>
24e71d31daSStefan Richter #include <linux/spinlock.h>
25e71d31daSStefan Richter #include <linux/string.h>
26e71d31daSStefan Richter #include <linux/workqueue.h>
27e71d31daSStefan Richter
2860063497SArun Sharma #include <linux/atomic.h>
29e71d31daSStefan Richter #include <asm/byteorder.h>
30e71d31daSStefan Richter
31e71d31daSStefan Richter #include "core.h"
32e71d31daSStefan Richter
33afa36dadSTakashi Sakamoto #define ROOT_DIR_OFFSET 5
34afa36dadSTakashi Sakamoto
fw_csr_iterator_init(struct fw_csr_iterator * ci,const u32 * p)3513b302d0SStefan Richter void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p)
36e71d31daSStefan Richter {
37e71d31daSStefan Richter ci->p = p + 1;
38e71d31daSStefan Richter ci->end = ci->p + (p[0] >> 16);
39e71d31daSStefan Richter }
40e71d31daSStefan Richter EXPORT_SYMBOL(fw_csr_iterator_init);
41e71d31daSStefan Richter
fw_csr_iterator_next(struct fw_csr_iterator * ci,int * key,int * value)42e71d31daSStefan Richter int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value)
43e71d31daSStefan Richter {
44e71d31daSStefan Richter *key = *ci->p >> 24;
45e71d31daSStefan Richter *value = *ci->p & 0xffffff;
46e71d31daSStefan Richter
47e71d31daSStefan Richter return ci->p++ < ci->end;
48e71d31daSStefan Richter }
49e71d31daSStefan Richter EXPORT_SYMBOL(fw_csr_iterator_next);
50e71d31daSStefan Richter
search_directory(const u32 * directory,int search_key)51b6a38057STakashi Sakamoto static const u32 *search_directory(const u32 *directory, int search_key)
52b6a38057STakashi Sakamoto {
53b6a38057STakashi Sakamoto struct fw_csr_iterator ci;
54b6a38057STakashi Sakamoto int key, value;
55b6a38057STakashi Sakamoto
56b6a38057STakashi Sakamoto search_key |= CSR_DIRECTORY;
57b6a38057STakashi Sakamoto
58b6a38057STakashi Sakamoto fw_csr_iterator_init(&ci, directory);
59b6a38057STakashi Sakamoto while (fw_csr_iterator_next(&ci, &key, &value)) {
60b6a38057STakashi Sakamoto if (key == search_key)
61b6a38057STakashi Sakamoto return ci.p - 1 + value;
62b6a38057STakashi Sakamoto }
63b6a38057STakashi Sakamoto
64b6a38057STakashi Sakamoto return NULL;
65b6a38057STakashi Sakamoto }
66b6a38057STakashi Sakamoto
search_leaf(const u32 * directory,int search_key)6713b302d0SStefan Richter static const u32 *search_leaf(const u32 *directory, int search_key)
681f8fef7bSClemens Ladisch {
691f8fef7bSClemens Ladisch struct fw_csr_iterator ci;
701f8fef7bSClemens Ladisch int last_key = 0, key, value;
711f8fef7bSClemens Ladisch
721f8fef7bSClemens Ladisch fw_csr_iterator_init(&ci, directory);
731f8fef7bSClemens Ladisch while (fw_csr_iterator_next(&ci, &key, &value)) {
741f8fef7bSClemens Ladisch if (last_key == search_key &&
751f8fef7bSClemens Ladisch key == (CSR_DESCRIPTOR | CSR_LEAF))
761f8fef7bSClemens Ladisch return ci.p - 1 + value;
773c2c58cbSStefan Richter
781f8fef7bSClemens Ladisch last_key = key;
791f8fef7bSClemens Ladisch }
803c2c58cbSStefan Richter
811f8fef7bSClemens Ladisch return NULL;
821f8fef7bSClemens Ladisch }
831f8fef7bSClemens Ladisch
textual_leaf_to_string(const u32 * block,char * buf,size_t size)8413b302d0SStefan Richter static int textual_leaf_to_string(const u32 *block, char *buf, size_t size)
851f8fef7bSClemens Ladisch {
863c2c58cbSStefan Richter unsigned int quadlets, i;
873c2c58cbSStefan Richter char c;
881f8fef7bSClemens Ladisch
891f8fef7bSClemens Ladisch if (!size || !buf)
901f8fef7bSClemens Ladisch return -EINVAL;
911f8fef7bSClemens Ladisch
923c2c58cbSStefan Richter quadlets = min(block[0] >> 16, 256U);
931f8fef7bSClemens Ladisch if (quadlets < 2)
941f8fef7bSClemens Ladisch return -ENODATA;
951f8fef7bSClemens Ladisch
961f8fef7bSClemens Ladisch if (block[1] != 0 || block[2] != 0)
971f8fef7bSClemens Ladisch /* unknown language/character set */
981f8fef7bSClemens Ladisch return -ENODATA;
991f8fef7bSClemens Ladisch
1001f8fef7bSClemens Ladisch block += 3;
1011f8fef7bSClemens Ladisch quadlets -= 2;
1023c2c58cbSStefan Richter for (i = 0; i < quadlets * 4 && i < size - 1; i++) {
1033c2c58cbSStefan Richter c = block[i / 4] >> (24 - 8 * (i % 4));
1041f8fef7bSClemens Ladisch if (c == '\0')
1051f8fef7bSClemens Ladisch break;
1063c2c58cbSStefan Richter buf[i] = c;
1071f8fef7bSClemens Ladisch }
1083c2c58cbSStefan Richter buf[i] = '\0';
1093c2c58cbSStefan Richter
1103c2c58cbSStefan Richter return i;
1111f8fef7bSClemens Ladisch }
1121f8fef7bSClemens Ladisch
1131f8fef7bSClemens Ladisch /**
114656b7afdSStefan Richter * fw_csr_string() - reads a string from the configuration ROM
1153c2c58cbSStefan Richter * @directory: e.g. root directory or unit directory
1161f8fef7bSClemens Ladisch * @key: the key of the preceding directory entry
1171f8fef7bSClemens Ladisch * @buf: where to put the string
1181f8fef7bSClemens Ladisch * @size: size of @buf, in bytes
1191f8fef7bSClemens Ladisch *
1205f9ab173STakashi Sakamoto * The string is taken from a minimal ASCII text descriptor leaf just after the entry with the
1215f9ab173STakashi Sakamoto * @key. The string is zero-terminated. An overlong string is silently truncated such that it
1225f9ab173STakashi Sakamoto * and the zero byte fit into @size.
1230238507bSStefan Richter *
1243c2c58cbSStefan Richter * Returns strlen(buf) or a negative error code.
1251f8fef7bSClemens Ladisch */
fw_csr_string(const u32 * directory,int key,char * buf,size_t size)12613b302d0SStefan Richter int fw_csr_string(const u32 *directory, int key, char *buf, size_t size)
1271f8fef7bSClemens Ladisch {
12813b302d0SStefan Richter const u32 *leaf = search_leaf(directory, key);
1291f8fef7bSClemens Ladisch if (!leaf)
1301f8fef7bSClemens Ladisch return -ENOENT;
1313c2c58cbSStefan Richter
1321f8fef7bSClemens Ladisch return textual_leaf_to_string(leaf, buf, size);
1331f8fef7bSClemens Ladisch }
1341f8fef7bSClemens Ladisch EXPORT_SYMBOL(fw_csr_string);
1351f8fef7bSClemens Ladisch
get_ids(const u32 * directory,int * id)136fe43d6d9SStefan Richter static void get_ids(const u32 *directory, int *id)
137e71d31daSStefan Richter {
138e71d31daSStefan Richter struct fw_csr_iterator ci;
1395ae73518SStefan Richter int key, value;
140e71d31daSStefan Richter
141e71d31daSStefan Richter fw_csr_iterator_init(&ci, directory);
142e71d31daSStefan Richter while (fw_csr_iterator_next(&ci, &key, &value)) {
1435ae73518SStefan Richter switch (key) {
1445ae73518SStefan Richter case CSR_VENDOR: id[0] = value; break;
1455ae73518SStefan Richter case CSR_MODEL: id[1] = value; break;
1465ae73518SStefan Richter case CSR_SPECIFIER_ID: id[2] = value; break;
1475ae73518SStefan Richter case CSR_VERSION: id[3] = value; break;
1485ae73518SStefan Richter }
1495ae73518SStefan Richter }
150e71d31daSStefan Richter }
151e71d31daSStefan Richter
get_modalias_ids(const struct fw_unit * unit,int * id)152162736b0SGreg Kroah-Hartman static void get_modalias_ids(const struct fw_unit *unit, int *id)
153fe43d6d9SStefan Richter {
154986c20bbSTakashi Sakamoto const u32 *root_directory = &fw_parent_device(unit)->config_rom[ROOT_DIR_OFFSET];
155986c20bbSTakashi Sakamoto const u32 *directories[] = {NULL, NULL, NULL};
156986c20bbSTakashi Sakamoto const u32 *vendor_directory;
157986c20bbSTakashi Sakamoto int i;
158986c20bbSTakashi Sakamoto
159986c20bbSTakashi Sakamoto directories[0] = root_directory;
160986c20bbSTakashi Sakamoto
161986c20bbSTakashi Sakamoto // Legacy layout of configuration ROM described in Annex 1 of 'Configuration ROM for AV/C
162986c20bbSTakashi Sakamoto // Devices 1.0 (December 12, 2000, 1394 Trading Association, TA Document 1999027)'.
163986c20bbSTakashi Sakamoto vendor_directory = search_directory(root_directory, CSR_VENDOR);
164986c20bbSTakashi Sakamoto if (!vendor_directory) {
165986c20bbSTakashi Sakamoto directories[1] = unit->directory;
166986c20bbSTakashi Sakamoto } else {
167986c20bbSTakashi Sakamoto directories[1] = vendor_directory;
168986c20bbSTakashi Sakamoto directories[2] = unit->directory;
169986c20bbSTakashi Sakamoto }
170986c20bbSTakashi Sakamoto
171986c20bbSTakashi Sakamoto for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i)
172986c20bbSTakashi Sakamoto get_ids(directories[i], id);
173e71d31daSStefan Richter }
174e71d31daSStefan Richter
match_ids(const struct ieee1394_device_id * id_table,int * id)175fe43d6d9SStefan Richter static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
176fe43d6d9SStefan Richter {
177fe43d6d9SStefan Richter int match = 0;
178fe43d6d9SStefan Richter
179fe43d6d9SStefan Richter if (id[0] == id_table->vendor_id)
180fe43d6d9SStefan Richter match |= IEEE1394_MATCH_VENDOR_ID;
181fe43d6d9SStefan Richter if (id[1] == id_table->model_id)
182fe43d6d9SStefan Richter match |= IEEE1394_MATCH_MODEL_ID;
183fe43d6d9SStefan Richter if (id[2] == id_table->specifier_id)
184fe43d6d9SStefan Richter match |= IEEE1394_MATCH_SPECIFIER_ID;
185fe43d6d9SStefan Richter if (id[3] == id_table->version)
186fe43d6d9SStefan Richter match |= IEEE1394_MATCH_VERSION;
187fe43d6d9SStefan Richter
188fe43d6d9SStefan Richter return (match & id_table->match_flags) == id_table->match_flags;
189fe43d6d9SStefan Richter }
190fe43d6d9SStefan Richter
unit_match(struct device * dev,const struct device_driver * drv)19194a87157SStefan Richter static const struct ieee1394_device_id *unit_match(struct device *dev,
192d69d8048SGreg Kroah-Hartman const struct device_driver *drv)
193e71d31daSStefan Richter {
194fe43d6d9SStefan Richter const struct ieee1394_device_id *id_table =
195d69d8048SGreg Kroah-Hartman container_of_const(drv, struct fw_driver, driver)->id_table;
196fe43d6d9SStefan Richter int id[] = {0, 0, 0, 0};
197e71d31daSStefan Richter
198fe43d6d9SStefan Richter get_modalias_ids(fw_unit(dev), id);
199e71d31daSStefan Richter
200fe43d6d9SStefan Richter for (; id_table->match_flags != 0; id_table++)
201fe43d6d9SStefan Richter if (match_ids(id_table, id))
20294a87157SStefan Richter return id_table;
203e71d31daSStefan Richter
20494a87157SStefan Richter return NULL;
20594a87157SStefan Richter }
20694a87157SStefan Richter
207f1e2f878STakashi Sakamoto static bool is_fw_unit(const struct device *dev);
20894a87157SStefan Richter
fw_unit_match(struct device * dev,const struct device_driver * drv)209d69d8048SGreg Kroah-Hartman static int fw_unit_match(struct device *dev, const struct device_driver *drv)
21094a87157SStefan Richter {
21194a87157SStefan Richter /* We only allow binding to fw_units. */
21294a87157SStefan Richter return is_fw_unit(dev) && unit_match(dev, drv) != NULL;
21394a87157SStefan Richter }
21494a87157SStefan Richter
fw_unit_probe(struct device * dev)21594a87157SStefan Richter static int fw_unit_probe(struct device *dev)
21694a87157SStefan Richter {
21794a87157SStefan Richter struct fw_driver *driver =
21894a87157SStefan Richter container_of(dev->driver, struct fw_driver, driver);
21994a87157SStefan Richter
22094a87157SStefan Richter return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
22194a87157SStefan Richter }
22294a87157SStefan Richter
fw_unit_remove(struct device * dev)223fc7a6209SUwe Kleine-König static void fw_unit_remove(struct device *dev)
22494a87157SStefan Richter {
22594a87157SStefan Richter struct fw_driver *driver =
22694a87157SStefan Richter container_of(dev->driver, struct fw_driver, driver);
22794a87157SStefan Richter
228b2c852f4SUwe Kleine-König driver->remove(fw_unit(dev));
229e71d31daSStefan Richter }
230e71d31daSStefan Richter
get_modalias(const struct fw_unit * unit,char * buffer,size_t buffer_size)231162736b0SGreg Kroah-Hartman static int get_modalias(const struct fw_unit *unit, char *buffer, size_t buffer_size)
232e71d31daSStefan Richter {
2335ae73518SStefan Richter int id[] = {0, 0, 0, 0};
234e71d31daSStefan Richter
235fe43d6d9SStefan Richter get_modalias_ids(unit, id);
236e71d31daSStefan Richter
237e71d31daSStefan Richter return snprintf(buffer, buffer_size,
238e71d31daSStefan Richter "ieee1394:ven%08Xmo%08Xsp%08Xver%08X",
2395ae73518SStefan Richter id[0], id[1], id[2], id[3]);
240e71d31daSStefan Richter }
241e71d31daSStefan Richter
fw_unit_uevent(const struct device * dev,struct kobj_uevent_env * env)242162736b0SGreg Kroah-Hartman static int fw_unit_uevent(const struct device *dev, struct kobj_uevent_env *env)
243e71d31daSStefan Richter {
244162736b0SGreg Kroah-Hartman const struct fw_unit *unit = fw_unit(dev);
245e71d31daSStefan Richter char modalias[64];
246e71d31daSStefan Richter
247e71d31daSStefan Richter get_modalias(unit, modalias, sizeof(modalias));
248e71d31daSStefan Richter
249e71d31daSStefan Richter if (add_uevent_var(env, "MODALIAS=%s", modalias))
250e71d31daSStefan Richter return -ENOMEM;
251e71d31daSStefan Richter
252e71d31daSStefan Richter return 0;
253e71d31daSStefan Richter }
254e71d31daSStefan Richter
25510416a35SGreg Kroah-Hartman const struct bus_type fw_bus_type = {
256e71d31daSStefan Richter .name = "firewire",
257e71d31daSStefan Richter .match = fw_unit_match,
25894a87157SStefan Richter .probe = fw_unit_probe,
25994a87157SStefan Richter .remove = fw_unit_remove,
260e71d31daSStefan Richter };
261e71d31daSStefan Richter EXPORT_SYMBOL(fw_bus_type);
262e71d31daSStefan Richter
fw_device_enable_phys_dma(struct fw_device * device)263e71d31daSStefan Richter int fw_device_enable_phys_dma(struct fw_device *device)
264e71d31daSStefan Richter {
265e71d31daSStefan Richter int generation = device->generation;
266e71d31daSStefan Richter
267e71d31daSStefan Richter /* device->node_id, accessed below, must not be older than generation */
268e71d31daSStefan Richter smp_rmb();
269e71d31daSStefan Richter
270e71d31daSStefan Richter return device->card->driver->enable_phys_dma(device->card,
271e71d31daSStefan Richter device->node_id,
272e71d31daSStefan Richter generation);
273e71d31daSStefan Richter }
274e71d31daSStefan Richter EXPORT_SYMBOL(fw_device_enable_phys_dma);
275e71d31daSStefan Richter
276e71d31daSStefan Richter struct config_rom_attribute {
277e71d31daSStefan Richter struct device_attribute attr;
278e71d31daSStefan Richter u32 key;
279e71d31daSStefan Richter };
280e71d31daSStefan Richter
show_immediate(struct device * dev,struct device_attribute * dattr,char * buf)281e71d31daSStefan Richter static ssize_t show_immediate(struct device *dev,
282e71d31daSStefan Richter struct device_attribute *dattr, char *buf)
283e71d31daSStefan Richter {
284e71d31daSStefan Richter struct config_rom_attribute *attr =
285e71d31daSStefan Richter container_of(dattr, struct config_rom_attribute, attr);
286e71d31daSStefan Richter struct fw_csr_iterator ci;
287b6a38057STakashi Sakamoto const u32 *directories[] = {NULL, NULL};
288b6a38057STakashi Sakamoto int i, value = -1;
289e71d31daSStefan Richter
2902a6a58f0STakashi Sakamoto guard(rwsem_read)(&fw_device_rwsem);
291e71d31daSStefan Richter
292b6a38057STakashi Sakamoto if (is_fw_unit(dev)) {
293b6a38057STakashi Sakamoto directories[0] = fw_unit(dev)->directory;
294b6a38057STakashi Sakamoto } else {
295b6a38057STakashi Sakamoto const u32 *root_directory = fw_device(dev)->config_rom + ROOT_DIR_OFFSET;
296b6a38057STakashi Sakamoto const u32 *vendor_directory = search_directory(root_directory, CSR_VENDOR);
297e71d31daSStefan Richter
298b6a38057STakashi Sakamoto if (!vendor_directory) {
299b6a38057STakashi Sakamoto directories[0] = root_directory;
300b6a38057STakashi Sakamoto } else {
301b6a38057STakashi Sakamoto // Legacy layout of configuration ROM described in Annex 1 of
302b6a38057STakashi Sakamoto // 'Configuration ROM for AV/C Devices 1.0 (December 12, 2000, 1394 Trading
303b6a38057STakashi Sakamoto // Association, TA Document 1999027)'.
304b6a38057STakashi Sakamoto directories[0] = vendor_directory;
305b6a38057STakashi Sakamoto directories[1] = root_directory;
306b6a38057STakashi Sakamoto }
307b6a38057STakashi Sakamoto }
308b6a38057STakashi Sakamoto
309b6a38057STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) {
310b6a38057STakashi Sakamoto int key, val;
311b6a38057STakashi Sakamoto
312b6a38057STakashi Sakamoto fw_csr_iterator_init(&ci, directories[i]);
313b6a38057STakashi Sakamoto while (fw_csr_iterator_next(&ci, &key, &val)) {
314b6a38057STakashi Sakamoto if (attr->key == key)
315b6a38057STakashi Sakamoto value = val;
316b6a38057STakashi Sakamoto }
317e71d31daSStefan Richter }
318e71d31daSStefan Richter
319b6a38057STakashi Sakamoto if (value < 0)
320b6a38057STakashi Sakamoto return -ENOENT;
321b6a38057STakashi Sakamoto
322bfb1ad3cSTakashi Sakamoto // Note that this function is also called by init_fw_attribute_group() with NULL pointer.
323946593d1SLi Zhijian return buf ? sysfs_emit(buf, "0x%06x\n", value) : 0;
324e71d31daSStefan Richter }
325e71d31daSStefan Richter
326e71d31daSStefan Richter #define IMMEDIATE_ATTR(name, key) \
327e71d31daSStefan Richter { __ATTR(name, S_IRUGO, show_immediate, NULL), key }
328e71d31daSStefan Richter
show_text_leaf(struct device * dev,struct device_attribute * dattr,char * buf)329e71d31daSStefan Richter static ssize_t show_text_leaf(struct device *dev,
330e71d31daSStefan Richter struct device_attribute *dattr, char *buf)
331e71d31daSStefan Richter {
332e71d31daSStefan Richter struct config_rom_attribute *attr =
333e71d31daSStefan Richter container_of(dattr, struct config_rom_attribute, attr);
3342eab8bc0STakashi Sakamoto const u32 *directories[] = {NULL, NULL};
335946593d1SLi Zhijian size_t bufsize;
336946593d1SLi Zhijian char dummy_buf[2];
3372eab8bc0STakashi Sakamoto int i, ret = -ENOENT;
338e71d31daSStefan Richter
3392a6a58f0STakashi Sakamoto guard(rwsem_read)(&fw_device_rwsem);
340e71d31daSStefan Richter
3412eab8bc0STakashi Sakamoto if (is_fw_unit(dev)) {
3422eab8bc0STakashi Sakamoto directories[0] = fw_unit(dev)->directory;
3432eab8bc0STakashi Sakamoto } else {
3442eab8bc0STakashi Sakamoto const u32 *root_directory = fw_device(dev)->config_rom + ROOT_DIR_OFFSET;
3452eab8bc0STakashi Sakamoto const u32 *vendor_directory = search_directory(root_directory, CSR_VENDOR);
3462eab8bc0STakashi Sakamoto
3472eab8bc0STakashi Sakamoto if (!vendor_directory) {
3482eab8bc0STakashi Sakamoto directories[0] = root_directory;
3492eab8bc0STakashi Sakamoto } else {
3502eab8bc0STakashi Sakamoto // Legacy layout of configuration ROM described in Annex 1 of
3512eab8bc0STakashi Sakamoto // 'Configuration ROM for AV/C Devices 1.0 (December 12, 2000, 1394
3522eab8bc0STakashi Sakamoto // Trading Association, TA Document 1999027)'.
3532eab8bc0STakashi Sakamoto directories[0] = root_directory;
3542eab8bc0STakashi Sakamoto directories[1] = vendor_directory;
3552eab8bc0STakashi Sakamoto }
3562eab8bc0STakashi Sakamoto }
357e71d31daSStefan Richter
358bfb1ad3cSTakashi Sakamoto // Note that this function is also called by init_fw_attribute_group() with NULL pointer.
359946593d1SLi Zhijian if (buf) {
360946593d1SLi Zhijian bufsize = PAGE_SIZE - 1;
361946593d1SLi Zhijian } else {
362946593d1SLi Zhijian buf = dummy_buf;
363946593d1SLi Zhijian bufsize = 1;
364946593d1SLi Zhijian }
365946593d1SLi Zhijian
3662eab8bc0STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(directories) && !!directories[i]; ++i) {
367946593d1SLi Zhijian int result = fw_csr_string(directories[i], attr->key, buf, bufsize);
3682eab8bc0STakashi Sakamoto // Detected.
36947dc5518STakashi Sakamoto if (result >= 0) {
37047dc5518STakashi Sakamoto ret = result;
37147dc5518STakashi Sakamoto } else if (i == 0 && attr->key == CSR_VENDOR) {
37247dc5518STakashi Sakamoto // Sony DVMC-DA1 has configuration ROM such that the descriptor leaf entry
37347dc5518STakashi Sakamoto // in the root directory follows to the directory entry for vendor ID
37447dc5518STakashi Sakamoto // instead of the immediate value for vendor ID.
37547dc5518STakashi Sakamoto result = fw_csr_string(directories[i], CSR_DIRECTORY | attr->key, buf,
376946593d1SLi Zhijian bufsize);
3772eab8bc0STakashi Sakamoto if (result >= 0)
3782eab8bc0STakashi Sakamoto ret = result;
3792eab8bc0STakashi Sakamoto }
38047dc5518STakashi Sakamoto }
381e71d31daSStefan Richter
3822a6a58f0STakashi Sakamoto if (ret < 0)
3832a6a58f0STakashi Sakamoto return ret;
3842a6a58f0STakashi Sakamoto
3852a6a58f0STakashi Sakamoto // Strip trailing whitespace and add newline.
3861f8fef7bSClemens Ladisch while (ret > 0 && isspace(buf[ret - 1]))
3871f8fef7bSClemens Ladisch ret--;
3881f8fef7bSClemens Ladisch strcpy(buf + ret, "\n");
3891f8fef7bSClemens Ladisch ret++;
390e71d31daSStefan Richter
391e71d31daSStefan Richter return ret;
392e71d31daSStefan Richter }
393e71d31daSStefan Richter
394e71d31daSStefan Richter #define TEXT_LEAF_ATTR(name, key) \
395e71d31daSStefan Richter { __ATTR(name, S_IRUGO, show_text_leaf, NULL), key }
396e71d31daSStefan Richter
397e71d31daSStefan Richter static struct config_rom_attribute config_rom_attributes[] = {
398e71d31daSStefan Richter IMMEDIATE_ATTR(vendor, CSR_VENDOR),
399e71d31daSStefan Richter IMMEDIATE_ATTR(hardware_version, CSR_HARDWARE_VERSION),
400e71d31daSStefan Richter IMMEDIATE_ATTR(specifier_id, CSR_SPECIFIER_ID),
401e71d31daSStefan Richter IMMEDIATE_ATTR(version, CSR_VERSION),
402e71d31daSStefan Richter IMMEDIATE_ATTR(model, CSR_MODEL),
403e71d31daSStefan Richter TEXT_LEAF_ATTR(vendor_name, CSR_VENDOR),
404e71d31daSStefan Richter TEXT_LEAF_ATTR(model_name, CSR_MODEL),
405e71d31daSStefan Richter TEXT_LEAF_ATTR(hardware_version_name, CSR_HARDWARE_VERSION),
406e71d31daSStefan Richter };
407e71d31daSStefan Richter
init_fw_attribute_group(struct device * dev,struct device_attribute * attrs,struct fw_attribute_group * group)408e71d31daSStefan Richter static void init_fw_attribute_group(struct device *dev,
409e71d31daSStefan Richter struct device_attribute *attrs,
410e71d31daSStefan Richter struct fw_attribute_group *group)
411e71d31daSStefan Richter {
412e71d31daSStefan Richter struct device_attribute *attr;
413e71d31daSStefan Richter int i, j;
414e71d31daSStefan Richter
415e71d31daSStefan Richter for (j = 0; attrs[j].attr.name != NULL; j++)
416e71d31daSStefan Richter group->attrs[j] = &attrs[j].attr;
417e71d31daSStefan Richter
418e71d31daSStefan Richter for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++) {
419e71d31daSStefan Richter attr = &config_rom_attributes[i].attr;
420e71d31daSStefan Richter if (attr->show(dev, attr, NULL) < 0)
421e71d31daSStefan Richter continue;
422e71d31daSStefan Richter group->attrs[j++] = &attr->attr;
423e71d31daSStefan Richter }
424e71d31daSStefan Richter
425e71d31daSStefan Richter group->attrs[j] = NULL;
426e71d31daSStefan Richter group->groups[0] = &group->group;
427e71d31daSStefan Richter group->groups[1] = NULL;
428e71d31daSStefan Richter group->group.attrs = group->attrs;
429a4dbd674SDavid Brownell dev->groups = (const struct attribute_group **) group->groups;
430e71d31daSStefan Richter }
431e71d31daSStefan Richter
modalias_show(struct device * dev,struct device_attribute * attr,char * buf)432e71d31daSStefan Richter static ssize_t modalias_show(struct device *dev,
433e71d31daSStefan Richter struct device_attribute *attr, char *buf)
434e71d31daSStefan Richter {
435e71d31daSStefan Richter struct fw_unit *unit = fw_unit(dev);
436e71d31daSStefan Richter int length;
437e71d31daSStefan Richter
438e71d31daSStefan Richter length = get_modalias(unit, buf, PAGE_SIZE);
439e71d31daSStefan Richter strcpy(buf + length, "\n");
440e71d31daSStefan Richter
441e71d31daSStefan Richter return length + 1;
442e71d31daSStefan Richter }
443e71d31daSStefan Richter
rom_index_show(struct device * dev,struct device_attribute * attr,char * buf)444e71d31daSStefan Richter static ssize_t rom_index_show(struct device *dev,
445e71d31daSStefan Richter struct device_attribute *attr, char *buf)
446e71d31daSStefan Richter {
447e71d31daSStefan Richter struct fw_device *device = fw_device(dev->parent);
448e71d31daSStefan Richter struct fw_unit *unit = fw_unit(dev);
449e71d31daSStefan Richter
4502328fe7aSJiapeng Chong return sysfs_emit(buf, "%td\n", unit->directory - device->config_rom);
451e71d31daSStefan Richter }
452e71d31daSStefan Richter
453e71d31daSStefan Richter static struct device_attribute fw_unit_attributes[] = {
454e71d31daSStefan Richter __ATTR_RO(modalias),
455e71d31daSStefan Richter __ATTR_RO(rom_index),
456e71d31daSStefan Richter __ATTR_NULL,
457e71d31daSStefan Richter };
458e71d31daSStefan Richter
config_rom_show(struct device * dev,struct device_attribute * attr,char * buf)459e71d31daSStefan Richter static ssize_t config_rom_show(struct device *dev,
460e71d31daSStefan Richter struct device_attribute *attr, char *buf)
461e71d31daSStefan Richter {
462e71d31daSStefan Richter struct fw_device *device = fw_device(dev);
463e71d31daSStefan Richter size_t length;
464e71d31daSStefan Richter
4652a6a58f0STakashi Sakamoto guard(rwsem_read)(&fw_device_rwsem);
4662a6a58f0STakashi Sakamoto
467e71d31daSStefan Richter length = device->config_rom_length * 4;
468e71d31daSStefan Richter memcpy(buf, device->config_rom, length);
469e71d31daSStefan Richter
470e71d31daSStefan Richter return length;
471e71d31daSStefan Richter }
472e71d31daSStefan Richter
guid_show(struct device * dev,struct device_attribute * attr,char * buf)473e71d31daSStefan Richter static ssize_t guid_show(struct device *dev,
474e71d31daSStefan Richter struct device_attribute *attr, char *buf)
475e71d31daSStefan Richter {
476e71d31daSStefan Richter struct fw_device *device = fw_device(dev);
477e71d31daSStefan Richter
4782a6a58f0STakashi Sakamoto guard(rwsem_read)(&fw_device_rwsem);
479e71d31daSStefan Richter
4802a6a58f0STakashi Sakamoto return sysfs_emit(buf, "0x%08x%08x\n", device->config_rom[3], device->config_rom[4]);
481e71d31daSStefan Richter }
482e71d31daSStefan Richter
is_local_show(struct device * dev,struct device_attribute * attr,char * buf)483baedee17SClemens Ladisch static ssize_t is_local_show(struct device *dev,
484baedee17SClemens Ladisch struct device_attribute *attr, char *buf)
485baedee17SClemens Ladisch {
486baedee17SClemens Ladisch struct fw_device *device = fw_device(dev);
487baedee17SClemens Ladisch
488d4db89c3SLi Zhijian return sysfs_emit(buf, "%u\n", device->is_local);
489baedee17SClemens Ladisch }
490baedee17SClemens Ladisch
units_sprintf(char * buf,const u32 * directory)49113b302d0SStefan Richter static int units_sprintf(char *buf, const u32 *directory)
492e71d31daSStefan Richter {
493e71d31daSStefan Richter struct fw_csr_iterator ci;
494e71d31daSStefan Richter int key, value;
495e71d31daSStefan Richter int specifier_id = 0;
496e71d31daSStefan Richter int version = 0;
497e71d31daSStefan Richter
498e71d31daSStefan Richter fw_csr_iterator_init(&ci, directory);
499e71d31daSStefan Richter while (fw_csr_iterator_next(&ci, &key, &value)) {
500e71d31daSStefan Richter switch (key) {
501e71d31daSStefan Richter case CSR_SPECIFIER_ID:
502e71d31daSStefan Richter specifier_id = value;
503e71d31daSStefan Richter break;
504e71d31daSStefan Richter case CSR_VERSION:
505e71d31daSStefan Richter version = value;
506e71d31daSStefan Richter break;
507e71d31daSStefan Richter }
508e71d31daSStefan Richter }
509e71d31daSStefan Richter
510e71d31daSStefan Richter return sprintf(buf, "0x%06x:0x%06x ", specifier_id, version);
511e71d31daSStefan Richter }
512e71d31daSStefan Richter
units_show(struct device * dev,struct device_attribute * attr,char * buf)513e71d31daSStefan Richter static ssize_t units_show(struct device *dev,
514e71d31daSStefan Richter struct device_attribute *attr, char *buf)
515e71d31daSStefan Richter {
516e71d31daSStefan Richter struct fw_device *device = fw_device(dev);
517e71d31daSStefan Richter struct fw_csr_iterator ci;
518e71d31daSStefan Richter int key, value, i = 0;
519e71d31daSStefan Richter
5202a6a58f0STakashi Sakamoto guard(rwsem_read)(&fw_device_rwsem);
5212a6a58f0STakashi Sakamoto
522afa36dadSTakashi Sakamoto fw_csr_iterator_init(&ci, &device->config_rom[ROOT_DIR_OFFSET]);
523e71d31daSStefan Richter while (fw_csr_iterator_next(&ci, &key, &value)) {
524e71d31daSStefan Richter if (key != (CSR_UNIT | CSR_DIRECTORY))
525e71d31daSStefan Richter continue;
526e71d31daSStefan Richter i += units_sprintf(&buf[i], ci.p + value - 1);
527e71d31daSStefan Richter if (i >= PAGE_SIZE - (8 + 1 + 8 + 1))
528e71d31daSStefan Richter break;
529e71d31daSStefan Richter }
530e71d31daSStefan Richter
531e71d31daSStefan Richter if (i)
532e71d31daSStefan Richter buf[i - 1] = '\n';
533e71d31daSStefan Richter
534e71d31daSStefan Richter return i;
535e71d31daSStefan Richter }
536e71d31daSStefan Richter
537e71d31daSStefan Richter static struct device_attribute fw_device_attributes[] = {
538e71d31daSStefan Richter __ATTR_RO(config_rom),
539e71d31daSStefan Richter __ATTR_RO(guid),
540baedee17SClemens Ladisch __ATTR_RO(is_local),
541e71d31daSStefan Richter __ATTR_RO(units),
542e71d31daSStefan Richter __ATTR_NULL,
543e71d31daSStefan Richter };
544e71d31daSStefan Richter
read_rom(struct fw_device * device,int generation,int index,u32 * data)545e71d31daSStefan Richter static int read_rom(struct fw_device *device,
546e71d31daSStefan Richter int generation, int index, u32 *data)
547e71d31daSStefan Richter {
548aaff1203SStefan Richter u64 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
549aaff1203SStefan Richter int i, rcode;
550e71d31daSStefan Richter
551e71d31daSStefan Richter /* device->node_id, accessed below, must not be older than generation */
552e71d31daSStefan Richter smp_rmb();
553e71d31daSStefan Richter
554aaff1203SStefan Richter for (i = 10; i < 100; i += 10) {
555aaff1203SStefan Richter rcode = fw_run_transaction(device->card,
556aaff1203SStefan Richter TCODE_READ_QUADLET_REQUEST, device->node_id,
557aaff1203SStefan Richter generation, device->max_speed, offset, data, 4);
558aaff1203SStefan Richter if (rcode != RCODE_BUSY)
559aaff1203SStefan Richter break;
560aaff1203SStefan Richter msleep(i);
561aaff1203SStefan Richter }
562e71d31daSStefan Richter be32_to_cpus(data);
563e71d31daSStefan Richter
564e71d31daSStefan Richter return rcode;
565e71d31daSStefan Richter }
566e71d31daSStefan Richter
567e8b89bc1STakashi Sakamoto // By quadlet unit.
568e8b89bc1STakashi Sakamoto #define MAX_CONFIG_ROM_SIZE ((CSR_CONFIG_ROM_END - CSR_CONFIG_ROM) / sizeof(u32))
569e71d31daSStefan Richter
570e71d31daSStefan Richter /*
571e71d31daSStefan Richter * Read the bus info block, perform a speed probe, and read all of the rest of
572e71d31daSStefan Richter * the config ROM. We do all this with a cached bus generation. If the bus
573fd6e0c51SStefan Richter * generation changes under us, read_config_rom will fail and get retried.
574e71d31daSStefan Richter * It's better to start all over in this case because the node from which we
575e71d31daSStefan Richter * are reading the ROM may have changed the ROM during the reset.
57694fba9fbSClemens Ladisch * Returns either a result code or a negative error code.
577e71d31daSStefan Richter */
read_config_rom(struct fw_device * device,int generation)578fd6e0c51SStefan Richter static int read_config_rom(struct fw_device *device, int generation)
579e71d31daSStefan Richter {
58026b4950dSStefan Richter struct fw_card *card = device->card;
58113b302d0SStefan Richter const u32 *old_rom, *new_rom;
58213b302d0SStefan Richter u32 *rom, *stack;
583e71d31daSStefan Richter u32 sp, key;
58494fba9fbSClemens Ladisch int i, end, length, ret;
585e71d31daSStefan Richter
586fd6e0c51SStefan Richter rom = kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE +
587fd6e0c51SStefan Richter sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL);
588e71d31daSStefan Richter if (rom == NULL)
589e71d31daSStefan Richter return -ENOMEM;
590e71d31daSStefan Richter
591fd6e0c51SStefan Richter stack = &rom[MAX_CONFIG_ROM_SIZE];
592fd6e0c51SStefan Richter memset(rom, 0, sizeof(*rom) * MAX_CONFIG_ROM_SIZE);
593e71d31daSStefan Richter
594e71d31daSStefan Richter device->max_speed = SCODE_100;
595e71d31daSStefan Richter
596e71d31daSStefan Richter /* First read the bus info block. */
597e71d31daSStefan Richter for (i = 0; i < 5; i++) {
59894fba9fbSClemens Ladisch ret = read_rom(device, generation, i, &rom[i]);
59994fba9fbSClemens Ladisch if (ret != RCODE_COMPLETE)
600e71d31daSStefan Richter goto out;
601e71d31daSStefan Richter /*
602d33ec3b5SClemens Ladisch * As per IEEE1212 7.2, during initialization, devices can
603e71d31daSStefan Richter * reply with a 0 for the first quadlet of the config
604e71d31daSStefan Richter * rom to indicate that they are booting (for example,
605e71d31daSStefan Richter * if the firmware is on the disk of a external
606e71d31daSStefan Richter * harddisk). In that case we just fail, and the
607e71d31daSStefan Richter * retry mechanism will try again later.
608e71d31daSStefan Richter */
60994fba9fbSClemens Ladisch if (i == 0 && rom[i] == 0) {
61094fba9fbSClemens Ladisch ret = RCODE_BUSY;
611e71d31daSStefan Richter goto out;
612e71d31daSStefan Richter }
61394fba9fbSClemens Ladisch }
614e71d31daSStefan Richter
615e71d31daSStefan Richter device->max_speed = device->node->max_speed;
616e71d31daSStefan Richter
617e71d31daSStefan Richter /*
618e71d31daSStefan Richter * Determine the speed of
619e71d31daSStefan Richter * - devices with link speed less than PHY speed,
620e71d31daSStefan Richter * - devices with 1394b PHY (unless only connected to 1394a PHYs),
621e71d31daSStefan Richter * - all devices if there are 1394b repeaters.
622e71d31daSStefan Richter * Note, we cannot use the bus info block's link_spd as starting point
623e71d31daSStefan Richter * because some buggy firmwares set it lower than necessary and because
624e71d31daSStefan Richter * 1394-1995 nodes do not have the field.
625e71d31daSStefan Richter */
626e71d31daSStefan Richter if ((rom[2] & 0x7) < device->max_speed ||
627e71d31daSStefan Richter device->max_speed == SCODE_BETA ||
62826b4950dSStefan Richter card->beta_repeaters_present) {
629e71d31daSStefan Richter u32 dummy;
630e71d31daSStefan Richter
631e71d31daSStefan Richter /* for S1600 and S3200 */
632e71d31daSStefan Richter if (device->max_speed == SCODE_BETA)
63326b4950dSStefan Richter device->max_speed = card->link_speed;
634e71d31daSStefan Richter
635e71d31daSStefan Richter while (device->max_speed > SCODE_100) {
636e71d31daSStefan Richter if (read_rom(device, generation, 0, &dummy) ==
637e71d31daSStefan Richter RCODE_COMPLETE)
638e71d31daSStefan Richter break;
639e71d31daSStefan Richter device->max_speed--;
640e71d31daSStefan Richter }
641e71d31daSStefan Richter }
642e71d31daSStefan Richter
643e71d31daSStefan Richter /*
644e71d31daSStefan Richter * Now parse the config rom. The config rom is a recursive
645e71d31daSStefan Richter * directory structure so we parse it using a stack of
646e71d31daSStefan Richter * references to the blocks that make up the structure. We
647e71d31daSStefan Richter * push a reference to the root directory on the stack to
648e71d31daSStefan Richter * start things off.
649e71d31daSStefan Richter */
650e71d31daSStefan Richter length = i;
651e71d31daSStefan Richter sp = 0;
652e71d31daSStefan Richter stack[sp++] = 0xc0000005;
653e71d31daSStefan Richter while (sp > 0) {
654e71d31daSStefan Richter /*
655e71d31daSStefan Richter * Pop the next block reference of the stack. The
656e71d31daSStefan Richter * lower 24 bits is the offset into the config rom,
657e71d31daSStefan Richter * the upper 8 bits are the type of the reference the
658e71d31daSStefan Richter * block.
659e71d31daSStefan Richter */
660e71d31daSStefan Richter key = stack[--sp];
661e71d31daSStefan Richter i = key & 0xffffff;
66294fba9fbSClemens Ladisch if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE)) {
66394fba9fbSClemens Ladisch ret = -ENXIO;
664e71d31daSStefan Richter goto out;
66594fba9fbSClemens Ladisch }
666e71d31daSStefan Richter
667e71d31daSStefan Richter /* Read header quadlet for the block to get the length. */
66894fba9fbSClemens Ladisch ret = read_rom(device, generation, i, &rom[i]);
66994fba9fbSClemens Ladisch if (ret != RCODE_COMPLETE)
670e71d31daSStefan Richter goto out;
671e71d31daSStefan Richter end = i + (rom[i] >> 16) + 1;
672fd6e0c51SStefan Richter if (end > MAX_CONFIG_ROM_SIZE) {
673e71d31daSStefan Richter /*
6742799d5c5SStefan Richter * This block extends outside the config ROM which is
6752799d5c5SStefan Richter * a firmware bug. Ignore this whole block, i.e.
6762799d5c5SStefan Richter * simply set a fake block length of 0.
677e71d31daSStefan Richter */
67826b4950dSStefan Richter fw_err(card, "skipped invalid ROM block %x at %llx\n",
6792799d5c5SStefan Richter rom[i],
6802799d5c5SStefan Richter i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
6812799d5c5SStefan Richter rom[i] = 0;
6822799d5c5SStefan Richter end = i;
6832799d5c5SStefan Richter }
6842799d5c5SStefan Richter i++;
685e71d31daSStefan Richter
686e71d31daSStefan Richter /*
687e71d31daSStefan Richter * Now read in the block. If this is a directory
688e71d31daSStefan Richter * block, check the entries as we read them to see if
689e71d31daSStefan Richter * it references another block, and push it in that case.
690e71d31daSStefan Richter */
691d54423c6SStefan Richter for (; i < end; i++) {
69294fba9fbSClemens Ladisch ret = read_rom(device, generation, i, &rom[i]);
69394fba9fbSClemens Ladisch if (ret != RCODE_COMPLETE)
694e71d31daSStefan Richter goto out;
695d54423c6SStefan Richter
69658aaa542SStefan Richter if ((key >> 30) != 3 || (rom[i] >> 30) < 2)
697d54423c6SStefan Richter continue;
698d54423c6SStefan Richter /*
699d54423c6SStefan Richter * Offset points outside the ROM. May be a firmware
700d54423c6SStefan Richter * bug or an Extended ROM entry (IEEE 1212-2001 clause
701d54423c6SStefan Richter * 7.7.18). Simply overwrite this pointer here by a
702d54423c6SStefan Richter * fake immediate entry so that later iterators over
703d54423c6SStefan Richter * the ROM don't have to check offsets all the time.
704d54423c6SStefan Richter */
705fd6e0c51SStefan Richter if (i + (rom[i] & 0xffffff) >= MAX_CONFIG_ROM_SIZE) {
70626b4950dSStefan Richter fw_err(card,
70726b4950dSStefan Richter "skipped unsupported ROM entry %x at %llx\n",
708d54423c6SStefan Richter rom[i],
709d54423c6SStefan Richter i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
710d54423c6SStefan Richter rom[i] = 0;
711d54423c6SStefan Richter continue;
712d54423c6SStefan Richter }
713e71d31daSStefan Richter stack[sp++] = i + rom[i];
714e71d31daSStefan Richter }
715e71d31daSStefan Richter if (length < i)
716e71d31daSStefan Richter length = i;
717e71d31daSStefan Richter }
718e71d31daSStefan Richter
719e71d31daSStefan Richter old_rom = device->config_rom;
720e71d31daSStefan Richter new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
72194fba9fbSClemens Ladisch if (new_rom == NULL) {
72294fba9fbSClemens Ladisch ret = -ENOMEM;
723e71d31daSStefan Richter goto out;
72494fba9fbSClemens Ladisch }
725e71d31daSStefan Richter
7262a6a58f0STakashi Sakamoto scoped_guard(rwsem_write, &fw_device_rwsem) {
727e71d31daSStefan Richter device->config_rom = new_rom;
728e71d31daSStefan Richter device->config_rom_length = length;
7292a6a58f0STakashi Sakamoto }
730e71d31daSStefan Richter
731e71d31daSStefan Richter kfree(old_rom);
73294fba9fbSClemens Ladisch ret = RCODE_COMPLETE;
733837ec787SStefan Richter device->max_rec = rom[2] >> 12 & 0xf;
734e71d31daSStefan Richter device->cmc = rom[2] >> 30 & 1;
735837ec787SStefan Richter device->irmc = rom[2] >> 31 & 1;
736e71d31daSStefan Richter out:
737e71d31daSStefan Richter kfree(rom);
738e71d31daSStefan Richter
739e71d31daSStefan Richter return ret;
740e71d31daSStefan Richter }
741e71d31daSStefan Richter
fw_unit_release(struct device * dev)742e71d31daSStefan Richter static void fw_unit_release(struct device *dev)
743e71d31daSStefan Richter {
744e71d31daSStefan Richter struct fw_unit *unit = fw_unit(dev);
745e71d31daSStefan Richter
74621076226SStefan Richter fw_device_put(fw_parent_device(unit));
747e71d31daSStefan Richter kfree(unit);
748e71d31daSStefan Richter }
749e71d31daSStefan Richter
750e71d31daSStefan Richter static struct device_type fw_unit_type = {
751e71d31daSStefan Richter .uevent = fw_unit_uevent,
752e71d31daSStefan Richter .release = fw_unit_release,
753e71d31daSStefan Richter };
754e71d31daSStefan Richter
is_fw_unit(const struct device * dev)755f1e2f878STakashi Sakamoto static bool is_fw_unit(const struct device *dev)
756e71d31daSStefan Richter {
757e71d31daSStefan Richter return dev->type == &fw_unit_type;
758e71d31daSStefan Richter }
759e71d31daSStefan Richter
create_units(struct fw_device * device)760e71d31daSStefan Richter static void create_units(struct fw_device *device)
761e71d31daSStefan Richter {
762e71d31daSStefan Richter struct fw_csr_iterator ci;
763e71d31daSStefan Richter struct fw_unit *unit;
764e71d31daSStefan Richter int key, value, i;
765e71d31daSStefan Richter
766e71d31daSStefan Richter i = 0;
767afa36dadSTakashi Sakamoto fw_csr_iterator_init(&ci, &device->config_rom[ROOT_DIR_OFFSET]);
768e71d31daSStefan Richter while (fw_csr_iterator_next(&ci, &key, &value)) {
769e71d31daSStefan Richter if (key != (CSR_UNIT | CSR_DIRECTORY))
770e71d31daSStefan Richter continue;
771e71d31daSStefan Richter
772e71d31daSStefan Richter /*
773e71d31daSStefan Richter * Get the address of the unit directory and try to
774e71d31daSStefan Richter * match the drivers id_tables against it.
775e71d31daSStefan Richter */
776e71d31daSStefan Richter unit = kzalloc(sizeof(*unit), GFP_KERNEL);
777cfb0c9d1SStefan Richter if (unit == NULL)
778e71d31daSStefan Richter continue;
779e71d31daSStefan Richter
780e71d31daSStefan Richter unit->directory = ci.p + value - 1;
781e71d31daSStefan Richter unit->device.bus = &fw_bus_type;
782e71d31daSStefan Richter unit->device.type = &fw_unit_type;
783e71d31daSStefan Richter unit->device.parent = &device->device;
784e71d31daSStefan Richter dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++);
785e71d31daSStefan Richter
786e71d31daSStefan Richter BUILD_BUG_ON(ARRAY_SIZE(unit->attribute_group.attrs) <
787e71d31daSStefan Richter ARRAY_SIZE(fw_unit_attributes) +
788e71d31daSStefan Richter ARRAY_SIZE(config_rom_attributes));
789e71d31daSStefan Richter init_fw_attribute_group(&unit->device,
790e71d31daSStefan Richter fw_unit_attributes,
791e71d31daSStefan Richter &unit->attribute_group);
792e71d31daSStefan Richter
79321076226SStefan Richter fw_device_get(device);
794891e0eabSYang Yingliang if (device_register(&unit->device) < 0) {
795891e0eabSYang Yingliang put_device(&unit->device);
796e71d31daSStefan Richter continue;
797891e0eabSYang Yingliang }
798e71d31daSStefan Richter }
799e71d31daSStefan Richter }
800e71d31daSStefan Richter
shutdown_unit(struct device * device,void * data)801e71d31daSStefan Richter static int shutdown_unit(struct device *device, void *data)
802e71d31daSStefan Richter {
803e71d31daSStefan Richter device_unregister(device);
804e71d31daSStefan Richter
805e71d31daSStefan Richter return 0;
806e71d31daSStefan Richter }
807e71d31daSStefan Richter
808e71d31daSStefan Richter /*
809e71d31daSStefan Richter * fw_device_rwsem acts as dual purpose mutex:
810e71d31daSStefan Richter * - serializes accesses to fw_device.config_rom/.config_rom_length and
811e71d31daSStefan Richter * fw_unit.directory, unless those accesses happen at safe occasions
812e71d31daSStefan Richter */
813e71d31daSStefan Richter DECLARE_RWSEM(fw_device_rwsem);
814e71d31daSStefan Richter
8157e5a7725STakashi Sakamoto DEFINE_XARRAY_ALLOC(fw_device_xa);
816e71d31daSStefan Richter int fw_cdev_major;
817e71d31daSStefan Richter
fw_device_get_by_devt(dev_t devt)818e71d31daSStefan Richter struct fw_device *fw_device_get_by_devt(dev_t devt)
819e71d31daSStefan Richter {
820e71d31daSStefan Richter struct fw_device *device;
821e71d31daSStefan Richter
8227e5a7725STakashi Sakamoto device = xa_load(&fw_device_xa, MINOR(devt));
823e71d31daSStefan Richter if (device)
824e71d31daSStefan Richter fw_device_get(device);
825e71d31daSStefan Richter
826e71d31daSStefan Richter return device;
827e71d31daSStefan Richter }
828e71d31daSStefan Richter
829105e53f8SStefan Richter struct workqueue_struct *fw_workqueue;
830105e53f8SStefan Richter EXPORT_SYMBOL(fw_workqueue);
8316ea9e7bbSStefan Richter
fw_schedule_device_work(struct fw_device * device,unsigned long delay)8326ea9e7bbSStefan Richter static void fw_schedule_device_work(struct fw_device *device,
8336ea9e7bbSStefan Richter unsigned long delay)
8346ea9e7bbSStefan Richter {
835105e53f8SStefan Richter queue_delayed_work(fw_workqueue, &device->work, delay);
8366ea9e7bbSStefan Richter }
8376ea9e7bbSStefan Richter
838e71d31daSStefan Richter /*
839e71d31daSStefan Richter * These defines control the retry behavior for reading the config
840e71d31daSStefan Richter * rom. It shouldn't be necessary to tweak these; if the device
841e71d31daSStefan Richter * doesn't respond to a config rom read within 10 seconds, it's not
842e71d31daSStefan Richter * going to respond at all. As for the initial delay, a lot of
843e71d31daSStefan Richter * devices will be able to respond within half a second after bus
844e71d31daSStefan Richter * reset. On the other hand, it's not really worth being more
845e71d31daSStefan Richter * aggressive than that, since it scales pretty well; if 10 devices
846e71d31daSStefan Richter * are plugged in, they're all getting read within one second.
847e71d31daSStefan Richter */
848e71d31daSStefan Richter
849e71d31daSStefan Richter #define MAX_RETRIES 10
850e71d31daSStefan Richter #define RETRY_DELAY (3 * HZ)
851e71d31daSStefan Richter #define INITIAL_DELAY (HZ / 2)
852e71d31daSStefan Richter #define SHUTDOWN_DELAY (2 * HZ)
853e71d31daSStefan Richter
fw_device_shutdown(struct work_struct * work)854e71d31daSStefan Richter static void fw_device_shutdown(struct work_struct *work)
855e71d31daSStefan Richter {
856e71d31daSStefan Richter struct fw_device *device =
857e71d31daSStefan Richter container_of(work, struct fw_device, work.work);
858e71d31daSStefan Richter
859e71084afSClemens Ladisch if (time_before64(get_jiffies_64(),
860e71084afSClemens Ladisch device->card->reset_jiffies + SHUTDOWN_DELAY)
861e71d31daSStefan Richter && !list_empty(&device->card->link)) {
8626ea9e7bbSStefan Richter fw_schedule_device_work(device, SHUTDOWN_DELAY);
863e71d31daSStefan Richter return;
864e71d31daSStefan Richter }
865e71d31daSStefan Richter
866e71d31daSStefan Richter if (atomic_cmpxchg(&device->state,
867e71d31daSStefan Richter FW_DEVICE_GONE,
868e71d31daSStefan Richter FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE)
869e71d31daSStefan Richter return;
870e71d31daSStefan Richter
871e71d31daSStefan Richter fw_device_cdev_remove(device);
872e71d31daSStefan Richter device_for_each_child(&device->device, NULL, shutdown_unit);
873e71d31daSStefan Richter device_unregister(&device->device);
874e71d31daSStefan Richter
8757e5a7725STakashi Sakamoto xa_erase(&fw_device_xa, MINOR(device->device.devt));
876e71d31daSStefan Richter
877e71d31daSStefan Richter fw_device_put(device);
878e71d31daSStefan Richter }
879e71d31daSStefan Richter
fw_device_release(struct device * dev)880e71d31daSStefan Richter static void fw_device_release(struct device *dev)
881e71d31daSStefan Richter {
882e71d31daSStefan Richter struct fw_device *device = fw_device(dev);
883e71d31daSStefan Richter struct fw_card *card = device->card;
884e71d31daSStefan Richter
885e71d31daSStefan Richter /*
886e71d31daSStefan Richter * Take the card lock so we don't set this to NULL while a
887e71d31daSStefan Richter * FW_NODE_UPDATED callback is being handled or while the
888e71d31daSStefan Richter * bus manager work looks at this node.
889e71d31daSStefan Richter */
89027310d56STakashi Sakamoto scoped_guard(spinlock_irqsave, &card->lock)
891e71d31daSStefan Richter device->node->data = NULL;
892e71d31daSStefan Richter
893e71d31daSStefan Richter fw_node_put(device->node);
894e71d31daSStefan Richter kfree(device->config_rom);
895e71d31daSStefan Richter kfree(device);
896e71d31daSStefan Richter fw_card_put(card);
897e71d31daSStefan Richter }
898e71d31daSStefan Richter
899e71d31daSStefan Richter static struct device_type fw_device_type = {
900e71d31daSStefan Richter .release = fw_device_release,
901e71d31daSStefan Richter };
902e71d31daSStefan Richter
is_fw_device(const struct device * dev)903f1e2f878STakashi Sakamoto static bool is_fw_device(const struct device *dev)
904099d5414SStefan Richter {
905099d5414SStefan Richter return dev->type == &fw_device_type;
906099d5414SStefan Richter }
907099d5414SStefan Richter
update_unit(struct device * dev,void * data)908e71d31daSStefan Richter static int update_unit(struct device *dev, void *data)
909e71d31daSStefan Richter {
910e71d31daSStefan Richter struct fw_unit *unit = fw_unit(dev);
911e71d31daSStefan Richter struct fw_driver *driver = (struct fw_driver *)dev->driver;
912e71d31daSStefan Richter
913e71d31daSStefan Richter if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
9148e9394ceSGreg Kroah-Hartman device_lock(dev);
915e71d31daSStefan Richter driver->update(unit);
9168e9394ceSGreg Kroah-Hartman device_unlock(dev);
917e71d31daSStefan Richter }
918e71d31daSStefan Richter
919e71d31daSStefan Richter return 0;
920e71d31daSStefan Richter }
921e71d31daSStefan Richter
fw_device_update(struct work_struct * work)922e71d31daSStefan Richter static void fw_device_update(struct work_struct *work)
923e71d31daSStefan Richter {
924e71d31daSStefan Richter struct fw_device *device =
925e71d31daSStefan Richter container_of(work, struct fw_device, work.work);
926e71d31daSStefan Richter
927e71d31daSStefan Richter fw_device_cdev_update(device);
928e71d31daSStefan Richter device_for_each_child(&device->device, NULL, update_unit);
929e71d31daSStefan Richter }
930e71d31daSStefan Richter
931e71d31daSStefan Richter enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
932e71d31daSStefan Richter
set_broadcast_channel(struct fw_device * device,int generation)933099d5414SStefan Richter static void set_broadcast_channel(struct fw_device *device, int generation)
934e71d31daSStefan Richter {
935e71d31daSStefan Richter struct fw_card *card = device->card;
936e71d31daSStefan Richter __be32 data;
937e71d31daSStefan Richter int rcode;
938e71d31daSStefan Richter
939e71d31daSStefan Richter if (!card->broadcast_channel_allocated)
940e71d31daSStefan Richter return;
941e71d31daSStefan Richter
942837ec787SStefan Richter /*
943837ec787SStefan Richter * The Broadcast_Channel Valid bit is required by nodes which want to
944837ec787SStefan Richter * transmit on this channel. Such transmissions are practically
945837ec787SStefan Richter * exclusive to IP over 1394 (RFC 2734). IP capable nodes are required
946837ec787SStefan Richter * to be IRM capable and have a max_rec of 8 or more. We use this fact
947837ec787SStefan Richter * to narrow down to which nodes we send Broadcast_Channel updates.
948837ec787SStefan Richter */
949837ec787SStefan Richter if (!device->irmc || device->max_rec < 8)
950837ec787SStefan Richter return;
951837ec787SStefan Richter
952837ec787SStefan Richter /*
953837ec787SStefan Richter * Some 1394-1995 nodes crash if this 1394a-2000 register is written.
954837ec787SStefan Richter * Perform a read test first.
955837ec787SStefan Richter */
956e71d31daSStefan Richter if (device->bc_implemented == BC_UNKNOWN) {
957e71d31daSStefan Richter rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
958e71d31daSStefan Richter device->node_id, generation, device->max_speed,
959e71d31daSStefan Richter CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
960e71d31daSStefan Richter &data, 4);
961e71d31daSStefan Richter switch (rcode) {
962e71d31daSStefan Richter case RCODE_COMPLETE:
963e71d31daSStefan Richter if (data & cpu_to_be32(1 << 31)) {
964e71d31daSStefan Richter device->bc_implemented = BC_IMPLEMENTED;
965e71d31daSStefan Richter break;
966e71d31daSStefan Richter }
967df561f66SGustavo A. R. Silva fallthrough; /* to case address error */
968e71d31daSStefan Richter case RCODE_ADDRESS_ERROR:
969e71d31daSStefan Richter device->bc_implemented = BC_UNIMPLEMENTED;
970e71d31daSStefan Richter }
971e71d31daSStefan Richter }
972e71d31daSStefan Richter
973e71d31daSStefan Richter if (device->bc_implemented == BC_IMPLEMENTED) {
974e71d31daSStefan Richter data = cpu_to_be32(BROADCAST_CHANNEL_INITIAL |
975e71d31daSStefan Richter BROADCAST_CHANNEL_VALID);
976e71d31daSStefan Richter fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
977e71d31daSStefan Richter device->node_id, generation, device->max_speed,
978e71d31daSStefan Richter CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
979e71d31daSStefan Richter &data, 4);
980e71d31daSStefan Richter }
981e71d31daSStefan Richter }
982e71d31daSStefan Richter
fw_device_set_broadcast_channel(struct device * dev,void * gen)983099d5414SStefan Richter int fw_device_set_broadcast_channel(struct device *dev, void *gen)
984099d5414SStefan Richter {
985099d5414SStefan Richter if (is_fw_device(dev))
986099d5414SStefan Richter set_broadcast_channel(fw_device(dev), (long)gen);
987099d5414SStefan Richter
988099d5414SStefan Richter return 0;
989099d5414SStefan Richter }
990099d5414SStefan Richter
compare_configuration_rom(struct device * dev,const void * data)991*f1e8bf56SZijun Hu static int compare_configuration_rom(struct device *dev, const void *data)
992e2c87f48STakashi Sakamoto {
993e2c87f48STakashi Sakamoto const struct fw_device *old = fw_device(dev);
994e2c87f48STakashi Sakamoto const u32 *config_rom = data;
995e2c87f48STakashi Sakamoto
996e2c87f48STakashi Sakamoto if (!is_fw_device(dev))
997e2c87f48STakashi Sakamoto return 0;
998e2c87f48STakashi Sakamoto
999e2c87f48STakashi Sakamoto // Compare the bus information block and root_length/root_crc.
1000e2c87f48STakashi Sakamoto return !memcmp(old->config_rom, config_rom, 6 * 4);
1001e2c87f48STakashi Sakamoto }
1002e2c87f48STakashi Sakamoto
fw_device_init(struct work_struct * work)1003e71d31daSStefan Richter static void fw_device_init(struct work_struct *work)
1004e71d31daSStefan Richter {
1005e71d31daSStefan Richter struct fw_device *device =
1006e71d31daSStefan Richter container_of(work, struct fw_device, work.work);
100726b4950dSStefan Richter struct fw_card *card = device->card;
1008e2c87f48STakashi Sakamoto struct device *found;
10097e5a7725STakashi Sakamoto u32 minor;
10107e5a7725STakashi Sakamoto int ret;
1011e71d31daSStefan Richter
1012e71d31daSStefan Richter /*
1013e71d31daSStefan Richter * All failure paths here set node->data to NULL, so that we
1014e71d31daSStefan Richter * don't try to do device_for_each_child() on a kfree()'d
1015e71d31daSStefan Richter * device.
1016e71d31daSStefan Richter */
1017e71d31daSStefan Richter
101894fba9fbSClemens Ladisch ret = read_config_rom(device, device->generation);
101994fba9fbSClemens Ladisch if (ret != RCODE_COMPLETE) {
1020e71d31daSStefan Richter if (device->config_rom_retries < MAX_RETRIES &&
1021e71d31daSStefan Richter atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
1022e71d31daSStefan Richter device->config_rom_retries++;
10236ea9e7bbSStefan Richter fw_schedule_device_work(device, RETRY_DELAY);
1024e71d31daSStefan Richter } else {
1025115881d3SStefan Richter if (device->node->link_on)
102694fba9fbSClemens Ladisch fw_notice(card, "giving up on node %x: reading config rom failed: %s\n",
102794fba9fbSClemens Ladisch device->node_id,
102894fba9fbSClemens Ladisch fw_rcode_string(ret));
102926b4950dSStefan Richter if (device->node == card->root_node)
103026b4950dSStefan Richter fw_schedule_bm_work(card, 0);
1031e71d31daSStefan Richter fw_device_release(&device->device);
1032e71d31daSStefan Richter }
1033e71d31daSStefan Richter return;
1034e71d31daSStefan Richter }
1035e71d31daSStefan Richter
1036e2c87f48STakashi Sakamoto // If a device was pending for deletion because its node went away but its bus info block
1037e2c87f48STakashi Sakamoto // and root directory header matches that of a newly discovered device, revive the
1038e2c87f48STakashi Sakamoto // existing fw_device. The newly allocated fw_device becomes obsolete instead.
1039e2c87f48STakashi Sakamoto //
1040e2c87f48STakashi Sakamoto // serialize config_rom access.
1041e2c87f48STakashi Sakamoto scoped_guard(rwsem_read, &fw_device_rwsem) {
1042*f1e8bf56SZijun Hu found = device_find_child(card->device, device->config_rom,
1043e2c87f48STakashi Sakamoto compare_configuration_rom);
1044e2c87f48STakashi Sakamoto }
1045e2c87f48STakashi Sakamoto if (found) {
1046e2c87f48STakashi Sakamoto struct fw_device *reused = fw_device(found);
1047e2c87f48STakashi Sakamoto
1048e2c87f48STakashi Sakamoto if (atomic_cmpxchg(&reused->state,
1049e2c87f48STakashi Sakamoto FW_DEVICE_GONE,
1050e2c87f48STakashi Sakamoto FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
1051e2c87f48STakashi Sakamoto // serialize node access
1052e2c87f48STakashi Sakamoto scoped_guard(spinlock_irq, &card->lock) {
1053e2c87f48STakashi Sakamoto struct fw_node *current_node = device->node;
1054e2c87f48STakashi Sakamoto struct fw_node *obsolete_node = reused->node;
1055e2c87f48STakashi Sakamoto
1056e2c87f48STakashi Sakamoto device->node = obsolete_node;
1057e2c87f48STakashi Sakamoto device->node->data = device;
1058e2c87f48STakashi Sakamoto reused->node = current_node;
1059e2c87f48STakashi Sakamoto reused->node->data = reused;
1060e2c87f48STakashi Sakamoto
1061e2c87f48STakashi Sakamoto reused->max_speed = device->max_speed;
1062e2c87f48STakashi Sakamoto reused->node_id = current_node->node_id;
1063e2c87f48STakashi Sakamoto smp_wmb(); /* update node_id before generation */
1064e2c87f48STakashi Sakamoto reused->generation = card->generation;
1065e2c87f48STakashi Sakamoto reused->config_rom_retries = 0;
1066e2c87f48STakashi Sakamoto fw_notice(card, "rediscovered device %s\n",
1067e2c87f48STakashi Sakamoto dev_name(found));
1068e2c87f48STakashi Sakamoto
1069e2c87f48STakashi Sakamoto reused->workfn = fw_device_update;
1070e2c87f48STakashi Sakamoto fw_schedule_device_work(reused, 0);
1071e2c87f48STakashi Sakamoto
1072e2c87f48STakashi Sakamoto if (current_node == card->root_node)
1073e2c87f48STakashi Sakamoto fw_schedule_bm_work(card, 0);
1074e2c87f48STakashi Sakamoto }
1075e2c87f48STakashi Sakamoto
1076e2c87f48STakashi Sakamoto put_device(found);
1077e71d31daSStefan Richter fw_device_release(&device->device);
1078e71d31daSStefan Richter
1079e71d31daSStefan Richter return;
1080e71d31daSStefan Richter }
1081e71d31daSStefan Richter
1082e2c87f48STakashi Sakamoto put_device(found);
1083e2c87f48STakashi Sakamoto }
1084e2c87f48STakashi Sakamoto
1085e71d31daSStefan Richter device_initialize(&device->device);
1086e71d31daSStefan Richter
1087e71d31daSStefan Richter fw_device_get(device);
10887e5a7725STakashi Sakamoto
10897e5a7725STakashi Sakamoto // The index of allocated entry is used for minor identifier of device node.
10907e5a7725STakashi Sakamoto ret = xa_alloc(&fw_device_xa, &minor, device, XA_LIMIT(0, MINORMASK), GFP_KERNEL);
10917e5a7725STakashi Sakamoto if (ret < 0)
1092e71d31daSStefan Richter goto error;
1093e71d31daSStefan Richter
1094e71d31daSStefan Richter device->device.bus = &fw_bus_type;
1095e71d31daSStefan Richter device->device.type = &fw_device_type;
109626b4950dSStefan Richter device->device.parent = card->device;
1097e71d31daSStefan Richter device->device.devt = MKDEV(fw_cdev_major, minor);
1098e71d31daSStefan Richter dev_set_name(&device->device, "fw%d", minor);
1099e71d31daSStefan Richter
1100e71d31daSStefan Richter BUILD_BUG_ON(ARRAY_SIZE(device->attribute_group.attrs) <
1101e71d31daSStefan Richter ARRAY_SIZE(fw_device_attributes) +
1102e71d31daSStefan Richter ARRAY_SIZE(config_rom_attributes));
1103e71d31daSStefan Richter init_fw_attribute_group(&device->device,
1104e71d31daSStefan Richter fw_device_attributes,
1105e71d31daSStefan Richter &device->attribute_group);
1106e71d31daSStefan Richter
1107e71d31daSStefan Richter if (device_add(&device->device)) {
110826b4950dSStefan Richter fw_err(card, "failed to add device\n");
1109e71d31daSStefan Richter goto error_with_cdev;
1110e71d31daSStefan Richter }
1111e71d31daSStefan Richter
1112e71d31daSStefan Richter create_units(device);
1113e71d31daSStefan Richter
1114e71d31daSStefan Richter /*
1115e71d31daSStefan Richter * Transition the device to running state. If it got pulled
1116183b8021SMasahiro Yamada * out from under us while we did the initialization work, we
1117e71d31daSStefan Richter * have to shut down the device again here. Normally, though,
1118e71d31daSStefan Richter * fw_node_event will be responsible for shutting it down when
1119e71d31daSStefan Richter * necessary. We have to use the atomic cmpxchg here to avoid
1120e71d31daSStefan Richter * racing with the FW_NODE_DESTROYED case in
1121e71d31daSStefan Richter * fw_node_event().
1122e71d31daSStefan Richter */
1123e71d31daSStefan Richter if (atomic_cmpxchg(&device->state,
1124e71d31daSStefan Richter FW_DEVICE_INITIALIZING,
1125e71d31daSStefan Richter FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
112670044d71STejun Heo device->workfn = fw_device_shutdown;
11276ea9e7bbSStefan Richter fw_schedule_device_work(device, SHUTDOWN_DELAY);
1128e71d31daSStefan Richter } else {
112926b4950dSStefan Richter fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n",
1130e71d31daSStefan Richter dev_name(&device->device),
1131e71d31daSStefan Richter device->config_rom[3], device->config_rom[4],
1132e71d31daSStefan Richter 1 << device->max_speed);
1133e71d31daSStefan Richter device->config_rom_retries = 0;
1134e71d31daSStefan Richter
1135099d5414SStefan Richter set_broadcast_channel(device, device->generation);
1136badfcb24SClemens Ladisch
1137badfcb24SClemens Ladisch add_device_randomness(&device->config_rom[3], 8);
1138e71d31daSStefan Richter }
1139e71d31daSStefan Richter
1140e71d31daSStefan Richter /*
1141e71d31daSStefan Richter * Reschedule the IRM work if we just finished reading the
1142e71d31daSStefan Richter * root node config rom. If this races with a bus reset we
1143e71d31daSStefan Richter * just end up running the IRM work a couple of extra times -
1144e71d31daSStefan Richter * pretty harmless.
1145e71d31daSStefan Richter */
114626b4950dSStefan Richter if (device->node == card->root_node)
114726b4950dSStefan Richter fw_schedule_bm_work(card, 0);
1148e71d31daSStefan Richter
1149e71d31daSStefan Richter return;
1150e71d31daSStefan Richter
1151e71d31daSStefan Richter error_with_cdev:
11527e5a7725STakashi Sakamoto xa_erase(&fw_device_xa, minor);
1153e71d31daSStefan Richter error:
11547e5a7725STakashi Sakamoto fw_device_put(device); // fw_device_xa's reference.
1155e71d31daSStefan Richter
1156e71d31daSStefan Richter put_device(&device->device); /* our reference */
1157e71d31daSStefan Richter }
1158e71d31daSStefan Richter
1159e71d31daSStefan Richter /* Reread and compare bus info block and header of root directory */
reread_config_rom(struct fw_device * device,int generation,bool * changed)1160db7494e2SClemens Ladisch static int reread_config_rom(struct fw_device *device, int generation,
1161db7494e2SClemens Ladisch bool *changed)
1162e71d31daSStefan Richter {
1163e71d31daSStefan Richter u32 q;
1164db7494e2SClemens Ladisch int i, rcode;
1165e71d31daSStefan Richter
1166e71d31daSStefan Richter for (i = 0; i < 6; i++) {
1167db7494e2SClemens Ladisch rcode = read_rom(device, generation, i, &q);
1168db7494e2SClemens Ladisch if (rcode != RCODE_COMPLETE)
1169db7494e2SClemens Ladisch return rcode;
1170e71d31daSStefan Richter
1171e71d31daSStefan Richter if (i == 0 && q == 0)
1172d33ec3b5SClemens Ladisch /* inaccessible (see read_config_rom); retry later */
1173db7494e2SClemens Ladisch return RCODE_BUSY;
1174e71d31daSStefan Richter
1175db7494e2SClemens Ladisch if (q != device->config_rom[i]) {
1176db7494e2SClemens Ladisch *changed = true;
1177db7494e2SClemens Ladisch return RCODE_COMPLETE;
1178db7494e2SClemens Ladisch }
1179e71d31daSStefan Richter }
1180e71d31daSStefan Richter
1181db7494e2SClemens Ladisch *changed = false;
1182db7494e2SClemens Ladisch return RCODE_COMPLETE;
1183e71d31daSStefan Richter }
1184e71d31daSStefan Richter
fw_device_refresh(struct work_struct * work)1185e71d31daSStefan Richter static void fw_device_refresh(struct work_struct *work)
1186e71d31daSStefan Richter {
1187e71d31daSStefan Richter struct fw_device *device =
1188e71d31daSStefan Richter container_of(work, struct fw_device, work.work);
1189e71d31daSStefan Richter struct fw_card *card = device->card;
1190db7494e2SClemens Ladisch int ret, node_id = device->node_id;
1191db7494e2SClemens Ladisch bool changed;
1192e71d31daSStefan Richter
1193db7494e2SClemens Ladisch ret = reread_config_rom(device, device->generation, &changed);
11948527f8e2SClemens Ladisch if (ret != RCODE_COMPLETE)
11958527f8e2SClemens Ladisch goto failed_config_rom;
1196e71d31daSStefan Richter
1197db7494e2SClemens Ladisch if (!changed) {
1198e71d31daSStefan Richter if (atomic_cmpxchg(&device->state,
1199e71d31daSStefan Richter FW_DEVICE_INITIALIZING,
1200e71d31daSStefan Richter FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
1201e71d31daSStefan Richter goto gone;
1202e71d31daSStefan Richter
1203e71d31daSStefan Richter fw_device_update(work);
1204e71d31daSStefan Richter device->config_rom_retries = 0;
1205e71d31daSStefan Richter goto out;
1206e71d31daSStefan Richter }
1207e71d31daSStefan Richter
1208e71d31daSStefan Richter /*
1209e71d31daSStefan Richter * Something changed. We keep things simple and don't investigate
1210e71d31daSStefan Richter * further. We just destroy all previous units and create new ones.
1211e71d31daSStefan Richter */
1212e71d31daSStefan Richter device_for_each_child(&device->device, NULL, shutdown_unit);
1213e71d31daSStefan Richter
121494fba9fbSClemens Ladisch ret = read_config_rom(device, device->generation);
12158527f8e2SClemens Ladisch if (ret != RCODE_COMPLETE)
12168527f8e2SClemens Ladisch goto failed_config_rom;
1217e71d31daSStefan Richter
12188b4f70baSStefan Richter fw_device_cdev_update(device);
1219e71d31daSStefan Richter create_units(device);
1220e71d31daSStefan Richter
1221e71d31daSStefan Richter /* Userspace may want to re-read attributes. */
1222e71d31daSStefan Richter kobject_uevent(&device->device.kobj, KOBJ_CHANGE);
1223e71d31daSStefan Richter
1224e71d31daSStefan Richter if (atomic_cmpxchg(&device->state,
1225e71d31daSStefan Richter FW_DEVICE_INITIALIZING,
1226e71d31daSStefan Richter FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
1227e71d31daSStefan Richter goto gone;
1228e71d31daSStefan Richter
122926b4950dSStefan Richter fw_notice(card, "refreshed device %s\n", dev_name(&device->device));
1230e71d31daSStefan Richter device->config_rom_retries = 0;
1231e71d31daSStefan Richter goto out;
1232e71d31daSStefan Richter
12338527f8e2SClemens Ladisch failed_config_rom:
12348527f8e2SClemens Ladisch if (device->config_rom_retries < MAX_RETRIES &&
12358527f8e2SClemens Ladisch atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
12368527f8e2SClemens Ladisch device->config_rom_retries++;
12378527f8e2SClemens Ladisch fw_schedule_device_work(device, RETRY_DELAY);
12388527f8e2SClemens Ladisch return;
12398527f8e2SClemens Ladisch }
12408527f8e2SClemens Ladisch
124194fba9fbSClemens Ladisch fw_notice(card, "giving up on refresh of device %s: %s\n",
124294fba9fbSClemens Ladisch dev_name(&device->device), fw_rcode_string(ret));
1243e71d31daSStefan Richter gone:
1244e71d31daSStefan Richter atomic_set(&device->state, FW_DEVICE_GONE);
124570044d71STejun Heo device->workfn = fw_device_shutdown;
12466ea9e7bbSStefan Richter fw_schedule_device_work(device, SHUTDOWN_DELAY);
1247e71d31daSStefan Richter out:
1248e71d31daSStefan Richter if (node_id == card->root_node->node_id)
1249e71d31daSStefan Richter fw_schedule_bm_work(card, 0);
1250e71d31daSStefan Richter }
1251e71d31daSStefan Richter
fw_device_workfn(struct work_struct * work)125270044d71STejun Heo static void fw_device_workfn(struct work_struct *work)
125370044d71STejun Heo {
125470044d71STejun Heo struct fw_device *device = container_of(to_delayed_work(work),
125570044d71STejun Heo struct fw_device, work);
125670044d71STejun Heo device->workfn(work);
125770044d71STejun Heo }
125870044d71STejun Heo
fw_node_event(struct fw_card * card,struct fw_node * node,int event)1259e71d31daSStefan Richter void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
1260e71d31daSStefan Richter {
1261e71d31daSStefan Richter struct fw_device *device;
1262e71d31daSStefan Richter
1263e71d31daSStefan Richter switch (event) {
1264e71d31daSStefan Richter case FW_NODE_CREATED:
1265115881d3SStefan Richter /*
1266115881d3SStefan Richter * Attempt to scan the node, regardless whether its self ID has
1267115881d3SStefan Richter * the L (link active) flag set or not. Some broken devices
1268115881d3SStefan Richter * send L=0 but have an up-and-running link; others send L=1
1269115881d3SStefan Richter * without actually having a link.
1270115881d3SStefan Richter */
1271e71d31daSStefan Richter create:
12723c70de9bSTakashi Sakamoto device = kzalloc(sizeof(*device), GFP_ATOMIC);
1273e71d31daSStefan Richter if (device == NULL)
1274e71d31daSStefan Richter break;
1275e71d31daSStefan Richter
1276e71d31daSStefan Richter /*
1277183b8021SMasahiro Yamada * Do minimal initialization of the device here, the
1278e71d31daSStefan Richter * rest will happen in fw_device_init().
1279e71d31daSStefan Richter *
1280e71d31daSStefan Richter * Attention: A lot of things, even fw_device_get(),
1281e71d31daSStefan Richter * cannot be done before fw_device_init() finished!
1282e71d31daSStefan Richter * You can basically just check device->state and
1283e71d31daSStefan Richter * schedule work until then, but only while holding
1284e71d31daSStefan Richter * card->lock.
1285e71d31daSStefan Richter */
1286e71d31daSStefan Richter atomic_set(&device->state, FW_DEVICE_INITIALIZING);
1287e71d31daSStefan Richter device->card = fw_card_get(card);
1288e71d31daSStefan Richter device->node = fw_node_get(node);
1289e71d31daSStefan Richter device->node_id = node->node_id;
1290e71d31daSStefan Richter device->generation = card->generation;
1291e71d31daSStefan Richter device->is_local = node == card->local_node;
1292e71d31daSStefan Richter mutex_init(&device->client_list_mutex);
1293e71d31daSStefan Richter INIT_LIST_HEAD(&device->client_list);
1294e71d31daSStefan Richter
1295e71d31daSStefan Richter /*
1296e71d31daSStefan Richter * Set the node data to point back to this device so
1297e71d31daSStefan Richter * FW_NODE_UPDATED callbacks can update the node_id
1298e71d31daSStefan Richter * and generation for the device.
1299e71d31daSStefan Richter */
1300e71d31daSStefan Richter node->data = device;
1301e71d31daSStefan Richter
1302e71d31daSStefan Richter /*
1303e71d31daSStefan Richter * Many devices are slow to respond after bus resets,
1304e71d31daSStefan Richter * especially if they are bus powered and go through
1305e71d31daSStefan Richter * power-up after getting plugged in. We schedule the
1306e71d31daSStefan Richter * first config rom scan half a second after bus reset.
1307e71d31daSStefan Richter */
130870044d71STejun Heo device->workfn = fw_device_init;
130970044d71STejun Heo INIT_DELAYED_WORK(&device->work, fw_device_workfn);
13106ea9e7bbSStefan Richter fw_schedule_device_work(device, INITIAL_DELAY);
1311e71d31daSStefan Richter break;
1312e71d31daSStefan Richter
1313e71d31daSStefan Richter case FW_NODE_INITIATED_RESET:
1314115881d3SStefan Richter case FW_NODE_LINK_ON:
1315e71d31daSStefan Richter device = node->data;
1316e71d31daSStefan Richter if (device == NULL)
1317e71d31daSStefan Richter goto create;
1318e71d31daSStefan Richter
1319e71d31daSStefan Richter device->node_id = node->node_id;
1320e71d31daSStefan Richter smp_wmb(); /* update node_id before generation */
1321e71d31daSStefan Richter device->generation = card->generation;
1322e71d31daSStefan Richter if (atomic_cmpxchg(&device->state,
1323e71d31daSStefan Richter FW_DEVICE_RUNNING,
1324e71d31daSStefan Richter FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
132570044d71STejun Heo device->workfn = fw_device_refresh;
13266ea9e7bbSStefan Richter fw_schedule_device_work(device,
1327e71d31daSStefan Richter device->is_local ? 0 : INITIAL_DELAY);
1328e71d31daSStefan Richter }
1329e71d31daSStefan Richter break;
1330e71d31daSStefan Richter
1331e71d31daSStefan Richter case FW_NODE_UPDATED:
1332115881d3SStefan Richter device = node->data;
1333115881d3SStefan Richter if (device == NULL)
1334e71d31daSStefan Richter break;
1335e71d31daSStefan Richter
1336e71d31daSStefan Richter device->node_id = node->node_id;
1337e71d31daSStefan Richter smp_wmb(); /* update node_id before generation */
1338e71d31daSStefan Richter device->generation = card->generation;
1339e71d31daSStefan Richter if (atomic_read(&device->state) == FW_DEVICE_RUNNING) {
134070044d71STejun Heo device->workfn = fw_device_update;
13416ea9e7bbSStefan Richter fw_schedule_device_work(device, 0);
1342e71d31daSStefan Richter }
1343e71d31daSStefan Richter break;
1344e71d31daSStefan Richter
1345e71d31daSStefan Richter case FW_NODE_DESTROYED:
1346e71d31daSStefan Richter case FW_NODE_LINK_OFF:
1347e71d31daSStefan Richter if (!node->data)
1348e71d31daSStefan Richter break;
1349e71d31daSStefan Richter
1350e71d31daSStefan Richter /*
1351e71d31daSStefan Richter * Destroy the device associated with the node. There
1352e71d31daSStefan Richter * are two cases here: either the device is fully
1353e71d31daSStefan Richter * initialized (FW_DEVICE_RUNNING) or we're in the
1354e71d31daSStefan Richter * process of reading its config rom
1355e71d31daSStefan Richter * (FW_DEVICE_INITIALIZING). If it is fully
1356e71d31daSStefan Richter * initialized we can reuse device->work to schedule a
1357e71d31daSStefan Richter * full fw_device_shutdown(). If not, there's work
1358e71d31daSStefan Richter * scheduled to read it's config rom, and we just put
1359e71d31daSStefan Richter * the device in shutdown state to have that code fail
1360e71d31daSStefan Richter * to create the device.
1361e71d31daSStefan Richter */
1362e71d31daSStefan Richter device = node->data;
1363e71d31daSStefan Richter if (atomic_xchg(&device->state,
1364e71d31daSStefan Richter FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
136570044d71STejun Heo device->workfn = fw_device_shutdown;
13666ea9e7bbSStefan Richter fw_schedule_device_work(device,
1367e71d31daSStefan Richter list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
1368e71d31daSStefan Richter }
1369e71d31daSStefan Richter break;
1370e71d31daSStefan Richter }
1371e71d31daSStefan Richter }
13721770d39dSTakashi Sakamoto
13731770d39dSTakashi Sakamoto #ifdef CONFIG_FIREWIRE_KUNIT_DEVICE_ATTRIBUTE_TEST
13741770d39dSTakashi Sakamoto #include "device-attribute-test.c"
13751770d39dSTakashi Sakamoto #endif
1376