GICv3: Allow either G1S or G0 interrupts to be configured

Currently the GICv3 driver mandates that platform populate
both G1S and G0 interrupts. However, it is possible that a
given platform is not interested in both the groups and
just needs to specify either one of them.

This patch modifies the `gicv3_rdistif_init()` & `gicv3_distif_init()`
functions to allow either G1S or G0 interrupts to be configured.

Fixes ARM-software/tf-issues#400

Change-Id: I43572b0e08ae30bed5af9334f25d35bf439b0d2b

--- drivers/arm/gic/v3/gicv3_main.c
+++ drivers/arm/gic/v3/gicv3_main.c
@@ -120,10 +120,12 @@
  ******************************************************************************/
 void gicv3_distif_init(void)
 {
+	unsigned int bitmap = 0;
+
 	assert(driver_data);
 	assert(driver_data->gicd_base);
-	assert(driver_data->g1s_interrupt_array);
-	assert(driver_data->g0_interrupt_array);
+	assert(driver_data->g1s_interrupt_array ||
+	       driver_data->g0_interrupt_array);

 	assert(IS_IN_EL3());

@@ -146,21 +148,25 @@
 	gicv3_spis_configure_defaults(driver_data->gicd_base);

 	/* Configure the G1S SPIs */
-	gicv3_secure_spis_configure(driver_data->gicd_base,
+	if (driver_data->g1s_interrupt_array) {
+		gicv3_secure_spis_configure(driver_data->gicd_base,
 					driver_data->g1s_interrupt_num,
 					driver_data->g1s_interrupt_array,
 					INTR_GROUP1S);
+		bitmap |= CTLR_ENABLE_G1S_BIT;
+	}

 	/* Configure the G0 SPIs */
-	gicv3_secure_spis_configure(driver_data->gicd_base,
+	if (driver_data->g0_interrupt_array) {
+		gicv3_secure_spis_configure(driver_data->gicd_base,
 					driver_data->g0_interrupt_num,
 					driver_data->g0_interrupt_array,
 					INTR_GROUP0);
+		bitmap |= CTLR_ENABLE_G0_BIT;
+	}

 	/* Enable the secure SPIs now that they have been configured */
-	gicd_set_ctlr(driver_data->gicd_base,
-		      CTLR_ENABLE_G1S_BIT | CTLR_ENABLE_G0_BIT,
-		      RWP_TRUE);
+	gicd_set_ctlr(driver_data->gicd_base, bitmap, RWP_TRUE);
 }

 /*******************************************************************************
@@ -177,8 +183,8 @@
 	assert(driver_data->rdistif_base_addrs);
 	assert(driver_data->gicd_base);
 	assert(gicd_read_ctlr(driver_data->gicd_base) & CTLR_ARE_S_BIT);
-	assert(driver_data->g1s_interrupt_array);
-	assert(driver_data->g0_interrupt_array);
+	assert(driver_data->g1s_interrupt_array ||
+	       driver_data->g0_interrupt_array);

 	assert(IS_IN_EL3());

@@ -188,16 +194,20 @@
 	gicv3_ppi_sgi_configure_defaults(gicr_base);

 	/* Configure the G1S SGIs/PPIs */
-	gicv3_secure_ppi_sgi_configure(gicr_base,
-					   driver_data->g1s_interrupt_num,
-					   driver_data->g1s_interrupt_array,
-					   INTR_GROUP1S);
+	if (driver_data->g1s_interrupt_array) {
+		gicv3_secure_ppi_sgi_configure(gicr_base,
+					driver_data->g1s_interrupt_num,
+					driver_data->g1s_interrupt_array,
+					INTR_GROUP1S);
+	}

 	/* Configure the G0 SGIs/PPIs */
-	gicv3_secure_ppi_sgi_configure(gicr_base,
-					   driver_data->g0_interrupt_num,
-					   driver_data->g0_interrupt_array,
-					   INTR_GROUP0);
+	if (driver_data->g0_interrupt_array) {
+		gicv3_secure_ppi_sgi_configure(gicr_base,
+					driver_data->g0_interrupt_num,
+					driver_data->g0_interrupt_array,
+					INTR_GROUP0);
+	}
 }

 /*******************************************************************************


drbd: Removed the os parameter form sanitize_state()

Signed-off-by: Philipp Reisner <35a55a4ac466b5abd81eb66f3f7d6a972dd0dc24@linbit.com>
Signed-off-by: Lars Ellenberg <31df9cacdc65c624cc60c2dcd22bbf92dc230e16@linbit.com>

--- drivers/block/drbd/drbd_state.c
+++ drivers/block/drbd/drbd_state.c
@@ -48,8 +48,8 @@
 static enum drbd_state_rv is_valid_state(struct drbd_conf *, union drbd_state);
 static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state);
 static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort);
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns,
+				       const char **warn_sync_abort);

 /**
  * cl_wide_st_chg() - true if the state change is a cluster wide one
@@ -116,7 +116,7 @@
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, os, ns, NULL);
+	ns = sanitize_state(mdev, ns, NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv == SS_SUCCESS)
 		rv = SS_UNKNOWN_ERROR;  /* cont waiting, otherwise fail. */
@@ -163,7 +163,7 @@
 	spin_lock_irqsave(&mdev->tconn->req_lock, flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
-	ns = sanitize_state(mdev, os, ns, NULL);
+	ns = sanitize_state(mdev, ns, NULL);
 	rv = is_valid_transition(os, ns);
 	if (rv < SS_SUCCESS)
 		goto abort;
@@ -436,6 +436,13 @@
 	if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
 		rv = SS_IS_DISKLESS;

+	/* if we are only D_ATTACHING yet,
+	 * we can (and should) go directly to D_DISKLESS. */
+	if (ns.disk == D_FAILED && os.disk == D_ATTACHING) {
+		printk("TODO: FIX ME\n");
+		rv = SS_IS_DISKLESS;
+	}
+
 	return rv;
 }

@@ -449,8 +456,8 @@
  * When we loose connection, we have to set the state of the peers disk (pdsk)
  * to D_UNKNOWN. This rule and many more along those lines are in this function.
  */
-static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state os,
-				       union drbd_state ns, const char **warn_sync_abort)
+static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns,
+				       const char **warn_sync_abort)
 {
 	enum drbd_fencing_p fp;
 	enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max;
@@ -460,11 +467,6 @@
 		fp = mdev->ldev->dc.fencing;
 		put_ldev(mdev);
 	}
-
-	/* if we are only D_ATTACHING yet,
-	 * we can (and should) go directly to D_DISKLESS. */
-	if (ns.disk == D_FAILED && os.disk == D_ATTACHING)
-		ns.disk = D_DISKLESS;

 	/* Implications from connection to peer and peer_isp */
 	if (ns.conn < C_CONNECTED) {
@@ -478,12 +480,12 @@
 	if (ns.conn == C_STANDALONE && ns.disk == D_DISKLESS && ns.role == R_SECONDARY)
 		ns.aftr_isp = 0;

+	/* An implication of the disk states onto the connection state */
 	/* Abort resync if a disk fails/detaches */
-	if (os.conn > C_CONNECTED && ns.conn > C_CONNECTED &&
-	    (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
+	if (ns.conn > C_CONNECTED && (ns.disk <= D_FAILED || ns.pdsk <= D_FAILED)) {
 		if (warn_sync_abort)
 			*warn_sync_abort =
-				os.conn == C_VERIFY_S || os.conn == C_VERIFY_T ?
+				ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T ?
 				"Online-verify" : "Resync";
 		ns.conn = C_CONNECTED;
 	}
@@ -591,13 +593,11 @@
 	}

 	if (fp == FP_STONITH &&
-	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
-	    !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
+	    (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED))
 		ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */

 	if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO &&
-	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
-	    !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
+	    (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE))
 		ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */

 	if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
@@ -668,8 +668,7 @@

 	os = mdev->state;

-	ns = sanitize_state(mdev, os, ns, &warn_sync_abort);
-
+	ns = sanitize_state(mdev, ns, &warn_sync_abort);
 	if (ns.i == os.i)
 		return SS_NOTHING_TO_DO;


hwrng: n2-drv - Introduce the use of the managed version of kzalloc

This patch moves data allocated using kzalloc to managed data allocated
using devm_kzalloc and cleans now unnecessary kfrees in probe and remove
functions. The NULL assignment to np->units is removed as there is no
interaction between this field and sun4v_hvapi_unregister. Also, the
labels out_free_units and out_free are removed as they are no longer
required.

The following Coccinelle semantic patch was used for making the change:

@platform@
identifier p, probefn, removefn;
@@
struct platform_driver p = {
  .probe = probefn,
  .remove = removefn,
};

@prb@
identifier platform.probefn, pdev;
expression e, e1, e2;
@@
probefn(struct platform_device *pdev, ...) {
  <+...
- e = kzalloc(e1, e2)
+ e = devm_kzalloc(&pdev->dev, e1, e2)
  ...
?-kfree(e);
  ...+>
}

@rem depends on prb@
identifier platform.removefn;
expression e;
@@
removefn(...) {
  <...
- kfree(e);
  ...>
}

Signed-off-by: Himangi Saraogi <23256c5b125c18bd580b7fa252de87dcf0c3a427@gmail.com>
Signed-off-by: Herbert Xu <ef65de1c7be0aa837fe7b25ba9a7739905af6a55@gondor.apana.org.au>

--- drivers/char/hw_random/n2-drv.c
+++ drivers/char/hw_random/n2-drv.c
@@ -632,7 +632,7 @@
 	multi_capable = (match->data != NULL);

 	n2rng_driver_version();
-	np = kzalloc(sizeof(*np), GFP_KERNEL);
+	np = devm_kzalloc(&op->dev, sizeof(*np), GFP_KERNEL);
 	if (!np)
 		goto out;
 	np->op = op;
@@ -653,7 +653,7 @@
 					 &np->hvapi_minor)) {
 			dev_err(&op->dev, "Cannot register suitable "
 				"HVAPI version.\n");
-			goto out_free;
+			goto out;
 		}
 	}

@@ -676,15 +676,16 @@
 	dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",
 		 np->hvapi_major, np->hvapi_minor);

-	np->units = kzalloc(sizeof(struct n2rng_unit) * np->num_units,
-			    GFP_KERNEL);
+	np->units = devm_kzalloc(&op->dev,
+				 sizeof(struct n2rng_unit) * np->num_units,
+				 GFP_KERNEL);
 	err = -ENOMEM;
 	if (!np->units)
 		goto out_hvapi_unregister;

 	err = n2rng_init_control(np);
 	if (err)
-		goto out_free_units;
+		goto out_hvapi_unregister;

 	dev_info(&op->dev, "Found %s RNG, units: %d\n",
 		 ((np->flags & N2RNG_FLAG_MULTI) ?
@@ -697,23 +698,17 @@

 	err = hwrng_register(&np->hwrng);
 	if (err)
-		goto out_free_units;
+		goto out_hvapi_unregister;

 	platform_set_drvdata(op, np);

 	schedule_delayed_work(&np->work, 0);

 	return 0;
-
-out_free_units:
-	kfree(np->units);
-	np->units = NULL;

 out_hvapi_unregister:
 	sun4v_hvapi_unregister(HV_GRP_RNG);

-out_free:
-	kfree(np);
 out:
 	return err;
 }
@@ -729,11 +724,6 @@
 	hwrng_unregister(&np->hwrng);

 	sun4v_hvapi_unregister(HV_GRP_RNG);
-
-	kfree(np->units);
-	np->units = NULL;
-
-	kfree(np);

 	return 0;
 }


fix some bug

fix some bug

--- CPlusPlusPrimerExe/CPlusPlusPrimerExe/CplusPlusExe.h
+++ CPlusPlusPrimerExe/CPlusPlusPrimerExe/CplusPlusExe.h
@@ -38,5 +38,7 @@
 //Exe6_43 (a) inline in a source file ;(b) int a header file so as it can be found in every source file.
 //Exe6_44
 inline bool isShorter(const string &s1, const string &s2) { return s1.size < s2.size; }
+
+
 //Exe6_45 Exe6_46 pass..
 //Exe6_46


pcmcia/cm4000: fix lock imbalance

pcmcia/cm4000: fix lock imbalance

Don't return from switch/case, break instead, so that we unlock BKL.

Signed-off-by: Jiri Slaby <aeaaaa09d9a5fac7c38743ea79aa4bb8ffb08290@gmail.com>
Signed-off-by: Alan Cox <91e38e63b890fbb214c8914809fde03c73e7f24d@linux.intel.com>
Cc: 4fbacc2fa0ffdbb11bf1ad6925b886ebd08dd15f@kernel.org
Signed-off-by: Linus Torvalds <69652caca27c8b940640ad396ab71f93cacec34f@linux-foundation.org>

--- drivers/char/pcmcia/cm4000_cs.c
+++ drivers/char/pcmcia/cm4000_cs.c
@@ -1575,7 +1575,8 @@
 		clear_bit(LOCK_IO, &dev->flags);
 		wake_up_interruptible(&dev->ioq);

