[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 1/3] usb/msd: Deadlock beim Initialisieren neuer Geräte vermeiden



* usb/msd: usb1 darf eigentlich keine RPCs zulassen während es auf
  seiner Liste arbeitet, ansonsten bekommt man Race Conditions. Der
  nächste Patch fixt dieses Race, aber damit würde ein Deadlock
  entstehen. msd muss daher erst die Antwort schicken und dann die
  weitere Initialisierung machen, in deren Verlauf es auch RPCs an usb1
  schickt.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/usb/msd/init.c |   15 ++++++++++++---
 src/modules/usb/msd/msd.h  |   14 +++++++++++---
 src/modules/usb/msd/rpc.c  |    8 +++++++-
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/src/modules/usb/msd/init.c b/src/modules/usb/msd/init.c
index aa0d4a6..7670194 100644
--- a/src/modules/usb/msd/init.c
+++ b/src/modules/usb/msd/init.c
@@ -42,19 +42,28 @@
 void got_bo_msd(struct usb_prov_dev* dev);
 void got_cbi_msd(struct usb_prov_dev* dev);
 
-int got_msd(struct usb_prov_dev* dev)
+int is_valid_msd(struct usb_prov_dev* dev)
 {
     if (dev->type.protocol == 0x50) { // Bulk-only
-        got_bo_msd(dev);
         return 1;
     } else if ((dev->type.subclass == 0x04) && !dev->type.protocol) { // UFI/CBI
-        got_cbi_msd(dev);
         return 1;
     }
 
     return 0;
 }
 
+void got_msd(struct usb_prov_dev* dev)
+{
+    if (dev->type.protocol == 0x50) { // Bulk-only
+        got_bo_msd(dev);
+    } else if ((dev->type.subclass == 0x04) && !dev->type.protocol) { // UFI/CBI
+        got_cbi_msd(dev);
+    } else {
+        abort();
+    }
+}
+
 void got_bo_msd(struct usb_prov_dev* dev)
 {
     int endpoints = usb_get_number_of_endpoints(dev);
diff --git a/src/modules/usb/msd/msd.h b/src/modules/usb/msd/msd.h
index 892b207..3545df0 100644
--- a/src/modules/usb/msd/msd.h
+++ b/src/modules/usb/msd/msd.h
@@ -85,13 +85,21 @@ struct msc_gen_dev {
 };
 
 /**
- * Wird von einem RPC-Handler aufgerufen, sobald ein neues MSD gefunden wurde.
+ * Wird von einem RPC-Handler aufgerufen, um zu prüfen, ob das neue Gerät ein
+ * MSD ist, mit dem der Treiber etwas anfangen kann.
  *
  * @param dev Neues Gerät
  *
- * @return 1 bei Erfolg, sonst 0
+ * @return 1 wenn das Gerät benutzt werden kann, sonst 0
+ */
+int is_valid_msd(struct usb_prov_dev* dev);
+
+/**
+ * Wird von einem RPC-Handler aufgerufen, sobald ein neues MSD gefunden wurde.
+ *
+ * @param dev Neues Gerät
  */
-int got_msd(struct usb_prov_dev* dev);
+void got_msd(struct usb_prov_dev* dev);
 
 /**
  * Initialisiert das LostIO-Interface.
diff --git a/src/modules/usb/msd/rpc.c b/src/modules/usb/msd/rpc.c
index ae48d68..d54fa01 100644
--- a/src/modules/usb/msd/rpc.c
+++ b/src/modules/usb/msd/rpc.c
@@ -50,6 +50,7 @@ void msd_got_device_handler(pid_t src, uint32_t corr_id, size_t length,
     void* data)
 {
     struct usb_prov_dev* pd;
+    int ret;
 
     if (length < sizeof(*pd)) {
         rpc_send_int_response(src, corr_id, 0);
@@ -59,7 +60,12 @@ void msd_got_device_handler(pid_t src, uint32_t corr_id, size_t length,
     pd = malloc(sizeof(*pd));
     memcpy(pd, data, sizeof(*pd));
 
-    rpc_send_int_response(src, corr_id, got_msd(pd));
+    ret = is_valid_msd(pd);
+    rpc_send_int_response(src, corr_id, ret);
+    if (ret) {
+        got_msd(pd);
+    }
+
 }
 
 void init_rpc_interface(void)
-- 
1.6.0.2