diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/firewire/core-card.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/firewire/core-card.c')
-rw-r--r-- | drivers/firewire/core-card.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index be0492398ef9..29d2423fae6d 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -75,6 +75,15 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; | |||
75 | #define BIB_IRMC ((1) << 31) | 75 | #define BIB_IRMC ((1) << 31) |
76 | #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ | 76 | #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ |
77 | 77 | ||
78 | /* | ||
79 | * IEEE-1394 specifies a default SPLIT_TIMEOUT value of 800 cycles (100 ms), | ||
80 | * but we have to make it longer because there are many devices whose firmware | ||
81 | * is just too slow for that. | ||
82 | */ | ||
83 | #define DEFAULT_SPLIT_TIMEOUT (2 * 8000) | ||
84 | |||
85 | #define CANON_OUI 0x000085 | ||
86 | |||
78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) | 87 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
79 | { | 88 | { |
80 | struct fw_descriptor *desc; | 89 | struct fw_descriptor *desc; |
@@ -219,8 +228,8 @@ void fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset) | |||
219 | 228 | ||
220 | /* Use an arbitrary short delay to combine multiple reset requests. */ | 229 | /* Use an arbitrary short delay to combine multiple reset requests. */ |
221 | fw_card_get(card); | 230 | fw_card_get(card); |
222 | if (!schedule_delayed_work(&card->br_work, | 231 | if (!queue_delayed_work(fw_workqueue, &card->br_work, |
223 | delayed ? DIV_ROUND_UP(HZ, 100) : 0)) | 232 | delayed ? DIV_ROUND_UP(HZ, 100) : 0)) |
224 | fw_card_put(card); | 233 | fw_card_put(card); |
225 | } | 234 | } |
226 | EXPORT_SYMBOL(fw_schedule_bus_reset); | 235 | EXPORT_SYMBOL(fw_schedule_bus_reset); |
@@ -231,8 +240,8 @@ static void br_work(struct work_struct *work) | |||
231 | 240 | ||
232 | /* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */ | 241 | /* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */ |
233 | if (card->reset_jiffies != 0 && | 242 | if (card->reset_jiffies != 0 && |
234 | time_is_after_jiffies(card->reset_jiffies + 2 * HZ)) { | 243 | time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) { |
235 | if (!schedule_delayed_work(&card->br_work, 2 * HZ)) | 244 | if (!queue_delayed_work(fw_workqueue, &card->br_work, 2 * HZ)) |
236 | fw_card_put(card); | 245 | fw_card_put(card); |
237 | return; | 246 | return; |
238 | } | 247 | } |
@@ -249,8 +258,7 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation) | |||
249 | 258 | ||
250 | if (!card->broadcast_channel_allocated) { | 259 | if (!card->broadcast_channel_allocated) { |
251 | fw_iso_resource_manage(card, generation, 1ULL << 31, | 260 | fw_iso_resource_manage(card, generation, 1ULL << 31, |
252 | &channel, &bandwidth, true, | 261 | &channel, &bandwidth, true); |
253 | card->bm_transaction_data); | ||
254 | if (channel != 31) { | 262 | if (channel != 31) { |
255 | fw_notify("failed to allocate broadcast channel\n"); | 263 | fw_notify("failed to allocate broadcast channel\n"); |
256 | return; | 264 | return; |
@@ -284,6 +292,8 @@ static void bm_work(struct work_struct *work) | |||
284 | bool root_device_is_running; | 292 | bool root_device_is_running; |
285 | bool root_device_is_cmc; | 293 | bool root_device_is_cmc; |
286 | bool irm_is_1394_1995_only; | 294 | bool irm_is_1394_1995_only; |
295 | bool keep_this_irm; | ||
296 | __be32 transaction_data[2]; | ||
287 | 297 | ||
288 | spin_lock_irq(&card->lock); | 298 | spin_lock_irq(&card->lock); |
289 | 299 | ||
@@ -305,11 +315,16 @@ static void bm_work(struct work_struct *work) | |||
305 | irm_is_1394_1995_only = irm_device && irm_device->config_rom && | 315 | irm_is_1394_1995_only = irm_device && irm_device->config_rom && |
306 | (irm_device->config_rom[2] & 0x000000f0) == 0; | 316 | (irm_device->config_rom[2] & 0x000000f0) == 0; |
307 | 317 | ||
318 | /* Canon MV5i works unreliably if it is not root node. */ | ||
319 | keep_this_irm = irm_device && irm_device->config_rom && | ||
320 | irm_device->config_rom[3] >> 8 == CANON_OUI; | ||
321 | |||
308 | root_id = root_node->node_id; | 322 | root_id = root_node->node_id; |
309 | irm_id = card->irm_node->node_id; | 323 | irm_id = card->irm_node->node_id; |
310 | local_id = card->local_node->node_id; | 324 | local_id = card->local_node->node_id; |
311 | 325 | ||
312 | grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); | 326 | grace = time_after64(get_jiffies_64(), |
327 | card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); | ||
313 | 328 | ||
314 | if ((is_next_generation(generation, card->bm_generation) && | 329 | if ((is_next_generation(generation, card->bm_generation) && |
315 | !card->bm_abdicate) || | 330 | !card->bm_abdicate) || |
@@ -333,28 +348,28 @@ static void bm_work(struct work_struct *work) | |||
333 | goto pick_me; | 348 | goto pick_me; |
334 | } | 349 | } |
335 | 350 | ||
336 | if (irm_is_1394_1995_only) { | 351 | if (irm_is_1394_1995_only && !keep_this_irm) { |
337 | new_root_id = local_id; | 352 | new_root_id = local_id; |
338 | fw_notify("%s, making local node (%02x) root.\n", | 353 | fw_notify("%s, making local node (%02x) root.\n", |
339 | "IRM is not 1394a compliant", new_root_id); | 354 | "IRM is not 1394a compliant", new_root_id); |
340 | goto pick_me; | 355 | goto pick_me; |
341 | } | 356 | } |
342 | 357 | ||
343 | card->bm_transaction_data[0] = cpu_to_be32(0x3f); | 358 | transaction_data[0] = cpu_to_be32(0x3f); |
344 | card->bm_transaction_data[1] = cpu_to_be32(local_id); | 359 | transaction_data[1] = cpu_to_be32(local_id); |
345 | 360 | ||
346 | spin_unlock_irq(&card->lock); | 361 | spin_unlock_irq(&card->lock); |
347 | 362 | ||
348 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, | 363 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, |
349 | irm_id, generation, SCODE_100, | 364 | irm_id, generation, SCODE_100, |
350 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, | 365 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, |
351 | card->bm_transaction_data, 8); | 366 | transaction_data, 8); |
352 | 367 | ||
353 | if (rcode == RCODE_GENERATION) | 368 | if (rcode == RCODE_GENERATION) |
354 | /* Another bus reset, BM work has been rescheduled. */ | 369 | /* Another bus reset, BM work has been rescheduled. */ |
355 | goto out; | 370 | goto out; |
356 | 371 | ||
357 | bm_id = be32_to_cpu(card->bm_transaction_data[0]); | 372 | bm_id = be32_to_cpu(transaction_data[0]); |
358 | 373 | ||
359 | spin_lock_irq(&card->lock); | 374 | spin_lock_irq(&card->lock); |
360 | if (rcode == RCODE_COMPLETE && generation == card->generation) | 375 | if (rcode == RCODE_COMPLETE && generation == card->generation) |
@@ -382,7 +397,7 @@ static void bm_work(struct work_struct *work) | |||
382 | 397 | ||
383 | spin_lock_irq(&card->lock); | 398 | spin_lock_irq(&card->lock); |
384 | 399 | ||
385 | if (rcode != RCODE_COMPLETE) { | 400 | if (rcode != RCODE_COMPLETE && !keep_this_irm) { |
386 | /* | 401 | /* |
387 | * The lock request failed, maybe the IRM | 402 | * The lock request failed, maybe the IRM |
388 | * isn't really IRM capable after all. Let's | 403 | * isn't really IRM capable after all. Let's |
@@ -475,11 +490,11 @@ static void bm_work(struct work_struct *work) | |||
475 | /* | 490 | /* |
476 | * Make sure that the cycle master sends cycle start packets. | 491 | * Make sure that the cycle master sends cycle start packets. |
477 | */ | 492 | */ |
478 | card->bm_transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR); | 493 | transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR); |
479 | rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST, | 494 | rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST, |
480 | root_id, generation, SCODE_100, | 495 | root_id, generation, SCODE_100, |
481 | CSR_REGISTER_BASE + CSR_STATE_SET, | 496 | CSR_REGISTER_BASE + CSR_STATE_SET, |
482 | card->bm_transaction_data, 4); | 497 | transaction_data, 4); |
483 | if (rcode == RCODE_GENERATION) | 498 | if (rcode == RCODE_GENERATION) |
484 | goto out; | 499 | goto out; |
485 | } | 500 | } |
@@ -504,10 +519,11 @@ void fw_card_initialize(struct fw_card *card, | |||
504 | card->device = device; | 519 | card->device = device; |
505 | card->current_tlabel = 0; | 520 | card->current_tlabel = 0; |
506 | card->tlabel_mask = 0; | 521 | card->tlabel_mask = 0; |
507 | card->split_timeout_hi = 0; | 522 | card->split_timeout_hi = DEFAULT_SPLIT_TIMEOUT / 8000; |
508 | card->split_timeout_lo = 800 << 19; | 523 | card->split_timeout_lo = (DEFAULT_SPLIT_TIMEOUT % 8000) << 19; |
509 | card->split_timeout_cycles = 800; | 524 | card->split_timeout_cycles = DEFAULT_SPLIT_TIMEOUT; |
510 | card->split_timeout_jiffies = DIV_ROUND_UP(HZ, 10); | 525 | card->split_timeout_jiffies = |
526 | DIV_ROUND_UP(DEFAULT_SPLIT_TIMEOUT * HZ, 8000); | ||
511 | card->color = 0; | 527 | card->color = 0; |
512 | card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; | 528 | card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; |
513 | 529 | ||
@@ -614,6 +630,10 @@ static int dummy_queue_iso(struct fw_iso_context *ctx, struct fw_iso_packet *p, | |||
614 | return -ENODEV; | 630 | return -ENODEV; |
615 | } | 631 | } |
616 | 632 | ||
633 | static void dummy_flush_queue_iso(struct fw_iso_context *ctx) | ||
634 | { | ||
635 | } | ||
636 | |||
617 | static const struct fw_card_driver dummy_driver_template = { | 637 | static const struct fw_card_driver dummy_driver_template = { |
618 | .read_phy_reg = dummy_read_phy_reg, | 638 | .read_phy_reg = dummy_read_phy_reg, |
619 | .update_phy_reg = dummy_update_phy_reg, | 639 | .update_phy_reg = dummy_update_phy_reg, |
@@ -625,6 +645,7 @@ static const struct fw_card_driver dummy_driver_template = { | |||
625 | .start_iso = dummy_start_iso, | 645 | .start_iso = dummy_start_iso, |
626 | .set_iso_channels = dummy_set_iso_channels, | 646 | .set_iso_channels = dummy_set_iso_channels, |
627 | .queue_iso = dummy_queue_iso, | 647 | .queue_iso = dummy_queue_iso, |
648 | .flush_queue_iso = dummy_flush_queue_iso, | ||
628 | }; | 649 | }; |
629 | 650 | ||
630 | void fw_card_release(struct kref *kref) | 651 | void fw_card_release(struct kref *kref) |