-		return 0;
+		rc = 0;
+		break;
 	case CM_IOCSPTS:
 		{
 			struct ptsreq krnptsreq;


crypto/qat: fix typo in error message

crypto/qat: fix typo in error message

This commit fixes typo in bpi_cipher_decrypt error message

Fixes: d18ab45f7654 ("crypto/qat: support DOCSIS BPI mode")
Cc: stable@dpdk.org

Signed-off-by: Tomasz Jozwiak <3b0a3cc91976f7b049b477347dd7a4026144d56b@intel.com>
Acked-by: Fiona Trahe <7ba562cc372916cd557d0be347608f8b4da4f746@intel.com>

--- drivers/crypto/qat/qat_crypto.c
+++ drivers/crypto/qat/qat_crypto.c
@@ -139,7 +139,7 @@
 	return 0;

 cipher_decrypt_err:
-	PMD_DRV_LOG(ERR, "libcrypto ECB cipher encrypt for BPI IV failed");
+	PMD_DRV_LOG(ERR, "libcrypto ECB cipher decrypt for BPI IV failed");
 	return -EINVAL;
 }


Added ability to transpose, restrict to scale

--- synthinvert.c
+++ synthinvert.c
@@ -36,12 +36,14 @@
 const char *dbfname = NULL;
 midi_note_t lomidi = 0, himidi = 0;  /* range of our synth */
 midi_note_t stdmidi = 60;  /* note to calibrate against */
+midi_note_t transpose_semitones = 0;
+int note_scale [12] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 int stdmidi_npeaks = 50;  /* # of peaks to read for calibration */
 int velo0 = 100;
 int initial_sil_ms = 450;
 double wavebrk_sil_ms = 1.5;
 double note_recog_ms = 12;
-double note_recog_max_ms = 700;  // how much to analyze from a waveform
+double note_recog_max_ms = 250;  // how much to analyze from a waveform

 typedef struct {
   char *buf1, *buf2, *ptr, *end, *other;
@@ -151,7 +153,7 @@
   char **strings = backtrace_symbols (array, size);

   TRACE (TRACE_DIAG, "Obtained %zd stack frames", size);
-  for (size_t i = 0; i < size; i++)
+  for (size_t i = 0; i < size; ++i)
     TRACE (TRACE_DIAG, "%s", strings [i]);
   free (strings);
 }
@@ -193,26 +195,61 @@
   else return 0;
 }

-static const midi_note_t note_semitones [] = { 0, 2, 3, 5, 7, 8, 10, 12 };
+static const midi_note_t note_semitones [] = { 0, 2, 4, 5, 7, 9, 11, 12 };
 double note_midi2freq (midi_note_t midi) {
   return 27.5 * exp (.05776226504666210911 * (midi - 21));  // A0 = 27.5
 }
 void note_midi2sci (midi_note_t midi, char *sci) {
-  midi_note_t o = (midi - 21) / 12,
-    s = midi - 21 - 12 * o;
+  midi_note_t o = midi / 12 - 1, s = midi % 12;
   int sharp = 0;
   char l;
-  for (l = 'A'; l <= 'G' && note_semitones [l - 'A'] < s; l++);
-  if (note_semitones [l - 'A'] > s) { sharp = 1; l--; }
-  if (l >= 'C') o++;
+  for (l = 'C'; l <= 'I' && note_semitones [l - 'C'] < s; l++);
+  if (note_semitones [l - 'C'] > s) { sharp = 1; l--; }
+  if (l >= 'H') l += 'A' - 'H';
   sprintf (sci, "%c%d%s", l, o, sharp ? "#" : "");
 }
 midi_note_t note_sci2midi (const char *scinote) {
-  char lc = toupper (scinote [0]);
-
-  midi_note_t l =  lc - 'A',
-    o = scinote [1] - '0' - (lc < 'C' ? 0 : 1);
-  return 21 + 12 * o + note_semitones [l];
+  if (! isalpha (scinote [0])) goto bad;
+  char ul = toupper (scinote [0]);
+
+  if (ul >= 'H') goto bad;
+  if (ul < 'C') ul += 'H' - 'A';
+  if (! isdigit (scinote [1])) goto bad;
+  midi_note_t l =  ul - 'C',
+    o = scinote [1] - '0';
+  int sharp = 0;
+  if (scinote [2] == '#') sharp = 1;
+  else if (scinote [2] == 'b') sharp = -1;
+  // else if (scinote [2] != '\0') goto bad;
+
+  return 12 * (o + 1) + note_semitones [l] + sharp;
+
+bad:
+  return (midi_note_t) -1;
+}
+int scale2bits_aux (const char *name, int *scale, midi_note_t root) {
+  for (int i = 0; i < 12; ++i) {
+    if (name [i] == '0' || name [i] == '1')
+      scale [(root + i) % 12] = name [i] == '1';
+    else return 0;
+  }
+  return 1;
+}
+int scale2bits (const char *name, int *scale) {
+  if (isdigit (name [0])) {
+    return scale2bits_aux (name, scale, 0);
+  } else if (isupper (name [0])) {
+    char sciroot [4] = { name [0], '0', '\0', '\0' };
+    if (name [1] == '#' || name [1] == 'b') sciroot [2] = name++ [1];
+    midi_note_t root = note_sci2midi (sciroot);
+    TRACE (TRACE_INT, "scale root %d", (int) root);
+    if (root == (midi_note_t) -1) return 0;
+    if (0 == strcmp (&name [1], "maj"))
+      return scale2bits_aux ("101011010101", scale, root % 12);
+    else if (0 == strcmp (&name [1], "min"))
+      return scale2bits_aux ("101101011010", scale, root % 12);
+  }
+  return 0;
 }

 sigset_t sigmask;
@@ -299,7 +336,7 @@
 }
 static void gridpt_seq_fix_lengths (gridpt *seq, size_t len) {
   size_t i = 0;
-  for (; i < len - 1; i++)
+  for (; i < len - 1; ++i)
     seq [i].length = seq [i + 1].length - seq [i].length;
   seq [i].length = 0;
 }
@@ -325,7 +362,7 @@
   ++gridpt_seqdb_len;
 }
 static void gridpt_seq_add_all (midi_note_t note) {
-  for (size_t i = 0; i < gridpt_buf_len && gridpt_buf_dur (i) >= 0.9 * note_recog_frames; i++)
+  for (size_t i = 0; i < gridpt_buf_len && gridpt_buf_dur (i) >= 0.9 * note_recog_frames; ++i)
     gridpt_seq_add (note, &gridpt_buf [i], gridpt_buf_len - i);
 }

@@ -357,7 +394,7 @@
   analyzer_state anls; analyzer_state_init (&anls);

   // find noise level in waveform db
-  for (sf_count_t i = 0; i < initial_sil_frames; i++) {
+  for (sf_count_t i = 0; i < initial_sil_frames; ++i) {
     if (sf_read_double (dbf, &x, 1) < 1) goto premature;
     analyze_sample (x, &anls);
   }
@@ -508,7 +545,7 @@
     void *out = jack_port_get_buffer (jmidiport, nframes);
     jack_midi_clear_buffer (out);
     if (evtcnt > 0) {
-      for (size_t i = 0; i < evtcnt; i++)
+      for (size_t i = 0; i < evtcnt; ++i)
         jack_midi_event_write (out, 0, evt + 3 * i, sizeof (evt [0]) * 3);
     }

@@ -542,7 +579,7 @@

   // find noise level
   TRACE (TRACE_DIAG, "Analysing noise...");
-  for (jack_nframes_t i = 0; i < initial_sil_frames; i++)
+  for (jack_nframes_t i = 0; i < initial_sil_frames; ++i)
     analyze_sample (get_jsample (), &janls);
   noise_peak = janls.noise_peak = 4 * janls.max_x;
   TRACE (TRACE_DIAG, "Noise peak in input: %.5f", (float) noise_peak);
@@ -601,8 +638,9 @@
   for (end = mid + 1;
        end < gridpt_buf_len && gridpt_seq_cmp (&gseq, &gridpt_seqdb [end]) == 0; ++end);

-  for (size_t i = beg; i < end; i++) {
+  for (size_t i = beg; i < end; ++i) {
     if (fabs ((float) gridpt_seqdb [i].dur / gseq.dur - 1) > 0.04) continue;
+    if (! note_scale [gridpt_seqdb [i].note % 12]) continue;
     sample_t dist = 0.0;
     gridpt *seq2 = gridpt_seqdb [i].seq;
     size_t j = 0;
@@ -631,7 +669,7 @@
 }

 void send_note (midi_note_t note, int on) {
-  char ch = note; if (on) ch |= 1 << 7;
+  char ch = note + transpose_semitones; if (on) ch |= 1 << 7;
   jack_ringbuffer_write (jmidibuf, &ch, 1);
 }

@@ -751,11 +789,22 @@
       } else if (0 == strcmp (*argv, "--range")) {
         lomidi = note_sci2midi (argv [1]);
         himidi = note_sci2midi (argv [1] + 2);
+        ASSERT (lomidi != (midi_note_t) -1 && himidi != (midi_note_t) -1);
         ++argv;
       } else if (0 == strcmp (*argv, "-p") || 0 == strcmp (*argv, "--port")) {
         srcport = *++argv;
       } else if (0 == strcmp (*argv, "-d") || 0 == strcmp (*argv, "--delay")) {
         sscanf (*++argv, "%lf", &note_recog_ms);
+      } else if (0 == strcmp (*argv, "--anl-max")) {
+        sscanf (*++argv, "%lf", &note_recog_max_ms);
+      } else if (0 == strcmp (*argv, "--transpose")) {
+        int sems; sscanf (*++argv, "%d", &sems);
+        transpose_semitones = sems;
+      } else if (0 == strcmp (*argv, "--scale")) {
+        if (0 == scale2bits (*++argv, note_scale)) {
+          TRACE (TRACE_FATAL, "unknown scale %s", *argv);
+          myshutdown (1);
+        }
       } else if (0 == strcmp (*argv, "--log-level")) {
         int l; sscanf (*++argv, "%d", &l);
         TRACE (TRACE_IMPT, "Log level %d", l);
@@ -843,12 +892,12 @@
 void setup_sigs () {
   int sigarr [] = { SIGTERM, SIGQUIT, SIGABRT, SIGPIPE, SIGILL, SIGBUS, SIGFPE, SIGINT };
   sigemptyset (&sigmask);
-  for (unsigned i = 0; i < sizeof (sigarr) / sizeof (sigarr [0]); i++)
+  for (unsigned i = 0; i < sizeof (sigarr) / sizeof (sigarr [0]); ++i)
     sigaddset (&sigmask, sigarr [i]);
   pthread_sigmask (SIG_BLOCK, &sigmask, NULL);
   struct sigaction act =
     { .sa_mask = sigmask, .sa_flags = 0, .sa_handler = sig_handler };
-  for (unsigned i = 0; i < sizeof (sigarr) / sizeof (sigarr [0]); i++)
+  for (unsigned i = 0; i < sizeof (sigarr) / sizeof (sigarr [0]); ++i)
     sigaction (sigarr [i], &act, NULL);

 }


ble_mesh: Use mutex to protect client list operations

--- components/bt/esp_ble_mesh/mesh_models/client/client_common.c
+++ components/bt/esp_ble_mesh/mesh_models/client/client_common.c
@@ -28,19 +28,25 @@

 static bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, u16_t tx_dst)
 {
+    bt_mesh_client_node_t *node = NULL;
+    sys_snode_t *cur = NULL;
+
+    bt_mesh_irq_lock();
     if (sys_slist_is_empty(list)) {
-        return NULL;
-    }
-
-    sys_snode_t *cur = NULL; bt_mesh_client_node_t *node = NULL;
+        bt_mesh_irq_unlock();
+        return NULL;
+    }
+
     for (cur = sys_slist_peek_head(list);
             cur != NULL; cur = sys_slist_peek_next(cur)) {
         node = (bt_mesh_client_node_t *)cur;
         if (node->ctx.addr == tx_dst) {
+            bt_mesh_irq_unlock();
             return node;
         }
     }

+    bt_mesh_irq_unlock();
     return NULL;
 }

@@ -116,19 +122,25 @@

 static bool bt_mesh_client_check_node_in_list(sys_slist_t *list, u16_t tx_dst)
 {
+    bt_mesh_client_node_t *node = NULL;
+    sys_snode_t *cur = NULL;
+
+    bt_mesh_irq_lock();
     if (sys_slist_is_empty(list)) {
+        bt_mesh_irq_unlock();
         return false;
     }

-    sys_snode_t *cur = NULL; bt_mesh_client_node_t *node = NULL;
     for (cur = sys_slist_peek_head(list);
             cur != NULL; cur = sys_slist_peek_next(cur)) {
         node = (bt_mesh_client_node_t *)cur;
         if (node->ctx.addr == tx_dst) {
+            bt_mesh_irq_unlock();
             return true;
         }
     }

+    bt_mesh_irq_unlock();
     return false;
 }

