I really doubt that the result of this is exactly what you want, but maybe
you can improve it.

This critically relies on the function f having a return value.  If it
doesn't then you would need two versions, one with a return value and one
without.  It also critically relies on the request_firmware call being at
top level, not under an if.

Whatever rule you end up with, it would be good to provide a rule at the
end that detects the case where the transformation should have applied, but
does not, and do something to warn the user of that fact.

julia


/*
 * You can use this to convert a device driver from the old firmware API
 * to the new flexible sysdata API for sync behaviour
 *
 * For now the confidence is low as this is a new SmPL patch, however with
 * time, as more drivers get converted and this is fine tuned, this
 * confidence in it may grow higher.
 *
 * Confidence: Low
 *
 * Copyright: (C) 2016 Luis R. Rodriguez <[email protected]> GPLv2.
 */

@ find_request_fw_sync @
expression name, dev, E1, e;
type T;
identifier ret, fw_entry, f, drv;
@@

f (...) {
...
?T *drv = E1;
+const struct sysdata_file_desc sysdata_desc = {
+      SYSDATA_DEFAULT_SYNC(sync_found_cb, drv),
+};
...
(
-request_firmware(&drv->fw_entry, name, dev);
+sysdata_file_request(name, &sysdata_desc, dev);
|
ret =
-request_firmware(&drv->fw_entry, name, dev);
+sysdata_file_request(name, &sysdata_desc, dev);
)
<...
- return e;
+ RETURN(e);
...>
}

@@
expression name, dev, e;
identifier ret, fw_entry, find_request_fw_sync.f, drv;
@@

f (...) {
 ... when any
-RETURN(e);
+return e;
}

@ find_request_fw_sync1 @
expression name, dev, e;
identifier ret, fw_entry, find_request_fw_sync.f, drv;
@@

f (...) {
... when any
(
sysdata_file_request(name, &sysdata_desc, dev);
+{
...
+}
return e;
|
ret = sysdata_file_request(name, &sysdata_desc, dev);
+{
...
+}
return e;
)
}

@ find_request_fw_sync2 @
identifier find_request_fw_sync.f;
statement list S1;
symbol context, sysdata;
@@

+static int sync_found_cb(void *context, const struct sysdata_file *sysdata)
+{
+S1
+}

f (...) {
...
-{S1}
return ...;
}

@cleanup@
expression e;
@@

static int sync_found_cb(void *context, const struct sysdata_file *sysdata)
{
<...
- RETURN(e);
+ return e;
...>
}

@ change_headers depends on find_request_fw_sync @
@@

-#include <linux/firmware.h>
+#include <linux/sysdata.h>

@ use_new_struct depends on find_request_fw_sync @
identifier fn, data;
@@

fn (...,
-const struct firmware *data
+const struct sysdata_file *data
,...) { ... }

@ drop_fw_release depends on find_request_fw_sync @
@@

-release_firmware(...);
_______________________________________________
Cocci mailing list
[email protected]
https://systeme.lip6.fr/mailman/listinfo/cocci

Reply via email to