Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 395c6846 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: Kconfig help update
  ieee1394: sbp2: let nodemgr retry node updates during bus reset series
  ieee1394: don't drop nodes during bus reset series
  ieee1394: regression in 2.6.25: updates should happen before probes
parents ddd13dc6 30b0aa7c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -12,8 +12,8 @@ config FIREWIRE
	  This is the "Juju" FireWire stack, a new alternative implementation
	  designed for robustness and simplicity.  You can build either this
	  stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both.
	  Please read http://wiki.linux1394.org/JujuMigration before you
	  enable the new stack.
	  Please read http://ieee1394.wiki.kernel.org/index.php/Juju_Migration
	  before you enable the new stack.

	  To compile this driver as a module, say M here: the module will be
	  called firewire-core.
+33 −30
Original line number Diff line number Diff line
@@ -844,7 +844,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
	ne->host = host;
	ne->nodeid = nodeid;
	ne->generation = generation;
	ne->needs_probe = 1;
	ne->needs_probe = true;

	ne->guid = guid;
	ne->guid_vendor_id = (guid >> 40) & 0xffffff;
@@ -1144,7 +1144,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
	struct csr1212_keyval *kv, *vendor_name_kv = NULL;
	u8 last_key_id = 0;

	ne->needs_probe = 0;
	ne->needs_probe = false;

	csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) {
		switch (kv->key.id) {
@@ -1295,7 +1295,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
		nodemgr_update_bus_options(ne);

		/* Mark the node as new, so it gets re-probed */
		ne->needs_probe = 1;
		ne->needs_probe = true;
	} else {
		/* old cache is valid, so update its generation */
		struct nodemgr_csr_info *ci = ne->csr->private;
@@ -1566,56 +1566,59 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
struct probe_param {
	struct host_info *hi;
	int generation;
	bool probe_now;
};

static int __nodemgr_node_probe(struct device *dev, void *data)
static int node_probe(struct device *dev, void *data)
{
	struct probe_param *param = (struct probe_param *)data;
	struct probe_param *p = data;
	struct node_entry *ne;

	if (p->generation != get_hpsb_generation(p->hi->host))
		return -EAGAIN;

	ne = container_of(dev, struct node_entry, node_dev);
	if (!ne->needs_probe)
		nodemgr_probe_ne(param->hi, ne, param->generation);
	if (ne->needs_probe)
		nodemgr_probe_ne(param->hi, ne, param->generation);
	if (ne->needs_probe == p->probe_now)
		nodemgr_probe_ne(p->hi, ne, p->generation);
	return 0;
}

static void nodemgr_node_probe(struct host_info *hi, int generation)
{
	struct hpsb_host *host = hi->host;
	struct probe_param param;
	struct probe_param p;

	param.hi = hi;
	param.generation = generation;
	/* Do some processing of the nodes we've probed. This pulls them
	p.hi = hi;
	p.generation = generation;
	/*
	 * Do some processing of the nodes we've probed. This pulls them
	 * into the sysfs layer if needed, and can result in processing of
	 * unit-directories, or just updating the node and it's
	 * unit-directories.
	 *
	 * Run updates before probes. Usually, updates are time-critical
	 * while probes are time-consuming. (Well, those probes need some
	 * improvement...) */

	class_for_each_device(&nodemgr_ne_class, NULL, &param,
			      __nodemgr_node_probe);

	/* If we had a bus reset while we were scanning the bus, it is
	 * possible that we did not probe all nodes.  In that case, we
	 * skip the clean up for now, since we could remove nodes that
	 * were still on the bus.  Another bus scan is pending which will
	 * do the clean up eventually.
	 * while probes are time-consuming.
	 *
	 * Meanwhile, another bus reset may have happened. In this case we
	 * skip everything here and let the next bus scan handle it.
	 * Otherwise we may prematurely remove nodes which are still there.
	 */
	p.probe_now = false;
	if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
		return;

	p.probe_now = true;
	if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
		return;
	/*
	 * Now let's tell the bus to rescan our devices. This may seem
	 * like overhead, but the driver-model core will only scan a
	 * device for a driver when either the device is added, or when a
	 * new driver is added. A bus reset is a good reason to rescan
	 * devices that were there before.  For example, an sbp2 device
	 * may become available for login, if the host that held it was
	 * just removed.  */

	if (generation == get_hpsb_generation(host))
		if (bus_rescan_devices(&ieee1394_bus_type))
	 * just removed.
	 */
	if (bus_rescan_devices(&ieee1394_bus_type) != 0)
		HPSB_DEBUG("bus_rescan_devices had an error");
}

+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ struct node_entry {
	struct hpsb_host *host;		/* Host this node is attached to */
	nodeid_t nodeid;		/* NodeID */
	struct bus_options busopt;	/* Bus Options */
	int needs_probe;
	bool needs_probe;
	unsigned int generation;	/* Synced with hpsb generation */

	/* The following is read from the config rom */
+18 −7
Original line number Diff line number Diff line
@@ -731,15 +731,26 @@ static int sbp2_update(struct unit_directory *ud)
{
	struct sbp2_lu *lu = ud->device.driver_data;

	if (sbp2_reconnect_device(lu)) {
		/* Reconnect has failed. Perhaps we didn't reconnect fast
		 * enough. Try a regular login, but first log out just in
		 * case of any weirdness. */
	if (sbp2_reconnect_device(lu) != 0) {
		/*
		 * Reconnect failed.  If another bus reset happened,
		 * let nodemgr proceed and call sbp2_update again later
		 * (or sbp2_remove if this node went away).
		 */
		if (!hpsb_node_entry_valid(lu->ne))
			return 0;
		/*
		 * Or the target rejected the reconnect because we weren't
		 * fast enough.  Try a regular login, but first log out
		 * just in case of any weirdness.
		 */
		sbp2_logout_device(lu);

		if (sbp2_login_device(lu)) {
			/* Login failed too, just fail, and the backend
			 * will call our sbp2_remove for us */
		if (sbp2_login_device(lu) != 0) {
			if (!hpsb_node_entry_valid(lu->ne))
				return 0;

			/* Maybe another initiator won the login. */
			SBP2_ERR("Failed to reconnect to sbp2 device!");
			return -EBUSY;
		}