@@ -200,7 +212,9 @@
         if ((err = bt_mesh_model_send(model, ctx, msg, cb, cb_data)) != 0) {
             osi_free(node);
         } else {
+            bt_mesh_irq_lock();
             sys_slist_append(&internal->queue, &node->client_node);
+            bt_mesh_irq_unlock();
             k_delayed_work_init(&node->timer, timer_handler);
             k_delayed_work_submit(&node->timer, timeout ? timeout : CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT);
         }
@@ -293,7 +307,9 @@
     }

     // Release the client node from the queue
+    bt_mesh_irq_lock();
     sys_slist_find_and_remove(&internal->queue, &node->client_node);
+    bt_mesh_irq_unlock();
     // Free the node
     osi_free(node);


drm/i915: fix uninitialized variable warning in i915_setup_compression()

Fixes:

drivers/gpu/drm/i915/i915_dma.c: In function ‘i915_setup_compression’:
drivers/gpu/drm/i915/i915_dma.c:1311: error: ‘compressed_llb’ may be used uninitialized in this function

Signed-off-by: Prarit Bhargava <fe4655370dc87a32329d591d6e8472329333dfad@redhat.com>
Signed-off-by: Eric Anholt <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@anholt.net>

--- drivers/gpu/drm/i915/i915_dma.c
+++ drivers/gpu/drm/i915/i915_dma.c
@@ -1231,7 +1231,7 @@
 static void i915_setup_compression(struct drm_device *dev, int size)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_mm_node *compressed_fb, *compressed_llb;
+	struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
 	unsigned long cfb_base;
 	unsigned long ll_base = 0;


add TIMEOUT_INITIALIZER for initting timeout declaractions.

similar to TASK_INITIALIZER and all the queue _INITIALIZER things.

ok deraadt@

--- sys/timeout.h
+++ sys/timeout.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: timeout.h,v 1.24 2013/11/27 04:28:32 dlg Exp $	*/
+/*	$OpenBSD: timeout.h,v 1.25 2014/12/22 04:43:38 dlg Exp $	*/
 /*
  * Copyright (c) 2000-2001 Artur Grabowski <art@openbsd.org>
  * All rights reserved.
@@ -82,6 +82,9 @@
 #define timeout_initialized(to) ((to)->to_flags & TIMEOUT_INITIALIZED)
 #define timeout_triggered(to) ((to)->to_flags & TIMEOUT_TRIGGERED)

+#define TIMEOUT_INITIALIZER(_f, _a) \
+	{ { NULL, NULL }, (_f), (_a), 0, TIMEOUT_INITIALIZED }
+
 struct bintime;

 void timeout_set(struct timeout *, void (*)(void *), void *);


Make if do the things

Make if do the things

--- Josh_Zane_Sebastian/src/interpreter/interpreter.c
+++ Josh_Zane_Sebastian/src/interpreter/interpreter.c
@@ -92,15 +92,31 @@
     // IF
     char bit = fnCall->args[0].referant->val.bit;
     struct function f;
-    struct llnode args;
+    struct llnode argList;
+    struct call call;
+
+    // check which func to run
     if (bit) {
-      f = fnCall->args[1].referant->val.func;
-      args = fnCall->args[2].referant->val.list;
+      call.func = fnCall->args[1].referant->val.func;
+      call.name = fnCall->args[1].name;
+      argList = fnCall->args[2].referant->val.list;
     } else {
-      f = fnCall->args[3].referant->val.func;
-      args = fnCall->args[4].referant->val.list;
+      call.func = fnCall->args[3].referant->val.func;
+      call.name = fnCall->args[3].name;
+      argList = fnCall->args[4].referant->val.list;
     }
-    // TODO somehow run the function
+
+    // count args
+    int numArgs = 0;
+    while (argList.car) {
+      argList = *argList.cdr;
+      numArgs++;
+    }
+    struct symbol* args = calloc(numArgs, sizeof(struct symbol));
+    call.arguments = args;
+    call.numargs = numArgs;
+    runFunc(call);
+    free(args);
   } else if (strcmp(name, "[") == 0) {
     // CAR
     struct llnode list = fnCall->args[0].referant->val.list;


i915 / PM: Fix hibernate regression caused by suspend/resume splitting

Commit 84b79f8d2882b0a84330c04839ed4d3cefd2ff77 (drm/i915: Fix crash
while aborting hibernation) attempted to fix a regression introduced
by commit cbda12d77ea590082edb6d30bd342a67ebc459e0 (drm/i915:
implement new pm ops for i915), but it went too far trying to split
the freeze/suspend and resume/thaw parts of the code.  As a result,
it introduced another regression, which only is visible on some systems.

Fix the problem by merging i915_drm_suspend() with
i915_drm_freeze() and moving some code from i915_resume()
into i915_drm_thaw(), so that intel_opregion_free() and
intel_opregion_init() are also executed in the freeze and thaw code
paths, respectively.

Signed-off-by: Rafael J. Wysocki <a11f87183a953ab11f50fbafff689c5a7fa3506c@sisk.pl>
Reported-and-tested-by: Pedro Ribeiro <639bf7afcc42f61944130b59e2931b042f93bf83@gmail.com>
Tested-by: Tino Keitel <fbb3bd99d5c88e52f3a0371da2390c3c807e42a3@tikei.de>
Acked-by: Eric Anholt <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@anholt.net>
Signed-off-by: Linus Torvalds <69652caca27c8b940640ad396ab71f93cacec34f@linux-foundation.org>

--- drivers/gpu/drm/i915/i915_drv.c
+++ drivers/gpu/drm/i915/i915_drv.c
@@ -176,6 +176,8 @@

 static int i915_drm_freeze(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
 	pci_save_state(dev->pdev);

 	/* If KMS is active, we do the leavevt stuff here */
@@ -191,17 +193,12 @@

 	i915_save_state(dev);

-	return 0;
-}
-
-static void i915_drm_suspend(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
 	intel_opregion_free(dev, 1);

 	/* Modeset on resume, not lid events */
 	dev_priv->modeset_on_lid = 0;
+
+	return 0;
 }

 static int i915_suspend(struct drm_device *dev, pm_message_t state)
@@ -221,8 +218,6 @@
 	if (error)
 		return error;

-	i915_drm_suspend(dev);
-
 	if (state.event == PM_EVENT_SUSPEND) {
 		/* Shut down the device */
 		pci_disable_device(dev->pdev);
@@ -237,6 +232,10 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int error = 0;

+	i915_restore_state(dev);
+
+	intel_opregion_init(dev, 1);
+
 	/* KMS EnterVT equivalent */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		mutex_lock(&dev->struct_mutex);
@@ -262,10 +261,6 @@
 		return -EIO;

 	pci_set_master(dev->pdev);
-
-	i915_restore_state(dev);
-
-	intel_opregion_init(dev, 1);

 	return i915_drm_thaw(dev);
 }
@@ -423,8 +418,6 @@
 	if (error)
 		return error;

-	i915_drm_suspend(drm_dev);
-
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);

@@ -464,13 +457,8 @@
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct drm_device *drm_dev = pci_get_drvdata(pdev);
-	int error;
-
-	error = i915_drm_freeze(drm_dev);
-	if (!error)
-		i915_drm_suspend(drm_dev);
-
-	return error;
+
+	return i915_drm_freeze(drm_dev);
 }

 const struct dev_pm_ops i915_pm_ops = {


Only create watch if Unix socket can be created

--- sdpd/server.c
+++ sdpd/server.c
@@ -232,7 +232,7 @@

 	g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock);

-	if (compat) {
+	if (compat && unix_sock > fileno(stderr)) {
 		unix_io = g_io_channel_unix_new(unix_sock);
 		g_io_channel_set_close_on_unref(unix_io, TRUE);


drm/i915: fix pch pci device enumeration

pci_get_class(class, from) drops the refcount for 'from', so the
extra pci_dev_put we do on it will result in a use after free bug
starting with the WARN below.

Regression introduced in

commit 6a9c4b35e6696a63805b6da5e4889c6986e9ee1b
Author: Rui Guo <firemeteor@users.sourceforge.net>
Date:   Wed Jun 19 21:10:23 2013 +0800

    drm/i915: Fix PCH detect with multiple ISA bridges in VM

[  164.338460] WARNING: CPU: 1 PID: 2094 at include/linux/kref.h:47 klist_next+0xae/0x110()
[  164.347731] CPU: 1 PID: 2094 Comm: modprobe Tainted: G           O 3.13.0-imre+ #354
[  164.356468] Hardware name: Intel Corp. VALLEYVIEW B0 PLATFORM/NOTEBOOK, BIOS BYTICRB1.X64.0062.R70.1310112051 10/11/2013
[  164.368796] Call Trace:
[  164.371609]  [<ffffffff816a32a6>] dump_stack+0x4e/0x7a
[  164.377447]  [<ffffffff8104f75d>] warn_slowpath_common+0x7d/0xa0
[  164.384238]  [<ffffffff8104f83a>] warn_slowpath_null+0x1a/0x20
[  164.390851]  [<ffffffff8169aeae>] klist_next+0xae/0x110
[  164.396777]  [<ffffffff8130a110>] ? pci_do_find_bus+0x70/0x70
[  164.403286]  [<ffffffff813cb4a9>] bus_find_device+0x89/0xc0
[  164.409719]  [<ffffffff8130a373>] pci_get_dev_by_id+0x63/0xa0
[  164.416238]  [<ffffffff8130a4e4>] pci_get_class+0x44/0x50
[  164.422433]  [<ffffffffa034821f>] intel_dsm_detect+0x16f/0x1f0 [i915]
[  164.429801]  [<ffffffffa03482ae>] intel_register_dsm_handler+0xe/0x10 [i915]
[  164.437831]  [<ffffffffa02d30fe>] i915_driver_load+0xafe/0xf30 [i915]
[  164.445126]  [<ffffffff8158a150>] ? intel_alloc_coherent+0x110/0x110
[  164.452340]  [<ffffffffa0148c07>] drm_dev_register+0xc7/0x150 [drm]
[  164.459462]  [<ffffffffa014b23f>] drm_get_pci_dev+0x11f/0x1f0 [drm]
[  164.466554]  [<ffffffff816abb81>] ? _raw_spin_unlock_irqrestore+0x51/0x70
[  164.474287]  [<ffffffffa02cf7a6>] i915_pci_probe+0x56/0x60 [i915]
[  164.481185]  [<ffffffff8130a028>] pci_device_probe+0x78/0xf0
[  164.487603]  [<ffffffff813cd495>] driver_probe_device+0x155/0x350
[  164.494505]  [<ffffffff813cd74e>] __driver_attach+0x6e/0xa0
[  164.500826]  [<ffffffff813cd6e0>] ? __device_attach+0x50/0x50
[  164.507333]  [<ffffffff813cb2be>] bus_for_each_dev+0x6e/0xc0
[  164.513752]  [<ffffffff813ccefe>] driver_attach+0x1e/0x20
[  164.519870]  [<ffffffff813cc958>] bus_add_driver+0x138/0x260
[  164.526289]  [<ffffffffa0188000>] ? 0xffffffffa0187fff
[  164.532116]  [<ffffffff813cde78>] driver_register+0x98/0xe0
[  164.538558]  [<ffffffffa0188000>] ? 0xffffffffa0187fff
[  164.544389]  [<ffffffff813087b0>] __pci_register_driver+0x60/0x70
[  164.551336]  [<ffffffffa014b37d>] drm_pci_init+0x6d/0x120 [drm]
[  164.558040]  [<ffffffffa0188000>] ? 0xffffffffa0187fff
[  164.563928]  [<ffffffffa018806a>] i915_init+0x6a/0x6c [i915]
[  164.570363]  [<ffffffff810002da>] do_one_initcall+0xaa/0x160
[  164.576783]  [<ffffffff8103b140>] ? set_memory_nx+0x40/0x50
[  164.583100]  [<ffffffff810ce7f5>] load_module+0x1fb5/0x2550
[  164.589410]  [<ffffffff810caab0>] ? store_uevent+0x40/0x40
[  164.595628]  [<ffffffff810cee7d>] SyS_init_module+0xed/0x100
[  164.602048]  [<ffffffff816b3c52>] system_call_fastpath+0x16/0x1b

v2: simplify the loop further (Chris)

Signed-off-by: Imre Deak <fbd5edba1988036c8923f0cca0cce6ac4811db29@intel.com>
Cc: Jesse Barnes <bc7add126c2dbb8382bf1c28ac262b9363a32706@virtuousgeek.org>
Reported-by: Jesse Barnes <bc7add126c2dbb8382bf1c28ac262b9363a32706@virtuousgeek.org>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65652
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74161
Reviewed-by: Chris Wilson <711c73f64afdce07b7e38039a96d2224209e9a6c@chris-wilson.co.uk>
Cc: 4fbacc2fa0ffdbb11bf1ad6925b886ebd08dd15f@vger.kernel.org
Signed-off-by: Jani Nikula <ba783f3beccaedfda693f41a15407d612a629408@intel.com>

--- drivers/gpu/drm/i915/i915_drv.c
+++ drivers/gpu/drm/i915/i915_drv.c
@@ -403,7 +403,7 @@
 void intel_detect_pch(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct pci_dev *pch;
+	struct pci_dev *pch = NULL;

 	/* In all current cases, num_pipes is equivalent to the PCH_NOP setting
 	 * (which really amounts to a PCH but no South Display).
@@ -424,12 +424,9 @@
 	 * all the ISA bridge devices and check for the first match, instead
 	 * of only checking the first one.
 	 */
-	pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	while (pch) {
-		struct pci_dev *curr = pch;
+	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
 		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
-			unsigned short id;
-			id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
+			unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
 			dev_priv->pch_id = id;

 			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
@@ -461,18 +458,16 @@
 				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
 				WARN_ON(!IS_HASWELL(dev));
 				WARN_ON(!IS_ULT(dev));
-			} else {
-				goto check_next;
-			}
-			pci_dev_put(pch);
+			} else
+				continue;
+
 			break;
 		}
-check_next:
-		pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, curr);
-		pci_dev_put(curr);
 	}
 	if (!pch)
