1a59d1b8e05ea drivers/firewire/core-device.c (Thomas Gleixner 2019-05-27 08:55:05 +0200 1) // SPDX-License-Identifier: GPL-2.0-or-later
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 2) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 3) * Device probing and sysfs code.
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 4) *
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 5) * Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net>
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 6) */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 7)
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 8) #include <linux/bug.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 9) #include <linux/ctype.h>
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 10) #include <linux/delay.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 11) #include <linux/device.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 12) #include <linux/errno.h>
77c9a5daa9c4d drivers/firewire/fw-device.c (Stefan Richter 2009-06-05 16:26:18 +0200 13) #include <linux/firewire.h>
77c9a5daa9c4d drivers/firewire/fw-device.c (Stefan Richter 2009-06-05 16:26:18 +0200 14) #include <linux/firewire-constants.h>
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 15) #include <linux/idr.h>
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 16) #include <linux/jiffies.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 17) #include <linux/kobject.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 18) #include <linux/list.h>
b3b2988841ac6 drivers/firewire/fw-device.c (Stefan Richter 2009-02-15 23:12:34 +0100 19) #include <linux/mod_devicetable.h>
e8ca97021c8eb drivers/firewire/fw-device.c (Stefan Richter 2009-06-04 21:09:38 +0200 20) #include <linux/module.h>
d67cfb9613f37 drivers/firewire/fw-device.c (Stefan Richter 2008-10-05 10:37:11 +0200 21) #include <linux/mutex.h>
badfcb24891cc drivers/firewire/core-device.c (Clemens Ladisch 2012-08-13 09:08:41 +0200 22) #include <linux/random.h>
6188e10d38b8d drivers/firewire/fw-device.c (Matthew Wilcox 2008-04-18 22:21:05 -0400 23) #include <linux/rwsem.h>
5a0e3ad6af866 drivers/firewire/core-device.c (Tejun Heo 2010-03-24 17:04:11 +0900 24) #include <linux/slab.h>
cf417e5494582 drivers/firewire/fw-device.c (Jay Fenlason 2008-10-03 11:19:09 -0400 25) #include <linux/spinlock.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 26) #include <linux/string.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 27) #include <linux/workqueue.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 28)
60063497a95e7 drivers/firewire/core-device.c (Arun Sharma 2011-07-26 16:09:06 -0700 29) #include <linux/atomic.h>
e8ca97021c8eb drivers/firewire/fw-device.c (Stefan Richter 2009-06-04 21:09:38 +0200 30) #include <asm/byteorder.h>
41f321c2ecf41 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 31)
77c9a5daa9c4d drivers/firewire/fw-device.c (Stefan Richter 2009-06-05 16:26:18 +0200 32) #include "core.h"
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 33)
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 34) void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 35) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 36) ci->p = p + 1;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 37) ci->end = ci->p + (p[0] >> 16);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 38) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 39) EXPORT_SYMBOL(fw_csr_iterator_init);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 40)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 41) int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 42) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 43) *key = *ci->p >> 24;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 44) *value = *ci->p & 0xffffff;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 45)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 46) return ci->p++ < ci->end;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 47) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 48) EXPORT_SYMBOL(fw_csr_iterator_next);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 49)
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 50) static const u32 *search_leaf(const u32 *directory, int search_key)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 51) {
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 52) struct fw_csr_iterator ci;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 53) int last_key = 0, key, value;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 54)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 55) fw_csr_iterator_init(&ci, directory);
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 56) while (fw_csr_iterator_next(&ci, &key, &value)) {
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 57) if (last_key == search_key &&
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 58) key == (CSR_DESCRIPTOR | CSR_LEAF))
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 59) return ci.p - 1 + value;
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 60)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 61) last_key = key;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 62) }
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 63)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 64) return NULL;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 65) }
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 66)
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 67) static int textual_leaf_to_string(const u32 *block, char *buf, size_t size)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 68) {
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 69) unsigned int quadlets, i;
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 70) char c;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 71)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 72) if (!size || !buf)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 73) return -EINVAL;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 74)
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 75) quadlets = min(block[0] >> 16, 256U);
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 76) if (quadlets < 2)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 77) return -ENODATA;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 78)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 79) if (block[1] != 0 || block[2] != 0)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 80) /* unknown language/character set */
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 81) return -ENODATA;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 82)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 83) block += 3;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 84) quadlets -= 2;
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 85) for (i = 0; i < quadlets * 4 && i < size - 1; i++) {
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 86) c = block[i / 4] >> (24 - 8 * (i % 4));
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 87) if (c == '\0')
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 88) break;
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 89) buf[i] = c;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 90) }
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 91) buf[i] = '\0';
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 92)
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 93) return i;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 94) }
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 95)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 96) /**
656b7afd40a9f drivers/firewire/core-device.c (Stefan Richter 2010-07-07 13:26:18 +0200 97) * fw_csr_string() - reads a string from the configuration ROM
656b7afd40a9f drivers/firewire/core-device.c (Stefan Richter 2010-07-07 13:26:18 +0200 98) * @directory: e.g. root directory or unit directory
656b7afd40a9f drivers/firewire/core-device.c (Stefan Richter 2010-07-07 13:26:18 +0200 99) * @key: the key of the preceding directory entry
656b7afd40a9f drivers/firewire/core-device.c (Stefan Richter 2010-07-07 13:26:18 +0200 100) * @buf: where to put the string
656b7afd40a9f drivers/firewire/core-device.c (Stefan Richter 2010-07-07 13:26:18 +0200 101) * @size: size of @buf, in bytes
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 102) *
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 103) * The string is taken from a minimal ASCII text descriptor leaf after
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 104) * the immediate entry with @key. The string is zero-terminated.
0238507b95185 drivers/firewire/core-device.c (Stefan Richter 2014-11-19 11:52:00 +0100 105) * An overlong string is silently truncated such that it and the
0238507b95185 drivers/firewire/core-device.c (Stefan Richter 2014-11-19 11:52:00 +0100 106) * zero byte fit into @size.
0238507b95185 drivers/firewire/core-device.c (Stefan Richter 2014-11-19 11:52:00 +0100 107) *
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 108) * Returns strlen(buf) or a negative error code.
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 109) */
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 110) int fw_csr_string(const u32 *directory, int key, char *buf, size_t size)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 111) {
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 112) const u32 *leaf = search_leaf(directory, key);
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 113) if (!leaf)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 114) return -ENOENT;
3c2c58cb33b3b drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:43:21 +0100 115)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 116) return textual_leaf_to_string(leaf, buf, size);
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 117) }
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 118) EXPORT_SYMBOL(fw_csr_string);
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 119)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 120) static void get_ids(const u32 *directory, int *id)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 121) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 122) struct fw_csr_iterator ci;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 123) int key, value;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 124)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 125) fw_csr_iterator_init(&ci, directory);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 126) while (fw_csr_iterator_next(&ci, &key, &value)) {
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 127) switch (key) {
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 128) case CSR_VENDOR: id[0] = value; break;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 129) case CSR_MODEL: id[1] = value; break;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 130) case CSR_SPECIFIER_ID: id[2] = value; break;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 131) case CSR_VERSION: id[3] = value; break;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 132) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 133) }
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 134) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 135)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 136) static void get_modalias_ids(struct fw_unit *unit, int *id)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 137) {
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 138) get_ids(&fw_parent_device(unit)->config_rom[5], id);
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 139) get_ids(unit->directory, id);
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 140) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 141)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 142) static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 143) {
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 144) int match = 0;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 145)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 146) if (id[0] == id_table->vendor_id)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 147) match |= IEEE1394_MATCH_VENDOR_ID;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 148) if (id[1] == id_table->model_id)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 149) match |= IEEE1394_MATCH_MODEL_ID;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 150) if (id[2] == id_table->specifier_id)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 151) match |= IEEE1394_MATCH_SPECIFIER_ID;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 152) if (id[3] == id_table->version)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 153) match |= IEEE1394_MATCH_VERSION;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 154)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 155) return (match & id_table->match_flags) == id_table->match_flags;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 156) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 157)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 158) static const struct ieee1394_device_id *unit_match(struct device *dev,
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 159) struct device_driver *drv)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 160) {
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 161) const struct ieee1394_device_id *id_table =
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 162) container_of(drv, struct fw_driver, driver)->id_table;
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 163) int id[] = {0, 0, 0, 0};
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 164)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 165) get_modalias_ids(fw_unit(dev), id);
e41f8d709c31b drivers/firewire/fw-device.c (Stefan Richter 2009-02-16 00:22:05 +0100 166)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 167) for (; id_table->match_flags != 0; id_table++)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 168) if (match_ids(id_table, id))
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 169) return id_table;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 170)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 171) return NULL;
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 172) }
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 173)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 174) static bool is_fw_unit(struct device *dev);
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 175)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 176) static int fw_unit_match(struct device *dev, struct device_driver *drv)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 177) {
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 178) /* We only allow binding to fw_units. */
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 179) return is_fw_unit(dev) && unit_match(dev, drv) != NULL;
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 180) }
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 181)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 182) static int fw_unit_probe(struct device *dev)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 183) {
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 184) struct fw_driver *driver =
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 185) container_of(dev->driver, struct fw_driver, driver);
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 186)
bcabcfd2e09ce drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 187) return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 188) }
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 189)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 190) static int fw_unit_remove(struct device *dev)
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 191) {
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 192) struct fw_driver *driver =
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 193) container_of(dev->driver, struct fw_driver, driver);
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 194)
b2c852f490e08 drivers/firewire/core-device.c (Uwe Kleine-König 2021-01-26 23:14:44 +0100 195) driver->remove(fw_unit(dev));
b2c852f490e08 drivers/firewire/core-device.c (Uwe Kleine-König 2021-01-26 23:14:44 +0100 196)
b2c852f490e08 drivers/firewire/core-device.c (Uwe Kleine-König 2021-01-26 23:14:44 +0100 197) return 0;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 198) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 199)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 200) static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 201) {
5ae73518cb39d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:38:29 +0100 202) int id[] = {0, 0, 0, 0};
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 203)
fe43d6d9cf59d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:39:07 +0100 204) get_modalias_ids(unit, id);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 205)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 206) return snprintf(buffer, buffer_size,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 207) "ieee1394:ven%08Xmo%08Xsp%08Xver%08X",
5ae73518cb39d drivers/firewire/core-device.c (Stefan Richter 2010-03-19 00:38:29 +0100 208) id[0], id[1], id[2], id[3]);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 209) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 210)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 211) static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 212) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 213) struct fw_unit *unit = fw_unit(dev);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 214) char modalias[64];
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 215)
2d826cc5c791b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-09 19:23:14 -0400 216) get_modalias(unit, modalias, sizeof(modalias));
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 217)
7eff2e7a8b65c drivers/firewire/fw-device.c (Kay Sievers 2007-08-14 15:15:12 +0200 218) if (add_uevent_var(env, "MODALIAS=%s", modalias))
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 219) return -ENOMEM;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 220)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 221) return 0;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 222) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 223)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 224) struct bus_type fw_bus_type = {
362c2c8ca4a2f drivers/firewire/fw-device.c (Kristian Høgsberg 2007-02-06 14:49:37 -0500 225) .name = "firewire",
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 226) .match = fw_unit_match,
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 227) .probe = fw_unit_probe,
94a87157cde95 drivers/firewire/core-device.c (Stefan Richter 2013-06-09 18:15:00 +0200 228) .remove = fw_unit_remove,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 229) };
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 230) EXPORT_SYMBOL(fw_bus_type);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 231)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 232) int fw_device_enable_phys_dma(struct fw_device *device)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 233) {
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 234) int generation = device->generation;
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 235)
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 236) /* device->node_id, accessed below, must not be older than generation */
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 237) smp_rmb();
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 238)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 239) return device->card->driver->enable_phys_dma(device->card,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 240) device->node_id,
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 241) generation);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 242) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 243) EXPORT_SYMBOL(fw_device_enable_phys_dma);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 244)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 245) struct config_rom_attribute {
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 246) struct device_attribute attr;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 247) u32 key;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 248) };
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 249)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 250) static ssize_t show_immediate(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 251) struct device_attribute *dattr, char *buf)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 252) {
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 253) struct config_rom_attribute *attr =
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 254) container_of(dattr, struct config_rom_attribute, attr);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 255) struct fw_csr_iterator ci;
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 256) const u32 *dir;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 257) int key, value, ret = -ENOENT;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 258)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 259) down_read(&fw_device_rwsem);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 260)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 261) if (is_fw_unit(dev))
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 262) dir = fw_unit(dev)->directory;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 263) else
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 264) dir = fw_device(dev)->config_rom + 5;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 265)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 266) fw_csr_iterator_init(&ci, dir);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 267) while (fw_csr_iterator_next(&ci, &key, &value))
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 268) if (attr->key == key) {
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 269) ret = snprintf(buf, buf ? PAGE_SIZE : 0,
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 270) "0x%06x\n", value);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 271) break;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 272) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 273)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 274) up_read(&fw_device_rwsem);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 275)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 276) return ret;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 277) }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 278)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 279) #define IMMEDIATE_ATTR(name, key) \
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 280) { __ATTR(name, S_IRUGO, show_immediate, NULL), key }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 281)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 282) static ssize_t show_text_leaf(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 283) struct device_attribute *dattr, char *buf)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 284) {
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 285) struct config_rom_attribute *attr =
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 286) container_of(dattr, struct config_rom_attribute, attr);
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 287) const u32 *dir;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 288) size_t bufsize;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 289) char dummy_buf[2];
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 290) int ret;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 291)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 292) down_read(&fw_device_rwsem);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 293)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 294) if (is_fw_unit(dev))
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 295) dir = fw_unit(dev)->directory;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 296) else
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 297) dir = fw_device(dev)->config_rom + 5;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 298)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 299) if (buf) {
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 300) bufsize = PAGE_SIZE - 1;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 301) } else {
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 302) buf = dummy_buf;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 303) bufsize = 1;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 304) }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 305)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 306) ret = fw_csr_string(dir, attr->key, buf, bufsize);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 307)
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 308) if (ret >= 0) {
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 309) /* Strip trailing whitespace and add newline. */
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 310) while (ret > 0 && isspace(buf[ret - 1]))
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 311) ret--;
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 312) strcpy(buf + ret, "\n");
1f8fef7b3388b drivers/firewire/core-device.c (Clemens Ladisch 2009-12-24 11:59:57 +0100 313) ret++;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 314) }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 315)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 316) up_read(&fw_device_rwsem);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 317)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 318) return ret;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 319) }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 320)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 321) #define TEXT_LEAF_ATTR(name, key) \
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 322) { __ATTR(name, S_IRUGO, show_text_leaf, NULL), key }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 323)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 324) static struct config_rom_attribute config_rom_attributes[] = {
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 325) IMMEDIATE_ATTR(vendor, CSR_VENDOR),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 326) IMMEDIATE_ATTR(hardware_version, CSR_HARDWARE_VERSION),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 327) IMMEDIATE_ATTR(specifier_id, CSR_SPECIFIER_ID),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 328) IMMEDIATE_ATTR(version, CSR_VERSION),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 329) IMMEDIATE_ATTR(model, CSR_MODEL),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 330) TEXT_LEAF_ATTR(vendor_name, CSR_VENDOR),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 331) TEXT_LEAF_ATTR(model_name, CSR_MODEL),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 332) TEXT_LEAF_ATTR(hardware_version_name, CSR_HARDWARE_VERSION),
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 333) };
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 334)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 335) static void init_fw_attribute_group(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 336) struct device_attribute *attrs,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 337) struct fw_attribute_group *group)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 338) {
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 339) struct device_attribute *attr;
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 340) int i, j;
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 341)
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 342) for (j = 0; attrs[j].attr.name != NULL; j++)
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 343) group->attrs[j] = &attrs[j].attr;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 344)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 345) for (i = 0; i < ARRAY_SIZE(config_rom_attributes); i++) {
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 346) attr = &config_rom_attributes[i].attr;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 347) if (attr->show(dev, attr, NULL) < 0)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 348) continue;
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 349) group->attrs[j++] = &attr->attr;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 350) }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 351)
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 352) group->attrs[j] = NULL;
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 353) group->groups[0] = &group->group;
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 354) group->groups[1] = NULL;
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 355) group->group.attrs = group->attrs;
a4dbd6740df08 drivers/firewire/core-device.c (David Brownell 2009-06-24 10:06:31 -0700 356) dev->groups = (const struct attribute_group **) group->groups;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 357) }
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 358)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 359) static ssize_t modalias_show(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 360) struct device_attribute *attr, char *buf)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 361) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 362) struct fw_unit *unit = fw_unit(dev);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 363) int length;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 364)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 365) length = get_modalias(unit, buf, PAGE_SIZE);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 366) strcpy(buf + length, "\n");
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 367)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 368) return length + 1;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 369) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 370)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 371) static ssize_t rom_index_show(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 372) struct device_attribute *attr, char *buf)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 373) {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 374) struct fw_device *device = fw_device(dev->parent);
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 375) struct fw_unit *unit = fw_unit(dev);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 376)
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 377) return snprintf(buf, PAGE_SIZE, "%d\n",
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 378) (int)(unit->directory - device->config_rom));
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 379) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 380)
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 381) static struct device_attribute fw_unit_attributes[] = {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 382) __ATTR_RO(modalias),
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 383) __ATTR_RO(rom_index),
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 384) __ATTR_NULL,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 385) };
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 386)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 387) static ssize_t config_rom_show(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 388) struct device_attribute *attr, char *buf)
048961ef90b58 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:46 -0500 389) {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 390) struct fw_device *device = fw_device(dev);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 391) size_t length;
048961ef90b58 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:46 -0500 392)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 393) down_read(&fw_device_rwsem);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 394) length = device->config_rom_length * 4;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 395) memcpy(buf, device->config_rom, length);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 396) up_read(&fw_device_rwsem);
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 397)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 398) return length;
048961ef90b58 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:46 -0500 399) }
048961ef90b58 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:46 -0500 400)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 401) static ssize_t guid_show(struct device *dev,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 402) struct device_attribute *attr, char *buf)
bbd1494580462 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:35 -0400 403) {
bbd1494580462 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:35 -0400 404) struct fw_device *device = fw_device(dev);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 405) int ret;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 406)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 407) down_read(&fw_device_rwsem);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 408) ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 409) device->config_rom[3], device->config_rom[4]);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 410) up_read(&fw_device_rwsem);
bbd1494580462 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:35 -0400 411)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 412) return ret;
bbd1494580462 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:35 -0400 413) }
bbd1494580462 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:35 -0400 414)
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 415) static ssize_t is_local_show(struct device *dev,
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 416) struct device_attribute *attr, char *buf)
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 417) {
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 418) struct fw_device *device = fw_device(dev);
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 419)
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 420) return sprintf(buf, "%u\n", device->is_local);
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 421) }
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 422)
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 423) static int units_sprintf(char *buf, const u32 *directory)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 424) {
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 425) struct fw_csr_iterator ci;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 426) int key, value;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 427) int specifier_id = 0;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 428) int version = 0;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 429)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 430) fw_csr_iterator_init(&ci, directory);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 431) while (fw_csr_iterator_next(&ci, &key, &value)) {
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 432) switch (key) {
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 433) case CSR_SPECIFIER_ID:
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 434) specifier_id = value;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 435) break;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 436) case CSR_VERSION:
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 437) version = value;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 438) break;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 439) }
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 440) }
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 441)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 442) return sprintf(buf, "0x%06x:0x%06x ", specifier_id, version);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 443) }
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 444)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 445) static ssize_t units_show(struct device *dev,
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 446) struct device_attribute *attr, char *buf)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 447) {
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 448) struct fw_device *device = fw_device(dev);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 449) struct fw_csr_iterator ci;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 450) int key, value, i = 0;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 451)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 452) down_read(&fw_device_rwsem);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 453) fw_csr_iterator_init(&ci, &device->config_rom[5]);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 454) while (fw_csr_iterator_next(&ci, &key, &value)) {
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 455) if (key != (CSR_UNIT | CSR_DIRECTORY))
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 456) continue;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 457) i += units_sprintf(&buf[i], ci.p + value - 1);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 458) if (i >= PAGE_SIZE - (8 + 1 + 8 + 1))
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 459) break;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 460) }
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 461) up_read(&fw_device_rwsem);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 462)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 463) if (i)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 464) buf[i - 1] = '\n';
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 465)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 466) return i;
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 467) }
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 468)
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 469) static struct device_attribute fw_device_attributes[] = {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 470) __ATTR_RO(config_rom),
bbd1494580462 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:35 -0400 471) __ATTR_RO(guid),
baedee177e6c5 drivers/firewire/core-device.c (Clemens Ladisch 2012-06-17 16:40:36 +0200 472) __ATTR_RO(is_local),
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 473) __ATTR_RO(units),
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 474) __ATTR_NULL,
048961ef90b58 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:46 -0500 475) };
048961ef90b58 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:46 -0500 476)
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 477) static int read_rom(struct fw_device *device,
53dca51175cc2 drivers/firewire/fw-device.c (Stefan Richter 2008-12-14 21:47:04 +0100 478) int generation, int index, u32 *data)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 479) {
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 480) u64 offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 481) int i, rcode;
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 482)
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 483) /* device->node_id, accessed below, must not be older than generation */
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 484) smp_rmb();
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 485)
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 486) for (i = 10; i < 100; i += 10) {
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 487) rcode = fw_run_transaction(device->card,
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 488) TCODE_READ_QUADLET_REQUEST, device->node_id,
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 489) generation, device->max_speed, offset, data, 4);
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 490) if (rcode != RCODE_BUSY)
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 491) break;
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 492) msleep(i);
aaff12039ffd8 drivers/firewire/core-device.c (Stefan Richter 2011-08-07 15:20:18 +0200 493) }
1e119fa9950df drivers/firewire/fw-device.c (Jay Fenlason 2008-07-20 14:20:53 +0200 494) be32_to_cpus(data);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 495)
1e119fa9950df drivers/firewire/fw-device.c (Jay Fenlason 2008-07-20 14:20:53 +0200 496) return rcode;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 497) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 498)
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 499) #define MAX_CONFIG_ROM_SIZE 256
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 500)
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 501) /*
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 502) * Read the bus info block, perform a speed probe, and read all of the rest of
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 503) * the config ROM. We do all this with a cached bus generation. If the bus
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 504) * generation changes under us, read_config_rom will fail and get retried.
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 505) * It's better to start all over in this case because the node from which we
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 506) * are reading the ROM may have changed the ROM during the reset.
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 507) * Returns either a result code or a negative error code.
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 508) */
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 509) static int read_config_rom(struct fw_device *device, int generation)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 510) {
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 511) struct fw_card *card = device->card;
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 512) const u32 *old_rom, *new_rom;
13b302d0a2175 drivers/firewire/core-device.c (Stefan Richter 2009-12-26 01:44:10 +0100 513) u32 *rom, *stack;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 514) u32 sp, key;
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 515) int i, end, length, ret;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 516)
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 517) rom = kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE +
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 518) sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL);
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 519) if (rom == NULL)
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 520) return -ENOMEM;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 521)
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 522) stack = &rom[MAX_CONFIG_ROM_SIZE];
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 523) memset(rom, 0, sizeof(*rom) * MAX_CONFIG_ROM_SIZE);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 524)
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 525) device->max_speed = SCODE_100;
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 526)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 527) /* First read the bus info block. */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 528) for (i = 0; i < 5; i++) {
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 529) ret = read_rom(device, generation, i, &rom[i]);
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 530) if (ret != RCODE_COMPLETE)
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 531) goto out;
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 532) /*
d33ec3b55e91f drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:36:39 +0200 533) * As per IEEE1212 7.2, during initialization, devices can
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 534) * reply with a 0 for the first quadlet of the config
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 535) * rom to indicate that they are booting (for example,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 536) * if the firmware is on the disk of a external
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 537) * harddisk). In that case we just fail, and the
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 538) * retry mechanism will try again later.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 539) */
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 540) if (i == 0 && rom[i] == 0) {
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 541) ret = RCODE_BUSY;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 542) goto out;
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 543) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 544) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 545)
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 546) device->max_speed = device->node->max_speed;
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 547)
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 548) /*
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 549) * Determine the speed of
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 550) * - devices with link speed less than PHY speed,
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 551) * - devices with 1394b PHY (unless only connected to 1394a PHYs),
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 552) * - all devices if there are 1394b repeaters.
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 553) * Note, we cannot use the bus info block's link_spd as starting point
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 554) * because some buggy firmwares set it lower than necessary and because
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 555) * 1394-1995 nodes do not have the field.
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 556) */
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 557) if ((rom[2] & 0x7) < device->max_speed ||
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 558) device->max_speed == SCODE_BETA ||
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 559) card->beta_repeaters_present) {
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 560) u32 dummy;
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 561)
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 562) /* for S1600 and S3200 */
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 563) if (device->max_speed == SCODE_BETA)
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 564) device->max_speed = card->link_speed;
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 565)
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 566) while (device->max_speed > SCODE_100) {
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 567) if (read_rom(device, generation, 0, &dummy) ==
f8d2dc39389d6 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 17:53:49 +0100 568) RCODE_COMPLETE)
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 569) break;
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 570) device->max_speed--;
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 571) }
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 572) }
f1397490017e3 drivers/firewire/fw-device.c (Stefan Richter 2007-06-10 21:31:36 +0200 573)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 574) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 575) * Now parse the config rom. The config rom is a recursive
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 576) * directory structure so we parse it using a stack of
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 577) * references to the blocks that make up the structure. We
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 578) * push a reference to the root directory on the stack to
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 579) * start things off.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 580) */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 581) length = i;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 582) sp = 0;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 583) stack[sp++] = 0xc0000005;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 584) while (sp > 0) {
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 585) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 586) * Pop the next block reference of the stack. The
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 587) * lower 24 bits is the offset into the config rom,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 588) * the upper 8 bits are the type of the reference the
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 589) * block.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 590) */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 591) key = stack[--sp];
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 592) i = key & 0xffffff;
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 593) if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE)) {
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 594) ret = -ENXIO;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 595) goto out;
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 596) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 597)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 598) /* Read header quadlet for the block to get the length. */
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 599) ret = read_rom(device, generation, i, &rom[i]);
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 600) if (ret != RCODE_COMPLETE)
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 601) goto out;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 602) end = i + (rom[i] >> 16) + 1;
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 603) if (end > MAX_CONFIG_ROM_SIZE) {
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 604) /*
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 605) * This block extends outside the config ROM which is
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 606) * a firmware bug. Ignore this whole block, i.e.
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 607) * simply set a fake block length of 0.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 608) */
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 609) fw_err(card, "skipped invalid ROM block %x at %llx\n",
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 610) rom[i],
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 611) i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 612) rom[i] = 0;
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 613) end = i;
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 614) }
2799d5c5f9d20 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:52:45 +0100 615) i++;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 616)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 617) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 618) * Now read in the block. If this is a directory
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 619) * block, check the entries as we read them to see if
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 620) * it references another block, and push it in that case.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 621) */
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 622) for (; i < end; i++) {
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 623) ret = read_rom(device, generation, i, &rom[i]);
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 624) if (ret != RCODE_COMPLETE)
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 625) goto out;
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 626)
58aaa5427663b drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:54:00 +0100 627) if ((key >> 30) != 3 || (rom[i] >> 30) < 2)
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 628) continue;
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 629) /*
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 630) * Offset points outside the ROM. May be a firmware
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 631) * bug or an Extended ROM entry (IEEE 1212-2001 clause
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 632) * 7.7.18). Simply overwrite this pointer here by a
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 633) * fake immediate entry so that later iterators over
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 634) * the ROM don't have to check offsets all the time.
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 635) */
fd6e0c518121d drivers/firewire/core-device.c (Stefan Richter 2010-02-19 21:00:31 +0100 636) if (i + (rom[i] & 0xffffff) >= MAX_CONFIG_ROM_SIZE) {
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 637) fw_err(card,
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 638) "skipped unsupported ROM entry %x at %llx\n",
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 639) rom[i],
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 640) i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM);
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 641) rom[i] = 0;
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 642) continue;
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 643) }
d54423c62c2f6 drivers/firewire/core-device.c (Stefan Richter 2010-02-18 01:50:31 +0100 644) stack[sp++] = i + rom[i];
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 645) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 646) if (length < i)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 647) length = i;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 648) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 649)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 650) old_rom = device->config_rom;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 651) new_rom = kmemdup(rom, length * 4, GFP_KERNEL);
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 652) if (new_rom == NULL) {
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 653) ret = -ENOMEM;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 654) goto out;
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 655) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 656)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 657) down_write(&fw_device_rwsem);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 658) device->config_rom = new_rom;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 659) device->config_rom_length = length;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 660) up_write(&fw_device_rwsem);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 661)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 662) kfree(old_rom);
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 663) ret = RCODE_COMPLETE;
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 664) device->max_rec = rom[2] >> 12 & 0xf;
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 665) device->cmc = rom[2] >> 30 & 1;
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 666) device->irmc = rom[2] >> 31 & 1;
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 667) out:
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 668) kfree(rom);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 669)
1dadff71d6356 drivers/firewire/fw-device.c (Stefan Richter 2008-03-02 19:35:42 +0100 670) return ret;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 671) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 672)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 673) static void fw_unit_release(struct device *dev)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 674) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 675) struct fw_unit *unit = fw_unit(dev);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 676)
2107622684666 drivers/firewire/core-device.c (Stefan Richter 2011-08-27 18:53:03 +0200 677) fw_device_put(fw_parent_device(unit));
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 678) kfree(unit);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 679) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 680)
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 681) static struct device_type fw_unit_type = {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 682) .uevent = fw_unit_uevent,
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 683) .release = fw_unit_release,
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 684) };
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 685)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 686) static bool is_fw_unit(struct device *dev)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 687) {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 688) return dev->type == &fw_unit_type;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 689) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 690)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 691) static void create_units(struct fw_device *device)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 692) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 693) struct fw_csr_iterator ci;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 694) struct fw_unit *unit;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 695) int key, value, i;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 696)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 697) i = 0;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 698) fw_csr_iterator_init(&ci, &device->config_rom[5]);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 699) while (fw_csr_iterator_next(&ci, &key, &value)) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 700) if (key != (CSR_UNIT | CSR_DIRECTORY))
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 701) continue;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 702)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 703) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 704) * Get the address of the unit directory and try to
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 705) * match the drivers id_tables against it.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 706) */
2d826cc5c791b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-09 19:23:14 -0400 707) unit = kzalloc(sizeof(*unit), GFP_KERNEL);
cfb0c9d1ffbf9 drivers/firewire/core-device.c (Stefan Richter 2013-03-24 17:32:00 +0100 708) if (unit == NULL)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 709) continue;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 710)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 711) unit->directory = ci.p + value - 1;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 712) unit->device.bus = &fw_bus_type;
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 713) unit->device.type = &fw_unit_type;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 714) unit->device.parent = &device->device;
a1f64819fe9f1 drivers/firewire/fw-device.c (Kay Sievers 2008-10-30 01:41:56 +0100 715) dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 716)
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 717) BUILD_BUG_ON(ARRAY_SIZE(unit->attribute_group.attrs) <
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 718) ARRAY_SIZE(fw_unit_attributes) +
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 719) ARRAY_SIZE(config_rom_attributes));
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 720) init_fw_attribute_group(&unit->device,
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 721) fw_unit_attributes,
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 722) &unit->attribute_group);
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 723)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 724) if (device_register(&unit->device) < 0)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 725) goto skip_unit;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 726)
2107622684666 drivers/firewire/core-device.c (Stefan Richter 2011-08-27 18:53:03 +0200 727) fw_device_get(device);
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 728) continue;
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 729)
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 730) skip_unit:
7feb9cce2d07b drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-21 10:55:19 -0400 731) kfree(unit);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 732) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 733) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 734)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 735) static int shutdown_unit(struct device *device, void *data)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 736) {
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 737) device_unregister(device);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 738)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 739) return 0;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 740) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 741)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 742) /*
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 743) * fw_device_rwsem acts as dual purpose mutex:
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 744) * - serializes accesses to fw_device_idr,
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 745) * - serializes accesses to fw_device.config_rom/.config_rom_length and
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 746) * fw_unit.directory, unless those accesses happen at safe occasions
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 747) */
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 748) DECLARE_RWSEM(fw_device_rwsem);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 749)
d6053e08f5520 drivers/firewire/fw-device.c (Stefan Richter 2008-11-24 20:40:00 +0100 750) DEFINE_IDR(fw_device_idr);
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 751) int fw_cdev_major;
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 752)
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 753) struct fw_device *fw_device_get_by_devt(dev_t devt)
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 754) {
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 755) struct fw_device *device;
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 756)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 757) down_read(&fw_device_rwsem);
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 758) device = idr_find(&fw_device_idr, MINOR(devt));
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 759) if (device)
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 760) fw_device_get(device);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 761) up_read(&fw_device_rwsem);
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 762)
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 763) return device;
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 764) }
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 765)
105e53f863c04 drivers/firewire/core-device.c (Stefan Richter 2011-05-01 20:50:31 +0200 766) struct workqueue_struct *fw_workqueue;
105e53f863c04 drivers/firewire/core-device.c (Stefan Richter 2011-05-01 20:50:31 +0200 767) EXPORT_SYMBOL(fw_workqueue);
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 768)
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 769) static void fw_schedule_device_work(struct fw_device *device,
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 770) unsigned long delay)
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 771) {
105e53f863c04 drivers/firewire/core-device.c (Stefan Richter 2011-05-01 20:50:31 +0200 772) queue_delayed_work(fw_workqueue, &device->work, delay);
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 773) }
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 774)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 775) /*
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 776) * These defines control the retry behavior for reading the config
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 777) * rom. It shouldn't be necessary to tweak these; if the device
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 778) * doesn't respond to a config rom read within 10 seconds, it's not
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 779) * going to respond at all. As for the initial delay, a lot of
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 780) * devices will be able to respond within half a second after bus
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 781) * reset. On the other hand, it's not really worth being more
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 782) * aggressive than that, since it scales pretty well; if 10 devices
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 783) * are plugged in, they're all getting read within one second.
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 784) */
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 785)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 786) #define MAX_RETRIES 10
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 787) #define RETRY_DELAY (3 * HZ)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 788) #define INITIAL_DELAY (HZ / 2)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 789) #define SHUTDOWN_DELAY (2 * HZ)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 790)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 791) static void fw_device_shutdown(struct work_struct *work)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 792) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 793) struct fw_device *device =
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 794) container_of(work, struct fw_device, work.work);
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 795) int minor = MINOR(device->device.devt);
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 796)
e71084af58cf1 drivers/firewire/core-device.c (Clemens Ladisch 2011-01-22 15:05:03 +0100 797) if (time_before64(get_jiffies_64(),
e71084af58cf1 drivers/firewire/core-device.c (Clemens Ladisch 2011-01-22 15:05:03 +0100 798) device->card->reset_jiffies + SHUTDOWN_DELAY)
e747a5c0be3ef drivers/firewire/fw-device.c (Stefan Richter 2009-01-24 20:35:38 +0100 799) && !list_empty(&device->card->link)) {
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 800) fw_schedule_device_work(device, SHUTDOWN_DELAY);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 801) return;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 802) }
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 803)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 804) if (atomic_cmpxchg(&device->state,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 805) FW_DEVICE_GONE,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 806) FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 807) return;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 808)
2603bf219e9be drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:48 -0500 809) fw_device_cdev_remove(device);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 810) device_for_each_child(&device->device, NULL, shutdown_unit);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 811) device_unregister(&device->device);
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 812)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 813) down_write(&fw_device_rwsem);
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 814) idr_remove(&fw_device_idr, minor);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 815) up_write(&fw_device_rwsem);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 816)
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 817) fw_device_put(device);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 818) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 819)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 820) static void fw_device_release(struct device *dev)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 821) {
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 822) struct fw_device *device = fw_device(dev);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 823) struct fw_card *card = device->card;
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 824) unsigned long flags;
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 825)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 826) /*
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 827) * Take the card lock so we don't set this to NULL while a
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 828) * FW_NODE_UPDATED callback is being handled or while the
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 829) * bus manager work looks at this node.
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 830) */
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 831) spin_lock_irqsave(&card->lock, flags);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 832) device->node->data = NULL;
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 833) spin_unlock_irqrestore(&card->lock, flags);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 834)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 835) fw_node_put(device->node);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 836) kfree(device->config_rom);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 837) kfree(device);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 838) fw_card_put(card);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 839) }
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 840)
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 841) static struct device_type fw_device_type = {
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 842) .release = fw_device_release,
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 843) };
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 844)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 845) static bool is_fw_device(struct device *dev)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 846) {
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 847) return dev->type == &fw_device_type;
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 848) }
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 849)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 850) static int update_unit(struct device *dev, void *data)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 851) {
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 852) struct fw_unit *unit = fw_unit(dev);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 853) struct fw_driver *driver = (struct fw_driver *)dev->driver;
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 854)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 855) if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
8e9394ce24122 drivers/firewire/core-device.c (Greg Kroah-Hartman 2010-02-17 10:57:05 -0800 856) device_lock(dev);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 857) driver->update(unit);
8e9394ce24122 drivers/firewire/core-device.c (Greg Kroah-Hartman 2010-02-17 10:57:05 -0800 858) device_unlock(dev);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 859) }
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 860)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 861) return 0;
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 862) }
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 863)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 864) static void fw_device_update(struct work_struct *work)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 865) {
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 866) struct fw_device *device =
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 867) container_of(work, struct fw_device, work.work);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 868)
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 869) fw_device_cdev_update(device);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 870) device_for_each_child(&device->device, NULL, update_unit);
aed808927410d drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 871) }
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 872)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 873) /*
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 874) * If a device was pending for deletion because its node went away but its
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 875) * bus info block and root directory header matches that of a newly discovered
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 876) * device, revive the existing fw_device.
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 877) * The newly allocated fw_device becomes obsolete instead.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 878) */
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 879) static int lookup_existing_device(struct device *dev, void *data)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 880) {
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 881) struct fw_device *old = fw_device(dev);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 882) struct fw_device *new = data;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 883) struct fw_card *card = new->card;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 884) int match = 0;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 885)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 886) if (!is_fw_device(dev))
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 887) return 0;
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 888)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 889) down_read(&fw_device_rwsem); /* serialize config_rom access */
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 890) spin_lock_irq(&card->lock); /* serialize node access */
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 891)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 892) if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 &&
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 893) atomic_cmpxchg(&old->state,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 894) FW_DEVICE_GONE,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 895) FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 896) struct fw_node *current_node = new->node;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 897) struct fw_node *obsolete_node = old->node;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 898)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 899) new->node = obsolete_node;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 900) new->node->data = new;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 901) old->node = current_node;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 902) old->node->data = old;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 903)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 904) old->max_speed = new->max_speed;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 905) old->node_id = current_node->node_id;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 906) smp_wmb(); /* update node_id before generation */
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 907) old->generation = card->generation;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 908) old->config_rom_retries = 0;
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 909) fw_notice(card, "rediscovered device %s\n", dev_name(dev));
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 910)
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 911) old->workfn = fw_device_update;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 912) fw_schedule_device_work(old, 0);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 913)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 914) if (current_node == card->root_node)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 915) fw_schedule_bm_work(card, 0);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 916)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 917) match = 1;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 918) }
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 919)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 920) spin_unlock_irq(&card->lock);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 921) up_read(&fw_device_rwsem);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 922)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 923) return match;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 924) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 925)
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 926) enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 927)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 928) static void set_broadcast_channel(struct fw_device *device, int generation)
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 929) {
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 930) struct fw_card *card = device->card;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 931) __be32 data;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 932) int rcode;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 933)
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 934) if (!card->broadcast_channel_allocated)
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 935) return;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 936)
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 937) /*
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 938) * The Broadcast_Channel Valid bit is required by nodes which want to
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 939) * transmit on this channel. Such transmissions are practically
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 940) * exclusive to IP over 1394 (RFC 2734). IP capable nodes are required
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 941) * to be IRM capable and have a max_rec of 8 or more. We use this fact
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 942) * to narrow down to which nodes we send Broadcast_Channel updates.
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 943) */
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 944) if (!device->irmc || device->max_rec < 8)
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 945) return;
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 946)
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 947) /*
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 948) * Some 1394-1995 nodes crash if this 1394a-2000 register is written.
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 949) * Perform a read test first.
837ec787d85fd drivers/firewire/core-device.c (Stefan Richter 2009-06-09 23:56:55 +0200 950) */
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 951) if (device->bc_implemented == BC_UNKNOWN) {
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 952) rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 953) device->node_id, generation, device->max_speed,
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 954) CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 955) &data, 4);
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 956) switch (rcode) {
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 957) case RCODE_COMPLETE:
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 958) if (data & cpu_to_be32(1 << 31)) {
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 959) device->bc_implemented = BC_IMPLEMENTED;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 960) break;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 961) }
df561f6688fef drivers/firewire/core-device.c (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 962) fallthrough; /* to case address error */
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 963) case RCODE_ADDRESS_ERROR:
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 964) device->bc_implemented = BC_UNIMPLEMENTED;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 965) }
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 966) }
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 967)
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 968) if (device->bc_implemented == BC_IMPLEMENTED) {
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 969) data = cpu_to_be32(BROADCAST_CHANNEL_INITIAL |
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 970) BROADCAST_CHANNEL_VALID);
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 971) fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 972) device->node_id, generation, device->max_speed,
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 973) CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 974) &data, 4);
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 975) }
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 976) }
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 977)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 978) int fw_device_set_broadcast_channel(struct device *dev, void *gen)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 979) {
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 980) if (is_fw_device(dev))
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 981) set_broadcast_channel(fw_device(dev), (long)gen);
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 982)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 983) return 0;
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 984) }
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 985)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 986) static void fw_device_init(struct work_struct *work)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 987) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 988) struct fw_device *device =
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 989) container_of(work, struct fw_device, work.work);
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 990) struct fw_card *card = device->card;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 991) struct device *revived_dev;
e1eff7a393d4a drivers/firewire/fw-device.c (Stefan Richter 2009-02-03 17:55:19 +0100 992) int minor, ret;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 993)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 994) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 995) * All failure paths here set node->data to NULL, so that we
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 996) * don't try to do device_for_each_child() on a kfree()'d
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 997) * device.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 998) */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 999)
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1000) ret = read_config_rom(device, device->generation);
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1001) if (ret != RCODE_COMPLETE) {
855c603d61ede drivers/firewire/fw-device.c (Stefan Richter 2008-02-27 22:14:27 +0100 1002) if (device->config_rom_retries < MAX_RETRIES &&
855c603d61ede drivers/firewire/fw-device.c (Stefan Richter 2008-02-27 22:14:27 +0100 1003) atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1004) device->config_rom_retries++;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1005) fw_schedule_device_work(device, RETRY_DELAY);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1006) } else {
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1007) if (device->node->link_on)
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1008) fw_notice(card, "giving up on node %x: reading config rom failed: %s\n",
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1009) device->node_id,
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1010) fw_rcode_string(ret));
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1011) if (device->node == card->root_node)
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1012) fw_schedule_bm_work(card, 0);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1013) fw_device_release(&device->device);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1014) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1015) return;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1016) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1017)
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1018) revived_dev = device_find_child(card->device,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1019) device, lookup_existing_device);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1020) if (revived_dev) {
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1021) put_device(revived_dev);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1022) fw_device_release(&device->device);
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1023)
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1024) return;
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1025) }
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1026)
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1027) device_initialize(&device->device);
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 1028)
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 1029) fw_device_get(device);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1030) down_write(&fw_device_rwsem);
37b61890d757f drivers/firewire/core-device.c (Tejun Heo 2013-02-27 17:04:05 -0800 1031) minor = idr_alloc(&fw_device_idr, device, 0, 1 << MINORBITS,
37b61890d757f drivers/firewire/core-device.c (Tejun Heo 2013-02-27 17:04:05 -0800 1032) GFP_KERNEL);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1033) up_write(&fw_device_rwsem);
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 1034)
37b61890d757f drivers/firewire/core-device.c (Tejun Heo 2013-02-27 17:04:05 -0800 1035) if (minor < 0)
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 1036) goto error;
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 1037)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1038) device->device.bus = &fw_bus_type;
21351dbe4e612 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-20 20:58:33 -0400 1039) device->device.type = &fw_device_type;
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1040) device->device.parent = card->device;
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 1041) device->device.devt = MKDEV(fw_cdev_major, minor);
a1f64819fe9f1 drivers/firewire/fw-device.c (Kay Sievers 2008-10-30 01:41:56 +0100 1042) dev_set_name(&device->device, "fw%d", minor);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1043)
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 1044) BUILD_BUG_ON(ARRAY_SIZE(device->attribute_group.attrs) <
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 1045) ARRAY_SIZE(fw_device_attributes) +
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 1046) ARRAY_SIZE(config_rom_attributes));
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 1047) init_fw_attribute_group(&device->device,
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 1048) fw_device_attributes,
6f2e53d5135a8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-27 19:35:13 -0400 1049) &device->attribute_group);
e5333db9285e0 drivers/firewire/fw-device.c (Stefan Richter 2009-05-22 23:16:27 +0200 1050)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1051) if (device_add(&device->device)) {
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1052) fw_err(card, "failed to add device\n");
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 1053) goto error_with_cdev;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1054) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1055)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1056) create_units(device);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1057)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1058) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1059) * Transition the device to running state. If it got pulled
183b8021fc0a5 drivers/firewire/core-device.c (Masahiro Yamada 2017-02-27 14:29:20 -0800 1060) * out from under us while we did the initialization work, we
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1061) * have to shut down the device again here. Normally, though,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1062) * fw_node_event will be responsible for shutting it down when
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1063) * necessary. We have to use the atomic cmpxchg here to avoid
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1064) * racing with the FW_NODE_DESTROYED case in
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1065) * fw_node_event().
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1066) */
641f8791f031d drivers/firewire/fw-device.c (Stefan Richter 2007-01-27 10:34:55 +0100 1067) if (atomic_cmpxchg(&device->state,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1068) FW_DEVICE_INITIALIZING,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1069) FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1070) device->workfn = fw_device_shutdown;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1071) fw_schedule_device_work(device, SHUTDOWN_DELAY);
fa6e697b85d70 drivers/firewire/fw-device.c (Stefan Richter 2008-02-03 23:03:00 +0100 1072) } else {
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1073) fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n",
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1074) dev_name(&device->device),
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1075) device->config_rom[3], device->config_rom[4],
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1076) 1 << device->max_speed);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1077) device->config_rom_retries = 0;
7889b60ee71ea drivers/firewire/fw-device.c (Stefan Richter 2009-03-10 21:09:28 +0100 1078)
099d54143e49d drivers/firewire/core-device.c (Stefan Richter 2009-06-06 18:37:25 +0200 1079) set_broadcast_channel(device, device->generation);
badfcb24891cc drivers/firewire/core-device.c (Clemens Ladisch 2012-08-13 09:08:41 +0200 1080)
badfcb24891cc drivers/firewire/core-device.c (Clemens Ladisch 2012-08-13 09:08:41 +0200 1081) add_device_randomness(&device->config_rom[3], 8);
fa6e697b85d70 drivers/firewire/fw-device.c (Stefan Richter 2008-02-03 23:03:00 +0100 1082) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1083)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1084) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1085) * Reschedule the IRM work if we just finished reading the
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1086) * root node config rom. If this races with a bus reset we
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1087) * just end up running the IRM work a couple of extra times -
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1088) * pretty harmless.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1089) */
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1090) if (device->node == card->root_node)
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1091) fw_schedule_bm_work(card, 0);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1092)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1093) return;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1094)
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 1095) error_with_cdev:
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1096) down_write(&fw_device_rwsem);
a3aca3dabbcf0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:44 -0500 1097) idr_remove(&fw_device_idr, minor);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1098) up_write(&fw_device_rwsem);
373b2edd864b8 drivers/firewire/fw-device.c (Stefan Richter 2007-03-04 14:45:18 +0100 1099) error:
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 1100) fw_device_put(device); /* fw_device_idr's reference */
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 1101)
96b19062e741b drivers/firewire/fw-device.c (Stefan Richter 2008-02-02 15:01:09 +0100 1102) put_device(&device->device); /* our reference */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1103) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1104)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1105) /* Reread and compare bus info block and header of root directory */
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1106) static int reread_config_rom(struct fw_device *device, int generation,
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1107) bool *changed)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1108) {
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1109) u32 q;
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1110) int i, rcode;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1111)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1112) for (i = 0; i < 6; i++) {
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1113) rcode = read_rom(device, generation, i, &q);
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1114) if (rcode != RCODE_COMPLETE)
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1115) return rcode;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1116)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1117) if (i == 0 && q == 0)
d33ec3b55e91f drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:36:39 +0200 1118) /* inaccessible (see read_config_rom); retry later */
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1119) return RCODE_BUSY;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1120)
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1121) if (q != device->config_rom[i]) {
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1122) *changed = true;
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1123) return RCODE_COMPLETE;
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1124) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1125) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1126)
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1127) *changed = false;
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1128) return RCODE_COMPLETE;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1129) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1130)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1131) static void fw_device_refresh(struct work_struct *work)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1132) {
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1133) struct fw_device *device =
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1134) container_of(work, struct fw_device, work.work);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1135) struct fw_card *card = device->card;
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1136) int ret, node_id = device->node_id;
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1137) bool changed;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1138)
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1139) ret = reread_config_rom(device, device->generation, &changed);
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1140) if (ret != RCODE_COMPLETE)
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1141) goto failed_config_rom;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1142)
db7494e2ce616 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:37:36 +0200 1143) if (!changed) {
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1144) if (atomic_cmpxchg(&device->state,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1145) FW_DEVICE_INITIALIZING,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1146) FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1147) goto gone;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1148)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1149) fw_device_update(work);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1150) device->config_rom_retries = 0;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1151) goto out;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1152) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1153)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1154) /*
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1155) * Something changed. We keep things simple and don't investigate
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1156) * further. We just destroy all previous units and create new ones.
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1157) */
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1158) device_for_each_child(&device->device, NULL, shutdown_unit);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1159)
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1160) ret = read_config_rom(device, device->generation);
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1161) if (ret != RCODE_COMPLETE)
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1162) goto failed_config_rom;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1163)
8b4f70ba4967c drivers/firewire/core-device.c (Stefan Richter 2010-07-07 15:36:07 +0200 1164) fw_device_cdev_update(device);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1165) create_units(device);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1166)
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 1167) /* Userspace may want to re-read attributes. */
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 1168) kobject_uevent(&device->device.kobj, KOBJ_CHANGE);
0210b66dd88a2 drivers/firewire/fw-device.c (Stefan Richter 2009-05-23 00:03:29 +0200 1169)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1170) if (atomic_cmpxchg(&device->state,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1171) FW_DEVICE_INITIALIZING,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1172) FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1173) goto gone;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1174)
26b4950de174b drivers/firewire/core-device.c (Stefan Richter 2012-02-18 22:03:14 +0100 1175) fw_notice(card, "refreshed device %s\n", dev_name(&device->device));
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1176) device->config_rom_retries = 0;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1177) goto out;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1178)
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1179) failed_config_rom:
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1180) if (device->config_rom_retries < MAX_RETRIES &&
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1181) atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1182) device->config_rom_retries++;
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1183) fw_schedule_device_work(device, RETRY_DELAY);
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1184) return;
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1185) }
8527f8e293468 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:59 +0200 1186)
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1187) fw_notice(card, "giving up on refresh of device %s: %s\n",
94fba9fbeac44 drivers/firewire/core-device.c (Clemens Ladisch 2012-04-11 17:39:19 +0200 1188) dev_name(&device->device), fw_rcode_string(ret));
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1189) gone:
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1190) atomic_set(&device->state, FW_DEVICE_GONE);
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1191) device->workfn = fw_device_shutdown;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1192) fw_schedule_device_work(device, SHUTDOWN_DELAY);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1193) out:
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1194) if (node_id == card->root_node->node_id)
0fa1986f3a6c3 drivers/firewire/fw-device.c (Jay Fenlason 2008-11-29 17:44:57 +0100 1195) fw_schedule_bm_work(card, 0);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1196) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1197)
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1198) static void fw_device_workfn(struct work_struct *work)
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1199) {
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1200) struct fw_device *device = container_of(to_delayed_work(work),
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1201) struct fw_device, work);
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1202) device->workfn(work);
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1203) }
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1204)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1205) void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1206) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1207) struct fw_device *device;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1208)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1209) switch (event) {
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1210) case FW_NODE_CREATED:
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1211) /*
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1212) * Attempt to scan the node, regardless whether its self ID has
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1213) * the L (link active) flag set or not. Some broken devices
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1214) * send L=0 but have an up-and-running link; others send L=1
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1215) * without actually having a link.
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1216) */
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1217) create:
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1218) device = kzalloc(sizeof(*device), GFP_ATOMIC);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1219) if (device == NULL)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1220) break;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1221)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1222) /*
183b8021fc0a5 drivers/firewire/core-device.c (Masahiro Yamada 2017-02-27 14:29:20 -0800 1223) * Do minimal initialization of the device here, the
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1224) * rest will happen in fw_device_init().
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1225) *
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1226) * Attention: A lot of things, even fw_device_get(),
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1227) * cannot be done before fw_device_init() finished!
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1228) * You can basically just check device->state and
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1229) * schedule work until then, but only while holding
6230582320b72 drivers/firewire/fw-device.c (Stefan Richter 2009-01-09 20:49:37 +0100 1230) * card->lock.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1231) */
641f8791f031d drivers/firewire/fw-device.c (Stefan Richter 2007-01-27 10:34:55 +0100 1232) atomic_set(&device->state, FW_DEVICE_INITIALIZING);
459f79235d8fa drivers/firewire/fw-device.c (Stefan Richter 2008-05-24 16:50:22 +0200 1233) device->card = fw_card_get(card);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1234) device->node = fw_node_get(node);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1235) device->node_id = node->node_id;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1236) device->generation = card->generation;
92368890d5517 drivers/firewire/fw-device.c (Stefan Richter 2009-05-13 21:42:14 +0200 1237) device->is_local = node == card->local_node;
d67cfb9613f37 drivers/firewire/fw-device.c (Stefan Richter 2008-10-05 10:37:11 +0200 1238) mutex_init(&device->client_list_mutex);
97bd9efa5a4d8 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:41 -0500 1239) INIT_LIST_HEAD(&device->client_list);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1240)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1241) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1242) * Set the node data to point back to this device so
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1243) * FW_NODE_UPDATED callbacks can update the node_id
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1244) * and generation for the device.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1245) */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1246) node->data = device;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1247)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1248) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1249) * Many devices are slow to respond after bus resets,
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1250) * especially if they are bus powered and go through
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1251) * power-up after getting plugged in. We schedule the
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1252) * first config rom scan half a second after bus reset.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1253) */
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1254) device->workfn = fw_device_init;
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1255) INIT_DELAYED_WORK(&device->work, fw_device_workfn);
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1256) fw_schedule_device_work(device, INITIAL_DELAY);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1257) break;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1258)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1259) case FW_NODE_INITIATED_RESET:
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1260) case FW_NODE_LINK_ON:
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1261) device = node->data;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1262) if (device == NULL)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1263) goto create;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1264)
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1265) device->node_id = node->node_id;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1266) smp_wmb(); /* update node_id before generation */
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1267) device->generation = card->generation;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1268) if (atomic_cmpxchg(&device->state,
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1269) FW_DEVICE_RUNNING,
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1270) FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1271) device->workfn = fw_device_refresh;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1272) fw_schedule_device_work(device,
92368890d5517 drivers/firewire/fw-device.c (Stefan Richter 2009-05-13 21:42:14 +0200 1273) device->is_local ? 0 : INITIAL_DELAY);
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1274) }
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1275) break;
c9755e14a0198 drivers/firewire/fw-device.c (Stefan Richter 2008-03-24 20:54:28 +0100 1276)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1277) case FW_NODE_UPDATED:
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1278) device = node->data;
115881d395959 drivers/firewire/core-device.c (Stefan Richter 2011-03-15 00:08:41 +0100 1279) if (device == NULL)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1280) break;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1281)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1282) device->node_id = node->node_id;
b5d2a5e04e6a2 drivers/firewire/fw-device.c (Stefan Richter 2008-01-25 18:57:41 +0100 1283) smp_wmb(); /* update node_id before generation */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1284) device->generation = card->generation;
5f48047756339 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:39 -0500 1285) if (atomic_read(&device->state) == FW_DEVICE_RUNNING) {
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1286) device->workfn = fw_device_update;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1287) fw_schedule_device_work(device, 0);
5f48047756339 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-03-07 12:12:39 -0500 1288) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1289) break;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1290)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1291) case FW_NODE_DESTROYED:
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1292) case FW_NODE_LINK_OFF:
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1293) if (!node->data)
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1294) break;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1295)
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1296) /*
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1297) * Destroy the device associated with the node. There
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1298) * are two cases here: either the device is fully
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1299) * initialized (FW_DEVICE_RUNNING) or we're in the
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1300) * process of reading its config rom
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1301) * (FW_DEVICE_INITIALIZING). If it is fully
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1302) * initialized we can reuse device->work to schedule a
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1303) * full fw_device_shutdown(). If not, there's work
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1304) * scheduled to read it's config rom, and we just put
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1305) * the device in shutdown state to have that code fail
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1306) * to create the device.
c781c06d119d0 drivers/firewire/fw-device.c (Kristian Høgsberg 2007-05-07 20:33:32 -0400 1307) */
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1308) device = node->data;
641f8791f031d drivers/firewire/fw-device.c (Stefan Richter 2007-01-27 10:34:55 +0100 1309) if (atomic_xchg(&device->state,
3d36a0df3b473 drivers/firewire/fw-device.c (Stefan Richter 2009-01-17 22:45:54 +0100 1310) FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
70044d71d31d6 drivers/firewire/core-device.c (Tejun Heo 2014-03-07 10:19:57 -0500 1311) device->workfn = fw_device_shutdown;
6ea9e7bbfc389 drivers/firewire/core-device.c (Stefan Richter 2010-10-13 13:39:46 +0200 1312) fw_schedule_device_work(device,
e747a5c0be3ef drivers/firewire/fw-device.c (Stefan Richter 2009-01-24 20:35:38 +0100 1313) list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1314) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1315) break;
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1316) }
19a15b937b266 drivers/firewire/fw-device.c (Kristian Høgsberg 2006-12-19 19:58:31 -0500 1317) }