pmseries: support fabricated SIDs in /series/instances requests

When a fabricated (expression) SID param is passed to /series/instances,
lookup, parse and solve the associated expression and add the resulting
instances to the response. Fabricated and regular SIDs can be mixed in
the comma separated list of SIDs.

Docs and new QA still todo (e.g. qa/1874 and qa/1886 will need additional
subtests).

Related: https://github.com/performancecopilot/pcp/issues/1175

--- src/libpcp_web/src/query.c
+++ src/libpcp_web/src/query.c
@@ -79,6 +79,7 @@
 static void series_lookup_mapping(void *);
 static void series_lookup_finished(void *);
 static void series_query_mapping(void *arg);
+static void series_instances_reply_callback(redisAsyncContext *, redisReply *, const sds, void *);

 sds	cursorcount;	/* number of elements in each SCAN call */

@@ -1368,6 +1369,17 @@
 	fprintf(stderr, "on_series_solve_log: %s\n", message);
 }

+static void
+on_series_solve_done(int status, void *arg)
+{
+    seriesQueryBaton	*baton = arg;
+
+    seriesBatonCheckMagic(baton, MAGIC_QUERY, "on_series_solve_done");
+    if (pmDebugOptions.query && pmDebugOptions.desperate)
+	fprintf(stderr, "on_series_solve_done: arg=%p status=%d\n", arg, status);
+    baton->callbacks->on_done(status, baton->userdata);
+}
+
 static int
 on_series_solve_value(pmSID sid, pmSeriesValue *value, void *arg)
 {
@@ -1380,21 +1392,67 @@
     return baton->callbacks->on_value(sid, value, baton->userdata);
 }

-static void
-on_series_solve_done(int status, void *arg)
+
+static void
+on_series_solve_inst_done(int status, void *arg)
 {
     seriesQueryBaton	*baton = arg;

     seriesBatonCheckMagic(baton, MAGIC_QUERY, "on_series_solve_done");
     if (pmDebugOptions.query && pmDebugOptions.desperate)
 	fprintf(stderr, "on_series_solve_done: arg=%p status=%d\n", arg, status);
-    baton->callbacks->on_done(status, baton->userdata);
-    seriesBatonDereference(baton, "series_solve_sid_expr");
-}
-
-static pmSeriesSettings	series_solve_settings = {
+    /* on_done is called by series_query_finished */
+    seriesBatonDereference(baton, "on_series_solve_inst_done");
+}
+
+/*
+ * HMGETALL pcp:inst:series:(value->series)
+ * re-using series_instances_reply_callback as the callback.
+ */
+static int
+on_series_solve_inst_value(pmSID sid, pmSeriesValue *value, void *arg)
+{
+    seriesQueryBaton	*baton = arg;
+    seriesGetSID	*sidbat;
+    sds			key, cmd;
+
+    seriesBatonCheckMagic(baton, MAGIC_QUERY, "on_series_solve_inst_value");
+    if (pmDebugOptions.query) {
+	fprintf(stderr, "on_series_solve_inst_value: arg=%p %s %s %s\n",
+		arg, value->timestamp, value->data, value->series);
+    }
+
+    sidbat = calloc(1, sizeof(seriesGetSID));
+    initSeriesGetSID(sidbat, value->series, 1, baton);
+    sidbat->metric = sdsdup(sid);
+
+    seriesBatonReference(baton, "on_series_solve_inst_value");
+    seriesBatonReference(sidbat, "on_series_solve_inst_value");
+
+    key = sdscatfmt(sdsempty(), "pcp:inst:series:%S", value->series);
+    cmd = redis_command(5);
+    cmd = redis_param_str(cmd, HMGET, HMGET_LEN);
+    cmd = redis_param_sds(cmd, key);
+    cmd = redis_param_str(cmd, "inst", sizeof("inst")-1);
+    cmd = redis_param_str(cmd, "name", sizeof("name")-1);
+    cmd = redis_param_str(cmd, "source", sizeof("source")-1);
+    redisSlotsRequest(baton->slots, HMGET, key, cmd,
+			    series_instances_reply_callback, sidbat);
+    return 0;
+}
+
+/* settings and callbacks for /series/values with fabricated SID */
+static pmSeriesSettings	series_solve_values_settings = {
     .callbacks.on_value		= on_series_solve_value,
     .callbacks.on_done		= on_series_solve_done,
+    .module.on_setup		= on_series_solve_setup,
+    .module.on_info		= on_series_solve_log,
+};
+
+/* settings and callbacks for /series/instances with fabricated SID */
+static pmSeriesSettings	series_solve_inst_settings = {
+    .callbacks.on_value		= on_series_solve_inst_value,
+    .callbacks.on_done		= on_series_solve_inst_done,
     .module.on_setup		= on_series_solve_setup,
     .module.on_info		= on_series_solve_log,
 };
@@ -1406,7 +1464,7 @@
  * elements to the response series for original pmSeriesBaton.
  */
 static int
-series_solve_sid_expr(pmSeriesExpr *expr, void *arg)
+series_solve_sid_expr(pmSeriesSettings *settings, pmSeriesExpr *expr, void *arg)
 {
     seriesGetSID	*sid = (seriesGetSID *)arg;
     seriesQueryBaton	*baton = (seriesQueryBaton *)sid->baton;
@@ -1418,8 +1476,8 @@
     seriesBatonCheckMagic(baton, MAGIC_QUERY, "series_query_expr_reply");

     if (pmDebugOptions.query) {
-	fprintf(stderr, "series_solve_sid_expr: /series/values "
-		"SID %s, seriesQueryBaton=%p, pmSeriesBaton=userdata=%p expr=\"%s\"\n",
+	fprintf(stderr, "series_solve_sid_expr: SID %s, "
+		"seriesQueryBaton=%p, pmSeriesBaton=userdata=%p expr=\"%s\"\n",
 		sid->name, baton, baton->userdata, expr->query);
     }

@@ -1427,10 +1485,10 @@
     seriesBatonReference(baton, "series_solve_sid_expr");

     if ((sts = series_parse(expr->query, &sp, &errstr, arg)) == 0) {
-	pmSeriesSetSlots(&series_solve_settings.module, baton->slots);
-	series_solve_settings.module = *baton->module; /* struct cpy */
-
-	sts = series_solve(&series_solve_settings, sp.expr, &baton->u.query.timing,
+	pmSeriesSetSlots(&settings->module, baton->slots);
+	settings->module = *baton->module; /* struct cpy */
+
+	sts = series_solve(settings, sp.expr, &baton->u.query.timing,
 	    PM_SERIES_FLAG_NONE, baton);
     }

@@ -1464,7 +1522,7 @@
 	    baton->error = sts;
 	} else {
 	    /* Parse the expr (with timing) and series solve the resulting expr tree */
-	    baton->error = series_solve_sid_expr(&expr, arg);
+	    baton->error = series_solve_sid_expr(&series_solve_values_settings, &expr, arg);
 	}
     }
     series_query_end_phase(baton);
@@ -1654,7 +1712,8 @@

     for (i = 0; i < np->value_set.num_series; i++) {
 	series = np->value_set.series_values[i].sid->name;
-	baton->callbacks->on_match(series, baton->userdata);
+	if (baton->callbacks->on_match)
+	    baton->callbacks->on_match(series, baton->userdata);
     }
 }

@@ -4172,7 +4231,7 @@
 static int
 series_time_window(timing_t *tp)
 {
-    if (tp->window.range ||
+    if (tp->count || tp->window.range ||
 	tp->window.start || tp->window.end ||
 	tp->window.count || tp->window.delta)
 	return 1;
@@ -4972,12 +5031,48 @@
     sdsfree(name);
 }

+static void
+series_inst_expr_reply(redisAsyncContext *c, redisReply *reply, const sds cmd, void *arg)
+{
+    seriesGetSID	*sid = (seriesGetSID *)arg;
+    seriesQueryBaton	*baton = (seriesQueryBaton *)sid->baton;
+    pmSeriesExpr	expr = {0};
+    sds			msg;
+    int			sts;
+
+    seriesBatonCheckMagic(sid, MAGIC_SID, "series_inst_expr_reply");
+    seriesBatonCheckMagic(baton, MAGIC_QUERY, "series_inst_expr_reply");
+    sts = redisSlotsRedirect(baton->slots, reply, baton->info, baton->userdata,
+			     cmd, series_query_expr_reply, arg);
+    if (sts > 0)
+	return;	/* short-circuit as command was re-submitted */
+    if (UNLIKELY(reply == NULL || reply->type != REDIS_REPLY_ARRAY)) {
+    	if (sts < 0) {
+	    infofmt(msg, "expected array of one string element (got %lu) from series %s %s (type=%s)",
+   		reply->elements, sid->name, HMGET, redis_reply_type(reply));
+	    batoninfo(baton, PMLOG_RESPONSE, msg);
+	}
+    } else if (reply->element[0]->type == REDIS_REPLY_STRING) {
+	expr.query = sdsempty();
+    	if ((sts = extract_string(baton, sid->name, reply->element[0], &expr.query, "query")) < 0) {
+	    baton->error = sts;
+	} else {
+	    /* Parse the expr (with timing) and series solve the resulting expr tree */
+	    baton->u.query.timing.count = 1;
+	    baton->error = series_solve_sid_expr(&series_solve_inst_settings, &expr, arg);
+	}
+    }
+    series_query_end_phase(baton);
+}
+
 void
 series_lookup_instances_callback(
 	redisAsyncContext *c, redisReply *reply, const sds cmd, void *arg)
 {
     seriesGetSID	*sid = (seriesGetSID *)arg;
     seriesQueryBaton	*baton = (seriesQueryBaton *)sid->baton;
+    seriesGetSID	*expr;
+    sds			key, exprcmd;
     sds			msg;
     int			sts;

@@ -4989,7 +5084,28 @@
 	return;	/* short-circuit as command was re-submitted */

     if (LIKELY(reply && reply->type == REDIS_REPLY_ARRAY)) {
-	series_instances_reply(baton, sid->name, reply->elements, reply->element);
+	if (reply->elements > 0) {
+	    /* regular series */
+	    series_instances_reply(baton, sid->name, reply->elements, reply->element);
+	} else {
+	    /* Handle fabricated/expression SID in /series/instances :
+	     * - get the expr for sid->name from redis. In the callback for that,
+	     *   parse the expr and then solve the expression tree with timing from
+	     *   this series query baton, then merge the instances into the reply.
+	     */
+	    if (pmDebugOptions.query)
+		fprintf(stderr, "series_lookup_instances_callback: sid %s is fabricated\n", sid->name);
+	    expr = calloc(1, sizeof(seriesGetSID));
+	    initSeriesGetSID(expr, sid->name, 1, baton);
+	    seriesBatonReference(baton, "series_lookup_instances_callback");
+
+	    key = sdscatfmt(sdsempty(), "pcp:expr:series:%S", expr->name);
+	    exprcmd = redis_command(3);
+	    exprcmd = redis_param_str(exprcmd, HMGET, HMGET_LEN);
+	    exprcmd = redis_param_sds(exprcmd, key);
+	    exprcmd = redis_param_str(exprcmd, "query", sizeof("query")-1);
+	    redisSlotsRequest(baton->slots, HMGET, key, exprcmd, series_inst_expr_reply, expr);
+	}
     } else {
 	if (sts < 0) {
 	    infofmt(msg, "expected array from series %s %s (type=%s)",


ASoC: rt5677: Replace the string "micbias1" to "MICBIAS1"

The patch replaces the string "micbias1" to "MICBIAS1".

Signed-off-by: Oder Chiou <81d54fb0f3a9e1168f5ac492a462b8d0a59a67f4@realtek.com>
Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@linaro.org>


ASoC: wm0010: Split out the firmware file parsing from the boot

Move the firmware load and record parsing functionality out into
a separate function from the boot function.

Signed-off-by: Scott Ling <2b002dcf5ebaf365d031276a8f5e55d923723c20@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>

--- sound/soc/codecs/wm0010.c
+++ sound/soc/codecs/wm0010.c
@@ -332,24 +332,165 @@
 		data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
 }

-static int wm0010_boot(struct snd_soc_codec *codec)
+static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec)
 {
 	struct spi_device *spi = to_spi_device(codec->dev);
 	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
-	unsigned long flags;
 	struct list_head xfer_list;
 	struct wm0010_boot_xfer *xfer;
 	int ret;
 	struct completion done;
 	const struct firmware *fw;
 	const struct dfw_binrec *rec;
+	u64 *img;
+	u8 *out, dsp;
+	u32 len, offset;
+
+	INIT_LIST_HEAD(&xfer_list);
+
+	ret = request_firmware(&fw, name, codec->dev);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to request application: %d\n",
+			ret);
+		return ret;
+	}
+
+	rec = (const struct dfw_binrec *)fw->data;
+	offset = 0;
+	dsp = rec->data[0];
+	wm0010->boot_failed = false;
+	BUG_ON(!list_empty(&xfer_list));
+	init_completion(&done);
+
+	/* First record should be INFO */
+	if (rec->command != DFW_CMD_INFO) {
+		dev_err(codec->dev, "First record not INFO\r\n");
+		ret = -EINVAL;
+		goto abort;
+	}
+
+	/* Check it's a DSP file */
+	if (dsp != DEVICE_ID_WM0010) {
+		dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
+		ret = -EINVAL;
+		goto abort;
+	}
+
+	/* Skip the info record as we don't need to send it */
+	offset += ((rec->length) + 8);
+	rec = (void *)&rec->data[rec->length];
+
+	while (offset < fw->size) {
+		dev_dbg(codec->dev,
+			"Packet: command %d, data length = 0x%x\r\n",
+			rec->command, rec->length);
+		len = rec->length + 8;
+
+		out = kzalloc(len, GFP_KERNEL);
+		if (!out) {
+			dev_err(codec->dev,
+				"Failed to allocate RX buffer\n");
+			ret = -ENOMEM;
+			goto abort1;
+		}
+
+		img = kzalloc(len, GFP_KERNEL);
+		if (!img) {
+			dev_err(codec->dev,
+				"Failed to allocate image buffer\n");
+			ret = -ENOMEM;
+			goto abort1;
+		}
+
+		byte_swap_64((u64 *)&rec->command, img, len);
+
+		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
+		if (!xfer) {
+			dev_err(codec->dev, "Failed to allocate xfer\n");
+			ret = -ENOMEM;
+			goto abort1;
+		}
+
+		xfer->codec = codec;
+		list_add_tail(&xfer->list, &xfer_list);
+
+		spi_message_init(&xfer->m);
+		xfer->m.complete = wm0010_boot_xfer_complete;
+		xfer->m.context = xfer;
+		xfer->t.tx_buf = img;
+		xfer->t.rx_buf = out;
+		xfer->t.len = len;
+		xfer->t.bits_per_word = 8;
+
+		if (!wm0010->pll_running) {
+			xfer->t.speed_hz = wm0010->sysclk / 6;
+		} else {
+			xfer->t.speed_hz = wm0010->max_spi_freq;
+
+			if (wm0010->board_max_spi_speed &&
+			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
+					xfer->t.speed_hz = wm0010->board_max_spi_speed;
+		}
+
+		/* Store max usable spi frequency for later use */
+		wm0010->max_spi_freq = xfer->t.speed_hz;
+
+		spi_message_add_tail(&xfer->t, &xfer->m);
+
+		offset += ((rec->length) + 8);
+		rec = (void *)&rec->data[rec->length];
+
+		if (offset >= fw->size) {
+			dev_dbg(codec->dev, "All transfers scheduled\n");
+			xfer->done = &done;
+		}
+
+		ret = spi_async(spi, &xfer->m);
+		if (ret != 0) {
+			dev_err(codec->dev, "Write failed: %d\n", ret);
+			goto abort1;
+		}
+
+		if (wm0010->boot_failed) {
+			dev_dbg(codec->dev, "Boot fail!\n");
+			ret = -EINVAL;
+			goto abort1;
+		}
+	}
+
+	wait_for_completion(&done);
+
+	ret = 0;
+
+abort1:
+	while (!list_empty(&xfer_list)) {
+		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
+					list);
+		kfree(xfer->t.rx_buf);
+		kfree(xfer->t.tx_buf);
+		list_del(&xfer->list);
+		kfree(xfer);
+	}
+
+abort:
+	release_firmware(fw);
+	return ret;
+}
+
+static int wm0010_boot(struct snd_soc_codec *codec)
+{
+	struct spi_device *spi = to_spi_device(codec->dev);
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	unsigned long flags;
+	int ret;
+	const struct firmware *fw;
 	struct spi_message m;
 	struct spi_transfer t;
 	struct dfw_pllrec pll_rec;
 	u32 *img, *p;
 	u64 *img_swap;
 	u8 *out;
-	u32 len, offset;
+	u32 len;
 	int i;

 	spin_lock_irqsave(&wm0010->irq_lock, flags);
@@ -362,8 +503,6 @@
 		ret = -ECANCELED;
 		goto err;
 	}
-
-	INIT_LIST_HEAD(&xfer_list);

 	mutex_lock(&wm0010->lock);
 	wm0010->pll_running = false;
@@ -533,126 +672,16 @@
 	} else
 		dev_dbg(codec->dev, "Not enabling DSP PLL.");