-		DRM_DEBUG_KMS("No PCH found?\n");
+		DRM_DEBUG_KMS("No PCH found.\n");
+
+	pci_dev_put(pch);
 }

 bool i915_semaphore_is_enabled(struct drm_device *dev)


issue fix

issue fix

--- LPGoogleFunctions/AQGoogleSignature/LPURLSigner.h
+++ LPGoogleFunctions/AQGoogleSignature/LPURLSigner.h
@@ -10,7 +10,7 @@

 @interface LPURLSigner : NSObject

-+ (MOUtility *)sharedManager;
++ (LPURLSigner *)sharedManager;

 - (NSString *)createSignatureWithHMAC_SHA1:(NSString *)url key:(NSString *)key;


drm/i915: vlv: enable runtime PM

drm/i915: vlv: enable runtime PM

Signed-off-by: Imre Deak <fbd5edba1988036c8923f0cca0cce6ac4811db29@intel.com>
Signed-off-by: Daniel Vetter <c1b6782c4af8f0673da8923a0702a1832e5940f4@ffwll.ch>

--- drivers/gpu/drm/i915/i915_drv.h
+++ drivers/gpu/drm/i915/i915_drv.h
@@ -1952,7 +1952,7 @@
 #define HAS_FPGA_DBG_UNCLAIMED(dev)	(INTEL_INFO(dev)->has_fpga_dbg)
 #define HAS_PSR(dev)		(IS_HASWELL(dev) || IS_BROADWELL(dev))
 #define HAS_RUNTIME_PM(dev)	(IS_GEN6(dev) || IS_HASWELL(dev) || \
-				 IS_BROADWELL(dev))
+				 IS_BROADWELL(dev) || IS_VALLEYVIEW(dev))

 #define INTEL_PCH_DEVICE_ID_MASK		0xff00
 #define INTEL_PCH_IBX_DEVICE_ID_TYPE		0x3b00


add debugging to dpeaks

add debugging to dpeaks

git-svn-id: a4967eeb46e72ec0d67de3341f099b34cc11cf18@14345 03a3cea6-2c03-0410-ac9b-9271b1c66c29

--- blind/dpeaks.c
+++ blind/dpeaks.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <assert.h>

 #include "dimage.h"
 #include "permutedsort.h"
@@ -67,40 +68,75 @@
 	} else {
 		for (j = 0;j < ny;j++)
 			for (i = 0;i < nx;i++)
-				smooth[i + j*nx] = image[i + j * nx];
-	}
-
-	/* 2. find peaks */
+				smooth[i + j*nx] = image[i + j*nx];
+	}
+
+	/* 2. find peaks (highest in the 3x3 neighbourhood) */
 	peaks = (int *) malloc(sizeof(int) * nx * ny);
 	*npeaks = 0;
-	for (j = 1;j < ny - 1;j++) {
+	for (j = 1; j < ny - 1; j++) {
 		jst = j - 1;
 		jnd = j + 1;
-		for (i = 1;i < nx - 1;i++) {
+		for (i = 1; i < nx - 1; i++) {
+			if (smooth[i + j*nx] < minpeak)
+				continue;
 			ist = i - 1;
 			ind = i + 1;
-			if (smooth[i + j*nx] > minpeak) {
-				highest = 1;
-				for (ip = ist;ip <= ind;ip++)
-					for (jp = jst;jp <= jnd;jp++)
-						if (smooth[ip + jp*nx] > smooth[i + j*nx])
-							highest = 0;
-				if (highest) {
-					peaks[*npeaks] = i + j * nx;
-					(*npeaks)++;
-				}
+			highest = 1;
+			for (ip = ist; ip <= ind; ip++)
+				for (jp = jst; jp <= jnd; jp++)
+					if (smooth[ip + jp*nx] > smooth[i + j*nx])
+						highest = 0;
+			if (highest) {
+				peaks[*npeaks] = i + j * nx;
+				(*npeaks)++;
 			}
 		}
 	}

+	// DEBUG
+	for (i=0; i<(*npeaks); i++) {
+		float pk = smooth[peaks[i]];
+		assert((peaks[i] % nx) >= 1);
+		assert((peaks[i] % nx) <= (nx-2));
+		assert((peaks[i] / nx) >= 1);
+		assert((peaks[i] / nx) <= (ny-2));
+		assert(pk >= minpeak);
+		assert(pk >= smooth[peaks[i]-1]);
+		assert(pk >= smooth[peaks[i]+1]);
+		assert(pk >= smooth[peaks[i]-nx]);
+		assert(pk >= smooth[peaks[i]+nx]);
+		assert(pk >= smooth[peaks[i]+nx+1]);
+		assert(pk >= smooth[peaks[i]+nx-1]);
+		assert(pk >= smooth[peaks[i]-nx+1]);
+		assert(pk >= smooth[peaks[i]-nx-1]);
+	}
+
 	/* 2. sort peaks */
-	indx = (int *) malloc(sizeof(int) * (*npeaks));
-	for (i=0; i<(*npeaks); i++)
-		indx[i] = peaks[i];
-
-	FREEVEC(peaks);
-
+	indx = realloc(peaks, sizeof(int) * (*npeaks));
+	peaks = NULL;
     permuted_sort(smooth, sizeof(float), compare_floats_desc, indx, *npeaks);
+
+	// DEBUG
+	for (i=0; i<(*npeaks); i++) {
+		float pk = smooth[peaks[i]];
+		assert((peaks[i] % nx) >= 1);
+		assert((peaks[i] % nx) <= (nx-2));
+		assert((peaks[i] / nx) >= 1);
+		assert((peaks[i] / nx) <= (ny-2));
+		assert(pk >= minpeak);
+		assert(pk >= smooth[peaks[i]-1]);
+		assert(pk >= smooth[peaks[i]+1]);
+		assert(pk >= smooth[peaks[i]-nx]);
+		assert(pk >= smooth[peaks[i]+nx]);
+		assert(pk >= smooth[peaks[i]+nx+1]);
+		assert(pk >= smooth[peaks[i]+nx-1]);
+		assert(pk >= smooth[peaks[i]-nx+1]);
+		assert(pk >= smooth[peaks[i]-nx-1]);
+	}
+	for (i=1; i<(*npeaks); i++) {
+		assert(smooth[peaks[i]] >= smooth[peaks[i-1]]);
+	}

 	if ((*npeaks) > maxnpeaks)
 		*npeaks = maxnpeaks;
@@ -111,8 +147,16 @@
 		fullxcen[i] = indx[i] % nx;
 		fullycen[i] = indx[i] / nx;
 	}
-
 	FREEVEC(indx);
+
+	// DEBUG
+	for (i = 0;i < (*npeaks);i++) {
+		assert(fullxcen[i] >= 1);
+		assert(fullxcen[i] <= nx-2);
+		assert(fullycen[i] >= 1);
+		assert(fullycen[i] <= ny-2);
+	}
+

 	/* 3. trim close peaks and joined peaks */
 	mask = (int *) malloc(sizeof(int) * nx * ny);
@@ -149,13 +193,16 @@
 		}
 	}

+	// Grab just the keepers.
 	tmpnpeaks = 0;
-	for (i = 0;i < (*npeaks);i++) {
-		if (keep[i] && tmpnpeaks < maxnpeaks) {
-			xcen[tmpnpeaks] = fullxcen[i];
-			ycen[tmpnpeaks] = fullycen[i];
-			tmpnpeaks++;
-		}
+	for (i=0; i < (*npeaks); i++) {
+		if (!keep[i])
+			continue;
+		xcen[tmpnpeaks] = fullxcen[i];
+		ycen[tmpnpeaks] = fullycen[i];
+		tmpnpeaks++;
+		if (tmpnpeaks >= maxnpeaks)
+			break;
 	}
 	(*npeaks) = tmpnpeaks;


drm/i915: use vma->node directly and rewrap map&fence in bind

Use () to make for neater alignment of the split lines, too. With this
we ditch another jump through the obj_gtt_size/offset indirection
maze.

Cc: Ben Widawsky <cf148a1c890adeeb4308e9e093ed95f3d05c8318@intel.com>
Signed-off-by: Daniel Vetter <c1b6782c4af8f0673da8923a0702a1832e5940f4@ffwll.ch>

--- drivers/gpu/drm/i915/i915_gem.c
+++ drivers/gpu/drm/i915/i915_gem.c
@@ -3205,12 +3205,11 @@
 	if (i915_is_ggtt(vm)) {
 		bool mappable, fenceable;

-		fenceable =
-			i915_gem_obj_ggtt_size(obj) == fence_size &&
-			(i915_gem_obj_ggtt_offset(obj) & (fence_alignment - 1)) == 0;
-
-		mappable =
-			vma->node.start + obj->base.size <= dev_priv->gtt.mappable_end;
+		fenceable = (vma->node.size == fence_size &&
+			     (vma->node.start & (fence_alignment - 1)) == 0);
+
+		mappable = (vma->node.start + obj->base.size <=
+			    dev_priv->gtt.mappable_end);

 		obj->map_and_fenceable = mappable && fenceable;
 	}


handle no stars in range

handle no stars in range

git-svn-id: a4967eeb46e72ec0d67de3341f099b34cc11cf18@11273 03a3cea6-2c03-0410-ac9b-9271b1c66c29

--- blind/verify.c
+++ blind/verify.c
@@ -106,6 +106,12 @@

 	// Find all index stars within the bounding circle of the field.
 	startree_search_for(skdt, fieldcenter, fieldr2, &indxyz, NULL, &starid, &N);
+
+	if (!indxyz) {
+		// no stars in range.
+		*p_nindex = 0;
+		return;
+	}

 	// Find index stars within the rectangular field.
 	inbounds = sip_filter_stars_in_field(sip, tan, indxyz, NULL, N, indexpix,


drm/i915: Revert shrinker changes from "Track unbound pages"

This partially reverts

commit 6c085a728cf000ac1865d66f8c9b52935558b328
Author: Chris Wilson <711c73f64afdce07b7e38039a96d2224209e9a6c@chris-wilson.co.uk>
Date:   Mon Aug 20 11:40:46 2012 +0200

    drm/i915: Track unbound pages

Closer inspection of that patch revealed a bunch of unrelated changes
in the shrinker:
- The shrinker count is now in pages instead of objects.
- For counting the shrinkable objects the old code only looked at the
  inactive list, the new code looks at all bounds objects (including
  pinned ones). That is obviously in addition to the new unbound list.
- The shrinker cound is no longer scaled with
  sysctl_vfs_cache_pressure. Note though that with the default tuning
  value of vfs_cache_pressue = 100 this doesn't affect the shrinker
  behaviour.
- When actually shrinking objects, the old code first dropped
  purgeable objects, then normal (inactive) objects. Only then did it,
  in a last-ditch effort idle the gpu and evict everything. The new
  code omits the intermediate step of evicting normal inactive
  objects.

Safe for the first change, which seems benign, and the shrinker count
scaling, which is a bit a different story, the endresult of all these
changes is that the shrinker is _much_ more likely to fall back to the
last-ditch resort of idling the gpu and evicting everything.  The old
code could only do that if something else evicted lots of objects
meanwhile (since without any other changes the nr_to_scan will be
smaller than the object count).

Reverting the vfs_cache_pressure behaviour itself is a bit bogus: Only
dentry/inode object caches should scale their shrinker counts with
vfs_cache_pressure. Originally I've had that change reverted, too. But
Chris Wilson insisted that it's too bogus and shouldn't again see the
light of day.

Hence revert all these other changes and restore the old shrinker
behaviour, with the minor adjustment that we now first scan the
unbound list, then the inactive list for each object category
(purgeable or normal).

A similar patch has been tested by a few people affected by the gen4/5
hangs which started to appear in 3.7, which some people bisected to
the "drm/i915: Track unbound pages" commit. But just disabling the
unbound logic alone didn't change things at all.

Note that this patch doesn't fix the referenced bugs, it only hides
the underlying bug(s) well enough to restore pre-3.7 behaviour. The
key to achieve that is to massively reduce the likelyhood of going
into a full gpu stall and evicting everything.

v2: Reword commit message a bit, taking Chris Wilson's comment into
account.

v3: On Chris Wilson's insistency, do not reinstate the rather bogus
vfs_cache_pressure change.

Tested-by: Greg KH <4645f7897fd33786a2ee1264d590b3c400559d85@linuxfoundation.org>
Tested-by: Dave Kleikamp <d1e82e2813f00e3d60e00aa92378ef41c34f031b@oracle.com>
References: https://bugs.freedesktop.org/show_bug.cgi?id=55984
References: https://bugs.freedesktop.org/show_bug.cgi?id=57122
References: https://bugs.freedesktop.org/show_bug.cgi?id=56916
References: https://bugs.freedesktop.org/show_bug.cgi?id=57136
Cc: Chris Wilson <711c73f64afdce07b7e38039a96d2224209e9a6c@chris-wilson.co.uk>
Cc: 4fbacc2fa0ffdbb11bf1ad6925b886ebd08dd15f@vger.kernel.org
Acked-by: Chris Wilson <711c73f64afdce07b7e38039a96d2224209e9a6c@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <c1b6782c4af8f0673da8923a0702a1832e5940f4@ffwll.ch>

--- drivers/gpu/drm/i915/i915_gem.c
+++ drivers/gpu/drm/i915/i915_gem.c
@@ -1717,7 +1717,8 @@
 }

 static long
-i915_gem_purge(struct drm_i915_private *dev_priv, long target)
+__i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
+		  bool purgeable_only)
 {
 	struct drm_i915_gem_object *obj, *next;
 	long count = 0;
@@ -1725,7 +1726,7 @@
 	list_for_each_entry_safe(obj, next,
 				 &dev_priv->mm.unbound_list,
 				 gtt_list) {
-		if (i915_gem_object_is_purgeable(obj) &&
+		if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
 		    i915_gem_object_put_pages(obj) == 0) {
 			count += obj->base.size >> PAGE_SHIFT;
 			if (count >= target)
@@ -1736,7 +1737,7 @@
 	list_for_each_entry_safe(obj, next,
 				 &dev_priv->mm.inactive_list,
 				 mm_list) {
-		if (i915_gem_object_is_purgeable(obj) &&
+		if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
 		    i915_gem_object_unbind(obj) == 0 &&
 		    i915_gem_object_put_pages(obj) == 0) {
 			count += obj->base.size >> PAGE_SHIFT;
@@ -1746,6 +1747,12 @@
 	}

 	return count;
+}
+
+static long
+i915_gem_purge(struct drm_i915_private *dev_priv, long target)
+{
+	return __i915_gem_shrink(dev_priv, target, true);
 }

 static void
@@ -4396,6 +4403,9 @@
 	if (nr_to_scan) {
 		nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
 		if (nr_to_scan > 0)
+			nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan,
+							false);
+		if (nr_to_scan > 0)
 			i915_gem_shrink_all(dev_priv);
 	}

@@ -4403,7 +4413,7 @@
 	list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
 		if (obj->pages_pin_count == 0)
 			cnt += obj->base.size >> PAGE_SHIFT;
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
+	list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list)
 		if (obj->pin_count == 0 && obj->pages_pin_count == 0)
 			cnt += obj->base.size >> PAGE_SHIFT;


blk-mq: request initialization optimizations

We currently clear a lot more than we need to, so make that a bit
more clever. Make some of the init dependent on features, like
only setting start_time if we are going to use it.

Signed-off-by: Jens Axboe <cd8c6775e60d6f67a6984377324e5290df3d5358@fb.com>


drm/i915: Pin the object whilst faulting it in

In order to prevent reaping of the object whilst setting it up to
handle the pagefault, we need to mark it as pinned. This has the nice
side-effect of eliminating some special cases from the pagefault handler
as well!

Signed-off-by: Chris Wilson <711c73f64afdce07b7e38039a96d2224209e9a6c@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <c1b6782c4af8f0673da8923a0702a1832e5940f4@ffwll.ch>

--- drivers/gpu/drm/i915/i915_gem.c
+++ drivers/gpu/drm/i915/i915_gem.c
@@ -1345,30 +1345,17 @@
 	trace_i915_gem_object_fault(obj, page_offset, true, write);

 	/* Now bind it into the GTT if needed */
-	if (!obj->map_and_fenceable) {
-		ret = i915_gem_object_unbind(obj);
-		if (ret)
-			goto unlock;
-	}
-	if (!obj->gtt_space) {
-		ret = i915_gem_object_bind_to_gtt(obj, 0, true, false);
-		if (ret)
-			goto unlock;
-
-		ret = i915_gem_object_set_to_gtt_domain(obj, write);
-		if (ret)
-			goto unlock;
-	}
-
-	if (!obj->has_global_gtt_mapping)
-		i915_gem_gtt_bind_object(obj, obj->cache_level);
+	ret = i915_gem_object_pin(obj, 0, true, false);
+	if (ret)
+		goto unlock;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, write);
+	if (ret)
+		goto unpin;

 	ret = i915_gem_object_get_fence(obj);
 	if (ret)
