+err_undo_config:
+ indio_dev->active_scan_mask = NULL;
+
+ return ret;
+}
+
+static int iio_disable_buffers(struct iio_dev *indio_dev)
+{
+ int ret = 0;
+ int ret2;
+
+ /* Wind down existing buffers - iff there are any */
+ if (list_empty(&indio_dev->buffer_list))
+ return 0;
+
+ /*
+ * If things go wrong at some step in disable we still need to continue
+ * to perform the other steps, otherwise we leave the device in a
+ * inconsistent state. We return the error code for the first error we
+ * encountered.
+ */
+
+ if (indio_dev->setup_ops->predisable) {
+ ret2 = indio_dev->setup_ops->predisable(indio_dev);
+ if (ret2 && !ret)
+ ret = ret2;
+ }
+
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+
+ if (indio_dev->setup_ops->postdisable) {
+ ret2 = indio_dev->setup_ops->postdisable(indio_dev);
+ if (ret2 && !ret)
+ ret = ret2;
+ }
+
+ iio_free_scan_mask(indio_dev, indio_dev->active_scan_mask);
+ indio_dev->active_scan_mask = NULL;
+
+ return ret;
+}
+
+static int __iio_update_buffers(struct iio_dev *indio_dev,
+ struct iio_buffer *insert_buffer,
+ struct iio_buffer *remove_buffer)
+{
+ struct iio_device_config new_config;
+ int ret;
+
+ ret = iio_verify_update(indio_dev, insert_buffer, remove_buffer,
+ &new_config);
+ if (ret)
+ return ret;
+
+ if (insert_buffer) {
+ ret = iio_buffer_request_update(indio_dev, insert_buffer);
+ if (ret)
+ goto err_free_config;
+ }
+
+ ret = iio_disable_buffers(indio_dev);
+ if (ret)
+ goto err_deactivate_all;
+
+ if (remove_buffer)
+ iio_buffer_deactivate(remove_buffer);