-	ret = request_firmware(&fw, "wm0010.dfw", codec->dev);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request application: %d\n",
-			ret);
+	ret = wm0010_firmware_load("wm0010.dfw", codec);
+
+	if (ret != 0)
 		goto abort;
-	}
-
-	rec = (const struct dfw_binrec *)fw->data;
-	offset = 0;
-	wm0010->boot_failed = false;
-	BUG_ON(!list_empty(&xfer_list));
-	init_completion(&done);
-
-	/* First record should be INFO */
-	if (rec->command != DFW_CMD_INFO) {
-		dev_err(codec->dev, "First record not INFO\r\n");
-		goto abort;
-	}
-
-	/* Check it's a 0010 file */
-	if (rec->data[0] != DEVICE_ID_WM0010) {
-		dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
-		goto abort;
-	}
-
-	/* Skip the info record as we don't need to send it */
-	offset += ((rec->length) + 8);
-	rec = (void *)&rec->data[rec->length];
-
-	while (offset < fw->size) {
-		dev_dbg(codec->dev,
-			"Packet: command %d, data length = 0x%x\r\n",
-			rec->command, rec->length);
-		len = rec->length + 8;
-
-		out = kzalloc(len, GFP_KERNEL);
-		if (!out) {
-			dev_err(codec->dev,
-				"Failed to allocate RX buffer\n");
-			goto abort;
-		}
-
-		img_swap = kzalloc(len, GFP_KERNEL);
-		if (!img_swap) {
-			dev_err(codec->dev,
-				"Failed to allocate image buffer\n");
-			goto abort;
-		}
-
-		/* We need to re-order for 0010 */
-		byte_swap_64((u64 *)&rec->command, img_swap, len);
-
-		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
-		if (!xfer) {
-			dev_err(codec->dev, "Failed to allocate xfer\n");
-			goto abort;
-		}
-
-		xfer->codec = codec;
-		list_add_tail(&xfer->list, &xfer_list);
-
-		spi_message_init(&xfer->m);
-		xfer->m.complete = wm0010_boot_xfer_complete;
-		xfer->m.context = xfer;
-		xfer->t.tx_buf = img_swap;
-		xfer->t.rx_buf = out;
-		xfer->t.len = len;
-		xfer->t.bits_per_word = 8;
-
-		if (!wm0010->pll_running) {
-			xfer->t.speed_hz = wm0010->sysclk / 6;
-		} else {
-			xfer->t.speed_hz = wm0010->max_spi_freq;
-
-			if (wm0010->board_max_spi_speed &&
-			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
-					xfer->t.speed_hz = wm0010->board_max_spi_speed;
-		}
-
-		/* Store max usable spi frequency for later use */
-		wm0010->max_spi_freq = xfer->t.speed_hz;
-
-		spi_message_add_tail(&xfer->t, &xfer->m);
-
-		offset += ((rec->length) + 8);
-		rec = (void *)&rec->data[rec->length];
-
-		if (offset >= fw->size) {
-			dev_dbg(codec->dev, "All transfers scheduled\n");
-			xfer->done = &done;
-		}
-
-		ret = spi_async(spi, &xfer->m);
-		if (ret != 0) {
-			dev_err(codec->dev, "Write failed: %d\n", ret);
-			goto abort;
-		}
-
-		if (wm0010->boot_failed)
-			goto abort;
-	}
-
-	wait_for_completion(&done);

 	spin_lock_irqsave(&wm0010->irq_lock, flags);
 	wm0010->state = WM0010_FIRMWARE;
 	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

 	mutex_unlock(&wm0010->lock);
-
-	release_firmware(fw);
-
-	while (!list_empty(&xfer_list)) {
-		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
-					list);
-		kfree(xfer->t.rx_buf);
-		kfree(xfer->t.tx_buf);
-		list_del(&xfer->list);
-		kfree(xfer);
-	}

 	return 0;


ASoC: Correct WM8580 Capture control names

Should use Capture rather than ADC so the UI tools can identify their
function more readily.

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <a57ef363056e61beffa2efa59c68550d40db03b0@slimlogic.co.uk>

--- sound/soc/codecs/wm8580.c
+++ sound/soc/codecs/wm8580.c
@@ -273,8 +273,8 @@
 SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0),
 SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0),

-SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
-SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
+SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
+SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
 };

 static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {


ASoC: wm8731: Drop wm8731_writeable function

When .max_register is set and .writeable_reg is not implement, registers
between 0 and .max_register are writeable. This is the same as current
implementation of wm8731_writeable(), so just drop implementation for
.writeable_reg callback.

Signed-off-by: Axel Lin <b6ffd6973e972cb999e8e535ab74da7fee0c035f@ingics.com>
Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@kernel.org>


ASoC: Stop WM8903 SYSCLK when suspending

This will save some additional power.

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>

--- sound/soc/codecs/wm8903.c
+++ sound/soc/codecs/wm8903.c
@@ -997,6 +997,9 @@

 	case SND_SOC_BIAS_STANDBY:
 		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+			wm8903_write(codec, WM8903_CLOCK_RATES_2,
+				     WM8903_CLK_SYS_ENA);
+
 			wm8903_run_sequence(codec, 0);
 			wm8903_sync_reg_cache(codec, codec->reg_cache);

@@ -1027,6 +1030,9 @@

 	case SND_SOC_BIAS_OFF:
 		wm8903_run_sequence(codec, 32);
+		reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
+		reg &= ~WM8903_CLK_SYS_ENA;
+		wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
 		break;
 	}

@@ -1619,9 +1625,6 @@

 	wm8903_reset(codec);

-	/* SYSCLK is required for pretty much anything */
-	wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
-
 	/* power on device */
 	wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);


ASoC: Add missing break in WM8915 FLL source selection

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <a57ef363056e61beffa2efa59c68550d40db03b0@ti.com>

--- sound/soc/codecs/wm8915.c
+++ sound/soc/codecs/wm8915.c
@@ -2038,6 +2038,7 @@
 		break;
 	case WM8915_FLL_MCLK2:
 		reg = 1;
+		break;
 	case WM8915_FLL_DACLRCLK1:
 		reg = 2;
 		break;


ASoC: Remove internally generated WM8915 supplies

DCVDD and MICVDD are intended to be (and almost always are) generated by
on-board LDOs which are transparently controlled by the driver so we
shouldn't really be requesting them from the regulator API. If the driver
is updated to support external supply of these then we will need to change
the way we handle this.

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <a57ef363056e61beffa2efa59c68550d40db03b0@ti.com>

--- sound/soc/codecs/wm8915.c
+++ sound/soc/codecs/wm8915.c
@@ -41,14 +41,12 @@
 #define HPOUT2L 4
 #define HPOUT2R 8

-#define WM8915_NUM_SUPPLIES 6
+#define WM8915_NUM_SUPPLIES 4
 static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
-	"DCVDD",
 	"DBVDD",
 	"AVDD1",
 	"AVDD2",
 	"CPVDD",
-	"MICVDD",
 };

 struct wm8915_priv {
@@ -113,8 +111,6 @@
 WM8915_REGULATOR_EVENT(1)
 WM8915_REGULATOR_EVENT(2)
 WM8915_REGULATOR_EVENT(3)
-WM8915_REGULATOR_EVENT(4)
-WM8915_REGULATOR_EVENT(5)

 static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
 	[WM8915_SOFTWARE_RESET] = 0x8915,
@@ -2495,8 +2491,6 @@
 	wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
 	wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
 	wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
-	wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
-	wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;

 	/* This should really be moved into the regulator core */
 	for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {


ASoC: Report errors when we have a WM8962 IRQ and don't get FLL lock

We really should be getting the interrupt - if we don't get one it's very
likely that the configuration is incorrect and audio will fail. Also
increase the timeout substantially in this case for safety.

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <a57ef363056e61beffa2efa59c68550d40db03b0@ti.com>

--- sound/soc/codecs/wm8962.c
+++ sound/soc/codecs/wm8962.c
@@ -2186,6 +2186,8 @@
 			struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	unsigned long timeout;
 	int src;
 	int fll;

@@ -2205,9 +2207,19 @@

 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		if (fll)
+		if (fll) {
 			snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
 					    WM8962_FLL_ENA, WM8962_FLL_ENA);
+			if (wm8962->irq) {
+				timeout = msecs_to_jiffies(5);
+				timeout = wait_for_completion_timeout(&wm8962->fll_lock,
+								      timeout);
+
+				if (timeout == 0)
+					dev_err(codec->dev,
+						"Timed out starting FLL\n");
+			}
+		}
 		break;

 	case SND_SOC_DAPM_POST_PMD:
@@ -3263,16 +3275,31 @@

 	dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);

