Index: roard/container_framework.c
===================================================================
--- roard/container_framework.c	(revision 4957)
+++ roard/container_framework.c	(revision 5276)
@@ -198,5 +198,4 @@
 
 off_t   cont_fw_lseek   (struct roar_vio_calls * vio, off_t offset, int whence);
-int     cont_fw_nonblock(struct roar_vio_calls * vio, int state);
 
 int     cont_fw_sync    (struct roar_vio_calls * vio) {
@@ -245,5 +244,4 @@
  vio->write    = cont_pvio_write;
  vio->lseek    = cont_pvio_lseek;
- vio->nonblock = cont_pvio_nonblock;
  vio->sync     = cont_pvio_sync;
  vio->ctl      = cont_pvio_ctl;
@@ -264,8 +262,4 @@
 off_t   cont_pvio_lseek   (struct roar_vio_calls * vio, off_t offset, int whence) {
  return roar_vio_lseek(&(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream->vio), offset, whence);
-}
-
-int     cont_pvio_nonblock(struct roar_vio_calls * vio, int state) {
- return roar_vio_nonblock(&(((struct cont_fw_parent_inst*)(vio->inst))->stream.stream->vio), state);
 }
 
Index: roard/driver.c
===================================================================
--- roard/driver.c	(revision 5274)
+++ roard/driver.c	(revision 5276)
@@ -317,10 +317,18 @@
 #endif
 
-int  driver_dummy_nonblock(struct roar_vio_calls * vio, int state) {
- if ( state == ROAR_SOCKET_BLOCK )
-  return 0;
-
- roar_err_set(ROAR_ERROR_NOTSUP);
- return -1;
+int  driver_dummy_ctl(struct roar_vio_calls * vio, int cmd, void * data) {
+ switch (cmd) {
+  case ROAR_VIO_CTL_NONBLOCK:
+    if ( *(const int*)data == ROAR_SOCKET_BLOCK )
+     return 0;
+
+    roar_err_set(ROAR_ERROR_NOTSUP);
+    return -1;
+   break;
+  default:
+    roar_err_set(ROAR_ERROR_BADRQC);
+    return -1;
+   break;
+ }
 }
 
Index: roard/driver_alsa.c
===================================================================
--- roard/driver_alsa.c	(revision 5012)
+++ roard/driver_alsa.c	(revision 5276)
@@ -231,5 +231,4 @@
  inst->sync     = driver_alsa_sync;
  inst->ctl      = driver_alsa_ctl;
- inst->nonblock = driver_dummy_nonblock;
 
  ROAR_DBG("driver_alsa_open_vio(inst=%p, device='%s', info=%p, fh=%i, sstream=%p) = 0", inst, device, info, fh, sstream);
@@ -333,31 +332,39 @@
  switch (cmd) {
   case ROAR_VIO_CTL_GET_DELAY:
-   if ( snd_pcm_delay(device->handle, &alsa_delay) < 0 )
+    if ( snd_pcm_delay(device->handle, &alsa_delay) < 0 )
+     return -1;
+    else {
+     *(uint_least32_t *)data = snd_pcm_frames_to_bytes(device->handle, alsa_delay);
+     ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_DELAY(0x%.8x), data=%p): %i bytes.", vio, cmd, data, (int)(*(uint_least32_t*)data));
+    }
+   break;
+
+  case ROAR_VIO_CTL_SET_SSTREAMID:
+    device->ssid = *(int *)data;
+    ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_SSTREAMID(0x%.8x), data=%p): ssid=%i", vio, cmd, data, device->ssid);
+   break;
+
+  case ROAR_VIO_CTL_SET_SSTREAM:
+    device->sstream = data;
+    ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_SSTREAM(0x%.8x), data=%p): sstream=%p", vio, cmd, data, device->sstream);
+   break;
+
+  case ROAR_VIO_CTL_GET_AUINFO:
+    ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_AUINFO(0x%.8x), data=%p) = ?", vio, cmd, data);
+    memcpy(data, &(device->info), sizeof(struct roar_audio_info));
+   break;
+
+  case ROAR_VIO_CTL_SET_AUINFO:
+    ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_AUINFO(0x%.8x), data=%p) = ?", vio, cmd, data);
+    memcpy(&(device->info), data, sizeof(struct roar_audio_info));
+    return driver_alsa_reopen_device(device);
+   break;
+
+  case ROAR_VIO_CTL_NONBLOCK:
+    if ( *(int*)data == ROAR_SOCKET_BLOCK )
+     return 0;
+    roar_err_set(ROAR_ERROR_NOTSUP);
     return -1;
