/* * 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)
#define CANON_OUI 0x000085
staticvoid generate_config_rom(struct fw_card *card, __be32 *config_rom)
{ struct fw_descriptor *desc; int i, j, k, length;
/* * Initialize contents of config rom buffer. On the OHCI * 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 * sure the contents of bus info block in host memory matches * the version stored in the OHCI registers.
*/
/* End of root directory, now copy in descriptors. */
list_for_each_entry (desc, &descriptor_list, link) { for (k = 0; k < desc->length; k++)
config_rom[i + k] = cpu_to_be32(desc->data[k]);
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. */ for (i = 0; i < j; i += length + 1)
length = fw_compute_block_crc(config_rom + i);
int fw_core_add_descriptor(struct fw_descriptor *desc)
{
size_t i;
/* * Check descriptor is valid; the length of all blocks in the * descriptor has to add up to exactly the length of the * block.
*/
i = 0; while (i < desc->length)
i += (desc->data[i] >> 16) + 1;
if (i != desc->length) return -EINVAL;
guard(mutex)(&card_mutex);
if (config_rom_length + required_space(desc) > 256) return -EBUSY;
/* 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); if (!queue_delayed_work(fw_workqueue, &card->br_work,
delayed ? DIV_ROUND_UP(HZ, 100) : 0))
fw_card_put(card);
}
EXPORT_SYMBOL(fw_schedule_bus_reset);
/* 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;
if ((is_next_generation(generation, card->bm_generation) &&
!card->bm_abdicate) ||
(card->bm_generation != generation && grace)) { /* * This first step is to figure out who is IRM and * 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 * next generation.
*/
if (!card->irm_node->link_on) {
new_root_id = local_id;
fw_notice(card, "%s, making local node (%02x) root\n", "IRM has link off", new_root_id); goto pick_me;
}
if (irm_is_1394_1995_only && !keep_this_irm) {
new_root_id = local_id;
fw_notice(card, "%s, making local node (%02x) root\n", "IRM is not 1394a compliant", new_root_id); goto pick_me;
}
if (rcode == RCODE_COMPLETE && bm_id != 0x3f) { /* Somebody else is BM. Only act as IRM. */ if (local_id == irm_id)
allocate_broadcast_channel(card, generation);
goto out;
}
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;
}
spin_lock_irq(&card->lock);
if (rcode != RCODE_COMPLETE && !keep_this_irm) { /* * The lock request failed, maybe the IRM * isn't really IRM capable after all. Let's * do a bus reset and pick the local node as * root, and thus, IRM.
*/
new_root_id = local_id;
fw_notice(card, "BM lock failed (%s), making local node (%02x) root\n",
fw_rcode_string(rcode), new_root_id); goto pick_me;
}
} elseif (card->bm_generation != generation) { /* * We weren't BM in the last generation, and the last * bus reset is less than 125ms ago. Reschedule this job.
*/
spin_unlock_irq(&card->lock);
fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8)); goto out;
}
/* * We're bus manager for this generation, so next step is to * make sure we have an active cycle master and do gap count * optimization.
*/
card->bm_generation = generation;
if (card->gap_count == 0) { /* * If self IDs have inconsistent gap counts, do a * bus reset ASAP. The config rom read might never * complete, so don't wait for it. However, still * send a PHY configuration packet prior to the * bus reset. The PHY configuration packet might * fail, but 1394-2008 8.4.5.2 explicitly permits * it in this case, so it should be safe to try.
*/
new_root_id = local_id; /* * We must always send a bus reset if the gap count * is inconsistent, so bypass the 5-reset limit.
*/
card->bm_retries = 0;
} elseif (root_device == NULL) { /* * Either link_on is false, or we failed to read the * config rom. In either case, pick another root.
*/
new_root_id = local_id;
} elseif (!root_device_is_running) { /* * If we haven't probed this device yet, bail out now * and let's try again once that's done.
*/
spin_unlock_irq(&card->lock); goto out;
} elseif (root_device_is_cmc) { /* * We will send out a force root packet for this * node as part of the gap count optimization.
*/
new_root_id = root_id;
} else { /* * Current root has an active link layer and we * successfully read the config rom, but it's not * cycle master capable.
*/
new_root_id = local_id;
}
pick_me: /* * 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 &&
root_node->max_hops < ARRAY_SIZE(gap_count_table))
gap_count = gap_count_table[root_node->max_hops]; else
gap_count = 63;
/* * 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 * have either a new root or a new gap count setting, let's do it.
*/
if (do_reset) {
fw_notice(card, "phy config: new root=%x, gap_count=%d\n",
new_root_id, gap_count);
fw_send_phy_config(card, new_root_id, generation, gap_count); /* * Where possible, use a short bus reset to minimize * disruption to isochronous transfers. But in the event * of a gap count inconsistency, use a long bus reset. * * As noted in 1394a 8.4.6.2, nodes on a mixed 1394/1394a bus * may set different gap counts after a bus reset. On a mixed * 1394/1394a bus, a short bus reset can get doubled. Some * nodes may treat the double reset as one bus reset and others * may treat it as two, causing a gap count inconsistency * again. Using a long bus reset prevents this.
*/
reset_bus(card, card->gap_count != 0); /* Will allocate broadcast channel after the reset. */ goto out;
}
if (root_device_is_cmc) { /* * Make sure that the cycle master sends cycle start packets.
*/
transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
root_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_STATE_SET,
transaction_data, 4); if (rcode == RCODE_GENERATION) goto out;
}
if (local_id == irm_id)
allocate_broadcast_channel(card, generation);
int fw_card_add(struct fw_card *card, u32 max_receive, u32 link_speed, u64 guid, unsignedint supported_isoc_contexts)
{ int ret;
// This workqueue should be: // * != WQ_BH Sleepable. // * == WQ_UNBOUND Any core can process data for isoc context. The // implementation of unit protocol could consumes the core // longer somehow. // * != WQ_MEM_RECLAIM Not used for any backend of block device. // * == WQ_FREEZABLE Isochronous communication is at regular interval in real // time, thus should be drained if possible at freeze phase. // * == WQ_HIGHPRI High priority to process semi-realtime timestamped data. // * == WQ_SYSFS Parameters are available via sysfs. // * max_active == n_it + n_ir A hardIRQ could notify events for multiple isochronous // contexts if they are scheduled to the same cycle.
card->isoc_wq = alloc_workqueue("firewire-isoc-card%u",
WQ_UNBOUND | WQ_FREEZABLE | WQ_HIGHPRI | WQ_SYSFS,
supported_isoc_contexts, card->index); if (!card->isoc_wq) return -ENOMEM;
// This workqueue should be: // * != WQ_BH Sleepable. // * == WQ_UNBOUND Any core can process data for asynchronous context. // * == WQ_MEM_RECLAIM Used for any backend of block device. // * == WQ_FREEZABLE The target device would not be available when being freezed. // * == WQ_HIGHPRI High priority to process semi-realtime timestamped data. // * == WQ_SYSFS Parameters are available via sysfs. // * max_active == 4 A hardIRQ could notify events for a pair of requests and // response AR/AT contexts.
card->async_wq = alloc_workqueue("firewire-async-card%u",
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_HIGHPRI | WQ_SYSFS,
4, card->index); if (!card->async_wq) {
ret = -ENOMEM; goto err_isoc;
}
/* * 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. * * .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.
*/
staticint dummy_read_phy_reg(struct fw_card *card, int address)
{ return -ENODEV;
}
staticint dummy_update_phy_reg(struct fw_card *card, int address, int clear_bits, int set_bits)
{ return -ENODEV;
}
/** * fw_card_read_cycle_time: read from Isochronous Cycle Timer Register of 1394 OHCI in MMIO region * for controller card. * @card: The instance of card for 1394 OHCI controller. * @cycle_time: The mutual reference to value of cycle time for the read operation. * * Read value from Isochronous Cycle Timer Register of 1394 OHCI in MMIO region for the given * controller card. This function accesses the region without any lock primitives or IRQ mask. * When returning successfully, the content of @value argument has value aligned to host endianness, * formetted by CYCLE_TIME CSR Register of IEEE 1394 std. * * Context: Any context. * Return: * * 0 - Read successfully. * * -ENODEV - The controller is unavailable due to being removed or unbound.
*/ int fw_card_read_cycle_time(struct fw_card *card, u32 *cycle_time)
{ if (card->driver->read_csr == dummy_read_csr) return -ENODEV;
// It's possible to switch to dummy driver between the above and the below. This is the best // effort to return -ENODEV.
*cycle_time = card->driver->read_csr(card, CSR_CYCLE_TIME); return 0;
}
EXPORT_SYMBOL_GPL(fw_card_read_cycle_time);
Messung V0.5
¤ Dauer der Verarbeitung: 0.30 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.