-	/* This should be a massive overestimate */
-	timeout = msecs_to_jiffies(1);
-
-	wait_for_completion_timeout(&wm8962->fll_lock, timeout);
+	ret = 0;
+
+	if (fll1 & WM8962_FLL_ENA) {
+		/* This should be a massive overestimate but go even
+		 * higher if we'll error out
+		 */
+		if (wm8962->irq)
+			timeout = msecs_to_jiffies(5);
+		else
+			timeout = msecs_to_jiffies(1);
+
+		timeout = wait_for_completion_timeout(&wm8962->fll_lock,
+						      timeout);
+
+		if (timeout == 0 && wm8962->irq) {
+			dev_err(codec->dev, "FLL lock timed out");
+			ret = -ETIMEDOUT;
+		}
+	}

 	wm8962->fll_fref = Fref;
 	wm8962->fll_fout = Fout;
 	wm8962->fll_src = source;

-	return 0;
+	return ret;
 }

 static int wm8962_mute(struct snd_soc_dai *dai, int mute)


ASoC: wm8962: Replace codec->control_data with wm8962->regmap

With the ongoing component-ization of the ASoC framework and the continuing
migration to using regmap for IO the control_data field of the snd_soc_codec
struct will eventually be removed. Prepare the wm8962 driver for this by using
wm8962->regmap instead of accessing the CODEC's control_data field.

Signed-off-by: Lars-Peter Clausen <3318dc5ce3e4fb7c28a0b841b6801c884e1d0896@metafoo.de>
Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@linaro.org>


ASoC: wm8994: Suppress noop updates of FLL K

Using snd_soc_write() means we always write to the register even if it
already contains the newly calculated value.

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>

--- sound/soc/codecs/wm8994.c
+++ sound/soc/codecs/wm8994.c
@@ -1918,7 +1918,8 @@
 			    WM8994_FLL1_OUTDIV_MASK |
 			    WM8994_FLL1_FRATIO_MASK, reg);

-	snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
+	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset,
+			    WM8994_FLL1_K_MASK, fll.k);

 	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
 			    WM8994_FLL1_N_MASK,


commit patch from Nall for riffutil

commit patch from Nall for riffutil

Original commit message from CVS:
commit patch from Nall for riffutil

--- gst-libs/gst/riff/riffutil.c
+++ gst-libs/gst/riff/riffutil.c
@@ -27,8 +27,8 @@
 gulong gst_riff_fourcc_to_id(gchar *fourcc) {
   g_return_val_if_fail(fourcc != NULL, 0);

-  return (fourcc[0] << 0) | (fourcc[1] << 8) |
-         (fourcc[2] << 16) | (fourcc[3] << 24);
+  return GUINT32_FROM_LE((gulong)(fourcc[0] << 0) | (fourcc[1] << 8) |
+         (fourcc[2] << 16) | (fourcc[3] << 24));
 }

 gchar *gst_riff_id_to_fourcc(gulong id) {
@@ -36,6 +36,7 @@

   g_return_val_if_fail(fourcc != NULL, NULL);

+  id = GUINT32_FROM_LE(id);
   fourcc[0] = (id >> 0) & 0xff;
   fourcc[1] = (id >> 8) & 0xff;
   fourcc[2] = (id >> 16) & 0xff;


ASoC: Hook up DC servo completion IRQ for WM8994 and WM8958

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>

--- sound/soc/codecs/wm8994.c
+++ sound/soc/codecs/wm8994.c
@@ -2932,6 +2932,12 @@
 		break;
 	}

+	ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+				 wm_hubs_dcs_done, "DC servo done",
+				 &wm8994->hubs);
+	if (ret == 0)
+		wm8994->hubs.dcs_done_irq = true;
+
 	switch (control->type) {
 	case WM8994:
 		if (wm8994->micdet_irq) {
@@ -3173,6 +3179,8 @@
 	wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
 	if (wm8994->micdet_irq)
 		free_irq(wm8994->micdet_irq, wm8994);
+	wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+			&wm8994->hubs);
 err:
 	kfree(wm8994);
 	return ret;
@@ -3186,6 +3194,9 @@
 	wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);

 	pm_runtime_disable(codec->dev);
+
+	wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+			&wm8994->hubs);

 	switch (control->type) {
 	case WM8994:


set SYNC_POINT flag on the frame if omx provides us with a SYNCFRAME flagged buffer

--- gst/droidcodec/gstdroidenc.c
+++ gst/droidcodec/gstdroidenc.c
@@ -256,6 +256,10 @@
         gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER (enc),
         buff->nFilledLen);

+    if (buff->nFlags & OMX_BUFFERFLAG_SYNCFRAME) {
+      GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
+    }
+
     gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
     memcpy (map.data, buff->pBuffer + buff->nOffset, buff->nFilledLen);
     gst_buffer_unmap (frame->output_buffer, &map);


ASoC: Clear completions from late WM8996 FLL lock IRQs

In case we have a pending completion, for example due to a problem with
the input clock which got corrected after we timed out.

Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <a57ef363056e61beffa2efa59c68550d40db03b0@ti.com>

--- sound/soc/codecs/wm8996.c
+++ sound/soc/codecs/wm8996.c
@@ -2111,6 +2111,9 @@

 	snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);

+	/* Clear any pending completions (eg, from failed startups) */
+	try_wait_for_completion(&wm8996->fll_lock);
+
 	snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
 			    WM8996_FLL_ENA, WM8996_FLL_ENA);


vaapipostproc: minor clean-ups.

vaapipostproc: minor clean-ups.

Use g_clear_object() wherever appropriate and remove dead-code.

--- gst/vaapi/gstvaapipostproc.c
+++ gst/vaapi/gstvaapipostproc.c
@@ -232,10 +232,7 @@
 static gboolean
 gst_vaapipostproc_stop(GstVaapiPostproc *postproc)
 {
-    if (postproc->display) {
-        g_object_unref(postproc->display);
-        postproc->display = NULL;
-    }
+    g_clear_object(&postproc->display);
     return TRUE;
 }

@@ -246,15 +243,13 @@
     GstVaapiSurfaceProxy *proxy;
     GstClockTime timestamp;
     GstFlowReturn ret;
-    GstBuffer *outbuf = NULL;
+    GstBuffer *outbuf;
     guint outbuf_flags, flags;
     gboolean tff;

     meta = gst_buffer_get_vaapi_video_meta(buf);
     if (!meta)
         goto error_invalid_buffer;
-
-    flags = gst_vaapi_video_meta_get_render_flags(meta);

     /* Deinterlacing disabled, push frame */
     if (!postproc->deinterlace) {
@@ -272,8 +267,9 @@
     proxy      = gst_vaapi_video_meta_get_surface_proxy(meta);
     tff        = GST_BUFFER_FLAG_IS_SET(buf, GST_VIDEO_BUFFER_FLAG_TFF);

-    flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD|
-               GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD);
+    flags = gst_vaapi_video_meta_get_render_flags(meta) &
+        ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD|
+          GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD);

     /* First field */
     outbuf = gst_vaapi_video_buffer_new_with_surface_proxy(proxy);


Another escape issue

Another escape issue

--- src/lio/authn/psk_server.c
+++ src/lio/authn/psk_server.c
@@ -491,7 +491,7 @@
         apr_hash_this(hi, NULL, &hlen, (void **)&pa);
         fprintf(fd, "[account-%s]\n", pa->account);
         zmq_z85_encode(key_z85, (unsigned char *)pa->key, pa->key_len);
-        key_escaped = tbx_stk_escape_text("[]\\#${}", '\\', key_z85);
+        key_escaped = tbx_stk_escape_text(TBX_INIP_ESCAPE_CHARS, '\\', key_z85);
         n = strlen(key_escaped);
         if (n<40) {
             fprintf(fd, "ERROR: Key is to short! encrypted keylen=%d\n", pa->key_len);


ASoC: Use data based init for wm9713 DAPM

Signed-off-by: Lu Guanqun <2dad72ae5fe48bf7bd43ddccece96ab3f4a6c25d@intel.com>
Acked-by: Liam Girdwood <a57ef363056e61beffa2efa59c68550d40db03b0@ti.com>
Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@opensource.wolfsonmicro.com>

--- sound/soc/codecs/wm9713.c
+++ sound/soc/codecs/wm9713.c
@@ -487,7 +487,7 @@
 SND_SOC_DAPM_VMID("VMID"),
 };

-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm9713_audio_map[] = {
 	/* left HP mixer */
 	{"Left HP Mixer", "Beep Playback Switch",    "PCBEEP"},
 	{"Left HP Mixer", "Voice Playback Switch",   "Voice DAC"},
@@ -643,18 +643,6 @@
 	{"Capture Mono Mux", "Left", "Left Capture Source"},
 	{"Capture Mono Mux", "Right", "Right Capture Source"},
 };
-
-static int wm9713_add_widgets(struct snd_soc_codec *codec)
-{
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
-				  ARRAY_SIZE(wm9713_dapm_widgets));
-
-	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-	return 0;
-}

 static unsigned int ac97_read(struct snd_soc_codec *codec,
 	unsigned int reg)
@@ -1231,7 +1219,6 @@

 	snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
 				ARRAY_SIZE(wm9713_snd_ac97_controls));
-	wm9713_add_widgets(codec);

 	return 0;

@@ -1262,6 +1249,10 @@
 	.reg_word_size = sizeof(u16),
 	.reg_cache_step = 2,
 	.reg_cache_default = wm9713_reg,
+	.dapm_widgets = wm9713_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
+	.dapm_routes = wm9713_audio_map,
+	.num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
 };

 static __devinit int wm9713_probe(struct platform_device *pdev)


* change to ANSI C style.

* change to ANSI C style.

--- gtk2/ext/gtk2/rbgtkfilesel.c
+++ gtk2/ext/gtk2/rbgtkfilesel.c
@@ -17,10 +17,7 @@
 #define _SELF(self) GTK_FILE_SELECTION(RVAL2GOBJ(self))

 static VALUE
-fsel_initialize(argc, argv, self)
-    int argc;
-    VALUE *argv;
-    VALUE self;
+fsel_initialize(int argc, VALUE *argv, VALUE self)
 {
     VALUE title;
     rb_scan_args(argc, argv, "01", &title);
@@ -29,32 +26,28 @@
 }

 static VALUE
-fsel_complete(self, pattern)
-    VALUE self, pattern;
+fsel_complete(VALUE self, VALUE pattern)
 {
     gtk_file_selection_complete(_SELF(self), RVAL2CSTR(pattern));
     return self;
 }

 static VALUE
-fsel_show_fileop_buttons(self)
-    VALUE self;
+fsel_show_fileop_buttons(VALUE self)
 {
     gtk_file_selection_show_fileop_buttons(_SELF(self));
     return Qnil;
 }

 static VALUE
-fsel_hide_fileop_buttons(self)
-    VALUE self;
+fsel_hide_fileop_buttons(VALUE self)
 {
     gtk_file_selection_hide_fileop_buttons(_SELF(self));
     return Qnil;
 }

 static VALUE
-fsel_get_selections(self)
-    VALUE self;
+fsel_get_selections(VALUE self)
 {
     gchar** ptr = gtk_file_selection_get_selections(_SELF(self));
     gchar** selections = ptr;
@@ -70,65 +63,56 @@
 }

 static VALUE
-fsel_fileop_dialog(self)
-    VALUE self;
+fsel_fileop_dialog(VALUE self)
 {
     GtkWidget* widget = _SELF(self)->fileop_dialog;
     return widget ? GOBJ2RVAL(widget) : Qnil;
 }

 static VALUE
-fsel_dir_list(self)
-    VALUE self;
+fsel_dir_list(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->dir_list);
 }

 static VALUE
-fsel_file_list(self)
-    VALUE self;
+fsel_file_list(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->file_list);
 }

 static VALUE
-fsel_ok_button(self)
-    VALUE self;
+fsel_ok_button(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->ok_button);
 }

 static VALUE
-fsel_cancel_button(self)
-    VALUE self;
+fsel_cancel_button(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->cancel_button);
 }

 static VALUE
-fsel_history_pulldown(self)
-    VALUE self;
+fsel_history_pulldown(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->history_pulldown);
 }

 static VALUE