-   else {
-    *(uint_least32_t *)data = snd_pcm_frames_to_bytes(device->handle, alsa_delay);
-    ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_DELAY(0x%.8x), data=%p): %i bytes.", vio, cmd, data, (int)(*(uint_least32_t*)data));
-   }
-   break;
-
-  case ROAR_VIO_CTL_SET_SSTREAMID:
-   device->ssid = *(int *)data;
-   ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_SSTREAMID(0x%.8x), data=%p): ssid=%i", vio, cmd, data, device->ssid);
-   break;
-
-  case ROAR_VIO_CTL_SET_SSTREAM:
-   device->sstream = data;
-   ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_SSTREAM(0x%.8x), data=%p): sstream=%p", vio, cmd, data, device->sstream);
-   break;
-
-  case ROAR_VIO_CTL_GET_AUINFO:
-   ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_AUINFO(0x%.8x), data=%p) = ?", vio, cmd, data);
-   memcpy(data, &(device->info), sizeof(struct roar_audio_info));
-   break;
-
-  case ROAR_VIO_CTL_SET_AUINFO:
-   ROAR_DBG("driver_alsa_ctl(vio=%p, cmd=ROAR_VIO_CTL_SET_AUINFO(0x%.8x), data=%p) = ?", vio, cmd, data);
-   memcpy(&(device->info), data, sizeof(struct roar_audio_info));
-   return driver_alsa_reopen_device(device);
+   break;
 
   default:
Index: roard/driver_ao.c
===================================================================
--- roard/driver_ao.c	(revision 5056)
+++ roard/driver_ao.c	(revision 5276)
@@ -134,5 +134,5 @@
  inst->write    = driver_ao_write;
  inst->close    = driver_ao_close;
- inst->nonblock = driver_dummy_nonblock;
+ inst->ctl      = driver_dummy_ctl;
 
  return 0;
Index: roard/driver_artsc.c
===================================================================
--- roard/driver_artsc.c	(revision 5108)
+++ roard/driver_artsc.c	(revision 5276)
@@ -124,5 +124,4 @@
  inst->close    = driver_artsc_close;
  inst->ctl      = driver_artsc_ctl;
- inst->nonblock = driver_artsc_nonblock;
 
  ROAR_DBG("driver_artsc_open_vio(*) = 0");
@@ -155,24 +154,4 @@
 
  return driver_artsc_init_shutdown(SHUTDOWN);
-}
-
-int     driver_artsc_nonblock(struct roar_vio_calls * vio, int state) {
- struct roar_artsc * self = vio->inst;
- int ret;
-
- switch (state) {
-  case ROAR_SOCKET_NONBLOCK:
-    ret = arts_stream_set(self->stream, ARTS_P_BLOCKING, 0);
-    if ( ret == 0 )
-     return 0;
-   break;
-  case ROAR_SOCKET_BLOCK:
-    ret = arts_stream_set(self->stream, ARTS_P_BLOCKING, 1);
-    if ( ret == 1 )
-     return 0;
-   break;
- }
-
- return -1;
 }
 
@@ -206,4 +185,20 @@
 
     return 0;
+  case ROAR_VIO_CTL_NONBLOCK:
+    switch (*(int*)data) {
+     case ROAR_SOCKET_NONBLOCK:
+       ret = arts_stream_set(self->stream, ARTS_P_BLOCKING, 0);
+       if ( ret == 0 )
+        return 0;
+       return -1;
+      break;
+     case ROAR_SOCKET_BLOCK:
+       ret = arts_stream_set(self->stream, ARTS_P_BLOCKING, 1);
+       if ( ret == 1 )
+        return 0;
+       return -1;
+      break;
+    }
+   break;
   default:
     return -1;
