Blame view
drivers/firewire/core-card.c
18.9 KB
c781c06d1 firewire: Clean u... |
1 2 |
/* * Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net> |
3038e353c firewire: Add cor... |
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
e8ca97021 firewire: clean u... |
18 |
#include <linux/bug.h> |
459f79235 firewire: clean u... |
19 20 |
#include <linux/completion.h> #include <linux/crc-itu-t.h> |
3038e353c firewire: Add cor... |
21 |
#include <linux/device.h> |
459f79235 firewire: clean u... |
22 |
#include <linux/errno.h> |
77c9a5daa firewire: reorgan... |
23 24 |
#include <linux/firewire.h> #include <linux/firewire-constants.h> |
e8ca97021 firewire: clean u... |
25 26 |
#include <linux/jiffies.h> #include <linux/kernel.h> |
459f79235 firewire: clean u... |
27 |
#include <linux/kref.h> |
e8ca97021 firewire: clean u... |
28 |
#include <linux/list.h> |
459f79235 firewire: clean u... |
29 |
#include <linux/module.h> |
6a5033be9 firewire: Convert... |
30 |
#include <linux/mutex.h> |
e8ca97021 firewire: clean u... |
31 |
#include <linux/spinlock.h> |
e8ca97021 firewire: clean u... |
32 |
#include <linux/workqueue.h> |
60063497a atomic: use <linu... |
33 |
#include <linux/atomic.h> |
e8ca97021 firewire: clean u... |
34 |
#include <asm/byteorder.h> |
459f79235 firewire: clean u... |
35 |
|
77c9a5daa firewire: reorgan... |
36 |
#include "core.h" |
3038e353c firewire: Add cor... |
37 |
|
cb7c96da3 firewire: core: o... |
38 |
int fw_compute_block_crc(__be32 *block) |
8e85973ef firewire: optimiz... |
39 40 41 42 43 44 45 46 47 48 |
{ int length; u16 crc; length = (be32_to_cpu(block[0]) >> 16) & 0xff; crc = crc_itu_t(0, (u8 *)&block[1], length * 4); *block |= cpu_to_be32(crc); return length; } |
6a5033be9 firewire: Convert... |
49 |
static DEFINE_MUTEX(card_mutex); |
3038e353c firewire: Add cor... |
50 51 52 53 |
static LIST_HEAD(card_list); static LIST_HEAD(descriptor_list); static int descriptor_count; |
fe242579e firewire: core: c... |
54 |
static __be32 tmp_config_rom[256]; |
e300839da firewire: core: a... |
55 56 |
/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */ static size_t config_rom_length = 1 + 4 + 1 + 1; |
fe242579e firewire: core: c... |
57 |
|
a77754a75 firewire: Upperca... |
58 59 60 |
#define BIB_CRC(v) ((v) << 0) #define BIB_CRC_LENGTH(v) ((v) << 16) #define BIB_INFO_LENGTH(v) ((v) << 24) |
edd5bdaf1 firewire: core: c... |
61 |
#define BIB_BUS_NAME 0x31333934 /* "1394" */ |
a77754a75 firewire: Upperca... |
62 63 64 65 66 67 68 69 70 |
#define BIB_LINK_SPEED(v) ((v) << 0) #define BIB_GENERATION(v) ((v) << 4) #define BIB_MAX_ROM(v) ((v) << 8) #define BIB_MAX_RECEIVE(v) ((v) << 12) #define BIB_CYC_CLK_ACC(v) ((v) << 16) #define BIB_PMC ((1) << 27) #define BIB_BMC ((1) << 28) #define BIB_ISC ((1) << 29) #define BIB_CMC ((1) << 30) |
edd5bdaf1 firewire: core: c... |
71 72 |
#define BIB_IRMC ((1) << 31) #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ |
3038e353c firewire: Add cor... |
73 |
|
dd5eeb99f firewire: core: i... |
74 75 76 77 78 79 |
/* * IEEE-1394 specifies a default SPLIT_TIMEOUT value of 800 cycles (100 ms), * but we have to make it longer because there are many devices whose firmware * is just too slow for that. */ #define DEFAULT_SPLIT_TIMEOUT (2 * 8000) |
6044565af firewire: core: f... |
80 |
#define CANON_OUI 0x000085 |
e300839da firewire: core: a... |
81 |
static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
3038e353c firewire: Add cor... |
82 83 |
{ struct fw_descriptor *desc; |
8e85973ef firewire: optimiz... |
84 |
int i, j, k, length; |
3038e353c firewire: Add cor... |
85 |
|
c781c06d1 firewire: Clean u... |
86 87 |
/* * Initialize contents of config rom buffer. On the OHCI |
5e20c2821 firewire: whitesp... |
88 89 90 |
* controller, block reads to the config rom accesses the host * memory, but quadlet read access the hardware bus info block * registers. That's just crack, but it means we should make |
2cc489c21 firewire: typo in... |
91 |
* sure the contents of bus info block in host memory matches |
c781c06d1 firewire: Clean u... |
92 93 |
* the version stored in the OHCI registers. */ |
3038e353c firewire: Add cor... |
94 |
|
8e85973ef firewire: optimiz... |
95 96 |
config_rom[0] = cpu_to_be32( BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); |
edd5bdaf1 firewire: core: c... |
97 |
config_rom[1] = cpu_to_be32(BIB_BUS_NAME); |
8e85973ef firewire: optimiz... |
98 |
config_rom[2] = cpu_to_be32( |
a77754a75 firewire: Upperca... |
99 100 101 102 |
BIB_LINK_SPEED(card->link_speed) | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | BIB_MAX_ROM(2) | BIB_MAX_RECEIVE(card->max_receive) | |
edd5bdaf1 firewire: core: c... |
103 |
BIB_BMC | BIB_ISC | BIB_CMC | BIB_IRMC); |
8e85973ef firewire: optimiz... |
104 105 |
config_rom[3] = cpu_to_be32(card->guid >> 32); config_rom[4] = cpu_to_be32(card->guid); |
3038e353c firewire: Add cor... |
106 107 |
/* Generate root directory. */ |
edd5bdaf1 firewire: core: c... |
108 |
config_rom[6] = cpu_to_be32(NODE_CAPABILITIES); |
8e85973ef firewire: optimiz... |
109 110 |
i = 7; j = 7 + descriptor_count; |
3038e353c firewire: Add cor... |
111 112 113 |
/* Generate root directory entries for descriptors. */ list_for_each_entry (desc, &descriptor_list, link) { |
937f68796 firewire: Let an ... |
114 |
if (desc->immediate > 0) |
8e85973ef firewire: optimiz... |
115 116 |
config_rom[i++] = cpu_to_be32(desc->immediate); config_rom[i] = cpu_to_be32(desc->key | (j - i)); |
3038e353c firewire: Add cor... |
117 118 119 120 121 |
i++; j += desc->length; } /* Update root directory length. */ |
8e85973ef firewire: optimiz... |
122 |
config_rom[5] = cpu_to_be32((i - 5 - 1) << 16); |
3038e353c firewire: Add cor... |
123 124 125 |
/* End of root directory, now copy in descriptors. */ list_for_each_entry (desc, &descriptor_list, link) { |
8e85973ef firewire: optimiz... |
126 127 |
for (k = 0; k < desc->length; k++) config_rom[i + k] = cpu_to_be32(desc->data[k]); |
3038e353c firewire: Add cor... |
128 129 130 131 132 133 134 |
i += desc->length; } /* Calculate CRCs for all blocks in the config rom. This * assumes that CRC length and info length are identical for * the bus info block, which is always the case for this * implementation. */ |
e175569c4 firewire: Use lib... |
135 |
for (i = 0; i < j; i += length + 1) |
cb7c96da3 firewire: core: o... |
136 |
length = fw_compute_block_crc(config_rom + i); |
3038e353c firewire: Add cor... |
137 |
|
e300839da firewire: core: a... |
138 |
WARN_ON(j != config_rom_length); |
3038e353c firewire: Add cor... |
139 |
} |
53dca5117 firewire: remove ... |
140 |
static void update_config_roms(void) |
3038e353c firewire: Add cor... |
141 142 |
{ struct fw_card *card; |
3038e353c firewire: Add cor... |
143 144 |
list_for_each_entry (card, &card_list, link) { |
e300839da firewire: core: a... |
145 146 147 |
generate_config_rom(card, tmp_config_rom); card->driver->set_config_rom(card, tmp_config_rom, config_rom_length); |
3038e353c firewire: Add cor... |
148 149 |
} } |
e300839da firewire: core: a... |
150 151 152 153 154 |
static size_t required_space(struct fw_descriptor *desc) { /* descriptor + entry into root dir + optional immediate entry */ return desc->length + 1 + (desc->immediate > 0 ? 1 : 0); } |
53dca5117 firewire: remove ... |
155 |
int fw_core_add_descriptor(struct fw_descriptor *desc) |
3038e353c firewire: Add cor... |
156 157 |
{ size_t i; |
e300839da firewire: core: a... |
158 |
int ret; |
3038e353c firewire: Add cor... |
159 |
|
c781c06d1 firewire: Clean u... |
160 161 |
/* * Check descriptor is valid; the length of all blocks in the |
3038e353c firewire: Add cor... |
162 |
* descriptor has to add up to exactly the length of the |
c781c06d1 firewire: Clean u... |
163 164 |
* block. */ |
3038e353c firewire: Add cor... |
165 166 167 168 169 |
i = 0; while (i < desc->length) i += (desc->data[i] >> 16) + 1; if (i != desc->length) |
66dea3e5f firewire: Add ioc... |
170 |
return -EINVAL; |
3038e353c firewire: Add cor... |
171 |
|
6a5033be9 firewire: Convert... |
172 |
mutex_lock(&card_mutex); |
3038e353c firewire: Add cor... |
173 |
|
e300839da firewire: core: a... |
174 175 176 177 178 |
if (config_rom_length + required_space(desc) > 256) { ret = -EBUSY; } else { list_add_tail(&desc->link, &descriptor_list); config_rom_length += required_space(desc); |
937f68796 firewire: Let an ... |
179 |
descriptor_count++; |
e300839da firewire: core: a... |
180 181 182 183 184 |
if (desc->immediate > 0) descriptor_count++; update_config_roms(); ret = 0; } |
3038e353c firewire: Add cor... |
185 |
|
6a5033be9 firewire: Convert... |
186 |
mutex_unlock(&card_mutex); |
3038e353c firewire: Add cor... |
187 |
|
e300839da firewire: core: a... |
188 |
return ret; |
3038e353c firewire: Add cor... |
189 |
} |
c76acec6d firewire: add IPv... |
190 |
EXPORT_SYMBOL(fw_core_add_descriptor); |
3038e353c firewire: Add cor... |
191 |
|
53dca5117 firewire: remove ... |
192 |
void fw_core_remove_descriptor(struct fw_descriptor *desc) |
3038e353c firewire: Add cor... |
193 |
{ |
6a5033be9 firewire: Convert... |
194 |
mutex_lock(&card_mutex); |
3038e353c firewire: Add cor... |
195 196 |
list_del(&desc->link); |
e300839da firewire: core: a... |
197 |
config_rom_length -= required_space(desc); |
3038e353c firewire: Add cor... |
198 |
descriptor_count--; |
937f68796 firewire: Let an ... |
199 200 |
if (desc->immediate > 0) descriptor_count--; |
3038e353c firewire: Add cor... |
201 |
update_config_roms(); |
6a5033be9 firewire: Convert... |
202 |
mutex_unlock(&card_mutex); |
3038e353c firewire: Add cor... |
203 |
} |
c76acec6d firewire: add IPv... |
204 |
EXPORT_SYMBOL(fw_core_remove_descriptor); |
3038e353c firewire: Add cor... |
205 |
|
02d37bed1 firewire: core: i... |
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
static int reset_bus(struct fw_card *card, bool short_reset) { int reg = short_reset ? 5 : 1; int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET; return card->driver->update_phy_reg(card, reg, 0, bit); } void fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset) { /* We don't try hard to sort out requests of long vs. short resets. */ card->br_short = short_reset; /* Use an arbitrary short delay to combine multiple reset requests. */ fw_card_get(card); |
105e53f86 firewire: sbp2: p... |
221 |
if (!queue_delayed_work(fw_workqueue, &card->br_work, |
6ea9e7bbf firewire: core: u... |
222 |
delayed ? DIV_ROUND_UP(HZ, 100) : 0)) |
02d37bed1 firewire: core: i... |
223 224 225 226 227 228 229 230 231 232 |
fw_card_put(card); } EXPORT_SYMBOL(fw_schedule_bus_reset); static void br_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, br_work.work); /* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */ if (card->reset_jiffies != 0 && |
e71084af5 firewire: core: f... |
233 |
time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) { |
105e53f86 firewire: sbp2: p... |
234 |
if (!queue_delayed_work(fw_workqueue, &card->br_work, 2 * HZ)) |
02d37bed1 firewire: core: i... |
235 236 237 238 239 240 241 242 243 |
fw_card_put(card); return; } fw_send_phy_config(card, FW_PHY_CONFIG_NO_NODE_ID, card->generation, FW_PHY_CONFIG_CURRENT_GAP_COUNT); reset_bus(card, card->br_short); fw_card_put(card); } |
cbae787c0 firewire: core: s... |
244 |
static void allocate_broadcast_channel(struct fw_card *card, int generation) |
6104ee92d firewire: broadca... |
245 |
{ |
cbae787c0 firewire: core: s... |
246 |
int channel, bandwidth = 0; |
e91b2787d firewire: allocat... |
247 248 |
if (!card->broadcast_channel_allocated) { fw_iso_resource_manage(card, generation, 1ULL << 31, |
f30e6d3e4 firewire: octlet ... |
249 |
&channel, &bandwidth, true); |
e91b2787d firewire: allocat... |
250 251 252 253 254 |
if (channel != 31) { fw_notify("failed to allocate broadcast channel "); return; } |
7889b60ee firewire: core: o... |
255 |
card->broadcast_channel_allocated = true; |
6104ee92d firewire: broadca... |
256 |
} |
e91b2787d firewire: allocat... |
257 258 259 |
device_for_each_child(card->device, (void *)(long)generation, fw_device_set_broadcast_channel); |
6104ee92d firewire: broadca... |
260 |
} |
6104ee92d firewire: broadca... |
261 |
|
83db801ce firewire: Impleme... |
262 263 264 |
static const char gap_count_table[] = { 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 }; |
53dca5117 firewire: remove ... |
265 |
void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) |
0fa1986f3 firewire: improve... |
266 |
{ |
0fa1986f3 firewire: improve... |
267 |
fw_card_get(card); |
02d37bed1 firewire: core: i... |
268 |
if (!schedule_delayed_work(&card->bm_work, delay)) |
0fa1986f3 firewire: improve... |
269 270 |
fw_card_put(card); } |
02d37bed1 firewire: core: i... |
271 |
static void bm_work(struct work_struct *work) |
19a15b937 firewire: Add dev... |
272 |
{ |
02d37bed1 firewire: core: i... |
273 |
struct fw_card *card = container_of(work, struct fw_card, bm_work.work); |
103895367 firewire: core: c... |
274 |
struct fw_device *root_device, *irm_device; |
cbae787c0 firewire: core: s... |
275 |
struct fw_node *root_node; |
250b2b6dd firewire: cdev: f... |
276 |
int root_id, new_root_id, irm_id, bm_id, local_id; |
cbae787c0 firewire: core: s... |
277 |
int gap_count, generation, grace, rcode; |
25b1c3d88 firewire: fix syn... |
278 |
bool do_reset = false; |
623058232 firewire: core: f... |
279 280 |
bool root_device_is_running; bool root_device_is_cmc; |
103895367 firewire: core: c... |
281 |
bool irm_is_1394_1995_only; |
6044565af firewire: core: f... |
282 |
bool keep_this_irm; |
f30e6d3e4 firewire: octlet ... |
283 |
__be32 transaction_data[2]; |
19a15b937 firewire: Add dev... |
284 |
|
ae9480110 firewire: core: n... |
285 |
spin_lock_irq(&card->lock); |
15803478f firewire: potenti... |
286 |
|
cbae787c0 firewire: core: s... |
287 |
if (card->local_node == NULL) { |
ae9480110 firewire: core: n... |
288 |
spin_unlock_irq(&card->lock); |
0fa1986f3 firewire: improve... |
289 |
goto out_put_card; |
15803478f firewire: potenti... |
290 |
} |
19a15b937 firewire: Add dev... |
291 292 |
generation = card->generation; |
103895367 firewire: core: c... |
293 |
|
cbae787c0 firewire: core: s... |
294 295 |
root_node = card->root_node; fw_node_get(root_node); |
15803478f firewire: potenti... |
296 |
root_device = root_node->data; |
623058232 firewire: core: f... |
297 298 299 |
root_device_is_running = root_device && atomic_read(&root_device->state) == FW_DEVICE_RUNNING; root_device_is_cmc = root_device && root_device->cmc; |
103895367 firewire: core: c... |
300 301 302 303 |
irm_device = card->irm_node->data; irm_is_1394_1995_only = irm_device && irm_device->config_rom && (irm_device->config_rom[2] & 0x000000f0) == 0; |
6044565af firewire: core: f... |
304 305 306 |
/* Canon MV5i works unreliably if it is not root node. */ keep_this_irm = irm_device && irm_device->config_rom && irm_device->config_rom[3] >> 8 == CANON_OUI; |
cbae787c0 firewire: core: s... |
307 308 309 |
root_id = root_node->node_id; irm_id = card->irm_node->node_id; local_id = card->local_node->node_id; |
e1dc7cab4 firewire: core: i... |
310 |
|
e71084af5 firewire: core: f... |
311 312 |
grace = time_after64(get_jiffies_64(), card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); |
e1dc7cab4 firewire: core: i... |
313 |
|
7e0e314f1 firewire: core: a... |
314 315 |
if ((is_next_generation(generation, card->bm_generation) && !card->bm_abdicate) || |
931c4834c firewire: Impleme... |
316 |
(card->bm_generation != generation && grace)) { |
c781c06d1 firewire: Clean u... |
317 318 |
/* * This first step is to figure out who is IRM and |
931c4834c firewire: Impleme... |
319 320 321 322 323 324 325 |
* then try to become bus manager. If the IRM is not * well defined (e.g. does not have an active link * layer or does not responds to our lock request, we * will have to do a little vigilante bus management. * In that case, we do a goto into the gap count logic * so that when we do the reset, we still optimize the * gap count. That could well save a reset in the |
c781c06d1 firewire: Clean u... |
326 327 |
* next generation. */ |
931c4834c firewire: Impleme... |
328 |
|
cbae787c0 firewire: core: s... |
329 330 |
if (!card->irm_node->link_on) { new_root_id = local_id; |
103895367 firewire: core: c... |
331 332 333 334 335 |
fw_notify("%s, making local node (%02x) root. ", "IRM has link off", new_root_id); goto pick_me; } |
6044565af firewire: core: f... |
336 |
if (irm_is_1394_1995_only && !keep_this_irm) { |
103895367 firewire: core: c... |
337 338 339 340 |
new_root_id = local_id; fw_notify("%s, making local node (%02x) root. ", "IRM is not 1394a compliant", new_root_id); |
931c4834c firewire: Impleme... |
341 342 |
goto pick_me; } |
f30e6d3e4 firewire: octlet ... |
343 344 |
transaction_data[0] = cpu_to_be32(0x3f); transaction_data[1] = cpu_to_be32(local_id); |
931c4834c firewire: Impleme... |
345 |
|
ae9480110 firewire: core: n... |
346 |
spin_unlock_irq(&card->lock); |
931c4834c firewire: Impleme... |
347 |
|
1e119fa99 firewire: fw_send... |
348 349 350 |
rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, irm_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, |
f30e6d3e4 firewire: octlet ... |
351 |
transaction_data, 8); |
931c4834c firewire: Impleme... |
352 |
|
1e119fa99 firewire: fw_send... |
353 354 |
if (rcode == RCODE_GENERATION) /* Another bus reset, BM work has been rescheduled. */ |
15803478f firewire: potenti... |
355 |
goto out; |
931c4834c firewire: Impleme... |
356 |
|
f30e6d3e4 firewire: octlet ... |
357 |
bm_id = be32_to_cpu(transaction_data[0]); |
cbae787c0 firewire: core: s... |
358 |
|
250b2b6dd firewire: cdev: f... |
359 360 361 362 363 |
spin_lock_irq(&card->lock); if (rcode == RCODE_COMPLETE && generation == card->generation) card->bm_node_id = bm_id == 0x3f ? local_id : 0xffc0 | bm_id; spin_unlock_irq(&card->lock); |
cbae787c0 firewire: core: s... |
364 |
|
250b2b6dd firewire: cdev: f... |
365 |
if (rcode == RCODE_COMPLETE && bm_id != 0x3f) { |
cbae787c0 firewire: core: s... |
366 367 368 |
/* Somebody else is BM. Only act as IRM. */ if (local_id == irm_id) allocate_broadcast_channel(card, generation); |
15803478f firewire: potenti... |
369 |
goto out; |
6104ee92d firewire: broadca... |
370 |
} |
931c4834c firewire: Impleme... |
371 |
|
bda3b8a1f firewire: core: r... |
372 373 374 375 376 377 378 379 380 |
if (rcode == RCODE_SEND_ERROR) { /* * We have been unable to send the lock request due to * some local problem. Let's try again later and hope * that the problem has gone away by then. */ fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8)); goto out; } |
ae9480110 firewire: core: n... |
381 |
spin_lock_irq(&card->lock); |
1e119fa99 firewire: fw_send... |
382 |
|
6044565af firewire: core: f... |
383 |
if (rcode != RCODE_COMPLETE && !keep_this_irm) { |
c781c06d1 firewire: Clean u... |
384 385 |
/* * The lock request failed, maybe the IRM |
931c4834c firewire: Impleme... |
386 387 |
* isn't really IRM capable after all. Let's * do a bus reset and pick the local node as |
c781c06d1 firewire: Clean u... |
388 389 |
* root, and thus, IRM. */ |
cbae787c0 firewire: core: s... |
390 |
new_root_id = local_id; |
103895367 firewire: core: c... |
391 392 393 |
fw_notify("%s, making local node (%02x) root. ", "BM lock failed", new_root_id); |
931c4834c firewire: Impleme... |
394 395 396 |
goto pick_me; } } else if (card->bm_generation != generation) { |
c781c06d1 firewire: Clean u... |
397 |
/* |
e1dc7cab4 firewire: core: i... |
398 399 |
* We weren't BM in the last generation, and the last * bus reset is less than 125ms ago. Reschedule this job. |
c781c06d1 firewire: Clean u... |
400 |
*/ |
ae9480110 firewire: core: n... |
401 |
spin_unlock_irq(&card->lock); |
e1dc7cab4 firewire: core: i... |
402 |
fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8)); |
15803478f firewire: potenti... |
403 |
goto out; |
931c4834c firewire: Impleme... |
404 |
} |
c781c06d1 firewire: Clean u... |
405 406 |
/* * We're bus manager for this generation, so next step is to |
931c4834c firewire: Impleme... |
407 |
* make sure we have an active cycle master and do gap count |
c781c06d1 firewire: Clean u... |
408 409 |
* optimization. */ |
931c4834c firewire: Impleme... |
410 |
card->bm_generation = generation; |
19a15b937 firewire: Add dev... |
411 |
|
15803478f firewire: potenti... |
412 |
if (root_device == NULL) { |
c781c06d1 firewire: Clean u... |
413 414 415 416 |
/* * Either link_on is false, or we failed to read the * config rom. In either case, pick another root. */ |
cbae787c0 firewire: core: s... |
417 |
new_root_id = local_id; |
623058232 firewire: core: f... |
418 |
} else if (!root_device_is_running) { |
c781c06d1 firewire: Clean u... |
419 420 421 422 |
/* * If we haven't probed this device yet, bail out now * and let's try again once that's done. */ |
ae9480110 firewire: core: n... |
423 |
spin_unlock_irq(&card->lock); |
15803478f firewire: potenti... |
424 |
goto out; |
623058232 firewire: core: f... |
425 |
} else if (root_device_is_cmc) { |
c781c06d1 firewire: Clean u... |
426 |
/* |
c374ab424 firewire: core: a... |
427 428 |
* We will send out a force root packet for this * node as part of the gap count optimization. |
c781c06d1 firewire: Clean u... |
429 |
*/ |
931c4834c firewire: Impleme... |
430 |
new_root_id = root_id; |
83db801ce firewire: Impleme... |
431 |
} else { |
c781c06d1 firewire: Clean u... |
432 433 |
/* * Current root has an active link layer and we |
19a15b937 firewire: Add dev... |
434 |
* successfully read the config rom, but it's not |
c781c06d1 firewire: Clean u... |
435 436 |
* cycle master capable. */ |
cbae787c0 firewire: core: s... |
437 |
new_root_id = local_id; |
83db801ce firewire: Impleme... |
438 |
} |
931c4834c firewire: Impleme... |
439 |
pick_me: |
24d40125f firewire: optimiz... |
440 441 442 443 444 |
/* * Pick a gap count from 1394a table E-1. The table doesn't cover * the typically much larger 1394b beta repeater delays though. */ if (!card->beta_repeaters_present && |
15803478f firewire: potenti... |
445 446 |
root_node->max_hops < ARRAY_SIZE(gap_count_table)) gap_count = gap_count_table[root_node->max_hops]; |
83db801ce firewire: Impleme... |
447 448 |
else gap_count = 63; |
c781c06d1 firewire: Clean u... |
449 |
/* |
25b1c3d88 firewire: fix syn... |
450 451 |
* Finally, figure out if we should do a reset or not. If we have * done less than 5 resets with the same physical topology and we |
c781c06d1 firewire: Clean u... |
452 453 |
* have either a new root or a new gap count setting, let's do it. */ |
19a15b937 firewire: Add dev... |
454 |
|
931c4834c firewire: Impleme... |
455 456 |
if (card->bm_retries++ < 5 && (card->gap_count != gap_count || new_root_id != root_id)) |
25b1c3d88 firewire: fix syn... |
457 |
do_reset = true; |
19a15b937 firewire: Add dev... |
458 |
|
ae9480110 firewire: core: n... |
459 |
spin_unlock_irq(&card->lock); |
19a15b937 firewire: Add dev... |
460 |
|
83db801ce firewire: Impleme... |
461 462 463 |
if (do_reset) { fw_notify("phy config: card %d, new root=%x, gap_count=%d ", |
931c4834c firewire: Impleme... |
464 465 |
card->index, new_root_id, gap_count); fw_send_phy_config(card, new_root_id, generation, gap_count); |
02d37bed1 firewire: core: i... |
466 |
reset_bus(card, true); |
cbae787c0 firewire: core: s... |
467 |
/* Will allocate broadcast channel after the reset. */ |
c374ab424 firewire: core: a... |
468 |
goto out; |
19a15b937 firewire: Add dev... |
469 |
} |
6104ee92d firewire: broadca... |
470 |
|
c374ab424 firewire: core: a... |
471 472 473 474 |
if (root_device_is_cmc) { /* * Make sure that the cycle master sends cycle start packets. */ |
f30e6d3e4 firewire: octlet ... |
475 |
transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR); |
c374ab424 firewire: core: a... |
476 477 478 |
rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST, root_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_STATE_SET, |
f30e6d3e4 firewire: octlet ... |
479 |
transaction_data, 4); |
c374ab424 firewire: core: a... |
480 481 |
if (rcode == RCODE_GENERATION) goto out; |
19a15b937 firewire: Add dev... |
482 |
} |
6104ee92d firewire: broadca... |
483 |
|
c374ab424 firewire: core: a... |
484 485 |
if (local_id == irm_id) allocate_broadcast_channel(card, generation); |
15803478f firewire: potenti... |
486 |
out: |
15803478f firewire: potenti... |
487 |
fw_node_put(root_node); |
0fa1986f3 firewire: improve... |
488 489 |
out_put_card: fw_card_put(card); |
19a15b937 firewire: Add dev... |
490 |
} |
53dca5117 firewire: remove ... |
491 492 493 |
void fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, struct device *device) |
3038e353c firewire: Add cor... |
494 |
{ |
bbf19db37 firewire: Use ato... |
495 |
static atomic_t index = ATOMIC_INIT(-1); |
3038e353c firewire: Add cor... |
496 |
|
bbf19db37 firewire: Use ato... |
497 |
card->index = atomic_inc_return(&index); |
5e20c2821 firewire: whitesp... |
498 |
card->driver = driver; |
3038e353c firewire: Add cor... |
499 |
card->device = device; |
5e20c2821 firewire: whitesp... |
500 501 |
card->current_tlabel = 0; card->tlabel_mask = 0; |
dd5eeb99f firewire: core: i... |
502 503 504 505 506 |
card->split_timeout_hi = DEFAULT_SPLIT_TIMEOUT / 8000; card->split_timeout_lo = (DEFAULT_SPLIT_TIMEOUT % 8000) << 19; card->split_timeout_cycles = DEFAULT_SPLIT_TIMEOUT; card->split_timeout_jiffies = DIV_ROUND_UP(DEFAULT_SPLIT_TIMEOUT * HZ, 8000); |
3038e353c firewire: Add cor... |
507 |
card->color = 0; |
e534fe16b firewire: impleme... |
508 |
card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; |
3038e353c firewire: Add cor... |
509 |
|
459f79235 firewire: clean u... |
510 511 |
kref_init(&card->kref); init_completion(&card->done); |
5e20c2821 firewire: whitesp... |
512 |
INIT_LIST_HEAD(&card->transaction_list); |
bf54e1462 firewire: cdev: a... |
513 |
INIT_LIST_HEAD(&card->phy_receiver_list); |
3038e353c firewire: Add cor... |
514 |
spin_lock_init(&card->lock); |
3038e353c firewire: Add cor... |
515 516 |
card->local_node = NULL; |
02d37bed1 firewire: core: i... |
517 518 |
INIT_DELAYED_WORK(&card->br_work, br_work); INIT_DELAYED_WORK(&card->bm_work, bm_work); |
3038e353c firewire: Add cor... |
519 520 |
} EXPORT_SYMBOL(fw_card_initialize); |
53dca5117 firewire: remove ... |
521 522 |
int fw_card_add(struct fw_card *card, u32 max_receive, u32 link_speed, u64 guid) |
3038e353c firewire: Add cor... |
523 |
{ |
e1eff7a39 firewire: normali... |
524 |
int ret; |
3038e353c firewire: Add cor... |
525 526 527 528 |
card->max_receive = max_receive; card->link_speed = link_speed; card->guid = guid; |
6a5033be9 firewire: Convert... |
529 |
mutex_lock(&card_mutex); |
3038e353c firewire: Add cor... |
530 |
|
e300839da firewire: core: a... |
531 532 |
generate_config_rom(card, tmp_config_rom); ret = card->driver->enable(card, tmp_config_rom, config_rom_length); |
b171e204b firewire: core: f... |
533 534 535 536 |
if (ret == 0) list_add_tail(&card->link, &card_list); mutex_unlock(&card_mutex); |
e1eff7a39 firewire: normali... |
537 538 |
return ret; |
3038e353c firewire: Add cor... |
539 540 |
} EXPORT_SYMBOL(fw_card_add); |
c781c06d1 firewire: Clean u... |
541 |
/* |
d645f4dad firewire: core: f... |
542 543 544 545 546 |
* The next few functions implement a dummy driver that is used once a card * driver shuts down an fw_card. This allows the driver to cleanly unload, * as all IO to the card will be handled (and failed) by the dummy driver * instead of calling into the module. Only functions for iso context * shutdown still need to be provided by the card driver. |
208022242 firewire: core: a... |
547 548 549 550 551 |
* * .read/write_csr() should never be called anymore after the dummy driver * was bound since they are only used within request handler context. * .set_config_rom() is never called since the card is taken out of card_list * before switching to the dummy driver. |
c781c06d1 firewire: Clean u... |
552 |
*/ |
3038e353c firewire: Add cor... |
553 |
|
02d37bed1 firewire: core: i... |
554 |
static int dummy_read_phy_reg(struct fw_card *card, int address) |
3038e353c firewire: Add cor... |
555 |
{ |
02d37bed1 firewire: core: i... |
556 |
return -ENODEV; |
3038e353c firewire: Add cor... |
557 |
} |
53dca5117 firewire: remove ... |
558 559 |
static int dummy_update_phy_reg(struct fw_card *card, int address, int clear_bits, int set_bits) |
3038e353c firewire: Add cor... |
560 561 562 |
{ return -ENODEV; } |
53dca5117 firewire: remove ... |
563 |
static void dummy_send_request(struct fw_card *card, struct fw_packet *packet) |
3038e353c firewire: Add cor... |
564 |
{ |
18d0cdfd1 firewire: normali... |
565 |
packet->callback(packet, card, RCODE_CANCELLED); |
3038e353c firewire: Add cor... |
566 |
} |
53dca5117 firewire: remove ... |
567 |
static void dummy_send_response(struct fw_card *card, struct fw_packet *packet) |
3038e353c firewire: Add cor... |
568 |
{ |
18d0cdfd1 firewire: normali... |
569 |
packet->callback(packet, card, RCODE_CANCELLED); |
3038e353c firewire: Add cor... |
570 |
} |
53dca5117 firewire: remove ... |
571 |
static int dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet) |
730c32f58 firewire: Impleme... |
572 573 574 |
{ return -ENOENT; } |
53dca5117 firewire: remove ... |
575 576 |
static int dummy_enable_phys_dma(struct fw_card *card, int node_id, int generation) |
3038e353c firewire: Add cor... |
577 578 579 |
{ return -ENODEV; } |
208022242 firewire: core: a... |
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card, int type, int channel, size_t header_size) { return ERR_PTR(-ENODEV); } static int dummy_start_iso(struct fw_iso_context *ctx, s32 cycle, u32 sync, u32 tags) { return -ENODEV; } static int dummy_set_iso_channels(struct fw_iso_context *ctx, u64 *channels) { return -ENODEV; } static int dummy_queue_iso(struct fw_iso_context *ctx, struct fw_iso_packet *p, struct fw_iso_buffer *buffer, unsigned long payload) { return -ENODEV; } |
13882a82e firewire: optimiz... |
602 603 604 |
static void dummy_flush_queue_iso(struct fw_iso_context *ctx) { } |
d645f4dad firewire: core: f... |
605 |
static const struct fw_card_driver dummy_driver_template = { |
208022242 firewire: core: a... |
606 607 608 609 610 611 612 613 614 615 |
.read_phy_reg = dummy_read_phy_reg, .update_phy_reg = dummy_update_phy_reg, .send_request = dummy_send_request, .send_response = dummy_send_response, .cancel_packet = dummy_cancel_packet, .enable_phys_dma = dummy_enable_phys_dma, .allocate_iso_context = dummy_allocate_iso_context, .start_iso = dummy_start_iso, .set_iso_channels = dummy_set_iso_channels, .queue_iso = dummy_queue_iso, |
13882a82e firewire: optimiz... |
616 |
.flush_queue_iso = dummy_flush_queue_iso, |
3038e353c firewire: Add cor... |
617 |
}; |
53dca5117 firewire: remove ... |
618 |
void fw_card_release(struct kref *kref) |
459f79235 firewire: clean u... |
619 620 621 622 623 |
{ struct fw_card *card = container_of(kref, struct fw_card, kref); complete(&card->done); } |
53dca5117 firewire: remove ... |
624 |
void fw_core_remove_card(struct fw_card *card) |
3038e353c firewire: Add cor... |
625 |
{ |
d645f4dad firewire: core: f... |
626 |
struct fw_card_driver dummy_driver = dummy_driver_template; |
ecab41335 firewire: Add phy... |
627 628 |
card->driver->update_phy_reg(card, 4, PHY_LINK_ACTIVE | PHY_CONTENDER, 0); |
02d37bed1 firewire: core: i... |
629 |
fw_schedule_bus_reset(card, false, true); |
3038e353c firewire: Add cor... |
630 |
|
6a5033be9 firewire: Convert... |
631 |
mutex_lock(&card_mutex); |
e747a5c0b firewire: core: o... |
632 |
list_del_init(&card->link); |
6a5033be9 firewire: Convert... |
633 |
mutex_unlock(&card_mutex); |
3038e353c firewire: Add cor... |
634 |
|
d645f4dad firewire: core: f... |
635 636 637 |
/* Switch off most of the card driver interface. */ dummy_driver.free_iso_context = card->driver->free_iso_context; dummy_driver.stop_iso = card->driver->stop_iso; |
3038e353c firewire: Add cor... |
638 |
card->driver = &dummy_driver; |
3038e353c firewire: Add cor... |
639 |
fw_destroy_nodes(card); |
459f79235 firewire: clean u... |
640 641 642 643 |
/* Wait for all users, especially device workqueue jobs, to finish. */ fw_card_put(card); wait_for_completion(&card->done); |
8a2d9ed32 firewire: fix unl... |
644 |
|
1e8afea12 firewire: warn on... |
645 |
WARN_ON(!list_empty(&card->transaction_list)); |
3038e353c firewire: Add cor... |
646 647 |
} EXPORT_SYMBOL(fw_core_remove_card); |