-fsel_fileop_c_dir(self)
-    VALUE self;
+fsel_fileop_c_dir(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->fileop_c_dir);
 }

 static VALUE
-fsel_fileop_del_file(self)
-    VALUE self;
+fsel_fileop_del_file(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->fileop_del_file);
 }

 static VALUE
-fsel_fileop_ren_file(self)
-    VALUE self;
+fsel_fileop_ren_file(VALUE self)
 {
     return GOBJ2RVAL(_SELF(self)->fileop_ren_file);
 }


Have Jerase retry with an extra drive cushion

--- src/lio/segment/jerasure.c
+++ src/lio/segment/jerasure.c
@@ -1773,7 +1773,11 @@
                         log_printf(5, "seg=" XIDT " recoverable write error off=" XOT " len= "XOT " n_parity=%d n_failed=%d\n",
                                    segment_id(sw->seg), sw->iov[j].offset, sw->iov[j].len, s->n_parity_devs, op_status.error_code);
                         status.error_code = op_status.error_code;
-                        soft_error = 1;
+                        if (op_status.error_code == s->n_parity_devs) {  //** If we are at the RS limit then let's try again
+                            soft_error = 2;
+                        } else if (soft_error != 2) {
+                            soft_error = 1;
+                        }
                     }
                 }

@@ -1823,11 +1827,11 @@
                 poff = 0;
                 for (k=0; k<s->n_data_devs; k++) {
                     if (tbv.buffer[0].iov_base != NULL) {
-			if (quick == 1) {
+                        if (quick == 1) {
 	                        ptr[pstripe + k] = tbv.buffer[0].iov_base + poff;
-			} else {
+                        } else {
 	                        ptr[pstripe + k] = straddle_ptr + poff;
-			}
+                        }
                     } else { //** Got an error page
                         if (empty == NULL) {
                             empty = &(parity[parity_len]);
@@ -1887,7 +1891,7 @@
     gop_opque_free(q, OP_DESTROY);

     //** See if we need to retry without blacklisting enabled
-    if ((hard_error > 0) && (s->blacklist) && (loop == 0)) {
+    if (((soft_error == 2) || (hard_error > 0)) && (s->blacklist) && (loop == 0)) {
         log_printf(5, "sid=" XIDT " RETRY Looks like we failed to write with blacklisting enabled so trying again\n", segment_id(sw->seg));
         loop++;
         goto tryagain;


quick-fix

quick-fix

--- source/StreamGenerators.h
+++ source/StreamGenerators.h
@@ -265,7 +265,7 @@
 Stream<RemoveRef<T>> MakeStream::singleton(T&& value) {
     using R = RemoveRef<T>;
     return make_stream_provider<provider::Singleton, R>
-        (std::forward<R>(value));
+        (std::forward<T>(value));
 }

 template<typename Iterator>


Fix compiler warning for CpMsgSetTime()

Fix compiler warning for CpMsgSetTime()

CpMsgDlcToSize() and CpMsgSizeToDlc() are now inline


implemented gtk_tree_model_iter_nth_child()

* gundo-ui/gundo-popup-model.c: finish the implementation for now; we don't
  have any warnings now

--- gundo-ui/gundo-popup-model.c
+++ gundo-ui/gundo-popup-model.c
@@ -181,6 +181,18 @@
   return gundo_history_can_undo (PRIV (model)->history);
 }

+static gboolean
+model_iter_nth_child (GtkTreeModel* model,
+                      GtkTreeIter * iter,
+                      GtkTreeIter * parent,
+                      gint          n)
+{
+  if (parent)
+    return FALSE;
+
+  return model_iter_from_index (model, iter, n);
+}
+
 static void
 implement_gtk_tree_model (GtkTreeModelIface* iface)
 {
@@ -191,5 +203,6 @@

   iface->iter_next       = model_iter_next;
   iface->iter_has_child  = model_iter_has_child;
-}
-
+  iface->iter_nth_child  = model_iter_nth_child;
+}
+


i40e compilation fix for RH8

i40e compilation fix for RH8

--- drivers/intel/i40e/i40e-2.4.6-zc/src/i40e_main.c
+++ drivers/intel/i40e/i40e-2.4.6-zc/src/i40e_main.c
@@ -300,7 +300,11 @@
  * device is munged, not just the one netdev port, so go for the full
  * reset.
  **/
+#ifdef HAVE_TX_TIMEOUT_TXQUEUE
+static void i40e_tx_timeout(struct net_device *netdev, unsigned int txqueue)
+#else
 static void i40e_tx_timeout(struct net_device *netdev)
+#endif
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_vsi *vsi = np->vsi;
@@ -13367,10 +13371,10 @@
 			result = PCI_ERS_RESULT_DISCONNECT;
 	}

-	err = pci_cleanup_aer_uncorrect_error_status(pdev);
+	err = pci_aer_clear_nonfatal_status(pdev);
 	if (err) {
 		dev_info(&pdev->dev,
-			 "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n",
+			 "pci_aer_clear_nonfatal_status failed 0x%0x\n",
 			 err);
 		/* non-fatal, continue */
 	}


Handle consecutive slashes before ".."

Handle consecutive slashes before ".."


bnx2x: fix I2C non-respondent issue

bnx2x: fix I2C non-respondent issue

When I2C is not responding it's usually due to a previous
unexpected reset during I2C operation. We release it by
powering down and up the SFP+ module.

Signed-off-by: Yaniv Rosner <c79402ec94292eaae8ed78db632df3ae21af09cf@broadcom.com>
Signed-off-by: Yuval Mintz <e41f02d814a2deb46df84f79ae7bb01b88dc4260@broadcom.com>
Signed-off-by: Eilon Greenstein <5ba67022bcc5f9ee9b9819ddc35fa83823aa47ee@broadcom.com>
Signed-off-by: David S. Miller <fe08d3c717adf2ae63592e4c9aec6e3e404d8e3e@davemloft.net>

--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -40,6 +40,7 @@
 #define I2C_BSC0			0
 #define I2C_BSC1			1
 #define I2C_WA_RETRY_CNT		3
+#define I2C_WA_PWR_ITER			(I2C_WA_RETRY_CNT - 1)
 #define MCPR_IMC_COMMAND_READ_OP	1
 #define MCPR_IMC_COMMAND_WRITE_OP	2

@@ -7659,6 +7660,28 @@
 	return -EINVAL;
 }

+static void bnx2x_warpcore_power_module(struct link_params *params,
+					struct bnx2x_phy *phy,
+					u8 power)
+{
+	u32 pin_cfg;
+	struct bnx2x *bp = params->bp;
+
+	pin_cfg = (REG_RD(bp, params->shmem_base +
+			  offsetof(struct shmem_region,
+			dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
+			PORT_HW_CFG_E3_PWR_DIS_MASK) >>
+			PORT_HW_CFG_E3_PWR_DIS_SHIFT;
+
+	if (pin_cfg == PIN_CFG_NA)
+		return;
+	DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
+		       power, pin_cfg);
+	/* Low ==> corresponding SFP+ module is powered
+	 * high ==> the SFP+ module is powered down
+	 */
+	bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
+}
 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
 						 struct link_params *params,
 						 u16 addr, u8 byte_cnt,
@@ -7678,6 +7701,12 @@
 	/* 4 byte aligned address */
 	addr32 = addr & (~0x3);
 	do {
+		if (cnt == I2C_WA_PWR_ITER) {
+			bnx2x_warpcore_power_module(params, phy, 0);
+			/* Note that 100us are not enough here */
+			usleep_range(1000,1000);
+			bnx2x_warpcore_power_module(params, phy, 1);
+		}
 		rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
 				    data_array);
 	} while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
@@ -8198,29 +8227,6 @@
 		bnx2x_set_e3_module_fault_led(params, gpio_mode);
 	} else
 		bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
-}
-
-static void bnx2x_warpcore_power_module(struct link_params *params,
-					struct bnx2x_phy *phy,
-					u8 power)
-{
-	u32 pin_cfg;
-	struct bnx2x *bp = params->bp;
-
-	pin_cfg = (REG_RD(bp, params->shmem_base +
-			  offsetof(struct shmem_region,
-			dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
-			PORT_HW_CFG_E3_PWR_DIS_MASK) >>
-			PORT_HW_CFG_E3_PWR_DIS_SHIFT;
-
-	if (pin_cfg == PIN_CFG_NA)
-		return;
-	DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
-		       power, pin_cfg);
-	/* Low ==> corresponding SFP+ module is powered
-	 * high ==> the SFP+ module is powered down
-	 */
-	bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
 }

 static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,


ASoC: soc-compress: fix double unlock of fe card mutex

Fix double unlock of fe card mutex introduced by patch 8f70e515a8bb
"ASoC: soc-pcm: fix dpcm_path_get error handling"

The first unlock is at line 106, and the unlock is at line 149. we
should remove the first unlock.

Reported-by: Dan Carpenter <ff341aa343d564f9e53e9dcb6996be8c04859a66@oracle.com>
Signed-off-by: Qiao Zhou <50a4e6fe771972bee9e282d96184a32f17fd4b37@marvell.com>
Signed-off-by: Mark Brown <b51b9a92386687a9ac927cebfa0f978adeb8cea5@kernel.org>


bnx2x: Fix SFP+ current leakage

bnx2x: Fix SFP+ current leakage

Per measurements, the SFP+ suffered from small current leakage in two cases:
 - When no module was plugged and TX laser was disabled. The fix was to enable
   it, and when module is plugged in, check if it needs to be disabled.
 - When over-current event occurs due to invalid SFP+ module, the HW basically
   shuts down the current for this module, but the SW needs to complete this
   by issuing a power down via a GPIO.

Signed-off-by: Yaniv Rosner <863d04138a679eefe08d0a31ca0f8f3a07fae2ff@broadcom.com>
Signed-off-by: Eilon Greenstein <5ba67022bcc5f9ee9b9819ddc35fa83823aa47ee@broadcom.com>
Signed-off-by: David S. Miller <fe08d3c717adf2ae63592e4c9aec6e3e404d8e3e@davemloft.net>

--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -4414,6 +4414,27 @@
 	}
 }

+static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
+					 struct bnx2x_phy *phy,
+					 u8 tx_en)
+{
+	struct bnx2x *bp = params->bp;
+	u32 cfg_pin;
+	u8 port = params->port;
+
+	cfg_pin = REG_RD(bp, params->shmem_base +
+			 offsetof(struct shmem_region,
+				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
+		PORT_HW_CFG_E3_TX_LASER_MASK;
+	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
+	DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
+
+	/* For 20G, the expected pin to be used is 3 pins after the current */
+	bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
+	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
+		bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
+}
+
 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
 				       struct link_params *params,
 				       struct link_vars *vars)
@@ -4474,9 +4495,14 @@
 			break;

 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
-			/* Issue Module detection */
+			/* Issue Module detection if module is plugged, or
+			 * enabled transmitter to avoid current leakage in case
+			 * no module is connected
+			 */
 			if (bnx2x_is_sfp_module_plugged(phy, params))
 				bnx2x_sfp_module_detection(phy, params);
+			else
+				bnx2x_sfp_e3_set_transmitter(params, phy, 1);

 			bnx2x_warpcore_config_sfi(phy, params);
 			break;
@@ -4511,27 +4537,6 @@
 	/* Take lane out of reset after configuration is finished */
 	bnx2x_warpcore_reset_lane(bp, phy, 0);
 	DP(NETIF_MSG_LINK, "Exit config init\n");
-}
-
-static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
-					 struct bnx2x_phy *phy,
-					 u8 tx_en)
-{
-	struct bnx2x *bp = params->bp;
-	u32 cfg_pin;
-	u8 port = params->port;
-
-	cfg_pin = REG_RD(bp, params->shmem_base +
-				offsetof(struct shmem_region,
-				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
-				PORT_HW_CFG_TX_LASER_MASK;
-	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
-	DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
-	/* For 20G, the expected pin to be used is 3 pins after the current */
-
-	bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
-	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
-		bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
 }

 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
@@ -7833,7 +7838,6 @@
 }

 static void bnx2x_warpcore_power_module(struct link_params *params,
-					struct bnx2x_phy *phy,
 					u8 power)
 {
 	u32 pin_cfg;
@@ -7875,10 +7879,10 @@
 	addr32 = addr & (~0x3);
 	do {
 		if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
-			bnx2x_warpcore_power_module(params, phy, 0);
+			bnx2x_warpcore_power_module(params, 0);
 			/* Note that 100us are not enough here */
 			usleep_range(1000, 2000);
-			bnx2x_warpcore_power_module(params, phy, 1);
+			bnx2x_warpcore_power_module(params, 1);
 		}
 		rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
 				    data_array);
@@ -8464,7 +8468,7 @@
 				    struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
-	bnx2x_warpcore_power_module(params, phy, 0);
+	bnx2x_warpcore_power_module(params, 0);
 	/* Put Warpcore in low power mode */
 	REG_WR(bp, MISC_REG_WC0_RESET, 0x0c0e);

@@ -8487,7 +8491,7 @@
 		bnx2x_8727_power_module(params->bp, phy, power);
 		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
-		bnx2x_warpcore_power_module(params, phy, power);
+		bnx2x_warpcore_power_module(params, power);
 		break;
 	default:
 		break;
@@ -8560,7 +8564,8 @@
 	u32 val = REG_RD(bp, params->shmem_base +
 			     offsetof(struct shmem_region, dev_info.
 				     port_feature_config[params->port].config));
-
+	/* Enabled transmitter by default */
+	bnx2x_sfp_set_transmitter(params, phy, 1);
 	DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
 		 params->port);
 	/* Power up module */
