Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[firefly-linux-kernel-4.4.55.git] / drivers / rapidio / rio-scan.c
index 7bdc67419cc3c8dd8004f83f156d03f60fc08ee2..4c15dbf810871e04f55bb28d30d0f7e2d1cc826d 100644 (file)
@@ -1134,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable)
 /**
  * rio_enum_mport- Start enumeration through a master port
  * @mport: Master port to send transactions
+ * @flags: Enumeration control flags
  *
  * Starts the enumeration process. If somebody has enumerated our
  * master port device, then give up. If not and we have an active
  * link, then start recursive peer enumeration. Returns %0 if
  * enumeration succeeds or %-EBUSY if enumeration fails.
  */
-int rio_enum_mport(struct rio_mport *mport)
+int rio_enum_mport(struct rio_mport *mport, u32 flags)
 {
        struct rio_net *net = NULL;
        int rc = 0;
 
        printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
               mport->name);
+
+       /*
+        * To avoid multiple start requests (repeat enumeration is not supported
+        * by this method) check if enumeration/discovery was performed for this
+        * mport: if mport was added into the list of mports for a net exit
+        * with error.
+        */
+       if (mport->nnode.next || mport->nnode.prev)
+               return -EBUSY;
+
        /* If somebody else enumerated our master port device, bail. */
        if (rio_enum_host(mport) < 0) {
                printk(KERN_INFO
@@ -1236,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net)
 /**
  * rio_disc_mport- Start discovery through a master port
  * @mport: Master port to send transactions
+ * @flags: discovery control flags
  *
  * Starts the discovery process. If we have an active link,
- * then wait for the signal that enumeration is complete.
+ * then wait for the signal that enumeration is complete (if wait
+ * is allowed).
  * When enumeration completion is signaled, start recursive
  * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
  * on failure.
  */
-int rio_disc_mport(struct rio_mport *mport)
+int rio_disc_mport(struct rio_mport *mport, u32 flags)
 {
        struct rio_net *net = NULL;
        unsigned long to_end;
@@ -1253,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport)
 
        /* If master port has an active link, allocate net and discover peers */
        if (rio_mport_is_active(mport)) {
+               if (rio_enum_complete(mport))
+                       goto enum_done;
+               else if (flags & RIO_SCAN_ENUM_NO_WAIT)
+                       return -EAGAIN;
+
                pr_debug("RIO: wait for enumeration to complete...\n");
 
                to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;