Index: c/src/lib/libbsp/arm/gp32/smc/smc.c
===================================================================
--- c/src/lib/libbsp/arm/gp32/smc/smc.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ c/src/lib/libbsp/arm/gp32/smc/smc.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -545,5 +545,5 @@
 static int smc_write(rtems_blkdev_request *req)
 {
-	req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
+	rtems_blkdev_request_done(req, RTEMS_SUCCESSFUL);
 	return 0;
 }
@@ -574,5 +574,5 @@
         remains -= count;
     }
-    req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
+    rtems_blkdev_request_done(req, RTEMS_SUCCESSFUL);
     return 0;
 }
Index: c/src/lib/libbsp/lm32/shared/milkymist_memcard/memcard.c
===================================================================
--- c/src/lib/libbsp/lm32/shared/milkymist_memcard/memcard.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ c/src/lib/libbsp/lm32/shared/milkymist_memcard/memcard.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -198,5 +198,5 @@
   }
 
-  r->req_done(r->done_arg, RTEMS_SUCCESSFUL);
+  rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
 
   return 0;
@@ -205,5 +205,7 @@
 static int memcard_disk_block_write(rtems_blkdev_request *r)
 {
-  return -RTEMS_IO_ERROR;
+  rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
+
+  return 0;
 }
 
Index: c/src/libchip/i2c/spi-sd-card.c
===================================================================
--- c/src/libchip/i2c/spi-sd-card.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ c/src/libchip/i2c/spi-sd-card.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -1118,5 +1118,5 @@
 
 	/* Done */
-	r->req_done( r->done_arg, RTEMS_SUCCESSFUL);
+	rtems_blkdev_request_done( r, RTEMS_SUCCESSFUL);
 
 	return 0;
@@ -1133,7 +1133,7 @@
 
 	/* Done */
-	r->req_done( r->done_arg, RTEMS_IO_ERROR);
-
-	return rv;
+	rtems_blkdev_request_done( r, RTEMS_IO_ERROR);
+
+	return 0;
 }
 
@@ -1207,5 +1207,5 @@
 
 	/* Done */
-	r->req_done( r->done_arg, RTEMS_SUCCESSFUL);
+	rtems_blkdev_request_done( r, RTEMS_SUCCESSFUL);
 
 	return 0;
@@ -1226,7 +1226,7 @@
 
 	/* Done */
-	r->req_done( r->done_arg, RTEMS_IO_ERROR);
-
-	return rv;
+	rtems_blkdev_request_done( r, RTEMS_IO_ERROR);
+
+	return 0;
 }
 
Index: c/src/libchip/ide/ata.c
===================================================================
--- c/src/libchip/ide/ata.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ c/src/libchip/ide/ata.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -186,5 +186,6 @@
     if (areq == NULL)
     {
-        return RTEMS_NO_MEMORY;
+        rtems_blkdev_request_done(req, RTEMS_NO_MEMORY);
+        return RTEMS_SUCCESSFUL;
     }
 
Index: c/src/libchip/ide/ata_internal.h
===================================================================
--- c/src/libchip/ide/ata_internal.h	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ c/src/libchip/ide/ata_internal.h	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -219,6 +219,6 @@
 #define ATA_EXEC_CALLBACK(areq, status) \
     do {\
-        if (((areq)->breq != NULL) && ((areq)->breq->req_done != NULL)) \
-            (areq)->breq->req_done((areq)->breq->done_arg, status); \
+        if ((areq)->breq != NULL) \
+            rtems_blkdev_request_done((areq)->breq, status); \
     } while (0)
 
Index: cpukit/libblock/include/rtems/blkdev.h
===================================================================
--- cpukit/libblock/include/rtems/blkdev.h	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ cpukit/libblock/include/rtems/blkdev.h	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -54,16 +54,13 @@
 } rtems_blkdev_request_op;
 