@@ -8593,14 +8598,12 @@
 	 */
 	bnx2x_set_limiting_mode(params, phy, edc_mode);

-	/* Enable transmit for this module if the module is approved, or
-	 * if unapproved modules should also enable the Tx laser
+	/* Disable transmit for this module if the module is not approved, and
+	 * laser needs to be disabled.
 	 */
-	if (rc == 0 ||
-	    (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
-	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
-		bnx2x_sfp_set_transmitter(params, phy, 1);
-	else
+	if ((rc) &&
+	    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
+	     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER))
 		bnx2x_sfp_set_transmitter(params, phy, 0);

 	return rc;
@@ -8612,11 +8615,13 @@
 	struct bnx2x_phy *phy;
 	u32 gpio_val;
 	u8 gpio_num, gpio_port;
-	if (CHIP_IS_E3(bp))
+	if (CHIP_IS_E3(bp)) {
 		phy = &params->phy[INT_PHY];
-	else
+		/* Always enable TX laser,will be disabled in case of fault */
+		bnx2x_sfp_set_transmitter(params, phy, 1);
+	} else {
 		phy = &params->phy[EXT_PHY1];
-
+	}
 	if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
 				      params->port, &gpio_num, &gpio_port) ==
 	    -EINVAL) {
@@ -8661,10 +8666,6 @@
 			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
 		}
 	} else {
-		u32 val = REG_RD(bp, params->shmem_base +
-				 offsetof(struct shmem_region, dev_info.
-					  port_feature_config[params->port].
-					  config));
 		bnx2x_set_gpio_int(bp, gpio_num,
 				   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
 				   gpio_port);
@@ -8672,10 +8673,6 @@
 		 * Disable transmit for this module
 		 */
 		phy->media_type = ETH_PHY_NOT_PRESENT;
-		if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
-		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) ||
-		    CHIP_IS_E3(bp))
-			bnx2x_sfp_set_transmitter(params, phy, 0);
 	}
 }

@@ -9415,6 +9412,7 @@
 			bnx2x_cl45_read(bp, phy,
 				MDIO_PMA_DEVAD,
 				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
+			bnx2x_8727_power_module(params->bp, phy, 0);
 			return 0;
 		}
 	} /* Over current check */
@@ -13194,6 +13192,7 @@
 					    " error.\n",
 			 params->port);
 			vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
+			bnx2x_warpcore_power_module(params, 0);
 		}
 	} else
 		vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;


qlcnic: silence false positive overflow warning

We actually store the MAC address as well as the board_name here.  The
longest board_name is 75 characters so there is more than enough room
to hold the 17 character MAC and the ": " divider.  But making this
buffer larger silences a static checker warning.

Signed-off-by: Dan Carpenter <ff341aa343d564f9e53e9dcb6996be8c04859a66@oracle.com>
Acked-By: Jitendra Kalsaria <c4f4e272f8d41a0305b1542acaa5e2b88e138f06@qlogic.com>
Signed-off-by: David S. Miller <fe08d3c717adf2ae63592e4c9aec6e3e404d8e3e@davemloft.net>

--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1813,7 +1813,7 @@
 	struct qlcnic_hardware_context *ahw;
 	int err, pci_using_dac = -1;
 	u32 capab2;
-	char board_name[QLCNIC_MAX_BOARD_NAME_LEN];
+	char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */

 	err = pci_enable_device(pdev);
 	if (err)


Use curses_cleanup() with an empty reason to properly free windows memory at exit.

--- dcf77pi.c
+++ dcf77pi.c
@@ -58,7 +58,8 @@
 	if (main_win != NULL)
 		delwin(main_win);
 	endwin();
-	printf("%s", reason);
+	if (reason != NULL)
+		printf("%s", reason);
 }

 void
@@ -348,9 +349,9 @@
 		}
 	}

-	cleanup();
-	if (infilename == NULL) {
-		endwin();
-	}
+	if (infilename == NULL)
+		curses_cleanup(NULL);
+	else
+		cleanup();
 	return 0;
 }


brcmfmac: prohibit ACPI power management for brcmfmac driver

ACPI will manage WiFi chip's power state during suspend/resume
process on some tablet platforms(such as ASUS T100TA). This is
not supported by brcmfmac driver now, and the context of WiFi
chip will be damaged after resume. This patch informs ACPI not
to manage WiFi chip's power state.

Signed-off-by: Zhonghui Fu <737f31c534f6779be6dc7b3808cab016164a88e8@linux.intel.com>
Acked-by: Arend van Spriel <06447fbe43693466d3293d0b5eaeeb2efd3d7d3a@broadcom.com>
Signed-off-by: Kalle Valo <7081a7d99b8c74c0698a728df19e3915a995d7e1@codeaurora.org>


Fix using a non xft font with xft compiled

Due to #ifndef XFT, which is defined in this case, a step to set
the style was beign skipped when using a BMF font.
Free BMF fonts even when XFT is defined.
Simplified return value in defont_get_text_width.

--- de/font.c
+++ de/font.c
@@ -221,6 +221,26 @@
     style->font=font;
     font->refcount++;

+#ifdef HAVE_X11_BMF
+    if(style->font->fontstruct!=NULL){
+        XSetFont(ioncore_g.dpy, style->normal_gc,
+                 style->font->fontstruct->fid);
+    }
+#endif /* HAVE_X11_BMF */
+    return TRUE;
+}
+
+
+bool de_load_font_for_style(DEStyle *style, const char *fontname)
+{
+    if(style->font!=NULL)
+        de_free_font(style->font);
+
+    style->font=de_load_font(fontname);
+
+    if(style->font==NULL)
+        return FALSE;
+
 #ifndef HAVE_X11_XFT
     if(style->font->fontstruct!=NULL){
         XSetFont(ioncore_g.dpy, style->normal_gc,
@@ -232,27 +252,6 @@
 }

-bool de_load_font_for_style(DEStyle *style, const char *fontname)
-{
-    if(style->font!=NULL)
-        de_free_font(style->font);
-
-    style->font=de_load_font(fontname);
-
-    if(style->font==NULL)
-        return FALSE;
-
-#ifndef HAVE_X11_XFT
-    if(style->font->fontstruct!=NULL){
-        XSetFont(ioncore_g.dpy, style->normal_gc,
-                 style->font->fontstruct->fid);
-    }
-
-#endif /* ! HAVE_X11_XFT */
-    return TRUE;
-}
-
-
 void de_free_font(DEFont *font)
 {
     if(--font->refcount!=0)
@@ -261,12 +260,13 @@
 #ifdef HAVE_X11_XFT
     if(font->font!=NULL)
         XftFontClose(ioncore_g.dpy, font->font);
-#else /* HAVE_X11_XFT */
+#endif /* HAVE_X11_XFT */
+#if HAVE_X11_BMF
     if(font->fontset!=NULL)
         XFreeFontSet(ioncore_g.dpy, font->fontset);
     if(font->fontstruct!=NULL)
         XFreeFont(ioncore_g.dpy, font->fontstruct);
-#endif /* HAVE_X11_XFT */
+#endif /* HAVE_X11_BMF */
     if(font->pattern!=NULL)
         free(font->pattern);

@@ -373,9 +373,7 @@
         }
     }
 #endif /* HAVE_X11_BMF */
-    else{
-        return 0;
-    }
+    return 0;
 }

@@ -507,7 +505,6 @@
         }
 #endif
     }
-
 }


staging/lustre: Always clamp cdls_delay between min and max

In libcfs_debug_vmsg2, cdls_delay is only clamped between the minimum
and the maximum when it is increased by multiplying by the backoff
factor.  It is not clamped when it is decreased by dividing by the
backoff factor.  This allows it to achieve values less than the
minimum, which allows a console message to be printed that should have
been skipped.  This patch moves the clamping outside of the else
statement, ensuring that cdls_delay is always between the min and the
max after the first time through libcfs_debug_vmsg2.

Signed-off-by: Ryan Haasken <9b87c4e2e634a27bf5dc11cefe49c1d3bb6c3043@cray.com>
Reviewed-on: http://review.whamcloud.com/9503
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4711
Reviewed-by: Chris Horn <2b37723cebf1ae30e02f5498d4fdc651eea76f8e@cray.com>
Reviewed-by: Ann Koehler <58da972422935a8ed6008561b42b94133a217d5a@cray.com>
Reviewed-by: Andreas Dilger <fb9bfcd2d82414390637ce05921b7d9f9341a408@intel.com>
Signed-off-by: Oleg Drokin <65b2ca07820e940f66d8901813c729ec10a548f5@intel.com>
Signed-off-by: Greg Kroah-Hartman <4645f7897fd33786a2ee1264d590b3c400559d85@linuxfoundation.org>


Kraken: Fix the way best journey is picked (filter)

based on sooner arrival (clockwise), or later departure (anti-clockwise)

--- source/routing/journey.h
+++ source/routing/journey.h
@@ -96,12 +96,12 @@
     if (journeys.size() == 0)
         throw recoverable_exception("get_best_journey takes a list of at least 1 journey");

-    auto earliest_journey = [](const Journey& j1, const Journey& j2) { return j1.departure_dt < j2.departure_dt; };
+    auto departure_comp = [](const Journey& j1, const Journey& j2) { return j1.departure_dt < j2.departure_dt; };

-    auto latest_journey = [](const Journey& j1, const Journey& j2) { return j1.arrival_dt < j2.arrival_dt; };
+    auto arrival_comp = [](const Journey& j1, const Journey& j2) { return j1.arrival_dt < j2.arrival_dt; };

-    const auto best = clockwise ? std::min_element(journeys.cbegin(), journeys.cend(), earliest_journey)
-                                : std::max_element(journeys.cbegin(), journeys.cend(), latest_journey);
+    const auto best = clockwise ? std::min_element(journeys.cbegin(), journeys.cend(), arrival_comp)
+                                : std::max_element(journeys.cbegin(), journeys.cend(), departure_comp);

     return *best;
 }


[exotica_core] BoxQP: Feasible warm-start

--- exotica_core/include/exotica_core/tools/box_qp.h
+++ exotica_core/include/exotica_core/tools/box_qp.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2019, University of Edinburgh
+// Copyright (c) 2019-2020, University of Edinburgh, University of Oxford
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
 typedef struct BoxQPSolution
 {
     Eigen::MatrixXd Hff_inv;
-    Eigen::MatrixXd x;
+    Eigen::VectorXd x;
     std::vector<size_t> free_idx;
     std::vector<size_t> clamped_idx;
 } BoxQPSolution;
@@ -53,6 +53,12 @@
     std::vector<size_t> clamped_idx, free_idx;
     Eigen::VectorXd grad = q + H * x_init;
     Eigen::MatrixXd Hff, Hfc, Hff_inv;
+
+    // Ensure a feasible warm-start
+    for (int i = 0; i < x.size(); ++i)
+    {
+        x(i) = std::max(std::min(x_init(i), b_high(i)), b_low(i));
+    }

     Hff_inv = (Eigen::MatrixXd::Identity(H.rows(), H.cols()) * 1e-5 + H).inverse();


Avoid unstable duk_tval pointer

Avoid unstable duk_tval pointer

--- src-input/duk_api_stack.c
+++ src-input/duk_api_stack.c
@@ -3230,8 +3230,14 @@
 	duk_hobject *h_obj;
 	duk_small_uint_t classnum;
 	duk_small_uint_t stridx;