-		goto unlock;
-
-	if (i915_gem_object_is_inactive(obj))
-		list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
+		goto unpin;

 	obj->fault_mappable = true;

@@ -1377,6 +1364,8 @@

 	/* Finally, remap it using the new GTT offset */
 	ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
+unpin:
+	i915_gem_object_unpin(obj);
 unlock:
 	mutex_unlock(&dev->struct_mutex);
 out:


Fix another problem in the same way

Fix another problem in the same way

git-svn-id: 31d9d2f6432a47c86a3640814024c107794ea77c@15512 0785d39b-7218-0410-832d-ea1e28bc413d

--- deal.II/lac/include/lac/full_matrix.templates.h
+++ deal.II/lac/include/lac/full_matrix.templates.h
@@ -1611,16 +1611,16 @@
 	  ExcIndexRange (dst_offset_i, 0, m()));
   Assert (dst_offset_j < n(),
 	  ExcIndexRange (dst_offset_j, 0, n()));
-  Assert (src_offset_i < src.m(),
-	  ExcIndexRange (src_offset_i, 0, src.m()));
-  Assert (src_offset_j < src.n(),
-	  ExcIndexRange (src_offset_j, 0, src.n()));
+  Assert (src_offset_i < src.n(),
+	  ExcIndexRange (src_offset_i, 0, src.n()));
+  Assert (src_offset_j < src.m(),
+	  ExcIndexRange (src_offset_j, 0, src.m()));

 				   // Compute maximal size of copied block
   const unsigned int rows = std::min (m() - dst_offset_i,
-				      src.m() - src_offset_i);
+				      src.m() - src_offset_j);
   const unsigned int cols = std::min (n() - dst_offset_j,
-				      src.n() - src_offset_j);
+				      src.n() - src_offset_i);

   for (unsigned int i=0; i<rows ; ++i)
     for (unsigned int j=0; j<cols ; ++j)


Move #ifdef __cplusplus  after #include section


drm/i915: Do not unmap object unless no other VMAs reference it

When using an IOMMU, GEM objects are mapped by their DMA address as the
physical address is unknown. This depends on the underlying IOMMU
driver to map and unmap the physical pages properly as defined in
intel_iommu.c.

The current code will tell the IOMMU to unmap the GEM BO's pages on the
destruction of the first VMA that "maps" that BO. This is clearly wrong
as there may be other VMAs "mapping" that BO (using flink). The scanout
is one such example.

The patch fixes this issue by only unmapping the DMA maps when there are
no more VMAs mapping that object. This is equivalent to when an object
is considered unbound as can be seen by the code. On the first VMA that
again because bound, we will remap.

An alternate solution would be to move the dma mapping to object
creation and destrubtion. I am not sure if this is considered an
unfriendly thing to do.

Some notes to backporters trying to backport full PPGTT:

The bug can never be hit without enabling the IOMMU. The existing code
will also do the right thing when the object is shared via dmabuf. The
failure should be demonstrable with flink. In cases when not using
intel_iommu_strict it is likely (likely, as defined by: off the top of
my head) on current workloads to *not* hit this bug since we often
teardown all VMAs for an object shared across multiple VMs.  We also
finish access to that object before the first dma_unmapping.
intel_iommu_strict with flinked buffers is likely to hit this issue.

Signed-off-by: Armin Reese <fc0d8b6c00286bcba581a6e9d1c2e99011f91c47@intel.com>
[danvet: Add the excellent commit message provided by Ben.]
Reviewed-by: Ben Widawsky <73675debcd8a436be48ec22211dcf44fe0df0a64@bwidawsk.net>
Signed-off-by: Daniel Vetter <c1b6782c4af8f0673da8923a0702a1832e5940f4@ffwll.ch>

--- drivers/gpu/drm/i915/i915_gem.c
+++ drivers/gpu/drm/i915/i915_gem.c
@@ -2927,8 +2927,6 @@

 	vma->unbind_vma(vma);

-	i915_gem_gtt_finish_object(obj);
-
 	list_del_init(&vma->mm_list);
 	/* Avoid an unnecessary call to unbind on rebind. */
 	if (i915_is_ggtt(vma->vm))
@@ -2939,8 +2937,10 @@

 	/* Since the unbound list is global, only move to that list if
 	 * no more VMAs exist. */
-	if (list_empty(&obj->vma_list))
+	if (list_empty(&obj->vma_list)) {
+		i915_gem_gtt_finish_object(obj);
 		list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list);