+struct rtems_blkdev_request;
+
 /**
  * @brief Block device request done callback function type.
- *
- * The first parameter @a arg must be the argument provided by the block device
- * request structure @ref rtems_blkdev_request.
- *
- * The second parameter @a status should contain the status of the operation:
- *  - @c RTEMS_SUCCESSFUL Operation was successful.
- *  - @c RTEMS_IO_ERROR Some sort of input or output error.
- *  - @c RTEMS_UNSATISFIED Media no more present.
- */
-typedef void (*rtems_blkdev_request_cb)(void *arg, rtems_status_code status);
+ */
+typedef void (*rtems_blkdev_request_cb)(
+  struct rtems_blkdev_request *req,
+  rtems_status_code status
+);
 
 /**
@@ -93,13 +90,14 @@
 
 /**
- * The block device request structure is used to read or write a number of
- * blocks from or to the device.
- *
- * TODO: The use of these req blocks is not a great design. The req is a
- *       struct with a single 'bufs' declared in the req struct and the
- *       others are added in the outer level struct. This relies on the
- *       structs joining as a single array and that assumes the compiler
- *       packs the structs. Why not just place on a list ? The BD has a
- *       node that can be used.
+ * @brief The block device transfer request is used to read or write a number
+ * of blocks from or to the device.
+ *
+ * Transfer requests are issued to the disk device driver with the
+ * @ref RTEMS_BLKIO_REQUEST IO control.  The transfer request completion status
+ * must be signalled with rtems_blkdev_request_done().  This function must be
+ * called exactly once per request.  The return value of the IO control will be
+ * ignored for transfer requests.
+ *
+ * @see rtems_blkdev_create().
  */
 typedef struct rtems_blkdev_request {
@@ -112,5 +110,5 @@
    * Request done callback function.
    */
-  rtems_blkdev_request_cb req_done;
+  rtems_blkdev_request_cb done;
 
   /**
@@ -133,4 +131,13 @@
    */
   rtems_id io_task;
+
+  /*
+   * TODO: The use of these req blocks is not a great design. The req is a
+   *       struct with a single 'bufs' declared in the req struct and the
+   *       others are added in the outer level struct. This relies on the
+   *       structs joining as a single array and that assumes the compiler
+   *       packs the structs. Why not just place on a list ? The BD has a
+   *       node that can be used.
+   */
 
   /**
@@ -139,4 +146,23 @@
   rtems_blkdev_sg_buffer bufs[0];
 } rtems_blkdev_request;
+
+/**
+ * @brief Signals transfer request completion status.
+ *
+ * This function must be called exactly once per request.
+ *
+ * @param[in,out] req The transfer request.
+ * @param[in] status The status of the operation should be
+ *  - @c RTEMS_SUCCESSFUL, if the operation was successful,
+ *  - @c RTEMS_IO_ERROR, if some sort of input or output error occured, or
+ *  - @c RTEMS_UNSATISFIED, if media is no more present.
+ */
+static inline void rtems_blkdev_request_done(
+  rtems_blkdev_request *req,
+  rtems_status_code status
+)
+{
+  (*req->done)(req, status);
+}
 
 /**
@@ -342,4 +368,6 @@
  * @retval RTEMS_NO_MEMORY Not enough memory.
  * @retval RTEMS_UNSATISFIED Cannot create generic device node.
+ *
+ * @see rtems_blkdev_create_partition() and rtems_blkdev_request.
  */
 rtems_status_code rtems_blkdev_create(
@@ -371,4 +399,6 @@
  * @retval RTEMS_NO_MEMORY Not enough memory.
  * @retval RTEMS_UNSATISFIED Cannot create generic device node.
+ *
+ * @see rtems_blkdev_create().
  */
 rtems_status_code rtems_blkdev_create_partition(
Index: cpukit/libblock/src/bdbuf.c
===================================================================
--- cpukit/libblock/src/bdbuf.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ cpukit/libblock/src/bdbuf.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -1872,8 +1872,6 @@
  */
 static void
-rtems_bdbuf_transfer_done (void* arg, rtems_status_code status)
-{
-  rtems_blkdev_request* req = (rtems_blkdev_request*) arg;
-
+rtems_bdbuf_transfer_done (rtems_blkdev_request* req, rtems_status_code status)
+{
   req->status = status;
 
@@ -1887,5 +1885,4 @@
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
-  int result = 0;
   uint32_t transfer_index = 0;
   bool wake_transfer_waiters = false;
@@ -1895,13 +1892,10 @@
     rtems_bdbuf_unlock_cache ();
 
-  result = dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST, req);
-
-  if (result == 0)
-  {
-    rtems_bdbuf_wait_for_transient_event ();
-    sc = req->status;
-  }
-  else
-    sc = RTEMS_IO_ERROR;
+  /* The return value will be ignored for transfer requests */
+  dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST, req);
+
+  /* Wait for transfer request completion */
+  rtems_bdbuf_wait_for_transient_event ();
+  sc = req->status;
 
   rtems_bdbuf_lock_cache ();
@@ -1978,8 +1972,6 @@
 
   req->req = RTEMS_BLKDEV_REQ_READ;
-  req->req_done = rtems_bdbuf_transfer_done;
-  req->done_arg = req;
+  req->done = rtems_bdbuf_transfer_done;
   req->io_task = rtems_task_self ();
-  req->status = RTEMS_RESOURCE_IN_USE;
   req->bufnum = 0;
 
@@ -2656,6 +2648,5 @@
 
   write_req->req = RTEMS_BLKDEV_REQ_WRITE;
-  write_req->req_done = rtems_bdbuf_transfer_done;
-  write_req->done_arg = write_req;
+  write_req->done = rtems_bdbuf_transfer_done;
   write_req->io_task = rtems_task_self ();
 
Index: cpukit/libblock/src/flashdisk.c
===================================================================
--- cpukit/libblock/src/flashdisk.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ cpukit/libblock/src/flashdisk.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -2087,6 +2087,5 @@
   }
 
-  req->status = ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL;
-  req->req_done (req->done_arg, req->status);
+  rtems_blkdev_request_done (req, ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL);
 
   return 0;
@@ -2123,6 +2122,5 @@
   }
 
-  req->status = ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL;
-  req->req_done (req->done_arg, req->status);
+  rtems_blkdev_request_done (req, ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL);
 
   return 0;
Index: cpukit/libblock/src/nvdisk.c
===================================================================
--- cpukit/libblock/src/nvdisk.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ cpukit/libblock/src/nvdisk.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -598,8 +598,7 @@
   }
 