-
-	DUK_ASSERT_API_ENTRY(thr);
+	duk_tval tv_tmp;
+
+	DUK_ASSERT_API_ENTRY(thr);
+	DUK_ASSERT(tv != NULL);
+
+	/* Stabilize 'tv', duk_push_literal() may trigger side effects. */
+	DUK_TVAL_SET_TVAL(&tv_tmp, tv);
+	tv = &tv_tmp;

 	/* Conceptually for any non-undefined/null value we should do a
 	 * ToObject() coercion and look up @@toStringTag (from the object


Added DMA register definition.

Added DMA register definition.

error: pathspec 'dma/dma.h' did not match any file(s) known to git

--- dma/dma.h
+++ dma/dma.h
@@ -0,0 +1,37 @@
+#ifndef DMA_H
+#define DMA_H
+
+#include <stdint.h>
+
+struct DMA_stream_reg_t {
+	volatile uint32_t CR;
+	volatile uint32_t NDTR;
+	volatile uint32_t PAR;
+	volatile uint32_t M0AR;
+	volatile uint32_t M1AR;
+	volatile uint32_t FCR;
+};
+
+struct DMA_reg_t {
+	volatile uint32_t LISR;
+	volatile uint32_t HISR;
+	volatile uint32_t LIFCR;
+	volatile uint32_t HIFCR;
+	DMA_stream_reg_t S[8];
+};
+
+class DMA_t {
+	public:
+		DMA_reg_t& reg;
+
+		DMA_t(uint32_t reg_addr) : reg(*(DMA_reg_t*)reg_addr) {}
+};
+
+#if defined(STM32F1)
+
+#elif defined(STM32F4)
+static DMA_t DMA1(0x40026000);
+static DMA_t DMA2(0x40026400);
+#endif
+
+#endif


parse_kvs_servers refactored into separate func

--- agent_config.c
+++ agent_config.c
@@ -22,6 +22,14 @@
                                     proxy_behavior  *next,
                                     int   next_num,
                                     char *descrip);
+
+char *parse_kvs_servers(char *prefix,
+                        char *pool_name,
+                        kvpair_t *kvs,
+                        char **servers,
+                        int num_servers,
+                        proxy_behavior *behavior_head,
+                        proxy_behavior *behaviors);

 char **parse_kvs_behavior(kvpair_t *kvs,
                           char *prefix,
@@ -372,12 +380,6 @@
                     }
                 }

-                // Create a config string that libmemcached likes.
-                // See memcached_servers_parse().
-                //
-                int   config_len = 200;
-                char *config_str = calloc(config_len, 1);
-
                 // Number of servers in this pool.
                 //
                 int s = 0;
@@ -390,62 +392,13 @@
                 proxy_behavior *behaviors =
                     calloc(s, sizeof(proxy_behavior));

-                if (config_str != NULL &&
-                    behaviors != NULL) {
-                    for (int j = 0; servers[j]; j++) {
-                        assert(j < s);
-
-                        // Inherit default behavior.
-                        //
-                        behaviors[j] = proxyb;
-
-                        parse_kvs_behavior(kvs, "svr", servers[j],
-                                           &behaviors[j]);
-
-                        // Grow config string for libmemcached.
-                        //
-                        int x = 40 + // For port and weight.
-                            strlen(config_str) +
-                            strlen(behaviors[j].host);
-                        if (config_len < x) {
-                            config_len = 2 * (config_len + x);
-                            config_str = realloc(config_str, config_len);
-                        }
-
-                        char *config_end = config_str + strlen(config_str);
-                        if (config_end != config_str)
-                            *config_end++ = ',';
-
-                        if (strlen(behaviors[j].host) > 0 &&
-                            behaviors[j].port > 0) {
-                            snprintf(config_end,
-                                     config_len - (config_end - config_str),
-                                     "%s:%u",
-                                     behaviors[j].host,
-                                     behaviors[j].port);
-                        } else {
-                            if (settings.verbose > 1)
-                                fprintf(stderr,
-                                        "missing host:port for svr-%s in %s\n",
-                                        servers[j], pool_name);
-
-                            goto fail;
-                        }
-
-                        if (behaviors[j].downstream_weight > 0) {
-                            config_end = config_str + strlen(config_str);
-                            snprintf(config_end,
-                                     config_len - (config_end - config_str),
-                                     ":%u",
-                                     behaviors[j].downstream_weight);
-                        }
-
-                        if (settings.verbose > 1) {
-                            cproxy_dump_behavior(&behaviors[j],
-                                                 "conc on_new_config", 0);
-                        }
-                    }
-
+                char *config_str = parse_kvs_servers("svr", pool_name, kvs,
+                                                     servers, s,
+                                                     &proxyb,
+                                                     behaviors);
+
+                if (behaviors != NULL &&
+                    config_str != NULL) {
                     if (settings.verbose > 1)
                         fprintf(stderr, "conc config: %s\n",
                                 config_str);
@@ -800,6 +753,92 @@
 // ----------------------------------------------------------

 /**
+ * Parse server-level behaviors from a pool into a given
+ * array of behaviors, one entry for each server.
+ *
+ * An example prefix is "svr".
+ */
+char *parse_kvs_servers(char *prefix,
+                        char *pool_name,
+                        kvpair_t *kvs,
+                        char **servers,
+                        int num_servers,
+                        proxy_behavior *behavior_head,
+                        proxy_behavior *behaviors) {
+    assert(prefix);
+    assert(pool_name);
+    assert(kvs);
+    assert(servers);
+    assert(behavior_head);
+    assert(behaviors);
+
+    if (num_servers <= 0)
+        return NULL;
+
+    // Create a config string that libmemcached likes.
+    // See memcached_servers_parse().
+    //
+    int   config_len = 200;
+    char *config_str = calloc(config_len, 1);
+
+    for (int j = 0; servers[j]; j++) {
+        assert(j < num_servers);
+
+        // Inherit default behavior.
+        //
+        behaviors[j] = *behavior_head;
+
+        parse_kvs_behavior(kvs, prefix, servers[j],
+                           &behaviors[j]);
+
+        // Grow config string for libmemcached.
+        //
+        int x = 40 + // For port and weight.
+            strlen(config_str) +
+            strlen(behaviors[j].host);
+        if (config_len < x) {
+            config_len = 2 * (config_len + x);
+            config_str = realloc(config_str, config_len);
+        }
+
+        char *config_end = config_str + strlen(config_str);
+        if (config_end != config_str)
+            *config_end++ = ',';
+
+        if (strlen(behaviors[j].host) > 0 &&
+            behaviors[j].port > 0) {
+            snprintf(config_end,
+                     config_len - (config_end - config_str),
+                     "%s:%u",
+                     behaviors[j].host,
+                     behaviors[j].port);
+        } else {
+            if (settings.verbose > 1)
+                fprintf(stderr,
+                        "missing host:port for svr-%s in %s\n",
+                        servers[j], pool_name);
+        }
+
+        if (behaviors[j].downstream_weight > 0) {
+            config_end = config_str + strlen(config_str);
+            snprintf(config_end,
+                     config_len - (config_end - config_str),
+                     ":%u",
+                     behaviors[j].downstream_weight);
+        }
+
+        if (settings.verbose > 1) {
+            cproxy_dump_behavior(&behaviors[j],
+                                 "pks", 0);
+        }
+    }
+
+    return config_str;
+}
+
+// ----------------------------------------------------------
+
+/**
  * Parse a "[prefix]-[name]" configuration section into a behavior.
  */
 char **parse_kvs_behavior(kvpair_t *kvs,


app/testpmd: avoid process ID out of range

The 'proc_id' should be less than 'num_procs', if not, exit the testpmd
and show the error message.

Fixes: a550baf24af9 ("app/testpmd: support multi-process")

Signed-off-by: Haiyue Wang <037d5f2d0d83548aebdad8ba0c69c0b30ec44c86@intel.com>
Acked-by: Min Hu (Connor) <f02e10cb0a484c51b0f8634f83fbb4ab9ded1c6a@huawei.com>
Reviewed-by: Ferruh Yigit <ba8734c3c506d2e3557bd4ac8fdaccd25bdb9aa7@intel.com>

--- app/test-pmd/parameters.c
+++ app/test-pmd/parameters.c
@@ -1527,6 +1527,12 @@
 		rte_exit(EXIT_FAILURE, "Command line is incorrect\n");
 	}

+	if (proc_id >= (int)num_procs)
+		rte_exit(EXIT_FAILURE,
+			 "The multi-process option '%s(%d)' should be less than '%s(%u)'\n",
+			 PARAM_PROC_ID, proc_id,
+			 PARAM_NUM_PROCS, num_procs);
+
 	/* Set offload configuration from command line parameters. */
 	rx_mode.offloads = rx_offloads;
 	tx_mode.offloads = tx_offloads;


android/A2DP: Add handling of incoming transport connection

This adds handling of incoming transport connection attempt.

--- android/a2dp.c
+++ android/a2dp.c
@@ -477,6 +477,60 @@
 	{ bt_a2dp_disconnect, false, sizeof(struct hal_cmd_a2dp_disconnect) },
 };

+static struct a2dp_setup *find_setup_by_device(struct a2dp_device *dev)
+{
+	GSList *l;
+
+	for (l = setups; l; l = g_slist_next(l)) {
+		struct a2dp_setup *setup = l->data;
+
+		if (setup->dev == dev)
+			return setup;
+	}
+
+	return NULL;
+}
+
+static void transport_connect_cb(GIOChannel *chan, GError *err,
+							gpointer user_data)
+{
+	struct a2dp_device *dev = user_data;
+	struct a2dp_setup *setup;
+	uint16_t imtu, omtu;
+	GError *gerr = NULL;
+	int fd;
+
+	if (err) {
+		error("%s", err->message);
+		return;
+	}
+
+	setup = find_setup_by_device(dev);
+	if (!setup) {
+		error("Unable to find stream setup");
+		return;
+	}
+
+	bt_io_get(chan, &gerr,
+			BT_IO_OPT_IMTU, &imtu,
+			BT_IO_OPT_OMTU, &omtu,
+			BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		return;
+	}
+
+	fd = g_io_channel_unix_get_fd(chan);
+
+	if (!avdtp_stream_set_transport(setup->stream, fd, imtu, omtu)) {
+		error("avdtp_stream_set_transport: failed");
+		return;
+	}
+
+	g_io_channel_set_close_on_unref(chan, FALSE);
+}
+
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct a2dp_device *dev;
@@ -501,12 +555,14 @@
 		return;
 	}

-	l = g_slist_find_custom(devices, &dst, device_cmp);
-	if (l)
-		return;
-
 	ba2str(&dst, address);
 	DBG("Incoming connection from %s", address);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (l) {
+		transport_connect_cb(chan, err, l->data);
+		return;
+	}

 	dev = a2dp_device_new(&dst);
 	signaling_connect_cb(chan, err, dev);


Modified welcome mess

Modified welcome mess

