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