18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/bug.h>
78c2ecf20Sopenharmony_ci#include <linux/completion.h>
88c2ecf20Sopenharmony_ci#include <linux/crc-itu-t.h>
98c2ecf20Sopenharmony_ci#include <linux/device.h>
108c2ecf20Sopenharmony_ci#include <linux/errno.h>
118c2ecf20Sopenharmony_ci#include <linux/firewire.h>
128c2ecf20Sopenharmony_ci#include <linux/firewire-constants.h>
138c2ecf20Sopenharmony_ci#include <linux/jiffies.h>
148c2ecf20Sopenharmony_ci#include <linux/kernel.h>
158c2ecf20Sopenharmony_ci#include <linux/kref.h>
168c2ecf20Sopenharmony_ci#include <linux/list.h>
178c2ecf20Sopenharmony_ci#include <linux/module.h>
188c2ecf20Sopenharmony_ci#include <linux/mutex.h>
198c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
208c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include <linux/atomic.h>
238c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include "core.h"
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define define_fw_printk_level(func, kern_level)		\
288c2ecf20Sopenharmony_civoid func(const struct fw_card *card, const char *fmt, ...)	\
298c2ecf20Sopenharmony_ci{								\
308c2ecf20Sopenharmony_ci	struct va_format vaf;					\
318c2ecf20Sopenharmony_ci	va_list args;						\
328c2ecf20Sopenharmony_ci								\
338c2ecf20Sopenharmony_ci	va_start(args, fmt);					\
348c2ecf20Sopenharmony_ci	vaf.fmt = fmt;						\
358c2ecf20Sopenharmony_ci	vaf.va = &args;						\
368c2ecf20Sopenharmony_ci	printk(kern_level KBUILD_MODNAME " %s: %pV",		\
378c2ecf20Sopenharmony_ci	       dev_name(card->device), &vaf);			\
388c2ecf20Sopenharmony_ci	va_end(args);						\
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_cidefine_fw_printk_level(fw_err, KERN_ERR);
418c2ecf20Sopenharmony_cidefine_fw_printk_level(fw_notice, KERN_NOTICE);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciint fw_compute_block_crc(__be32 *block)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	int length;
468c2ecf20Sopenharmony_ci	u16 crc;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	length = (be32_to_cpu(block[0]) >> 16) & 0xff;
498c2ecf20Sopenharmony_ci	crc = crc_itu_t(0, (u8 *)&block[1], length * 4);
508c2ecf20Sopenharmony_ci	*block |= cpu_to_be32(crc);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	return length;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(card_mutex);
568c2ecf20Sopenharmony_cistatic LIST_HEAD(card_list);
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic LIST_HEAD(descriptor_list);
598c2ecf20Sopenharmony_cistatic int descriptor_count;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistatic __be32 tmp_config_rom[256];
628c2ecf20Sopenharmony_ci/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */
638c2ecf20Sopenharmony_cistatic size_t config_rom_length = 1 + 4 + 1 + 1;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define BIB_CRC(v)		((v) <<  0)
668c2ecf20Sopenharmony_ci#define BIB_CRC_LENGTH(v)	((v) << 16)
678c2ecf20Sopenharmony_ci#define BIB_INFO_LENGTH(v)	((v) << 24)
688c2ecf20Sopenharmony_ci#define BIB_BUS_NAME		0x31333934 /* "1394" */
698c2ecf20Sopenharmony_ci#define BIB_LINK_SPEED(v)	((v) <<  0)
708c2ecf20Sopenharmony_ci#define BIB_GENERATION(v)	((v) <<  4)
718c2ecf20Sopenharmony_ci#define BIB_MAX_ROM(v)		((v) <<  8)
728c2ecf20Sopenharmony_ci#define BIB_MAX_RECEIVE(v)	((v) << 12)
738c2ecf20Sopenharmony_ci#define BIB_CYC_CLK_ACC(v)	((v) << 16)
748c2ecf20Sopenharmony_ci#define BIB_PMC			((1) << 27)
758c2ecf20Sopenharmony_ci#define BIB_BMC			((1) << 28)
768c2ecf20Sopenharmony_ci#define BIB_ISC			((1) << 29)
778c2ecf20Sopenharmony_ci#define BIB_CMC			((1) << 30)
788c2ecf20Sopenharmony_ci#define BIB_IRMC		((1) << 31)
798c2ecf20Sopenharmony_ci#define NODE_CAPABILITIES	0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/*
828c2ecf20Sopenharmony_ci * IEEE-1394 specifies a default SPLIT_TIMEOUT value of 800 cycles (100 ms),
838c2ecf20Sopenharmony_ci * but we have to make it longer because there are many devices whose firmware
848c2ecf20Sopenharmony_ci * is just too slow for that.
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_ci#define DEFAULT_SPLIT_TIMEOUT	(2 * 8000)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#define CANON_OUI		0x000085
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic void generate_config_rom(struct fw_card *card, __be32 *config_rom)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	struct fw_descriptor *desc;
938c2ecf20Sopenharmony_ci	int i, j, k, length;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	/*
968c2ecf20Sopenharmony_ci	 * Initialize contents of config rom buffer.  On the OHCI
978c2ecf20Sopenharmony_ci	 * controller, block reads to the config rom accesses the host
988c2ecf20Sopenharmony_ci	 * memory, but quadlet read access the hardware bus info block
998c2ecf20Sopenharmony_ci	 * registers.  That's just crack, but it means we should make
1008c2ecf20Sopenharmony_ci	 * sure the contents of bus info block in host memory matches
1018c2ecf20Sopenharmony_ci	 * the version stored in the OHCI registers.
1028c2ecf20Sopenharmony_ci	 */
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	config_rom[0] = cpu_to_be32(
1058c2ecf20Sopenharmony_ci		BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0));
1068c2ecf20Sopenharmony_ci	config_rom[1] = cpu_to_be32(BIB_BUS_NAME);
1078c2ecf20Sopenharmony_ci	config_rom[2] = cpu_to_be32(
1088c2ecf20Sopenharmony_ci		BIB_LINK_SPEED(card->link_speed) |
1098c2ecf20Sopenharmony_ci		BIB_GENERATION(card->config_rom_generation++ % 14 + 2) |
1108c2ecf20Sopenharmony_ci		BIB_MAX_ROM(2) |
1118c2ecf20Sopenharmony_ci		BIB_MAX_RECEIVE(card->max_receive) |
1128c2ecf20Sopenharmony_ci		BIB_BMC | BIB_ISC | BIB_CMC | BIB_IRMC);
1138c2ecf20Sopenharmony_ci	config_rom[3] = cpu_to_be32(card->guid >> 32);
1148c2ecf20Sopenharmony_ci	config_rom[4] = cpu_to_be32(card->guid);
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	/* Generate root directory. */
1178c2ecf20Sopenharmony_ci	config_rom[6] = cpu_to_be32(NODE_CAPABILITIES);
1188c2ecf20Sopenharmony_ci	i = 7;
1198c2ecf20Sopenharmony_ci	j = 7 + descriptor_count;
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/* Generate root directory entries for descriptors. */
1228c2ecf20Sopenharmony_ci	list_for_each_entry (desc, &descriptor_list, link) {
1238c2ecf20Sopenharmony_ci		if (desc->immediate > 0)
1248c2ecf20Sopenharmony_ci			config_rom[i++] = cpu_to_be32(desc->immediate);
1258c2ecf20Sopenharmony_ci		config_rom[i] = cpu_to_be32(desc->key | (j - i));
1268c2ecf20Sopenharmony_ci		i++;
1278c2ecf20Sopenharmony_ci		j += desc->length;
1288c2ecf20Sopenharmony_ci	}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* Update root directory length. */
1318c2ecf20Sopenharmony_ci	config_rom[5] = cpu_to_be32((i - 5 - 1) << 16);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	/* End of root directory, now copy in descriptors. */
1348c2ecf20Sopenharmony_ci	list_for_each_entry (desc, &descriptor_list, link) {
1358c2ecf20Sopenharmony_ci		for (k = 0; k < desc->length; k++)
1368c2ecf20Sopenharmony_ci			config_rom[i + k] = cpu_to_be32(desc->data[k]);
1378c2ecf20Sopenharmony_ci		i += desc->length;
1388c2ecf20Sopenharmony_ci	}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	/* Calculate CRCs for all blocks in the config rom.  This
1418c2ecf20Sopenharmony_ci	 * assumes that CRC length and info length are identical for
1428c2ecf20Sopenharmony_ci	 * the bus info block, which is always the case for this
1438c2ecf20Sopenharmony_ci	 * implementation. */
1448c2ecf20Sopenharmony_ci	for (i = 0; i < j; i += length + 1)
1458c2ecf20Sopenharmony_ci		length = fw_compute_block_crc(config_rom + i);
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	WARN_ON(j != config_rom_length);
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic void update_config_roms(void)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	struct fw_card *card;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	list_for_each_entry (card, &card_list, link) {
1558c2ecf20Sopenharmony_ci		generate_config_rom(card, tmp_config_rom);
1568c2ecf20Sopenharmony_ci		card->driver->set_config_rom(card, tmp_config_rom,
1578c2ecf20Sopenharmony_ci					     config_rom_length);
1588c2ecf20Sopenharmony_ci	}
1598c2ecf20Sopenharmony_ci}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_cistatic size_t required_space(struct fw_descriptor *desc)
1628c2ecf20Sopenharmony_ci{
1638c2ecf20Sopenharmony_ci	/* descriptor + entry into root dir + optional immediate entry */
1648c2ecf20Sopenharmony_ci	return desc->length + 1 + (desc->immediate > 0 ? 1 : 0);
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ciint fw_core_add_descriptor(struct fw_descriptor *desc)
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	size_t i;
1708c2ecf20Sopenharmony_ci	int ret;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/*
1738c2ecf20Sopenharmony_ci	 * Check descriptor is valid; the length of all blocks in the
1748c2ecf20Sopenharmony_ci	 * descriptor has to add up to exactly the length of the
1758c2ecf20Sopenharmony_ci	 * block.
1768c2ecf20Sopenharmony_ci	 */
1778c2ecf20Sopenharmony_ci	i = 0;
1788c2ecf20Sopenharmony_ci	while (i < desc->length)
1798c2ecf20Sopenharmony_ci		i += (desc->data[i] >> 16) + 1;
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	if (i != desc->length)
1828c2ecf20Sopenharmony_ci		return -EINVAL;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	mutex_lock(&card_mutex);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	if (config_rom_length + required_space(desc) > 256) {
1878c2ecf20Sopenharmony_ci		ret = -EBUSY;
1888c2ecf20Sopenharmony_ci	} else {
1898c2ecf20Sopenharmony_ci		list_add_tail(&desc->link, &descriptor_list);
1908c2ecf20Sopenharmony_ci		config_rom_length += required_space(desc);
1918c2ecf20Sopenharmony_ci		descriptor_count++;
1928c2ecf20Sopenharmony_ci		if (desc->immediate > 0)
1938c2ecf20Sopenharmony_ci			descriptor_count++;
1948c2ecf20Sopenharmony_ci		update_config_roms();
1958c2ecf20Sopenharmony_ci		ret = 0;
1968c2ecf20Sopenharmony_ci	}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	mutex_unlock(&card_mutex);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	return ret;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fw_core_add_descriptor);
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_civoid fw_core_remove_descriptor(struct fw_descriptor *desc)
2058c2ecf20Sopenharmony_ci{
2068c2ecf20Sopenharmony_ci	mutex_lock(&card_mutex);
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	list_del(&desc->link);
2098c2ecf20Sopenharmony_ci	config_rom_length -= required_space(desc);
2108c2ecf20Sopenharmony_ci	descriptor_count--;
2118c2ecf20Sopenharmony_ci	if (desc->immediate > 0)
2128c2ecf20Sopenharmony_ci		descriptor_count--;
2138c2ecf20Sopenharmony_ci	update_config_roms();
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	mutex_unlock(&card_mutex);
2168c2ecf20Sopenharmony_ci}
2178c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fw_core_remove_descriptor);
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_cistatic int reset_bus(struct fw_card *card, bool short_reset)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	int reg = short_reset ? 5 : 1;
2228c2ecf20Sopenharmony_ci	int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET;
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	return card->driver->update_phy_reg(card, reg, 0, bit);
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_civoid fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset)
2288c2ecf20Sopenharmony_ci{
2298c2ecf20Sopenharmony_ci	/* We don't try hard to sort out requests of long vs. short resets. */
2308c2ecf20Sopenharmony_ci	card->br_short = short_reset;
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	/* Use an arbitrary short delay to combine multiple reset requests. */
2338c2ecf20Sopenharmony_ci	fw_card_get(card);
2348c2ecf20Sopenharmony_ci	if (!queue_delayed_work(fw_workqueue, &card->br_work,
2358c2ecf20Sopenharmony_ci				delayed ? DIV_ROUND_UP(HZ, 100) : 0))
2368c2ecf20Sopenharmony_ci		fw_card_put(card);
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fw_schedule_bus_reset);
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_cistatic void br_work(struct work_struct *work)
2418c2ecf20Sopenharmony_ci{
2428c2ecf20Sopenharmony_ci	struct fw_card *card = container_of(work, struct fw_card, br_work.work);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	/* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */
2458c2ecf20Sopenharmony_ci	if (card->reset_jiffies != 0 &&
2468c2ecf20Sopenharmony_ci	    time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) {
2478c2ecf20Sopenharmony_ci		if (!queue_delayed_work(fw_workqueue, &card->br_work, 2 * HZ))
2488c2ecf20Sopenharmony_ci			fw_card_put(card);
2498c2ecf20Sopenharmony_ci		return;
2508c2ecf20Sopenharmony_ci	}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	fw_send_phy_config(card, FW_PHY_CONFIG_NO_NODE_ID, card->generation,
2538c2ecf20Sopenharmony_ci			   FW_PHY_CONFIG_CURRENT_GAP_COUNT);
2548c2ecf20Sopenharmony_ci	reset_bus(card, card->br_short);
2558c2ecf20Sopenharmony_ci	fw_card_put(card);
2568c2ecf20Sopenharmony_ci}
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_cistatic void allocate_broadcast_channel(struct fw_card *card, int generation)
2598c2ecf20Sopenharmony_ci{
2608c2ecf20Sopenharmony_ci	int channel, bandwidth = 0;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	if (!card->broadcast_channel_allocated) {
2638c2ecf20Sopenharmony_ci		fw_iso_resource_manage(card, generation, 1ULL << 31,
2648c2ecf20Sopenharmony_ci				       &channel, &bandwidth, true);
2658c2ecf20Sopenharmony_ci		if (channel != 31) {
2668c2ecf20Sopenharmony_ci			fw_notice(card, "failed to allocate broadcast channel\n");
2678c2ecf20Sopenharmony_ci			return;
2688c2ecf20Sopenharmony_ci		}
2698c2ecf20Sopenharmony_ci		card->broadcast_channel_allocated = true;
2708c2ecf20Sopenharmony_ci	}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	device_for_each_child(card->device, (void *)(long)generation,
2738c2ecf20Sopenharmony_ci			      fw_device_set_broadcast_channel);
2748c2ecf20Sopenharmony_ci}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_cistatic const char gap_count_table[] = {
2778c2ecf20Sopenharmony_ci	63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
2788c2ecf20Sopenharmony_ci};
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_civoid fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	fw_card_get(card);
2838c2ecf20Sopenharmony_ci	if (!schedule_delayed_work(&card->bm_work, delay))
2848c2ecf20Sopenharmony_ci		fw_card_put(card);
2858c2ecf20Sopenharmony_ci}
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_cistatic void bm_work(struct work_struct *work)
2888c2ecf20Sopenharmony_ci{
2898c2ecf20Sopenharmony_ci	struct fw_card *card = container_of(work, struct fw_card, bm_work.work);
2908c2ecf20Sopenharmony_ci	struct fw_device *root_device, *irm_device;
2918c2ecf20Sopenharmony_ci	struct fw_node *root_node;
2928c2ecf20Sopenharmony_ci	int root_id, new_root_id, irm_id, bm_id, local_id;
2938c2ecf20Sopenharmony_ci	int gap_count, generation, grace, rcode;
2948c2ecf20Sopenharmony_ci	bool do_reset = false;
2958c2ecf20Sopenharmony_ci	bool root_device_is_running;
2968c2ecf20Sopenharmony_ci	bool root_device_is_cmc;
2978c2ecf20Sopenharmony_ci	bool irm_is_1394_1995_only;
2988c2ecf20Sopenharmony_ci	bool keep_this_irm;
2998c2ecf20Sopenharmony_ci	__be32 transaction_data[2];
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	spin_lock_irq(&card->lock);
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	if (card->local_node == NULL) {
3048c2ecf20Sopenharmony_ci		spin_unlock_irq(&card->lock);
3058c2ecf20Sopenharmony_ci		goto out_put_card;
3068c2ecf20Sopenharmony_ci	}
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	generation = card->generation;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	root_node = card->root_node;
3118c2ecf20Sopenharmony_ci	fw_node_get(root_node);
3128c2ecf20Sopenharmony_ci	root_device = root_node->data;
3138c2ecf20Sopenharmony_ci	root_device_is_running = root_device &&
3148c2ecf20Sopenharmony_ci			atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
3158c2ecf20Sopenharmony_ci	root_device_is_cmc = root_device && root_device->cmc;
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	irm_device = card->irm_node->data;
3188c2ecf20Sopenharmony_ci	irm_is_1394_1995_only = irm_device && irm_device->config_rom &&
3198c2ecf20Sopenharmony_ci			(irm_device->config_rom[2] & 0x000000f0) == 0;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	/* Canon MV5i works unreliably if it is not root node. */
3228c2ecf20Sopenharmony_ci	keep_this_irm = irm_device && irm_device->config_rom &&
3238c2ecf20Sopenharmony_ci			irm_device->config_rom[3] >> 8 == CANON_OUI;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	root_id  = root_node->node_id;
3268c2ecf20Sopenharmony_ci	irm_id   = card->irm_node->node_id;
3278c2ecf20Sopenharmony_ci	local_id = card->local_node->node_id;
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	grace = time_after64(get_jiffies_64(),
3308c2ecf20Sopenharmony_ci			     card->reset_jiffies + DIV_ROUND_UP(HZ, 8));
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	if ((is_next_generation(generation, card->bm_generation) &&
3338c2ecf20Sopenharmony_ci	     !card->bm_abdicate) ||
3348c2ecf20Sopenharmony_ci	    (card->bm_generation != generation && grace)) {
3358c2ecf20Sopenharmony_ci		/*
3368c2ecf20Sopenharmony_ci		 * This first step is to figure out who is IRM and
3378c2ecf20Sopenharmony_ci		 * then try to become bus manager.  If the IRM is not
3388c2ecf20Sopenharmony_ci		 * well defined (e.g. does not have an active link
3398c2ecf20Sopenharmony_ci		 * layer or does not responds to our lock request, we
3408c2ecf20Sopenharmony_ci		 * will have to do a little vigilante bus management.
3418c2ecf20Sopenharmony_ci		 * In that case, we do a goto into the gap count logic
3428c2ecf20Sopenharmony_ci		 * so that when we do the reset, we still optimize the
3438c2ecf20Sopenharmony_ci		 * gap count.  That could well save a reset in the
3448c2ecf20Sopenharmony_ci		 * next generation.
3458c2ecf20Sopenharmony_ci		 */
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci		if (!card->irm_node->link_on) {
3488c2ecf20Sopenharmony_ci			new_root_id = local_id;
3498c2ecf20Sopenharmony_ci			fw_notice(card, "%s, making local node (%02x) root\n",
3508c2ecf20Sopenharmony_ci				  "IRM has link off", new_root_id);
3518c2ecf20Sopenharmony_ci			goto pick_me;
3528c2ecf20Sopenharmony_ci		}
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci		if (irm_is_1394_1995_only && !keep_this_irm) {
3558c2ecf20Sopenharmony_ci			new_root_id = local_id;
3568c2ecf20Sopenharmony_ci			fw_notice(card, "%s, making local node (%02x) root\n",
3578c2ecf20Sopenharmony_ci				  "IRM is not 1394a compliant", new_root_id);
3588c2ecf20Sopenharmony_ci			goto pick_me;
3598c2ecf20Sopenharmony_ci		}
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci		transaction_data[0] = cpu_to_be32(0x3f);
3628c2ecf20Sopenharmony_ci		transaction_data[1] = cpu_to_be32(local_id);
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci		spin_unlock_irq(&card->lock);
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci		rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
3678c2ecf20Sopenharmony_ci				irm_id, generation, SCODE_100,
3688c2ecf20Sopenharmony_ci				CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
3698c2ecf20Sopenharmony_ci				transaction_data, 8);
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci		if (rcode == RCODE_GENERATION)
3728c2ecf20Sopenharmony_ci			/* Another bus reset, BM work has been rescheduled. */
3738c2ecf20Sopenharmony_ci			goto out;
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci		bm_id = be32_to_cpu(transaction_data[0]);
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci		spin_lock_irq(&card->lock);
3788c2ecf20Sopenharmony_ci		if (rcode == RCODE_COMPLETE && generation == card->generation)
3798c2ecf20Sopenharmony_ci			card->bm_node_id =
3808c2ecf20Sopenharmony_ci			    bm_id == 0x3f ? local_id : 0xffc0 | bm_id;
3818c2ecf20Sopenharmony_ci		spin_unlock_irq(&card->lock);
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci		if (rcode == RCODE_COMPLETE && bm_id != 0x3f) {
3848c2ecf20Sopenharmony_ci			/* Somebody else is BM.  Only act as IRM. */
3858c2ecf20Sopenharmony_ci			if (local_id == irm_id)
3868c2ecf20Sopenharmony_ci				allocate_broadcast_channel(card, generation);
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci			goto out;
3898c2ecf20Sopenharmony_ci		}
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci		if (rcode == RCODE_SEND_ERROR) {
3928c2ecf20Sopenharmony_ci			/*
3938c2ecf20Sopenharmony_ci			 * We have been unable to send the lock request due to
3948c2ecf20Sopenharmony_ci			 * some local problem.  Let's try again later and hope
3958c2ecf20Sopenharmony_ci			 * that the problem has gone away by then.
3968c2ecf20Sopenharmony_ci			 */
3978c2ecf20Sopenharmony_ci			fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8));
3988c2ecf20Sopenharmony_ci			goto out;
3998c2ecf20Sopenharmony_ci		}
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci		spin_lock_irq(&card->lock);
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci		if (rcode != RCODE_COMPLETE && !keep_this_irm) {
4048c2ecf20Sopenharmony_ci			/*
4058c2ecf20Sopenharmony_ci			 * The lock request failed, maybe the IRM
4068c2ecf20Sopenharmony_ci			 * isn't really IRM capable after all. Let's
4078c2ecf20Sopenharmony_ci			 * do a bus reset and pick the local node as
4088c2ecf20Sopenharmony_ci			 * root, and thus, IRM.
4098c2ecf20Sopenharmony_ci			 */
4108c2ecf20Sopenharmony_ci			new_root_id = local_id;
4118c2ecf20Sopenharmony_ci			fw_notice(card, "BM lock failed (%s), making local node (%02x) root\n",
4128c2ecf20Sopenharmony_ci				  fw_rcode_string(rcode), new_root_id);
4138c2ecf20Sopenharmony_ci			goto pick_me;
4148c2ecf20Sopenharmony_ci		}
4158c2ecf20Sopenharmony_ci	} else if (card->bm_generation != generation) {
4168c2ecf20Sopenharmony_ci		/*
4178c2ecf20Sopenharmony_ci		 * We weren't BM in the last generation, and the last
4188c2ecf20Sopenharmony_ci		 * bus reset is less than 125ms ago.  Reschedule this job.
4198c2ecf20Sopenharmony_ci		 */
4208c2ecf20Sopenharmony_ci		spin_unlock_irq(&card->lock);
4218c2ecf20Sopenharmony_ci		fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8));
4228c2ecf20Sopenharmony_ci		goto out;
4238c2ecf20Sopenharmony_ci	}
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	/*
4268c2ecf20Sopenharmony_ci	 * We're bus manager for this generation, so next step is to
4278c2ecf20Sopenharmony_ci	 * make sure we have an active cycle master and do gap count
4288c2ecf20Sopenharmony_ci	 * optimization.
4298c2ecf20Sopenharmony_ci	 */
4308c2ecf20Sopenharmony_ci	card->bm_generation = generation;
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_ci	if (root_device == NULL) {
4338c2ecf20Sopenharmony_ci		/*
4348c2ecf20Sopenharmony_ci		 * Either link_on is false, or we failed to read the
4358c2ecf20Sopenharmony_ci		 * config rom.  In either case, pick another root.
4368c2ecf20Sopenharmony_ci		 */
4378c2ecf20Sopenharmony_ci		new_root_id = local_id;
4388c2ecf20Sopenharmony_ci	} else if (!root_device_is_running) {
4398c2ecf20Sopenharmony_ci		/*
4408c2ecf20Sopenharmony_ci		 * If we haven't probed this device yet, bail out now
4418c2ecf20Sopenharmony_ci		 * and let's try again once that's done.
4428c2ecf20Sopenharmony_ci		 */
4438c2ecf20Sopenharmony_ci		spin_unlock_irq(&card->lock);
4448c2ecf20Sopenharmony_ci		goto out;
4458c2ecf20Sopenharmony_ci	} else if (root_device_is_cmc) {
4468c2ecf20Sopenharmony_ci		/*
4478c2ecf20Sopenharmony_ci		 * We will send out a force root packet for this
4488c2ecf20Sopenharmony_ci		 * node as part of the gap count optimization.
4498c2ecf20Sopenharmony_ci		 */
4508c2ecf20Sopenharmony_ci		new_root_id = root_id;
4518c2ecf20Sopenharmony_ci	} else {
4528c2ecf20Sopenharmony_ci		/*
4538c2ecf20Sopenharmony_ci		 * Current root has an active link layer and we
4548c2ecf20Sopenharmony_ci		 * successfully read the config rom, but it's not
4558c2ecf20Sopenharmony_ci		 * cycle master capable.
4568c2ecf20Sopenharmony_ci		 */
4578c2ecf20Sopenharmony_ci		new_root_id = local_id;
4588c2ecf20Sopenharmony_ci	}
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci pick_me:
4618c2ecf20Sopenharmony_ci	/*
4628c2ecf20Sopenharmony_ci	 * Pick a gap count from 1394a table E-1.  The table doesn't cover
4638c2ecf20Sopenharmony_ci	 * the typically much larger 1394b beta repeater delays though.
4648c2ecf20Sopenharmony_ci	 */
4658c2ecf20Sopenharmony_ci	if (!card->beta_repeaters_present &&
4668c2ecf20Sopenharmony_ci	    root_node->max_hops < ARRAY_SIZE(gap_count_table))
4678c2ecf20Sopenharmony_ci		gap_count = gap_count_table[root_node->max_hops];
4688c2ecf20Sopenharmony_ci	else
4698c2ecf20Sopenharmony_ci		gap_count = 63;
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_ci	/*
4728c2ecf20Sopenharmony_ci	 * Finally, figure out if we should do a reset or not.  If we have
4738c2ecf20Sopenharmony_ci	 * done less than 5 resets with the same physical topology and we
4748c2ecf20Sopenharmony_ci	 * have either a new root or a new gap count setting, let's do it.
4758c2ecf20Sopenharmony_ci	 */
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci	if (card->bm_retries++ < 5 &&
4788c2ecf20Sopenharmony_ci	    (card->gap_count != gap_count || new_root_id != root_id))
4798c2ecf20Sopenharmony_ci		do_reset = true;
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	spin_unlock_irq(&card->lock);
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci	if (do_reset) {
4848c2ecf20Sopenharmony_ci		fw_notice(card, "phy config: new root=%x, gap_count=%d\n",
4858c2ecf20Sopenharmony_ci			  new_root_id, gap_count);
4868c2ecf20Sopenharmony_ci		fw_send_phy_config(card, new_root_id, generation, gap_count);
4878c2ecf20Sopenharmony_ci		reset_bus(card, true);
4888c2ecf20Sopenharmony_ci		/* Will allocate broadcast channel after the reset. */
4898c2ecf20Sopenharmony_ci		goto out;
4908c2ecf20Sopenharmony_ci	}
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_ci	if (root_device_is_cmc) {
4938c2ecf20Sopenharmony_ci		/*
4948c2ecf20Sopenharmony_ci		 * Make sure that the cycle master sends cycle start packets.
4958c2ecf20Sopenharmony_ci		 */
4968c2ecf20Sopenharmony_ci		transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
4978c2ecf20Sopenharmony_ci		rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
4988c2ecf20Sopenharmony_ci				root_id, generation, SCODE_100,
4998c2ecf20Sopenharmony_ci				CSR_REGISTER_BASE + CSR_STATE_SET,
5008c2ecf20Sopenharmony_ci				transaction_data, 4);
5018c2ecf20Sopenharmony_ci		if (rcode == RCODE_GENERATION)
5028c2ecf20Sopenharmony_ci			goto out;
5038c2ecf20Sopenharmony_ci	}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	if (local_id == irm_id)
5068c2ecf20Sopenharmony_ci		allocate_broadcast_channel(card, generation);
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci out:
5098c2ecf20Sopenharmony_ci	fw_node_put(root_node);
5108c2ecf20Sopenharmony_ci out_put_card:
5118c2ecf20Sopenharmony_ci	fw_card_put(card);
5128c2ecf20Sopenharmony_ci}
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_civoid fw_card_initialize(struct fw_card *card,
5158c2ecf20Sopenharmony_ci			const struct fw_card_driver *driver,
5168c2ecf20Sopenharmony_ci			struct device *device)
5178c2ecf20Sopenharmony_ci{
5188c2ecf20Sopenharmony_ci	static atomic_t index = ATOMIC_INIT(-1);
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	card->index = atomic_inc_return(&index);
5218c2ecf20Sopenharmony_ci	card->driver = driver;
5228c2ecf20Sopenharmony_ci	card->device = device;
5238c2ecf20Sopenharmony_ci	card->current_tlabel = 0;
5248c2ecf20Sopenharmony_ci	card->tlabel_mask = 0;
5258c2ecf20Sopenharmony_ci	card->split_timeout_hi = DEFAULT_SPLIT_TIMEOUT / 8000;
5268c2ecf20Sopenharmony_ci	card->split_timeout_lo = (DEFAULT_SPLIT_TIMEOUT % 8000) << 19;
5278c2ecf20Sopenharmony_ci	card->split_timeout_cycles = DEFAULT_SPLIT_TIMEOUT;
5288c2ecf20Sopenharmony_ci	card->split_timeout_jiffies =
5298c2ecf20Sopenharmony_ci			DIV_ROUND_UP(DEFAULT_SPLIT_TIMEOUT * HZ, 8000);
5308c2ecf20Sopenharmony_ci	card->color = 0;
5318c2ecf20Sopenharmony_ci	card->broadcast_channel = BROADCAST_CHANNEL_INITIAL;
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	kref_init(&card->kref);
5348c2ecf20Sopenharmony_ci	init_completion(&card->done);
5358c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&card->transaction_list);
5368c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&card->phy_receiver_list);
5378c2ecf20Sopenharmony_ci	spin_lock_init(&card->lock);
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	card->local_node = NULL;
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci	INIT_DELAYED_WORK(&card->br_work, br_work);
5428c2ecf20Sopenharmony_ci	INIT_DELAYED_WORK(&card->bm_work, bm_work);
5438c2ecf20Sopenharmony_ci}
5448c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fw_card_initialize);
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ciint fw_card_add(struct fw_card *card,
5478c2ecf20Sopenharmony_ci		u32 max_receive, u32 link_speed, u64 guid)
5488c2ecf20Sopenharmony_ci{
5498c2ecf20Sopenharmony_ci	int ret;
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_ci	card->max_receive = max_receive;
5528c2ecf20Sopenharmony_ci	card->link_speed = link_speed;
5538c2ecf20Sopenharmony_ci	card->guid = guid;
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci	mutex_lock(&card_mutex);
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	generate_config_rom(card, tmp_config_rom);
5588c2ecf20Sopenharmony_ci	ret = card->driver->enable(card, tmp_config_rom, config_rom_length);
5598c2ecf20Sopenharmony_ci	if (ret == 0)
5608c2ecf20Sopenharmony_ci		list_add_tail(&card->link, &card_list);
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	mutex_unlock(&card_mutex);
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci	return ret;
5658c2ecf20Sopenharmony_ci}
5668c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fw_card_add);
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci/*
5698c2ecf20Sopenharmony_ci * The next few functions implement a dummy driver that is used once a card
5708c2ecf20Sopenharmony_ci * driver shuts down an fw_card.  This allows the driver to cleanly unload,
5718c2ecf20Sopenharmony_ci * as all IO to the card will be handled (and failed) by the dummy driver
5728c2ecf20Sopenharmony_ci * instead of calling into the module.  Only functions for iso context
5738c2ecf20Sopenharmony_ci * shutdown still need to be provided by the card driver.
5748c2ecf20Sopenharmony_ci *
5758c2ecf20Sopenharmony_ci * .read/write_csr() should never be called anymore after the dummy driver
5768c2ecf20Sopenharmony_ci * was bound since they are only used within request handler context.
5778c2ecf20Sopenharmony_ci * .set_config_rom() is never called since the card is taken out of card_list
5788c2ecf20Sopenharmony_ci * before switching to the dummy driver.
5798c2ecf20Sopenharmony_ci */
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_cistatic int dummy_read_phy_reg(struct fw_card *card, int address)
5828c2ecf20Sopenharmony_ci{
5838c2ecf20Sopenharmony_ci	return -ENODEV;
5848c2ecf20Sopenharmony_ci}
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_cistatic int dummy_update_phy_reg(struct fw_card *card, int address,
5878c2ecf20Sopenharmony_ci				int clear_bits, int set_bits)
5888c2ecf20Sopenharmony_ci{
5898c2ecf20Sopenharmony_ci	return -ENODEV;
5908c2ecf20Sopenharmony_ci}
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_cistatic void dummy_send_request(struct fw_card *card, struct fw_packet *packet)
5938c2ecf20Sopenharmony_ci{
5948c2ecf20Sopenharmony_ci	packet->callback(packet, card, RCODE_CANCELLED);
5958c2ecf20Sopenharmony_ci}
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_cistatic void dummy_send_response(struct fw_card *card, struct fw_packet *packet)
5988c2ecf20Sopenharmony_ci{
5998c2ecf20Sopenharmony_ci	packet->callback(packet, card, RCODE_CANCELLED);
6008c2ecf20Sopenharmony_ci}
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_cistatic int dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
6038c2ecf20Sopenharmony_ci{
6048c2ecf20Sopenharmony_ci	return -ENOENT;
6058c2ecf20Sopenharmony_ci}
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_cistatic int dummy_enable_phys_dma(struct fw_card *card,
6088c2ecf20Sopenharmony_ci				 int node_id, int generation)
6098c2ecf20Sopenharmony_ci{
6108c2ecf20Sopenharmony_ci	return -ENODEV;
6118c2ecf20Sopenharmony_ci}
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_cistatic struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card,
6148c2ecf20Sopenharmony_ci				int type, int channel, size_t header_size)
6158c2ecf20Sopenharmony_ci{
6168c2ecf20Sopenharmony_ci	return ERR_PTR(-ENODEV);
6178c2ecf20Sopenharmony_ci}
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_cistatic int dummy_start_iso(struct fw_iso_context *ctx,
6208c2ecf20Sopenharmony_ci			   s32 cycle, u32 sync, u32 tags)
6218c2ecf20Sopenharmony_ci{
6228c2ecf20Sopenharmony_ci	return -ENODEV;
6238c2ecf20Sopenharmony_ci}
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_cistatic int dummy_set_iso_channels(struct fw_iso_context *ctx, u64 *channels)
6268c2ecf20Sopenharmony_ci{
6278c2ecf20Sopenharmony_ci	return -ENODEV;
6288c2ecf20Sopenharmony_ci}
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_cistatic int dummy_queue_iso(struct fw_iso_context *ctx, struct fw_iso_packet *p,
6318c2ecf20Sopenharmony_ci			   struct fw_iso_buffer *buffer, unsigned long payload)
6328c2ecf20Sopenharmony_ci{
6338c2ecf20Sopenharmony_ci	return -ENODEV;
6348c2ecf20Sopenharmony_ci}
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_cistatic void dummy_flush_queue_iso(struct fw_iso_context *ctx)
6378c2ecf20Sopenharmony_ci{
6388c2ecf20Sopenharmony_ci}
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_cistatic int dummy_flush_iso_completions(struct fw_iso_context *ctx)
6418c2ecf20Sopenharmony_ci{
6428c2ecf20Sopenharmony_ci	return -ENODEV;
6438c2ecf20Sopenharmony_ci}
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_cistatic const struct fw_card_driver dummy_driver_template = {
6468c2ecf20Sopenharmony_ci	.read_phy_reg		= dummy_read_phy_reg,
6478c2ecf20Sopenharmony_ci	.update_phy_reg		= dummy_update_phy_reg,
6488c2ecf20Sopenharmony_ci	.send_request		= dummy_send_request,
6498c2ecf20Sopenharmony_ci	.send_response		= dummy_send_response,
6508c2ecf20Sopenharmony_ci	.cancel_packet		= dummy_cancel_packet,
6518c2ecf20Sopenharmony_ci	.enable_phys_dma	= dummy_enable_phys_dma,
6528c2ecf20Sopenharmony_ci	.allocate_iso_context	= dummy_allocate_iso_context,
6538c2ecf20Sopenharmony_ci	.start_iso		= dummy_start_iso,
6548c2ecf20Sopenharmony_ci	.set_iso_channels	= dummy_set_iso_channels,
6558c2ecf20Sopenharmony_ci	.queue_iso		= dummy_queue_iso,
6568c2ecf20Sopenharmony_ci	.flush_queue_iso	= dummy_flush_queue_iso,
6578c2ecf20Sopenharmony_ci	.flush_iso_completions	= dummy_flush_iso_completions,
6588c2ecf20Sopenharmony_ci};
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_civoid fw_card_release(struct kref *kref)
6618c2ecf20Sopenharmony_ci{
6628c2ecf20Sopenharmony_ci	struct fw_card *card = container_of(kref, struct fw_card, kref);
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	complete(&card->done);
6658c2ecf20Sopenharmony_ci}
6668c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(fw_card_release);
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_civoid fw_core_remove_card(struct fw_card *card)
6698c2ecf20Sopenharmony_ci{
6708c2ecf20Sopenharmony_ci	struct fw_card_driver dummy_driver = dummy_driver_template;
6718c2ecf20Sopenharmony_ci	unsigned long flags;
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ci	card->driver->update_phy_reg(card, 4,
6748c2ecf20Sopenharmony_ci				     PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
6758c2ecf20Sopenharmony_ci	fw_schedule_bus_reset(card, false, true);
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci	mutex_lock(&card_mutex);
6788c2ecf20Sopenharmony_ci	list_del_init(&card->link);
6798c2ecf20Sopenharmony_ci	mutex_unlock(&card_mutex);
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	/* Switch off most of the card driver interface. */
6828c2ecf20Sopenharmony_ci	dummy_driver.free_iso_context	= card->driver->free_iso_context;
6838c2ecf20Sopenharmony_ci	dummy_driver.stop_iso		= card->driver->stop_iso;
6848c2ecf20Sopenharmony_ci	card->driver = &dummy_driver;
6858c2ecf20Sopenharmony_ci
6868c2ecf20Sopenharmony_ci	spin_lock_irqsave(&card->lock, flags);
6878c2ecf20Sopenharmony_ci	fw_destroy_nodes(card);
6888c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&card->lock, flags);
6898c2ecf20Sopenharmony_ci
6908c2ecf20Sopenharmony_ci	/* Wait for all users, especially device workqueue jobs, to finish. */
6918c2ecf20Sopenharmony_ci	fw_card_put(card);
6928c2ecf20Sopenharmony_ci	wait_for_completion(&card->done);
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	WARN_ON(!list_empty(&card->transaction_list));
6958c2ecf20Sopenharmony_ci}
6968c2ecf20Sopenharmony_ciEXPORT_SYMBOL(fw_core_remove_card);
697