--- app/src/main.c
+++ app/src/main.c
@@ -56,7 +56,7 @@
   // Welcome
   if(!(debug)){
     printf("\n---------------------\n");
-    printf("Welcome to AnklebotOS\n");
+    printf("Welcome to openWearable v0.1\n");
     printf("---------------------\n");
   }
   else{


typo fix

typo fix

--- app/src/main.c
+++ app/src/main.c
@@ -1041,7 +1041,7 @@
   //check the state upon start - maybe card is already inserted
   int prev_ins_state = check_insert_update_content_id(0);

-  while(get_app_running() > 0
+  while(get_app_running() > 0)
   {
     //wait 1 second
     sceKernelDelayThread(1000000);


354008: klocwork bugs in freebl. r=nelson


Use at

Use at


doveadm search: Don't print "mailbox-guid" and "uid" texts in output.


nir/spirv: Better handle OpCopyMemory

nir/spirv: Better handle OpCopyMemory


add safety wrapper around Creature.h

add safety wrapper around Creature.h

--- Creature.h
+++ Creature.h
@@ -16,6 +16,9 @@
  *  Lesser General Public License for more details.
  *
  */
+
+#ifndef __CREATURE_H
+#define __CREATURE_H

 #include "Agent.h"
 #include "genome.h"
@@ -251,4 +254,6 @@
 	float *getLocusPointer(bool receptor, unsigned char o, unsigned char t, unsigned char l);
 };

+#endif
+
 /* vim: set noet: */


put some more stuff in the Creature class

--- Creature.h
+++ Creature.h
@@ -18,17 +18,44 @@
  */

 #include "Agent.h"
+#include "genome.h"
+
+class Organ {
+public:
+};
+
+class Brain {
+public:
+};

 class Creature : public Agent {
 protected:
+	std::vector<Organ *> organs;
+	Brain brain;
+
 	// biochemistry
 	float chemicals[256];

 	// non-specific bits
 	unsigned int variant;
 	bool female;
-	class genomeFile *genome;
-	bool alive;
+	genomeFile *genome;
+
+	bool alive, asleep, dreaming;
+
+	bool zombie;
+
+	unsigned int age; // in ticks
+	lifestage stage;
+
+	Agent *attention, *focus;
+
+	// clothes
+	// linguistic stuff
+
+	// drives
+	// to-be-processed instincts
+	// conscious flag? brain/motor enabled flags? flags for each 'faculty'?

 public:
 	Creature(genomeFile *g, unsigned char _family, bool is_female, unsigned char _variant);


Doc update.

Doc update.

--- gnelib/include/gnelib/ServerConnectionListener.h
+++ gnelib/include/gnelib/ServerConnectionListener.h
@@ -105,19 +105,25 @@
   /**
    * A new connection is starting, and now we want the parameters for this
    * new connection.  The three parameters passed should be modified to give
-   * the new connection's flow control parameters and listener.\n
+   * the new connection's flow control parameters and listener.
+   *
    * The third parameter should be set to the initial event listener for the
    * ServerConnection that is being created.  This could be an entirely new
    * ConnectionListener or an already existing one, it doesn't matter.  The
    * returned listener cannot be NULL, since onNewConn must be called or a
-   * memory leak will occur.\n
+   * memory leak will occur.
+   *
    * This pointer will be returned to you through the socket failure event
    * (in this case it was never used, but it is returned in case you need to
    * delete it).  If the connection is successful you can get your pointer
    * back through the resulting ServerConnection class by using
-   * Connection::getListener.\n
-   * This function can be called from multiple threads at the same time.\n
-   * See Connection::Connection for more info about inRate and outRate.
+   * Connection::getListener.
+   *
+   * This function can be called from multiple threads at the same time.
+   *
+   * See PacketStream::PacketStream for more info about inRate and outRate.
+   * @param inRate the maximum rate we will accept.
+   * @param outRate the maximum rate of data we are able/willing to send.
    */
   //##ModelId=3BCFAE5A0064
   virtual void getNewConnectionParams(int& inRate, int& outRate, ConnectionListener*& listener) = 0;


prepare next macros

prepare next macros

--- src/vm_exec.c
+++ src/vm_exec.c
@@ -25,17 +25,18 @@
 static SLVAL
 vm_helper_build_string(sl_vm_t* vm, SLVAL* vals, size_t count);

-#define NEXT() (ctx->section->insns[ip++])
+#define NEXT(type) (*(sl_vm_insn_t*)&ctx->section->insns_bytes[(ip += sizeof(type)) - sizeof(type)])

-#define NEXT_IMM() (NEXT().imm)
-#define NEXT_UINT() (NEXT().uint)
-#define NEXT_PTR() ((void*)NEXT().uint)
-#define NEXT_IMC() (NEXT().imc)
-#define NEXT_ICC() (NEXT().icc)
-#define NEXT_ID() (NEXT().id)
-#define NEXT_REG() (ctx->registers[NEXT().reg])
-#define NEXT_STR() (NEXT().str)
-#define NEXT_SECTION() (NEXT().section)
+#define NEXT_OPCODE()   (NEXT(sl_vm_insn_t).opcode)
+#define NEXT_IMM()      (NEXT(sl_vm_insn_t).imm)
+#define NEXT_UINT()     (NEXT(sl_vm_insn_t).uint)
+#define NEXT_IMC()      (NEXT(sl_vm_insn_t).imc)
+#define NEXT_ICC()      (NEXT(sl_vm_insn_t).icc)
+#define NEXT_ID()       (NEXT(sl_vm_insn_t).id)
+#define NEXT_REG_IDX()  (NEXT(sl_vm_insn_t).reg)
+#define NEXT_SECTION()  (NEXT(sl_vm_insn_t).section)
+
+#define NEXT_REG() (ctx->registers[NEXT_REG_IDX()])

 #define V_TRUE (vm->lib._true)
 #define V_FALSE (vm->lib._false)
@@ -84,7 +85,7 @@
     }

     while(1) {
-        switch(NEXT().opcode) {
+        switch(NEXT_OPCODE()) {
             #undef INSTRUCTION
             #define INSTRUCTION(opcode, code) \
                 case opcode: { \
@@ -93,7 +94,7 @@
             #include "vm_defn.inc"

             default:
-                sl_throw_message(vm, "BUG: Unknown opcode in VM"); /* never reached */
+                sl_throw_message(vm, "BUG: Unknown opcode in VM"); /* should never be reached */
         }
     }
 }


vmx: Relax virtualHW.version check

vmx: Relax virtualHW.version check

The original implementation of the VMX config parser assumed that the
virtualHW.version would have more influence on the content of the VMX
file than it actually seems to have. It started with accepting only
version 4. Additonal versions were added later without any additional
changes in the parser itself. This suggests that the influence of the
virtualHW.version on the content and format of the VMX file is small
or non-existent.

The parser worked without any changes across several virtualHW and
vSphere versions. So instead of adding new virtualHW.version values to
the parser as they come along, or adding an extra flag to allow unknown
virtualHW.version values just relax the check to require version 4 or
later.

--- src/vmx/vmx.c
+++ src/vmx/vmx.c
@@ -1316,12 +1316,10 @@
         goto cleanup;
     }

-    if (virtualHW_version != 4 && virtualHW_version != 7 &&
-        virtualHW_version != 8 && virtualHW_version != 9 &&
-        virtualHW_version != 10) {
+    if (virtualHW_version < 4) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Expecting VMX entry 'virtualHW.version' to be "
-                         "4, 7, 8, 9 or 10 but found %lld"),
+                         "4 or higher but found %lld"),
                        virtualHW_version);
         goto cleanup;
     }


split run_instruction

split run_instruction

--- semantics/lpg_interpret.c
+++ semantics/lpg_interpret.c
@@ -185,6 +185,253 @@
                                         lpg_interface const *const all_interfaces,
                                         optional_function_id const current_function);