+	}

 	/* And finally now the object is completely decoupled from this vma,
 	 * we can drop its hold on the backing storage and allow it to be


Centralize and improve to_x/copy/crop

Centralize and improve to_x/copy/crop

--- src/omv/modules/py_image.c
+++ src/omv/modules/py_image.c
@@ -867,434 +867,155 @@
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_midpoint_pooled_obj, 3, py_image_midpoint_pooled);
 #endif // IMLIB_ENABLE_MIDPOINT_POOLING

+static mp_obj_t py_image_to(int bpp, const uint16_t *default_color_palette, bool copy_to_fb,
+                            uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
+{
+    image_t *src_img = py_helper_arg_to_image_mutable(args[0]);
+
+    float arg_x_scale = 1.f;
+    bool got_x_scale = py_helper_keyword_float_maybe(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_scale), &arg_x_scale);
+
+    float arg_y_scale = 1.f;
+    bool got_y_scale = py_helper_keyword_float_maybe(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_scale), &arg_y_scale);
+
+    rectangle_t arg_roi;
+    py_helper_keyword_rectangle_roi(src_img, n_args, args, 3, kw_args, &arg_roi);
+
+    int arg_rgb_channel = py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
+    if ((arg_rgb_channel < -1) || (2 < arg_rgb_channel)) {
+        mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("-1 <= rgb_channel <= 2!"));
+    }
+
+    int arg_alpha = py_helper_keyword_int(n_args, args, 5, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 256);
+    if ((arg_alpha < 0) || (256 < arg_alpha)) {
+        mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("0 <= alpha <= 256!"));
+    }
+
+    const uint16_t *color_palette = py_helper_keyword_color_palette(n_args, args, 6, kw_args, default_color_palette);
+    const uint8_t *alpha_palette = py_helper_keyword_alpha_palette(n_args, args, 7, kw_args, NULL);
+
+    image_hint_t hint = py_helper_keyword_int(n_args, args, 8, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hint), 0);
+
+    int arg_x_size;
+    bool got_x_size = py_helper_keyword_int_maybe(n_args, args, 9, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_size), &arg_x_size);
+
+    int arg_y_size;
+    bool got_y_size = py_helper_keyword_int_maybe(n_args, args, 10, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_size), &arg_y_size);
+
+    if (got_x_scale && got_x_size) {
+        mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either x_scale or x_size not both!"));
+    }
+
+    if (got_y_scale && got_y_size) {
+        mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either y_scale or y_size not both!"));
+    }
+
+    if (got_x_size) {
+        arg_x_scale = arg_x_size / ((float) arg_roi.w);
+    }
+
+    if (got_y_size) {
+        arg_y_scale = arg_y_size / ((float) arg_roi.h);
+    }
+
+    if ((!got_x_scale) && (!got_x_size) && got_y_size) {
+        arg_x_scale = arg_y_scale;
+    }
+
+    if ((!got_y_scale) && (!got_y_size) && got_x_size) {
+        arg_y_scale = arg_x_scale;
+    }
+
+    mp_obj_t copy_obj = py_helper_keyword_object(n_args, args, 11, kw_args,
+            MP_OBJ_NEW_QSTR(copy_to_fb ? MP_QSTR_copy_to_fb : MP_QSTR_copy), NULL);
+    bool copy = false;
+    image_t *arg_other = copy_to_fb ? NULL : src_img;
+
+    if (copy_obj) {
+        if (mp_obj_is_integer(copy_obj)) {
+            copy = mp_obj_get_int(copy_obj);
+        } else {
+            arg_other = py_helper_arg_to_image_mutable(copy_obj);
+        }
+    }
+
+    if (copy_to_fb && copy) {
+        fb_update_jpeg_buffer();
+    }
+
+    image_t dst_img;
+    dst_img.w = fast_floorf(arg_roi.w * arg_x_scale);
+    dst_img.h = fast_floorf(arg_roi.h * arg_y_scale);
+    dst_img.bpp = (bpp >= 0) ? bpp : src_img->bpp;
+
+    if (copy) {
+        if (copy_to_fb) {
+            py_helper_set_to_framebuffer(&dst_img);
+        } else {
+            dst_img.data = xalloc(image_size(&dst_img));
+        }
+    } else if (arg_other) {
+        bool fb = py_helper_is_equal_to_framebuffer(arg_other);
+        size_t size = fb ? framebuffer_get_buffer_size() : image_size(arg_other);
+        PY_ASSERT_TRUE_MSG((image_size(&dst_img) <= size),
+                "The new image won't fit in the target frame buffer!");
+        // DO NOT MODIFY arg_other YET (as it could point to src_img)!
+        dst_img.data = arg_other->data;
+        py_helper_update_framebuffer(&dst_img);
+    } else {
+        dst_img.data = xalloc(image_size(&dst_img));
+    }
+
+    fb_alloc_mark();
+    imlib_draw_image(&dst_img, src_img, 0, 0, arg_x_scale, arg_y_scale, &arg_roi,
+                     arg_rgb_channel, arg_alpha, color_palette, alpha_palette,
+                     (hint & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL);
+    fb_alloc_free_till_mark();
+
+    if (arg_other) {
+        arg_other->w = dst_img.w;
+        arg_other->h = dst_img.h;
+        arg_other->bpp = dst_img.bpp;
+    }
+
+    return py_image_from_struct(&dst_img);
+}
+
 static mp_obj_t py_image_to_bitmap(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
 {
-    image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
-    bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
-    int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
-
-    image_t out;
-    out.w = arg_img->w;
-    out.h = arg_img->h;
-    out.bpp = IMAGE_BPP_BINARY;
-    out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
-
-    switch(arg_img->bpp) {
-        case IMAGE_BPP_BINARY: {
-            if (copy) memcpy(out.data, arg_img->data, image_size(&out));
-            break;
-        }
-        case IMAGE_BPP_GRAYSCALE: {
-            PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint8_t))) || copy,
-                               "Can't convert to bitmap in place!");
-            fb_alloc_mark();
-            uint32_t *out_row_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out), FB_ALLOC_NO_HINT);
-            for (int y = 0, yy = out.h; y < yy; y++) {
-                uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
-                for (int x = 0, xx = out.w; x < xx; x++) {
-                    IMAGE_PUT_BINARY_PIXEL_FAST(out_row_ptr, x,
-                        COLOR_GRAYSCALE_TO_BINARY(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)));
-                }
-                memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
-                       out_row_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
-            }
-            fb_alloc_free_till_mark();
-            break;
-        }
-        case IMAGE_BPP_RGB565: {
-            PY_ASSERT_TRUE_MSG((out.w >= (sizeof(uint32_t)/sizeof(uint16_t))) || copy,
-                               "Can't convert to bitmap in place!");
-            fb_alloc_mark();
-            uint32_t *out_row_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(&out), FB_ALLOC_NO_HINT);
-            for (int y = 0, yy = out.h; y < yy; y++) {
-                uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
-                for (int x = 0, xx = out.w; x < xx; x++) {
-                    int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
-                    switch (channel) {
-                        case 0: {
-                            pixel = COLOR_RGB565_TO_R5(pixel) > (((COLOR_R5_MAX - COLOR_R5_MIN) / 2) + COLOR_R5_MIN);
-                            break;
-                        }
-                        case 1: {
-                            pixel = COLOR_RGB565_TO_G6(pixel) > (((COLOR_G6_MAX - COLOR_G6_MIN) / 2) + COLOR_G6_MIN);
-                            break;
-                        }
-                        case 2: {
-                            pixel = COLOR_RGB565_TO_B5(pixel) > (((COLOR_B5_MAX - COLOR_B5_MIN) / 2) + COLOR_B5_MIN);
-                            break;
-                        }
-                        default: {
-                            pixel = COLOR_RGB565_TO_BINARY(pixel);
-                            break;
-                        }
-                    }
-                    IMAGE_PUT_BINARY_PIXEL_FAST(out_row_ptr, x, pixel);
-                }
-                memcpy(IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&out, y),
-                       out_row_ptr, IMAGE_BINARY_LINE_LEN_BYTES(&out));
-            }
-            fb_alloc_free_till_mark();
-            break;
-        }
-        default: {
-            break;
-        }
-    }
-
-    if (!copy) {
-        arg_img->bpp = IMAGE_BPP_BINARY;
-        py_helper_update_framebuffer(&out);
-    }
-
-    return py_image_from_struct(&out);
+    return py_image_to(IMAGE_BPP_BINARY, NULL, false, n_args, args, kw_args);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_bitmap_obj, 1, py_image_to_bitmap);

 static mp_obj_t py_image_to_grayscale(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
 {
-    image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
-    bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
-    int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
-
-    image_t out;
-    out.w = arg_img->w;
-    out.h = arg_img->h;
-    out.bpp = IMAGE_BPP_GRAYSCALE;
-    out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
-
-    switch(arg_img->bpp) {
-        case IMAGE_BPP_BINARY: {
-            if (copy || (!py_helper_is_equal_to_framebuffer(&out))) {
-                PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
-                    "Can't convert to grayscale in place!");
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
-                    uint8_t *out_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x,
-                            COLOR_BINARY_TO_GRAYSCALE(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x)));
-                    }
-                }
-            } else {
-                image_t temp;
-                memcpy(&temp, arg_img, sizeof(image_t));
-                fb_alloc_mark();
-                temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
-                memcpy(temp.data, arg_img->data, image_size(&temp));
-                py_helper_set_to_framebuffer(&out);
-
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&temp, y);
-                    uint8_t *out_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x,
-                            COLOR_BINARY_TO_GRAYSCALE(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x)));
-                    }
-                }
-
-                fb_alloc_free_till_mark();
-            }
-            break;
-        }
-        case IMAGE_BPP_GRAYSCALE: {
-            if (copy) memcpy(out.data, arg_img->data, image_size(&out));
-            break;
-        }
-        case IMAGE_BPP_RGB565: {
-            for (int y = 0, yy = out.h; y < yy; y++) {
-                uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
-                uint8_t *out_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&out, y);
-                for (int x = 0, xx = out.w; x < xx; x++) {
-                    int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
-                    switch (channel) {
-                        case 0: {
-                            pixel = COLOR_RGB565_TO_R8(pixel);
-                            break;
-                        }
-                        case 1: {
-                            pixel = COLOR_RGB565_TO_G8(pixel);
-                            break;
-                        }
-                        case 2: {
-                            pixel = COLOR_RGB565_TO_B8(pixel);
-                            break;
-                        }
-                        default: {
-                            pixel = COLOR_RGB565_TO_GRAYSCALE(pixel);
-                            break;
-                        }
-                    }
-                    IMAGE_PUT_GRAYSCALE_PIXEL_FAST(out_row_ptr, x, pixel);
-                }
-            }
-            break;
-        }
-        default: {
-            break;
-        }
-    }
-
-    if (!copy) {
-        arg_img->bpp = IMAGE_BPP_GRAYSCALE;
-        py_helper_update_framebuffer(&out);
-    }
-
-    return py_image_from_struct(&out);
+    return py_image_to(IMAGE_BPP_GRAYSCALE, NULL, false, n_args, args, kw_args);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_grayscale_obj, 1, py_image_to_grayscale);

 static mp_obj_t py_image_to_rgb565(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
 {
-    image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
-    bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
-    int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
-
-    image_t out;
-    out.w = arg_img->w;
-    out.h = arg_img->h;
-    out.bpp = IMAGE_BPP_RGB565;
-    out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
-
-    switch(arg_img->bpp) {
-        case IMAGE_BPP_BINARY: {
-            if (copy || (!py_helper_is_equal_to_framebuffer(&out))) {
-                PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
-                    "Can't convert to grayscale in place!");
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            imlib_yuv_to_rgb(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) * COLOR_GRAYSCALE_MAX, 0, 0));
-                    }
-                }
-            } else {
-                image_t temp;
-                memcpy(&temp, arg_img, sizeof(image_t));
-                fb_alloc_mark();
-                temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
-                memcpy(temp.data, arg_img->data, image_size(&temp));
-                py_helper_set_to_framebuffer(&out);
-
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&temp, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            imlib_yuv_to_rgb(IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) * COLOR_GRAYSCALE_MAX, 0, 0));
-                    }
-                }
-
-                fb_alloc_free_till_mark();
-            }
-            break;
-        }
-        case IMAGE_BPP_GRAYSCALE: {
-            if (copy || (!py_helper_is_equal_to_framebuffer(&out))) {
-                PY_ASSERT_TRUE_MSG(copy,
-                    "Can't convert to rgb565 in place!");
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            imlib_yuv_to_rgb(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), 0, 0));
-                    }
-                }
-            } else {
-                image_t temp;
-                memcpy(&temp, arg_img, sizeof(image_t));
-                fb_alloc_mark();
-                temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
-                memcpy(temp.data, arg_img->data, image_size(&temp));
-                py_helper_set_to_framebuffer(&out);
-
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&temp, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            imlib_yuv_to_rgb(IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x), 0, 0));
-                    }
-                }
-
-                fb_alloc_free_till_mark();
-            }
-            break;
-        }
-        case IMAGE_BPP_RGB565: {
-            for (int y = 0, yy = out.h; y < yy; y++) {
-                uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
-                uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                for (int x = 0, xx = out.w; x < xx; x++) {
-                    int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
-                    switch (channel) {
-                        case 0: {
-                            pixel = COLOR_R5_G6_B5_TO_RGB565(COLOR_RGB565_TO_R5(pixel), 0, 0);
-                            break;
-                        }
-                        case 1: {
-                            pixel = COLOR_R5_G6_B5_TO_RGB565(0, COLOR_RGB565_TO_G6(pixel), 0);
-                            break;
-                        }
-                        case 2: {
-                            pixel = COLOR_R5_G6_B5_TO_RGB565(0, 0, COLOR_RGB565_TO_B5(pixel));
-                            break;
-                        }
-                        default: {
-                            break;
-                        }
-                    }
-                    IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x, pixel);
-                }
-            }
-            break;
-        }
-        default: {
-            break;
-        }
-    }
-
-    if (!copy) {
-        arg_img->bpp = IMAGE_BPP_RGB565;
-        py_helper_update_framebuffer(&out);
-    }
-
-    return py_image_from_struct(&out);
+    return py_image_to(IMAGE_BPP_RGB565, NULL, false, n_args, args, kw_args);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_rgb565_obj, 1, py_image_to_rgb565);

 static mp_obj_t py_image_to_rainbow(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
 {
-    image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
-    bool copy = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_copy), false);
-    int channel = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
-    int palette = py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_palette), COLOR_PALETTE_RAINBOW);
-    const uint16_t *color_palette = NULL;
-
-    if (palette == COLOR_PALETTE_RAINBOW) {
-        color_palette = rainbow_table;
-    } else if (palette == COLOR_PALETTE_IRONBOW) {
-        color_palette = ironbow_table;
-    } else {
-        mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid color palette!"));
-    }
-
-    image_t out;
-    out.w = arg_img->w;
-    out.h = arg_img->h;
-    out.bpp = IMAGE_BPP_RGB565;
-    out.data = copy ? xalloc(image_size(&out)) : arg_img->data;
-
-    switch(arg_img->bpp) {
-        case IMAGE_BPP_BINARY: {
-            if (copy || (!py_helper_is_equal_to_framebuffer(&out))) {
-                PY_ASSERT_TRUE_MSG((out.w == 1) || copy,
-                    "Can't convert to rainbow in place!");
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            color_palette[IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) * COLOR_GRAYSCALE_MAX]);
-                    }
-                }
-            } else {
-                image_t temp;
-                memcpy(&temp, arg_img, sizeof(image_t));
-                fb_alloc_mark();
-                temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
-                memcpy(temp.data, arg_img->data, image_size(&temp));
-                py_helper_set_to_framebuffer(&out);
-
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&temp, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            color_palette[IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) * COLOR_GRAYSCALE_MAX]);
-                    }
-                }
-
-                fb_alloc_free_till_mark();
-            }
-            break;
-        }
-        case IMAGE_BPP_GRAYSCALE: {
-            if (copy || (!py_helper_is_equal_to_framebuffer(&out))) {
-                PY_ASSERT_TRUE_MSG(copy,
-                    "Can't convert to rainbow in place!");
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            color_palette[IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)]);
-                    }
-                }
-            } else {
-                image_t temp;
-                memcpy(&temp, arg_img, sizeof(image_t));
-                fb_alloc_mark();
-                temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
-                memcpy(temp.data, arg_img->data, image_size(&temp));
-                py_helper_set_to_framebuffer(&out);
-
-                for (int y = 0, yy = out.h; y < yy; y++) {
-                    uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&temp, y);
-                    uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                    for (int x = 0, xx = out.w; x < xx; x++) {
-                        IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x,
-                            color_palette[IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x)]);
-                    }
-                }
-
-                fb_alloc_free_till_mark();
-            }
-            break;
-        }
-        case IMAGE_BPP_RGB565: {
-            for (int y = 0, yy = out.h; y < yy; y++) {
-                uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, y);
-                uint16_t *out_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&out, y);
-                for (int x = 0, xx = out.w; x < xx; x++) {
-                    int pixel = IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x);
-                    switch (channel) {
-                        case 0: {
-                            pixel = color_palette[COLOR_RGB565_TO_R8(pixel)];
-                            break;
-                        }
-                        case 1: {
-                            pixel = color_palette[COLOR_RGB565_TO_G8(pixel)];
-                            break;
-                        }
-                        case 2: {
-                            pixel = color_palette[COLOR_RGB565_TO_B8(pixel)];
-                            break;
-                        }
-                        default: {
-                            pixel = color_palette[COLOR_RGB565_TO_GRAYSCALE(pixel)];
-                            break;
-                        }
-                    }
-                    IMAGE_PUT_RGB565_PIXEL_FAST(out_row_ptr, x, pixel);
-                }
-            }
-            break;
-        }
-        default: {
-            break;
-        }
-    }
-
-    if (!copy) {
-        arg_img->bpp = IMAGE_BPP_RGB565;
-        py_helper_update_framebuffer(&out);
-    }
-
-    return py_image_from_struct(&out);
+    return py_image_to(IMAGE_BPP_RGB565, rainbow_table, false, n_args, args, kw_args);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_rainbow_obj, 1, py_image_to_rainbow);
+
+static mp_obj_t py_image_copy(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
+{
+    return py_image_to(-1, NULL, true, n_args, args, kw_args);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_copy_obj, 1, py_image_copy);
+
+static mp_obj_t py_image_crop(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
+{
+    return py_image_to(-1, NULL, false, n_args, args, kw_args);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_crop_obj, 1, py_image_crop);

 static mp_obj_t py_image_jpeg_encode_for_ide(mp_obj_t img_obj)
 {
@@ -1433,153 +1154,6 @@
     return py_image_from_struct(&out);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_compressed_for_ide_obj, 1, py_image_compressed_for_ide);
-
-static mp_obj_t py_image_copy_int(uint n_args, const mp_obj_t *args, mp_map_t *kw_args, bool mode)
-{
-    // mode == false -> copy behavior
-    // mode == true -> crop/scale behavior
-    image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
-
-    rectangle_t roi;
-    py_helper_keyword_rectangle_roi(arg_img, n_args, args, 1, kw_args, &roi);
-
-    float arg_x_scale =
-        py_helper_keyword_float(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_scale), 1.0f);
-        PY_ASSERT_TRUE_MSG((0.0f <= arg_x_scale), "Error: 0.0 <= x_scale!");
-
-    float arg_y_scale =
-        py_helper_keyword_float(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_y_scale), 1.0f);
-        PY_ASSERT_TRUE_MSG((0.0f <= arg_y_scale), "Error: 0.0 <= y_scale!");
-
-    mp_obj_t copy_to_fb_obj = py_helper_keyword_object(n_args, args, 4, kw_args,
-            MP_OBJ_NEW_QSTR(mode ? MP_QSTR_copy : MP_QSTR_copy_to_fb), NULL);
-    bool copy_to_fb = false;
-    image_t *arg_other = mode ? arg_img : NULL;
-
-    if (copy_to_fb_obj) {
-        if (mp_obj_is_integer(copy_to_fb_obj)) {
-            if (!mode) {
-                copy_to_fb = mp_obj_get_int(copy_to_fb_obj);
-            } else if (mp_obj_get_int(copy_to_fb_obj)) {
-                arg_other = NULL;
-            }
-        } else {
-            arg_other = py_helper_arg_to_image_mutable(copy_to_fb_obj);
-        }
-    }
-
-    if (copy_to_fb) {
-        fb_update_jpeg_buffer();
-    }
-
-    image_t image;
-    image.w = fast_floorf(roi.w * arg_x_scale);
-    PY_ASSERT_TRUE_MSG(image.w >= 1, "Output image width is 0!");
-    image.h = fast_floorf(roi.h * arg_y_scale);
-    PY_ASSERT_TRUE_MSG(image.h >= 1, "Output image height is 0!");
-    image.bpp = arg_img->bpp;
-    image.data = NULL;
-
-    if (copy_to_fb) {
-        py_helper_set_to_framebuffer(&image);
-    } else if (arg_other) {
-        PY_ASSERT_TRUE_MSG((image_size(&image) <= image_size(arg_other)), "The new image won't fit in the target frame buffer!");
-        image.data = arg_other->data;
-    } else {
-        image.data = xalloc(image_size(&image));
-    }
-
-    bool in_place = arg_img->data == image.data;
-    image_t temp;
-
-    if (in_place) {
-        memcpy(&temp, arg_img, sizeof(image_t));
-        fb_alloc_mark();
-        temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
-        memcpy(temp.data, arg_img->data, image_size(&temp));
-        arg_img = &temp;
-        if (copy_to_fb) {
-            py_helper_set_to_framebuffer(&image);
-        }
-    }
-
-    float over_xscale = IM_DIV(1.0, arg_x_scale), over_yscale = IM_DIV(1.0f, arg_y_scale);
-
-    switch(arg_img->bpp) {
-        case IMAGE_BPP_BINARY: {
-            for (int y = 0, yy = image.h; y < yy; y++) {
-                uint32_t *row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(arg_img, fast_floorf(y * over_yscale) + roi.y);
-                uint32_t *row_ptr_2 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(&image, y);
-                for (int x = 0, xx = image.w; x < xx; x++) {
-                    IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr_2, x,
-                        IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, fast_floorf(x * over_xscale) + roi.x));
-                }
-            }
-            break;
-        }
-        case IMAGE_BPP_GRAYSCALE: {
-            for (int y = 0, yy = image.h; y < yy; y++) {
-                uint8_t *row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(arg_img, fast_floorf(y * over_yscale) + roi.y);
-                uint8_t *row_ptr_2 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&image, y);
-                for (int x = 0, xx = image.w; x < xx; x++) {
-                    IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr_2, x,
-                        IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, fast_floorf(x * over_xscale) + roi.x));
-                }
-            }
-            break;
-        }
-        case IMAGE_BPP_RGB565: {
-            for (int y = 0, yy = image.h; y < yy; y++) {
-                uint16_t *row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(arg_img, fast_floorf(y * over_yscale) + roi.y);
-                uint16_t *row_ptr_2 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&image, y);
-                for (int x = 0, xx = image.w; x < xx; x++) {
-                    IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr_2, x,
-                        IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, fast_floorf(x * over_xscale) + roi.x));
-                }
-            }
-            break;
-        }
-        default: {
-            break;
-        }
-    }
-
-    if (in_place) {
-        fb_alloc_free_till_mark();
-    }
-
-    py_helper_update_framebuffer(&image);
-
-    if (copy_to_fb) {
-        image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
-
-        if (py_helper_is_equal_to_framebuffer(arg_img)) {
-            arg_img->w = image.w;
-            arg_img->h = image.h;
-            arg_img->bpp = image.bpp;
-        }
-    } else {
-        if (arg_other) {
-            arg_other->w = image.w;
-            arg_other->h = image.h;
-            arg_other->bpp = image.bpp;
-        }
-    }
-
-    return py_image_from_struct(&image);
-}
-
-static mp_obj_t py_image_copy(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
-{
-    return py_image_copy_int(n_args, args, kw_args, false);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_copy_obj, 1, py_image_copy);
-
-static mp_obj_t py_image_crop(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
-{
-    return py_image_copy_int(n_args, args, kw_args, true);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_crop_obj, 1, py_image_crop);

 #if defined(IMLIB_ENABLE_IMAGE_FILE_IO)
 static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)


Create tarea02_3.c

Create tarea02_3.c

error: pathspec 'MNO/entrega_tareas_de_C/tarea2/172860/tarea02_3.c' did not match any file(s) known to git

--- MNO/entrega_tareas_de_C/tarea2/172860/tarea02_3.c
+++ MNO/entrega_tareas_de_C/tarea2/172860/tarea02_3.c
@@ -0,0 +1,19 @@
+/*
+Tarea 02 Métodos Numéricos y Optimización
+Ixchel G. Meza Chávez
+
+3) Utiliza getchar para escribir un programa que cuente el número de caracteres dado un stdin e imprima este número. Al dar enter (salto de línea) el programa termina.
+
+*/
+
+#include <stdio.h>
+main(void){
+    int c, nc;
+    nc=0;
+    c = getchar();
+    while( c != '\n'){
+        nc++;
+        c = getchar();
+    }
+    printf("Número de caracteres: %d\n", nc);
+}