Index: roard/driver_jack.c
===================================================================
--- roard/driver_jack.c	(revision 5259)
+++ roard/driver_jack.c	(revision 5276)
@@ -65,5 +65,4 @@
  inst->write    = driver_jack_write;
  inst->lseek    = NULL; // no seeking on this device
- inst->nonblock = driver_jack_nonblock;
  inst->sync     = driver_jack_sync;
  inst->ctl      = driver_jack_ctl;
@@ -157,13 +156,4 @@
 }
 
-int     driver_jack_nonblock(struct roar_vio_calls * vio, int state) {
- struct driver_jack * self = vio->inst;
- // control if read and write calls should block untill all data is read or written.
- // state could be:
- //  ROAR_SOCKET_BLOCK    - Block untill the data is read or written
- //  ROAR_SOCKET_NONBLOCK - Return as soon as possible
- return -1;
-}
-
 int     driver_jack_sync    (struct roar_vio_calls * vio) {
  struct driver_jack * self = vio->inst;
@@ -200,32 +190,38 @@
     return 0;
    break;
-   case ROAR_VIO_CTL_GET_AUINFO:
-   case ROAR_VIO_CTL_SET_AUINFO:
+  case ROAR_VIO_CTL_NONBLOCK:
+ // control if read and write calls should block untill all data is read or written.
+ // state is in *(int*)data and could be:
+ //  ROAR_SOCKET_BLOCK    - Block untill the data is read or written
+ //  ROAR_SOCKET_NONBLOCK - Return as soon as possible
+   break;
+  case ROAR_VIO_CTL_GET_AUINFO:
+  case ROAR_VIO_CTL_SET_AUINFO:
     // get or set audio info, data is a struct roar_audio_info*.
     return -1;
    break;
-   case ROAR_VIO_CTL_GET_DBLKSIZE:
-   case ROAR_VIO_CTL_SET_DBLKSIZE:
+  case ROAR_VIO_CTL_GET_DBLKSIZE:
+  case ROAR_VIO_CTL_SET_DBLKSIZE:
      // get or set block size used, data is uint_least32_t*, number of bytes.
     return -1;
    break;
-   case ROAR_VIO_CTL_GET_DBLOCKS:
-   case ROAR_VIO_CTL_SET_DBLOCKS:
+  case ROAR_VIO_CTL_GET_DBLOCKS:
+  case ROAR_VIO_CTL_SET_DBLOCKS:
      // get or set number of blocks used, data is uint_least32_t*.
     return -1;
    break;
-   case ROAR_VIO_CTL_SET_SSTREAM:
+  case ROAR_VIO_CTL_SET_SSTREAM:
     // set server stream object for this stream, data is struct roar_stream_server*
     return -1;
    break;
-   case ROAR_VIO_CTL_SET_SSTREAMID:
+  case ROAR_VIO_CTL_SET_SSTREAMID:
     // set stream ID for this stream, data is int*
     return -1;
    break;
-   case ROAR_VIO_CTL_SET_VOLUME:
+  case ROAR_VIO_CTL_SET_VOLUME:
     // set volume for this device, data is struct roar_mixer_settings*
     return -1;
    break;
-   case ROAR_VIO_CTL_GET_DELAY:
+  case ROAR_VIO_CTL_GET_DELAY:
     // get delay of this stream, data is uint_least32_t*, in bytes
     // there is more about delay. please ask.
Index: roard/driver_oss.c
===================================================================
--- roard/driver_oss.c	(revision 5055)
+++ roard/driver_oss.c	(revision 5276)
@@ -38,5 +38,4 @@
  vio->write    = driver_oss_write;
  vio->read     = driver_oss_read;
- vio->nonblock = driver_oss_nonblock;
  vio->sync     = driver_oss_sync;
  vio->ctl      = driver_oss_ctl;
@@ -448,24 +447,4 @@
 }
 