+static void run_new_array(new_array_instruction const new_array, garbage_collector *const gc, value *const registers)
+{
+    array_value *const array = garbage_collector_allocate(gc, sizeof(*array));
+    *array = array_value_create(NULL, 0, 0, new_array.element_type);
+    registers[new_array.into] = value_from_array(array);
+}
+
+static void run_get_method(get_method_instruction const get_method, garbage_collector *const gc, value *const registers,
+                           lpg_interface const *const all_interfaces)
+{
+    size_t const capture_count = 1;
+    value *const pseudo_captures = garbage_collector_allocate_array(gc, capture_count, sizeof(*pseudo_captures));
+    ASSUME(value_is_valid(registers[get_method.from]));
+    pseudo_captures[0] = registers[get_method.from];
+    lpg_interface const *const interface_ = &all_interfaces[get_method.interface_];
+    ASSUME(get_method.method < interface_->method_count);
+    method_description const method = interface_->methods[get_method.method];
+    invoke_method_parameters *const parameters = garbage_collector_allocate(gc, sizeof(*parameters));
+    parameters->method = get_method.method;
+    parameters->parameter_count = method.parameters.length;
+    type *const pseudo_capture_types =
+        garbage_collector_allocate_array(gc, capture_count, sizeof(*pseudo_capture_types));
+    pseudo_capture_types[0] = type_from_interface(get_method.interface_);
+    registers[get_method.into] = value_from_function_pointer(function_pointer_value_from_external(
+        invoke_method, parameters, pseudo_captures,
+        function_pointer_create(optional_type_create_set(method.result), method.parameters,
+                                tuple_type_create(pseudo_capture_types, capture_count), optional_type_create_empty())));
+}
+
+static void run_erase_type(erase_type_instruction const erase_type, garbage_collector *const gc, value *const registers)
+{
+    value *const self = garbage_collector_allocate(gc, sizeof(*self));
+    *self = registers[erase_type.self];
+    registers[erase_type.into] = value_from_type_erased(type_erased_value_create(erase_type.impl, self));
+}
+
+static run_sequence_result run_call(call_instruction const call, garbage_collector *const gc, value const *globals,
+                                    value *const registers, checked_function const *const all_functions,
+                                    lpg_interface const *const all_interfaces)
+{
+    value const callee = registers[call.callee];
+    if (callee.kind == value_kind_unit)
+    {
+        return run_sequence_result_unavailable_at_this_time;
+    }
+    value *const arguments = allocate_array(call.argument_count, sizeof(*arguments));
+    LPG_FOR(size_t, j, call.argument_count)
+    {
+        arguments[j] = registers[call.arguments[j]];
+    }
+    switch (callee.kind)
+    {
+    case value_kind_function_pointer:
+    {
+        optional_value const result = call_function(
+            callee.function_pointer, function_call_arguments_create(
+                                         optional_value_empty, arguments, globals, gc, all_functions, all_interfaces));
+        deallocate(arguments);
+        if (!result.is_set)
+        {
+            return run_sequence_result_unavailable_at_this_time;
+        }
+        ASSUME(value_is_valid(result.value_));
+        registers[call.result] = result.value_;
+        break;
+    }
+
+    case value_kind_type_erased:
+    case value_kind_integer:
+    case value_kind_string:
+    case value_kind_structure:
+    case value_kind_type:
+    case value_kind_enum_element:
+    case value_kind_unit:
+    case value_kind_tuple:
+    case value_kind_pattern:
+        LPG_UNREACHABLE();
+
+    case value_kind_enum_constructor:
+    case value_kind_generic_enum:
+    case value_kind_generic_interface:
+    case value_kind_generic_struct:
+    case value_kind_generic_lambda:
+    case value_kind_array:
+        LPG_TO_DO();
+    }
+    return run_sequence_result_continue;
+}
+
+static run_sequence_result run_loop(loop_instruction const loop, value *const return_value, value const *globals,
+                                    value *const registers, structure_value const captures, garbage_collector *const gc,
+                                    checked_function const *const all_functions,
+                                    lpg_interface const *const all_interfaces,
+                                    optional_function_id const current_function)
+{
+    bool is_running = true;
+    registers[loop.unit_goes_into] = value_from_unit();
+    while (is_running)
+    {
+        switch (run_sequence(
+            loop.body, return_value, globals, registers, captures, gc, all_functions, all_interfaces, current_function))
+        {
+        case run_sequence_result_break:
+            is_running = false;
+            break;
+
+        case run_sequence_result_continue:
+            break;
+
+        case run_sequence_result_unavailable_at_this_time:
+            return run_sequence_result_unavailable_at_this_time;
+
+        case run_sequence_result_return:
+            return run_sequence_result_return;
+        }
+    }
+    return run_sequence_result_continue;
+}
+
+static void run_tuple(tuple_instruction const tuple_, garbage_collector *const gc, value *const registers)
+{
+    value new_tuple;
+    new_tuple.kind = value_kind_tuple;
+    value *values = garbage_collector_allocate_array(gc, tuple_.element_count, sizeof(*values));
+    for (size_t j = 0; j < tuple_.element_count; ++j)
+    {
+        values[j] = registers[*(tuple_.elements + j)];
+        ASSUME(value_is_valid(values[j]));
+    }
+    new_tuple.tuple_ = value_tuple_create(values, tuple_.element_count);
+    registers[tuple_.result] = new_tuple;
+}
+
+static void run_instantiate_struct(instantiate_struct_instruction const instantiate_struct, garbage_collector *const gc,
+                                   value *const registers)
+{
+    value *const values = garbage_collector_allocate_array(gc, instantiate_struct.argument_count, sizeof(*values));
+    for (size_t j = 0; j < instantiate_struct.argument_count; ++j)
+    {
+        values[j] = registers[*(instantiate_struct.arguments + j)];
+        ASSUME(value_is_valid(values[j]));
+    }
+    registers[instantiate_struct.into] =
+        value_from_structure(structure_value_create(values, instantiate_struct.argument_count));
+}
+
+static void run_enum_construct(enum_construct_instruction const enum_construct, garbage_collector *const gc,
+                               value *const registers)
+{
+    value *const state = garbage_collector_allocate(gc, sizeof(*state));
+    *state = registers[enum_construct.state];
+    ASSUME(value_is_valid(*state));
+    registers[enum_construct.into] =
+        value_from_enum_element(enum_construct.which.which, enum_construct.state_type, state);
+}
+
+static run_sequence_result run_match(match_instruction const match, value *const return_value, value const *globals,
+                                     value *const registers, structure_value const captures,
+                                     garbage_collector *const gc, checked_function const *const all_functions,
+                                     lpg_interface const *const all_interfaces,
+                                     optional_function_id const current_function)
+{
+    value const key = registers[match.key];
+    ASSUME(value_is_valid(key));
+    bool found_match = false;
+    for (size_t j = 0; j < match.count; ++j)
+    {
+        match_instruction_case *const this_case = match.cases + j;
+        bool matches = false;
+        switch (this_case->kind)
+        {
+        case match_instruction_case_kind_stateful_enum:
+            ASSUME(key.kind == value_kind_enum_element);
+            matches = (key.enum_element.which == this_case->stateful_enum.element);
+            if (matches)
+            {
+                registers[this_case->stateful_enum.where] = value_or_unit(key.enum_element.state);
+            }
+            break;
+
+        case match_instruction_case_kind_value:
+            matches = value_equals(registers[this_case->key_value], key);
+            break;
+        }
+        if (!matches)
+        {
+            continue;
+        }
+        found_match = true;
+        switch (run_sequence(this_case->action, return_value, globals, registers, captures, gc, all_functions,
+                             all_interfaces, current_function))
+        {
+        case run_sequence_result_break:
+            return run_sequence_result_break;
+
+        case run_sequence_result_continue:
+            break;
+
+        case run_sequence_result_unavailable_at_this_time:
+            return run_sequence_result_unavailable_at_this_time;
+
+        case run_sequence_result_return:
+            return run_sequence_result_return;
+        }
+        if (this_case->value.is_set)
+        {
+            ASSUME(value_is_valid(registers[this_case->value.value]));
+            ASSUME(value_conforms_to_type(registers[this_case->value.value], match.result_type));
+            registers[match.result] = registers[this_case->value.value];
+        }
+        break;
+    }
+    ASSUME(found_match);
+    return run_sequence_result_continue;
+}
+
+static void run_lambda_with_captures(lambda_with_captures_instruction const lambda_with_captures,
+                                     garbage_collector *const gc, value *const registers)
+{
+    value *const inner_captures =
+        garbage_collector_allocate_array(gc, lambda_with_captures.capture_count, sizeof(*inner_captures));
+    for (size_t j = 0; j < lambda_with_captures.capture_count; ++j)
+    {
+        value const capture = registers[lambda_with_captures.captures[j]];
+        inner_captures[j] = capture;
+        ASSUME(value_is_valid(capture));
+    }
+    registers[lambda_with_captures.into] = value_from_function_pointer(function_pointer_value_from_internal(
+        lambda_with_captures.lambda, inner_captures, lambda_with_captures.capture_count));
+}
+
+static void run_current_function(current_function_instruction const current_function_instr,
+                                 structure_value const captures, value *const registers, garbage_collector *const gc,
+                                 optional_function_id const current_function)
+{
+    value *const inner_captures = garbage_collector_allocate_array(gc, captures.count, sizeof(*inner_captures));
+    for (size_t j = 0; j < captures.count; ++j)
+    {
+        value const capture = captures.members[j];
+        inner_captures[j] = capture;
+        ASSUME(value_is_valid(capture));
+    }
+    ASSUME(current_function.is_set);
+    registers[current_function_instr.into] = value_from_function_pointer(
+        function_pointer_value_from_internal(current_function.value, inner_captures, captures.count));
+}
+
 static run_sequence_result run_instruction(value *const return_value, value const *globals, value *const registers,
                                            structure_value const captures, garbage_collector *const gc,
                                            checked_function const *const all_functions,
@@ -194,95 +441,19 @@
     switch (element.type)
     {
     case instruction_new_array:
-    {
-        array_value *const array = garbage_collector_allocate(gc, sizeof(*array));
-        *array = array_value_create(NULL, 0, 0, element.new_array.element_type);
-        registers[element.new_array.into] = value_from_array(array);
-        break;
-    }
+        run_new_array(element.new_array, gc, registers);
+        break;

     case instruction_get_method:
-    {
-        size_t const capture_count = 1;
-        value *const pseudo_captures = garbage_collector_allocate_array(gc, capture_count, sizeof(*pseudo_captures));
-        ASSUME(value_is_valid(registers[element.get_method.from]));
-        pseudo_captures[0] = registers[element.get_method.from];
-        lpg_interface const *const interface_ = &all_interfaces[element.get_method.interface_];
-        ASSUME(element.get_method.method < interface_->method_count);
-        method_description const method = interface_->methods[element.get_method.method];
-        invoke_method_parameters *const parameters = garbage_collector_allocate(gc, sizeof(*parameters));
-        parameters->method = element.get_method.method;
-        parameters->parameter_count = method.parameters.length;
-        type *const pseudo_capture_types =
-            garbage_collector_allocate_array(gc, capture_count, sizeof(*pseudo_capture_types));
-        pseudo_capture_types[0] = type_from_interface(element.get_method.interface_);
-        registers[element.get_method.into] = value_from_function_pointer(function_pointer_value_from_external(
-            invoke_method, parameters, pseudo_captures,
-            function_pointer_create(optional_type_create_set(method.result), method.parameters,
-                                    tuple_type_create(pseudo_capture_types, capture_count),
-                                    optional_type_create_empty())));
-        break;
-    }
+        run_get_method(element.get_method, gc, registers, all_interfaces);
+        break;

     case instruction_erase_type:
-    {
-        value *const self = garbage_collector_allocate(gc, sizeof(*self));
-        *self = registers[element.erase_type.self];
-        registers[element.erase_type.into] =
-            value_from_type_erased(type_erased_value_create(element.erase_type.impl, self));
-        break;
-    }
+        run_erase_type(element.erase_type, gc, registers);
+        break;

     case instruction_call:
-    {
-        value const callee = registers[element.call.callee];
-        if (callee.kind == value_kind_unit)
-        {
-            return run_sequence_result_unavailable_at_this_time;
-        }
-        value *const arguments = allocate_array(element.call.argument_count, sizeof(*arguments));
-        LPG_FOR(size_t, j, element.call.argument_count)
-        {
-            arguments[j] = registers[element.call.arguments[j]];
-        }
-        switch (callee.kind)
-        {
-        case value_kind_function_pointer:
-        {
-            optional_value const result = call_function(
-                callee.function_pointer, function_call_arguments_create(optional_value_empty, arguments, globals, gc,
-                                                                        all_functions, all_interfaces));
-            deallocate(arguments);
-            if (!result.is_set)
-            {
-                return run_sequence_result_unavailable_at_this_time;
-            }
-            ASSUME(value_is_valid(result.value_));
-            registers[element.call.result] = result.value_;
-            break;
-        }
-
-        case value_kind_type_erased:
-        case value_kind_integer:
-        case value_kind_string:
-        case value_kind_structure:
-        case value_kind_type:
-        case value_kind_enum_element:
-        case value_kind_unit:
-        case value_kind_tuple:
-        case value_kind_pattern:
-            LPG_UNREACHABLE();
-
-        case value_kind_enum_constructor:
-        case value_kind_generic_enum:
-        case value_kind_generic_interface:
-        case value_kind_generic_struct:
-        case value_kind_generic_lambda:
-        case value_kind_array:
-            LPG_TO_DO();
-        }
-        break;
-    }
+        return run_call(element.call, gc, globals, registers, all_functions, all_interfaces);

     case instruction_return:
         *return_value = registers[element.return_.returned_value];
@@ -291,30 +462,8 @@
         return run_sequence_result_return;

     case instruction_loop:
-    {
-        bool is_running = true;
-        registers[element.loop.unit_goes_into] = value_from_unit();
-        while (is_running)
-        {
-            switch (run_sequence(element.loop.body, return_value, globals, registers, captures, gc, all_functions,
-                                 all_interfaces, current_function))
-            {
-            case run_sequence_result_break:
-                is_running = false;
-                break;
-
-            case run_sequence_result_continue:
-                break;
-
-            case run_sequence_result_unavailable_at_this_time:
-                return run_sequence_result_unavailable_at_this_time;
-
-            case run_sequence_result_return:
-                return run_sequence_result_return;
-            }
-        }
-        break;
-    }
+        return run_loop(element.loop, return_value, globals, registers, captures, gc, all_functions, all_interfaces,
+                        current_function);

     case instruction_global:
         registers[element.global_into] =
@@ -341,133 +490,32 @@
         break;

     case instruction_tuple:
-    {
-        value new_tuple;
-        new_tuple.kind = value_kind_tuple;
-        value *values = garbage_collector_allocate_array(gc, element.tuple_.element_count, sizeof(*values));
-        for (size_t j = 0; j < element.tuple_.element_count; ++j)
-        {
-            values[j] = registers[*(element.tuple_.elements + j)];
-            ASSUME(value_is_valid(values[j]));
-        }
-        new_tuple.tuple_ = value_tuple_create(values, element.tuple_.element_count);
-        registers[element.tuple_.result] = new_tuple;
-        break;
-    }
+        run_tuple(element.tuple_, gc, registers);
+        break;

     case instruction_instantiate_struct:
-    {
-        value *const values =
-            garbage_collector_allocate_array(gc, element.instantiate_struct.argument_count, sizeof(*values));
-        for (size_t j = 0; j < element.instantiate_struct.argument_count; ++j)
-        {
-            values[j] = registers[*(element.instantiate_struct.arguments + j)];
-            ASSUME(value_is_valid(values[j]));
-        }
-        registers[element.instantiate_struct.into] =
-            value_from_structure(structure_value_create(values, element.instantiate_struct.argument_count));
-        break;
-    }
+        run_instantiate_struct(element.instantiate_struct, gc, registers);
+        break;

     case instruction_enum_construct:
-    {
-        value *const state = garbage_collector_allocate(gc, sizeof(*state));
-        *state = registers[element.enum_construct.state];
-        ASSUME(value_is_valid(*state));
-        registers[element.enum_construct.into] =
-            value_from_enum_element(element.enum_construct.which.which, element.enum_construct.state_type, state);
-        break;
-    }
+        run_enum_construct(element.enum_construct, gc, registers);
+        break;

     case instruction_match:
-    {
-        value const key = registers[element.match.key];
-        ASSUME(value_is_valid(key));
-        bool found_match = false;
-        for (size_t j = 0; j < element.match.count; ++j)
-        {
-            match_instruction_case *const this_case = element.match.cases + j;
-            bool matches = false;
-            switch (this_case->kind)
-            {
-            case match_instruction_case_kind_stateful_enum:
-                ASSUME(key.kind == value_kind_enum_element);
-                matches = (key.enum_element.which == this_case->stateful_enum.element);
-                if (matches)
-                {
-                    registers[this_case->stateful_enum.where] = value_or_unit(key.enum_element.state);
-                }
-                break;
-
-            case match_instruction_case_kind_value:
-                matches = value_equals(registers[this_case->key_value], key);
-                break;
-            }
-            if (!matches)
-            {
-                continue;
-            }
-            found_match = true;
-            switch (run_sequence(this_case->action, return_value, globals, registers, captures, gc, all_functions,
-                                 all_interfaces, current_function))
-            {
-            case run_sequence_result_break:
-                return run_sequence_result_break;
-
-            case run_sequence_result_continue:
-                break;
-
-            case run_sequence_result_unavailable_at_this_time:
-                return run_sequence_result_unavailable_at_this_time;
-
-            case run_sequence_result_return:
-                return run_sequence_result_return;
-            }
-            if (this_case->value.is_set)
-            {
-                ASSUME(value_is_valid(registers[this_case->value.value]));
-                ASSUME(value_conforms_to_type(registers[this_case->value.value], element.match.result_type));
-                registers[element.match.result] = registers[this_case->value.value];
-            }
-            break;
-        }
-        ASSUME(found_match);
-        break;
-    }
+        return run_match(element.match, return_value, globals, registers, captures, gc, all_functions, all_interfaces,
+                         current_function);

     case instruction_get_captures:
         registers[element.captures] = value_from_structure(captures);
         break;

     case instruction_lambda_with_captures:
-    {
-        value *const inner_captures =
-            garbage_collector_allocate_array(gc, element.lambda_with_captures.capture_count, sizeof(*inner_captures));
-        for (size_t j = 0; j < element.lambda_with_captures.capture_count; ++j)
-        {
-            value const capture = registers[element.lambda_with_captures.captures[j]];
-            inner_captures[j] = capture;
-            ASSUME(value_is_valid(capture));
-        }
-        registers[element.lambda_with_captures.into] = value_from_function_pointer(function_pointer_value_from_internal(
-            element.lambda_with_captures.lambda, inner_captures, element.lambda_with_captures.capture_count));
-        break;
-    }
+        run_lambda_with_captures(element.lambda_with_captures, gc, registers);
+        break;

     case instruction_current_function:
-    {
-        value *const inner_captures = garbage_collector_allocate_array(gc, captures.count, sizeof(*inner_captures));
-        for (size_t j = 0; j < captures.count; ++j)
-        {
-            value const capture = captures.members[j];
-            inner_captures[j] = capture;
-            ASSUME(value_is_valid(capture));
-        }
-        ASSUME(current_function.is_set);
-        registers[element.current_function.into] = value_from_function_pointer(
-            function_pointer_value_from_internal(current_function.value, inner_captures, captures.count));
-        break;
-    }
+        run_current_function(element.current_function, captures, registers, gc, current_function);
+        break;
     }
     return run_sequence_result_continue;
 }