drm/i915: vlv: clear master interrupt flag when disabling interrupts

Not clearing this flag causes spurious interrupts at least in D3 state,
so before enabling RPM we need to fix this. We were already setting this
flag when enabling interrupts, only clearing it was missing.

Signed-off-by: Imre Deak <fbd5edba1988036c8923f0cca0cce6ac4811db29@intel.com>
Reviewed-by: Ville Syrjälä <cd6e8d405ca90be3a03d5427c5b24fbd2d68dcc4@linux.intel.com>
Signed-off-by: Daniel Vetter <c1b6782c4af8f0673da8923a0702a1832e5940f4@ffwll.ch>

--- drivers/gpu/drm/i915/i915_irq.c
+++ drivers/gpu/drm/i915/i915_irq.c
@@ -3318,6 +3318,8 @@
 	if (!dev_priv)
 		return;

+	I915_WRITE(VLV_MASTER_IER, 0);
+
 	intel_hpd_irq_uninstall(dev_priv);

 	for_each_pipe(pipe)


Add test-deltaseq source

Add test-deltaseq source

error: pathspec 'bacula/src/plugins/fd/test-deltaseq-fd.c' did not match any file(s) known to git

--- bacula/src/plugins/fd/test-deltaseq-fd.c
+++ bacula/src/plugins/fd/test-deltaseq-fd.c
@@ -0,0 +1,499 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2007-2011 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation, which is
+   listed in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * A simple delta plugin for the Bacula File Daemon
+ *
+ *
+ */
+#include "bacula.h"
+#include "fd_plugins.h"
+#include "fd_common.h"
+
+#undef malloc
+#undef free
+#undef strdup
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const int dbglvl = 0;
+
+#define PLUGIN_LICENSE      "Bacula AGPLv3"
+#define PLUGIN_AUTHOR       "Eric Bollengier"
+#define PLUGIN_DATE         "November 2010"
+#define PLUGIN_VERSION      "1"
+#define PLUGIN_DESCRIPTION  "Bacula Delta Test Plugin"
+
+/* Forward referenced functions */
+static bRC newPlugin(bpContext *ctx);
+static bRC freePlugin(bpContext *ctx);
+static bRC getPluginValue(bpContext *ctx, pVariable var, void *value);
+static bRC setPluginValue(bpContext *ctx, pVariable var, void *value);
+static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value);
+static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp);
+static bRC endBackupFile(bpContext *ctx);
+static bRC pluginIO(bpContext *ctx, struct io_pkt *io);
+static bRC startRestoreFile(bpContext *ctx, const char *cmd);
+static bRC endRestoreFile(bpContext *ctx);
+static bRC createFile(bpContext *ctx, struct restore_pkt *rp);
+static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp);
+
+/* Pointers to Bacula functions */
+static bFuncs *bfuncs = NULL;
+static bInfo  *binfo = NULL;
+
+/* Plugin Information block */
+static pInfo pluginInfo = {
+   sizeof(pluginInfo),
+   FD_PLUGIN_INTERFACE_VERSION,
+   FD_PLUGIN_MAGIC,
+   PLUGIN_LICENSE,
+   PLUGIN_AUTHOR,
+   PLUGIN_DATE,
+   PLUGIN_VERSION,
+   PLUGIN_DESCRIPTION,
+};
+
+/* Plugin entry points for Bacula */
+static pFuncs pluginFuncs = {
+   sizeof(pluginFuncs),
+   FD_PLUGIN_INTERFACE_VERSION,
+
+   /* Entry points into plugin */
+   newPlugin,                         /* new plugin instance */
+   freePlugin,                        /* free plugin instance */
+   getPluginValue,
+   setPluginValue,
+   handlePluginEvent,
+   startBackupFile,
+   endBackupFile,
+   startRestoreFile,
+   endRestoreFile,
+   pluginIO,
+   createFile,
+   setFileAttributes,
+   NULL                         /* no checkFile */
+};
+
+#define get_self(x) ((delta_test*)((x)->pContext))
+#define FO_DELTA        (1<<28)       /* Do delta on file */
+#define FO_OFFSETS      (1<<30)       /* Keep block offsets */
+
+class delta_test
+{
+private:
+   bpContext *ctx;
+
+public:
+   POOLMEM *fname;              /* Filename to save */
+   int32_t delta;
+   FILE *fd;
+   bool done;
+   int level;
+
+   delta_test(bpContext *bpc) {
+      fd = NULL;
+      ctx = bpc;
+      done = false;
+      level = 0;
+      delta = 0;
+      fname = get_pool_memory(PM_FNAME);
+   }
+   ~delta_test() {
+      free_and_null_pool_memory(fname);
+   }
+};
+
+/*
+ * loadPlugin() and unloadPlugin() are entry points that are
+ *  exported, so Bacula can directly call these two entry points
+ *  they are common to all Bacula plugins.
+ */
+/*
+ * External entry point called by Bacula to "load the plugin
+ */
+bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
+{
+   bfuncs = lbfuncs;                  /* set Bacula funct pointers */
+   binfo  = lbinfo;
+   *pinfo  = &pluginInfo;             /* return pointer to our info */
+   *pfuncs = &pluginFuncs;            /* return pointer to our functions */
+
+   /* Activate this plugin only in developer mode */
+#ifdef DEVELOPER
+   return bRC_OK;
+#else
+   return bRC_Error;
+#endif
+}
+
+/*
+ * External entry point to unload the plugin
+ */
+bRC unloadPlugin()
+{
+// Dmsg(NULL, dbglvl, "delta-test-fd: Unloaded\n");
+   return bRC_OK;
+}
+
+/*
+ * The following entry points are accessed through the function
+ *   pointers we supplied to Bacula. Each plugin type (dir, fd, sd)
+ *   has its own set of entry points that the plugin must define.
+ */
+/*
+ * Create a new instance of the plugin i.e. allocate our private storage
+ */
+static bRC newPlugin(bpContext *ctx)
+{
+   delta_test *self = new delta_test(ctx);
+   if (!self) {
+      return bRC_Error;
+   }
+   ctx->pContext = (void *)self;        /* set our context pointer */
+   return bRC_OK;
+}
+
+/*
+ * Free a plugin instance, i.e. release our private storage
+ */
+static bRC freePlugin(bpContext *ctx)
+{
+   delta_test *self = get_self(ctx);
+   if (!self) {
+      return bRC_Error;
+   }
+   delete self;
+   return bRC_OK;
+}
+
+/*
+ * Return some plugin value (none defined)
+ */
+static bRC getPluginValue(bpContext *ctx, pVariable var, void *value)
+{
+   return bRC_OK;
+}
+
+/*
+ * Set a plugin value (none defined)
+ */
+static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
+{
+   return bRC_OK;
+}
+
+/*
+ * Handle an event that was generated in Bacula
+ */
+static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
+{
+   delta_test *self = get_self(ctx);
+   int accurate=0;
+
+   if (!self) {
+      return bRC_Error;
+   }
+
+// char *name;
+
+   /*
+    * Most events don't interest us so we ignore them.
+    *   the printfs are so that plugin writers can enable them to see
+    *   what is really going on.
+    */
+   switch (event->eventType) {
+   case bEventPluginCommand:
+//    Dmsg(ctx, dbglvl,
+//         "delta-test-fd: PluginCommand=%s\n", (char *)value);
+      break;
+   case bEventJobStart:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: JobStart=%s\n", (char *)value);
+      break;
+   case bEventJobEnd:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: JobEnd\n");
+      break;
+   case bEventStartBackupJob:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: StartBackupJob\n");
+      break;
+   case bEventEndBackupJob:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: EndBackupJob\n");
+      break;
+   case bEventLevel:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: JobLevel=%c %d\n", (int)value, (int)value);
+      self->level = (int)(intptr_t)value;
+      break;
+   case bEventSince:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: since=%d\n", (int)value);
+      break;
+
+   case bEventStartRestoreJob:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: StartRestoreJob\n");
+      break;
+
+   case bEventEndRestoreJob:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: EndRestoreJob\n");
+      break;
+
+   /* Plugin command e.g. plugin = <plugin-name>:<name-space>:read command:write command */
+   case bEventRestoreCommand:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: EventRestoreCommand cmd=%s\n", (char *)value);
+      /* Fall-through wanted */
+      break;
+   case bEventBackupCommand:
+      Dmsg(ctx, dbglvl, "delta-test-fd: pluginEvent cmd=%s\n", (char *)value);
+      if (self->level == 'I' || self->level == 'D') {
+         bfuncs->getBaculaValue(ctx, bVarAccurate, (void *)&accurate);
+         if (!accurate) {       /* can be changed to FATAL */
+            Jmsg(ctx, M_FATAL,
+                 "Accurate mode should be turned on when using the "
+                 "delta-test plugin\n");
+            return bRC_Error;
+         }
+      }
+      break;
+
+   default:
+//    Dmsg(ctx, dbglvl, "delta-test-fd: unknown event=%d\n", event->eventType);
+      break;
+   }
+   return bRC_OK;
+}
+
+static const char *files[] = {
+   "/etc/passwd",
+   "/etc/group",
+   "/etc/hosts",
+   "/etc/services"
+};
+static int nb_files = 4;
+
+/*
+ * Start the backup of a specific file
+ */
+static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp)
+{
+   delta_test *self = get_self(ctx);
+   if (!self) {
+      return bRC_Error;
+   }
+   time_t now = time(NULL);
+   sp->fname = (char *)"/delta.txt";
+   sp->type = FT_REG;
+   sp->statp.st_mode = 0700 | S_IFREG;
+   sp->statp.st_ctime = now;
+   sp->statp.st_mtime = now;
+   sp->statp.st_atime = now;
+   sp->statp.st_size = -1;
+   sp->statp.st_blksize = 4096;
+   sp->statp.st_blocks = 1;
+   if (self->level == 'I' || self->level == 'D') {
+      bRC state = bfuncs->checkChanges(ctx, sp);
+      /* Should always be bRC_OK */
+      sp->type = (state == bRC_Seen)? FT_NOCHG : FT_REG;
+      sp->flags |= (FO_DELTA|FO_OFFSETS);
+      self->delta = sp->delta_seq + 1;
+   }
+   pm_strcpy(self->fname, files[self->delta % nb_files]);
+   Dmsg(ctx, dbglvl, "delta-test-fd: delta_seq=%i delta=%i fname=%s\n",
+        sp->delta_seq, self->delta, self->fname);
+// Dmsg(ctx, dbglvl, "delta-test-fd: startBackupFile\n");
+   return bRC_OK;
+}
+
+/*
+ * Done with backup of this file
+ */
+static bRC endBackupFile(bpContext *ctx)
+{
+   /*
+    * We would return bRC_More if we wanted startBackupFile to be
+    * called again to backup another file
+    */
+   return bRC_OK;
+}
+
+
+/*
+ * Bacula is calling us to do the actual I/O
+ */
+static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
+{
+   delta_test *self = get_self(ctx);
+   struct stat statp;
+   if (!self) {
+      return bRC_Error;
+   }
+
+   io->status = 0;
+   io->io_errno = 0;
+   switch(io->func) {
+   case IO_OPEN:
+      Dmsg(ctx, dbglvl, "delta-test-fd: IO_OPEN\n");
+      if (io->flags & (O_CREAT | O_WRONLY)) {
+         /* TODO: if the file already exists, the result is undefined */
+         if (stat(io->fname, &statp) == 0) { /* file exists */
+            self->fd = fopen(io->fname, "r+");
+         } else {
+            self->fd = fopen(io->fname, "w"); /* file doesn't exist,create it */
+         }
+         if (!self->fd) {
+            io->io_errno = errno;
+            Jmsg(ctx, M_FATAL,
+                 "Open failed: ERR=%s\n", strerror(errno));
+            return bRC_Error;
+         }
+
+      } else {
+         self->fd = fopen(self->fname, "r");
+         if (!self->fd) {
+            io->io_errno = errno;
+            Jmsg(ctx, M_FATAL,
+               "Open failed: ERR=%s\n", strerror(errno));
+            return bRC_Error;
+         }
+      }
+      break;
+
+   case IO_READ:
+      if (!self->fd) {
+         Jmsg(ctx, M_FATAL, "Logic error: NULL read FD\n");
+         return bRC_Error;
+      }
+      if (self->done) {
+         io->status = 0;
+      } else {
+         /* first time, read 300, then replace 50-250 by other data */
+         if (self->delta == 0) {
+            io->status = fread(io->buf, 1, 400, self->fd);
+         } else {
+            io->offset = self->delta * 100 / 2; /* chunks are melted */
+            io->status = fread(io->buf, 1, 100, self->fd);
+         }
+         Dmsg(ctx, dbglvl, "delta-test-fd: READ offset=%lld\n", (int64_t)io->offset);
+         self->done = true;
+      }
+      if (io->status == 0 && ferror(self->fd)) {
+         Jmsg(ctx, M_FATAL,
+            "Pipe read error: ERR=%s\n", strerror(errno));
+         Dmsg(ctx, dbglvl,
+            "Pipe read error: ERR=%s\n", strerror(errno));
+         return bRC_Error;
+      }
+      Dmsg(ctx, dbglvl, "offset=%d\n", io->offset);
+      break;
+
+   case IO_WRITE:
+      if (!self->fd) {
+         Jmsg(ctx, M_FATAL, "Logic error: NULL write FD\n");
+         return bRC_Error;
+      }
+      Dmsg(ctx, dbglvl, "delta-test-fd: WRITE count=%lld\n", (int64_t)io->count);
+      io->status = fwrite(io->buf, 1, io->count, self->fd);
+      if (io->status == 0 && ferror(self->fd)) {
+         Jmsg(ctx, M_FATAL,
+            "Pipe write error\n");
+         Dmsg(ctx, dbglvl,
+            "Pipe read error: ERR=%s\n", strerror(errno));
+         return bRC_Error;
+      }
+      break;
+
+   case IO_CLOSE:
+      if (!self->fd) {
+         Jmsg(ctx, M_FATAL, "Logic error: NULL FD on delta close\n");
+         return bRC_Error;
+      }
+      io->status = fclose(self->fd);
+      break;
+
+   case IO_SEEK:
+      if (!self->fd) {
+         Jmsg(ctx, M_FATAL, "Logic error: NULL FD on delta close\n");
+         return bRC_Error;
+      }
+      Dmsg(ctx, dbglvl, "delta-test-fd: SEEK offset=%lld\n", (int64_t)io->offset);
+      io->status = fseek(self->fd, io->offset, io->whence);
+      Dmsg(ctx, dbglvl, "after SEEK=%lld\n", (int64_t)ftell(self->fd));
+      break;
+   }
+   return bRC_OK;
+}
+
+/*
+ * Bacula is notifying us that a plugin name string was found, and
+ *   passing us the plugin command, so we can prepare for a restore.
+ */
+static bRC startRestoreFile(bpContext *ctx, const char *cmd)
+{
+// Dmsg(ctx, dbglvl, "delta-test-fd: startRestoreFile cmd=%s\n", cmd);
+   return bRC_OK;
+}
+
+/*
+ * Bacula is notifying us that the plugin data has terminated, so
+ *  the restore for this particular file is done.
+ */
+static bRC endRestoreFile(bpContext *ctx)
+{
+// Dmsg(ctx, dbglvl, "delta-test-fd: endRestoreFile\n");
+   return bRC_OK;
+}
+
+/*
+ * This is called during restore to create the file (if necessary)
+ * We must return in rp->create_status:
+ *
+ *  CF_ERROR    -- error
+ *  CF_SKIP     -- skip processing this file
+ *  CF_EXTRACT  -- extract the file (i.e.call i/o routines)
+ *  CF_CREATED  -- created, but no content to extract (typically directories)
+ *
+ */
+static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
+{
+   delta_test *self = get_self(ctx);
+   pm_strcpy(self->fname, rp->ofname);
+   rp->create_status = CF_EXTRACT;
+   return bRC_OK;
+}
+
+/*
+ * We will get here if the File is a directory after everything
+ * is written in the directory.
+ */
+static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
+{
+// Dmsg(ctx, dbglvl, "delta-test-fd: setFileAttributes\n");
+   return bRC_OK;
+}
+
+#ifdef __cplusplus
+}
+#endif


BUG: m_Begin was not set to the current position at construction time

--- Code/Common/itkChildTreeIterator.h
+++ Code/Common/itkChildTreeIterator.h
@@ -84,6 +84,7 @@
   m_ListPosition = 0;
   m_ParentNode = this->m_Position;
   this->m_Position = m_ParentNode->GetChild( m_ListPosition );
+  this->m_Begin = this->m_Position;
 }

 template <class TTreeType>


Typo in previous commit.

Typo in previous commit.

git-svn-id: 2c9807fa3ff65b17195bd55dc8a6c4261e10127b@2188 d4fa192b-c00b-0410-8231-f00ffab90ce4

--- bin/varnishd/cache_hash.c
+++ bin/varnishd/cache_hash.c
@@ -88,7 +88,7 @@
 	if (w->nobj == NULL) {
 		st = STV_alloc(sp, params->mem_workspace);
 		XXXAN(st);
-		assert(st->size > sizeof *w->nobj);
+		assert(st->space > sizeof *w->nobj);
 		w->nobj = (void *)st->ptr; /* XXX: align ? */
 		st->len = sizeof *w->nobj;
 		memset(w->nobj, 0, sizeof *w->nobj);