-  req->status = ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL;
-  req->req_done (req->done_arg, req->status);
-
-  return ret;
+  rtems_blkdev_request_done (req, ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL);
+
+  return 0;
 }
 
@@ -638,6 +637,5 @@
   }
 
-  req->status = ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL;
-  req->req_done (req->done_arg, req->status);
+  rtems_blkdev_request_done (req, ret ? RTEMS_IO_ERROR : RTEMS_SUCCESSFUL);
 
   return 0;
Index: cpukit/libblock/src/ramdisk-driver.c
===================================================================
--- cpukit/libblock/src/ramdisk-driver.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ cpukit/libblock/src/ramdisk-driver.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -68,6 +68,5 @@
         memcpy(sg->buffer, from + (sg->block * rd->block_size), sg->length);
     }
-    req->status = RTEMS_SUCCESSFUL;
-    req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
+    rtems_blkdev_request_done (req, RTEMS_SUCCESSFUL);
     return 0;
 }
@@ -93,6 +92,5 @@
         memcpy(to + (sg->block * rd->block_size), sg->buffer, sg->length);
     }
-    req->status = RTEMS_SUCCESSFUL;
-    req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
+    rtems_blkdev_request_done (req, RTEMS_SUCCESSFUL);
     return 0;
 }
Index: testsuites/libtests/block05/init.c
===================================================================
--- testsuites/libtests/block05/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block05/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -380,5 +380,5 @@
       case RTEMS_BLKDEV_REQ_READ:
       case RTEMS_BLKDEV_REQ_WRITE:
-        r->req_done(r->done_arg, RTEMS_SUCCESSFUL);
+        rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
         return 0;
       default:
Index: testsuites/libtests/block06/init.c
===================================================================
--- testsuites/libtests/block06/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block06/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -489,5 +489,5 @@
           case RTEMS_BLKDEV_REQ_READ:
             if (!bdbuf_disk_ioctl_process (bdd, r))
-              errno = EIO;
+              rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
             else
             {
@@ -512,5 +512,5 @@
               }
 
-              r->req_done (r->done_arg, RTEMS_SUCCESSFUL);
+              rtems_blkdev_request_done (r, RTEMS_SUCCESSFUL);
             }
             bdbuf_disk_ioctl_leave (bdd, r->bufnum);
@@ -519,6 +519,7 @@
           case RTEMS_BLKDEV_REQ_WRITE:
             if (!bdbuf_disk_ioctl_process (bdd, r))
-              errno = EIO;
-            r->req_done (r->done_arg, RTEMS_SUCCESSFUL);
+              rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
+            else
+              rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
             bdbuf_disk_ioctl_leave (bdd, r->bufnum);
             break;
Index: testsuites/libtests/block08/test_disk.c
===================================================================
--- testsuites/libtests/block08/test_disk.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block08/test_disk.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -33,7 +33,8 @@
 test_disk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
 {
-    rtems_status_code rc;
-    bdbuf_test_msg    msg;
-    size_t            msg_size;
+    rtems_status_code     rc;
+    bdbuf_test_msg        msg;
+    size_t                msg_size;
+    rtems_blkdev_request *r;
 
     switch (req)
@@ -41,7 +42,8 @@
         case RTEMS_BLKIO_REQUEST:
         {
-            rtems_blkdev_request   *r = argp;
             rtems_blkdev_sg_buffer *sg;
             unsigned int            i;
+
+            r = argp;
 
             printk("DISK_DRV: %s ",
@@ -72,5 +74,6 @@
     {
         printf("Error while sending a message to Test task: %u\n", rc);
-        return -1;
+        rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
+        return 0;
     }
 
@@ -82,5 +85,6 @@
     {
         printf("Error while reading a message from Test task: %u\n", rc);
-        return rc;
+        rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
+        return 0;
     }
     if (msg.type != BDBUF_TEST_MSG_TYPE_DRIVER_REPLY)
@@ -88,19 +92,18 @@
         printf("Unexpected message comes to test disk driver: %d\n",
                msg.type);
-        return -1;
+        rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
+        return 0;
     }
 
     if (msg.val.driver_reply.ret_val != 0)
     {
-        errno = msg.val.driver_reply.ret_errno;
+        rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
     }
     else
     {
-        rtems_blkdev_request *r = (rtems_blkdev_request *)argp;
-
-        r->req_done(r->done_arg, msg.val.driver_reply.res_status);
+        rtems_blkdev_request_done(r, msg.val.driver_reply.res_status);
     }
 
-    return msg.val.driver_reply.ret_val;
+    return 0;
 }
 
Index: testsuites/libtests/block09/init.c
===================================================================
--- testsuites/libtests/block09/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block09/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -65,45 +65,48 @@
       char *buf = sg->buffer;
 
-      if (sg->length != 1) {
-        return -1;
-      }
-
-      switch (r->req) {
-        case RTEMS_BLKDEV_REQ_READ:
-          switch (sg->block) {
-            case BLOCK_READ_IO_ERROR:
-              sc = RTEMS_IO_ERROR;
-              break;
-            case BLOCK_READ_UNSATISFIED:
-              sc = RTEMS_UNSATISFIED;
-              break;
-            case BLOCK_READ_SUCCESSFUL:
-            case BLOCK_WRITE_IO_ERROR:
-              *buf = disk_data [sg->block];
-              break;
-            default:
-              return -1;
-          }
-          break;
-        case RTEMS_BLKDEV_REQ_WRITE:
-          switch (sg->block) {
-            case BLOCK_READ_IO_ERROR:
-            case BLOCK_READ_UNSATISFIED:
-            case BLOCK_READ_SUCCESSFUL:
-              disk_data [sg->block] = *buf;
-              break;
-            case BLOCK_WRITE_IO_ERROR:
-              sc = RTEMS_IO_ERROR;
-              break;
-            default:
-              return -1;
-          }
-          break;
-        default:
-          return -1;
+      if (sg->length == 1) {
+        switch (r->req) {
+          case RTEMS_BLKDEV_REQ_READ:
+            switch (sg->block) {
+              case BLOCK_READ_IO_ERROR:
+                sc = RTEMS_IO_ERROR;
+                break;
+              case BLOCK_READ_UNSATISFIED:
+                sc = RTEMS_UNSATISFIED;
+                break;
+              case BLOCK_READ_SUCCESSFUL:
+              case BLOCK_WRITE_IO_ERROR:
+                *buf = disk_data [sg->block];
+                break;
+              default:
+                sc = RTEMS_IO_ERROR;
+                break;
+            }
+            break;
+          case RTEMS_BLKDEV_REQ_WRITE:
+            switch (sg->block) {
+              case BLOCK_READ_IO_ERROR:
+              case BLOCK_READ_UNSATISFIED:
+              case BLOCK_READ_SUCCESSFUL:
+                disk_data [sg->block] = *buf;
+                break;
+              case BLOCK_WRITE_IO_ERROR:
+                sc = RTEMS_IO_ERROR;
+                break;
+              default:
+                sc = RTEMS_IO_ERROR;
+                break;
+            }
+            break;
+          default:
+            sc = RTEMS_IO_ERROR;
+            break;
+        }
+      } else {
+        sc = RTEMS_IO_ERROR;
       }
     }
 
-    r->req_done(r->done_arg, sc);
+    rtems_blkdev_request_done(r, sc);
 
     return 0;
Index: testsuites/libtests/block10/init.c
===================================================================
--- testsuites/libtests/block10/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block10/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -106,5 +106,5 @@
     }
 