-int     driver_oss_nonblock(struct roar_vio_calls * vio, int state) {
- ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = ?", vio, state);
-
- if ( roar_socket_nonblock(_get(vio,fh), state) == -1 ) {
-  ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = -1", vio, state);
-  return -1;
- }
-
- if ( state == ROAR_SOCKET_NONBLOCK ) {
-  ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = 0", vio, state);
-  return 0;
- }
-
- roar_vio_sync(vio);
-
- ROAR_DBG("driver_oss_nonblock(vio=%p, state=%i) = 0", vio, state);
-
- return 0;
-}
-
 int driver_oss_sync(struct roar_vio_calls * vio) {
 #ifdef SNDCTL_DSP_SYNC
@@ -558,4 +537,15 @@
    break;
 #endif
+  case ROAR_VIO_CTL_NONBLOCK:
+    if ( roar_socket_nonblock(_get(vio,fh), *(int*)data) == -1 ) {
+     return -1;
+    }
+
+    if ( *(int*)data == ROAR_SOCKET_NONBLOCK ) {
+     return 0;
+    }
+
+    roar_vio_sync(vio);
+   break;
   default:
    return -1;
Index: roard/driver_portaudio.c
===================================================================
--- roard/driver_portaudio.c	(revision 5134)
+++ roard/driver_portaudio.c	(revision 5276)
@@ -124,5 +124,5 @@
  inst->close = driver_portaudio_close;
  inst->write = driver_portaudio_write;
- inst->nonblock = driver_dummy_nonblock;
+ inst->ctl   = driver_dummy_ctl;
 
  Pa_Initialize();
Index: roard/driver_pulsesimple.c
===================================================================
--- roard/driver_pulsesimple.c	(revision 5056)
+++ roard/driver_pulsesimple.c	(revision 5276)
@@ -127,5 +127,4 @@
  inst->sync     = driver_pulsesimple_sync;
  inst->ctl      = driver_pulsesimple_ctl;
- inst->nonblock = driver_dummy_nonblock;
 
  return 0;
@@ -167,4 +166,14 @@
  ROAR_DBG("driver_pulsesimple_ctl(vio=%p) = ?", vio);
 
+ switch (cmd) {
+  case ROAR_VIO_CTL_NONBLOCK:
+    if ( *(int*)data == ROAR_SOCKET_BLOCK )
+     return 0;
+    roar_err_set(ROAR_ERROR_NOTSUP);
+    return -1;
+   break;
+ }
+
+ roar_err_set(ROAR_ERROR_NOSYS);
  return -1;
 }
Index: roard/driver_pwmled.c
===================================================================
--- roard/driver_pwmled.c	(revision 4957)
+++ roard/driver_pwmled.c	(revision 5276)
@@ -62,5 +62,4 @@
  inst->write    = driver_pwmled_write;
  inst->lseek    = NULL;
- inst->nonblock = NULL;
  inst->sync     = NULL;
  inst->ctl      = driver_pwmled_ctl;
Index: roard/driver_rsound.c
===================================================================
--- roard/driver_rsound.c	(revision 5107)
+++ roard/driver_rsound.c	(revision 5276)
@@ -171,5 +171,5 @@
  inst->close    = driver_rsound_close;
  inst->write    = driver_rsound_write;
- inst->nonblock = driver_dummy_nonblock;
+ inst->ctl      = driver_dummy_ctl;
 
  return 0;
Index: roard/driver_shout.c
===================================================================
--- roard/driver_shout.c	(revision 5012)
+++ roard/driver_shout.c	(revision 5276)
@@ -202,5 +202,5 @@
  inst->write    = driver_shout_write;
  inst->close    = driver_shout_close;
- inst->nonblock = driver_dummy_nonblock;
+ inst->ctl      = driver_dummy_ctl;
 
  return 0;
Index: roard/driver_sndio.c
===================================================================
--- roard/driver_sndio.c	(revision 5105)
+++ roard/driver_sndio.c	(revision 5276)
@@ -265,4 +265,10 @@
     return sio_setvol(self->shandle, d) == 0 ? -1 : 0;
    break;
+  case ROAR_VIO_CTL_NONBLOCK:
+    if ( *(int*)data == ROAR_SOCKET_BLOCK )
+     return 0;
+    roar_err_set(ROAR_ERROR_NOTSUP);
+    return -1;
+   break;
   default:
     return -1;
Index: roard/driver_sysclock.c
===================================================================
--- roard/driver_sysclock.c	(revision 5012)
+++ roard/driver_sysclock.c	(revision 5276)
@@ -42,6 +42,6 @@
  inst->inst     = self;
  inst->close    = driver_sysclock_close;