-    r->req_done(r->done_arg, sc);
+    rtems_blkdev_request_done(r, sc);
 
     return 0;
Index: testsuites/libtests/block12/init.c
===================================================================
--- testsuites/libtests/block12/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block12/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -56,5 +56,5 @@
     }
 
-    breq->req_done(breq->done_arg, RTEMS_SUCCESSFUL);
+    rtems_blkdev_request_done(breq, RTEMS_SUCCESSFUL);
   } else {
     errno = EINVAL;
Index: testsuites/libtests/block13/init.c
===================================================================
--- testsuites/libtests/block13/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block13/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -127,5 +127,5 @@
     }
 
-    (*breq->req_done)(breq->done_arg, RTEMS_SUCCESSFUL);
+    rtems_blkdev_request_done(breq, RTEMS_SUCCESSFUL);
   } else {
     errno = EINVAL;
Index: testsuites/libtests/block14/init.c
===================================================================
--- testsuites/libtests/block14/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block14/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -106,5 +106,5 @@
     }
 
-    (*breq->req_done)(breq->done_arg, sc);
+    rtems_blkdev_request_done(breq, sc);
   } else {
     errno = EINVAL;
Index: testsuites/libtests/block15/init.c
===================================================================
--- testsuites/libtests/block15/init.c	(revision 20e1e769f84089804dc94737c7aff595fc2397de)
+++ testsuites/libtests/block15/init.c	(revision 9f0a68ce5afca9d21d34bab83d42fbe4bb0cf8ef)
@@ -85,5 +85,5 @@
     }
 
-    (*breq->req_done)(breq->done_arg, RTEMS_SUCCESSFUL);
+    rtems_blkdev_request_done(breq, RTEMS_SUCCESSFUL);
   } else if (req == RTEMS_BLKIO_CAPABILITIES) {
     *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