- inst->nonblock = driver_dummy_nonblock;
  inst->write    = driver_sysclock_write;
+ inst->ctl      = driver_dummy_ctl;
 
  self->bps      = roar_info2bitspersec(info)/8;
Index: roard/driver_wmm.c
===================================================================
--- roard/driver_wmm.c	(revision 5062)
+++ roard/driver_wmm.c	(revision 5276)
@@ -191,5 +191,5 @@
  inst->close    = driver_wmm_close_vio;
  inst->write    = driver_wmm_write;
- inst->nonblock = driver_dummy_nonblock;
+ inst->ctl      = driver_dummy_ctl;
 
  info->codec = ROAR_CODEC_PCM_S_LE;
Index: roard/include/driver.h
===================================================================
--- roard/include/driver.h	(revision 5245)
+++ roard/include/driver.h	(revision 5276)
@@ -159,5 +159,5 @@
 #endif
 
-int  driver_dummy_nonblock(struct roar_vio_calls * vio, int state);
+int  driver_dummy_ctl(struct roar_vio_calls * vio, int cmd, void * data);
 
 #endif
Index: roard/include/driver_oss.h
===================================================================
--- roard/include/driver_oss.h	(revision 4815)
+++ roard/include/driver_oss.h	(revision 5276)
@@ -46,5 +46,4 @@
 ssize_t driver_oss_write    (struct roar_vio_calls * vio, void *buf, size_t count);
 ssize_t driver_oss_read     (struct roar_vio_calls * vio, void *buf, size_t count);
-int     driver_oss_nonblock (struct roar_vio_calls * vio, int state);
 int     driver_oss_close_vio(struct roar_vio_calls * vio);
 int     driver_oss_reopen_device(struct driver_oss * self);
Index: roard/include/midi.h
===================================================================
--- roard/include/midi.h	(revision 5194)
+++ roard/include/midi.h	(revision 5276)
@@ -174,4 +174,5 @@
 // dummys:
 int     midi_vio_set_dummy(int stream);
+int     midi_vio_ctl(struct roar_vio_calls * vio, int cmd, void * data);
 int     midi_vio_ok(struct roar_vio_calls * vio, ...);
 
Index: roard/midi.c
===================================================================
--- roard/midi.c	(revision 5210)
+++ roard/midi.c	(revision 5276)
@@ -1058,7 +1058,6 @@
  ss->vio.write    = NULL;
  ss->vio.lseek    = NULL;
- ss->vio.nonblock = (int (*)(struct roar_vio_calls * vio, int state))midi_vio_ok;
  ss->vio.sync     = (int (*)(struct roar_vio_calls * vio))midi_vio_ok;
- ss->vio.ctl      = NULL;
+ ss->vio.ctl      = midi_vio_ctl;
  ss->vio.close    = (int (*)(struct roar_vio_calls * vio))midi_vio_ok;
 
@@ -1066,4 +1065,10 @@
 }
 
+int midi_vio_ctl(struct roar_vio_calls * vio, int cmd, void * data) {
+ if ( cmd == ROAR_VIO_CTL_NONBLOCK )
+  return 0;
+ return -1;
+}
+
 int     midi_vio_ok(struct roar_vio_calls * vio, ...) {
  return 0;
Index: roard/sources.c
===================================================================
--- roard/sources.c	(revision 5246)
+++ roard/sources.c	(revision 5276)
@@ -418,4 +418,12 @@
 }
 
+static int  sources_radionoise_ctl(struct roar_vio_calls * vio, int cmd, void * data) {
+ if ( cmd == ROAR_VIO_CTL_NONBLOCK )
+  return 0;
+
+ roar_err_set(ROAR_ERROR_BADRQC);
+ return -1;
+}
+
 int sources_add_radionoise (int stream, const char * device, int fh, const char * driver) {
  struct roar_stream_server * ss;
@@ -437,5 +445,5 @@
  ss->vio.close    = sources_radionoise_return_zero;
  ss->vio.sync     = sources_radionoise_return_zero;
- ss->vio.nonblock = (int (*)(struct roar_vio_calls * vio, int state))sources_radionoise_return_zero;
+ ss->vio.ctl      = sources_radionoise_ctl;
 
  return streams_set_fh(stream, -2);
