示例#1
0
文件: init.c 项目: lanzhongheng/rtems
static bool
bdbuf_disk_ioctl_process (bdbuf_disk* bdd, rtems_blkdev_request* req)
{
  bool result = true;
  int  b;

  /*
   * Perform the requested action.
   */
  switch (bdd->driver_action)
  {
    case BDBUF_DISK_NOOP:
      break;

    case BDBUF_DISK_WAIT:
      if (bdd->waiting)
        bdbuf_test_printf ("disk ioctl: bad waiter: %s:%08x\n",
                           bdd->waiting_name, bdd->waiting);
      bdd->waiting_name = "bdd";

      bdd->waiting = rtems_task_self ();

      if (bdbuf_disk_unlock (bdd))
        result = bdbuf_wait (bdd->name, 0) == RTEMS_SUCCESSFUL;
      else
        result = false;

      /*
       * Ignore any error if one happens.
       */
      bdbuf_disk_lock (bdd);
      break;

    case BDBUF_DISK_SLEEP:
      bdbuf_test_printf ("disk ioctl: sleeping: %d msecs\n",
                         bdd->driver_sleep);
      result = bdbuf_sleep (bdd->driver_sleep);
      break;

    case BDBUF_DISK_BLOCKS_INORDER:
      bdbuf_test_printf ("disk ioctl: multi-block order check: count = %d\n",
                         req->bufnum);
      for (b = 0; b < (req->bufnum - 1); b++)
        if (req->bufs[b].block >= req->bufs[b + 1].block)
          bdbuf_test_printf ("disk ioctl: out of order: index:%d (%d >= %d\n",
                             b, req->bufs[b].block, req->bufs[b + 1].block);
      break;

    default:
      bdbuf_test_printf ("disk ioctl: invalid action: %d\n",
                         bdd->driver_action);
      result = false;
      break;
  }

  return result;
}
示例#2
0
文件: init.c 项目: lanzhongheng/rtems
/**
 * Set the disk driver action.
 */
static void
bdbuf_set_disk_driver_action (bdbuf_task_control* tc, bdbuf_disk_action action)
{
  /*
   * Set up a disk action.
   */
  bdbuf_disk_lock (&bdbuf_disks[tc->minor]);
  bdbuf_disks[tc->minor].driver_action = action;
  bdbuf_disk_unlock (&bdbuf_disks[tc->minor]);
}
/**
 * Read the block 5 from the disk modify it then release it modified.
 */
static void
bdbuf_tests_task_0_test_3 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  rtems_bdbuf_buffer* bd;
  dev_t               device;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  device = rtems_filesystem_make_dev_t (tc->major, tc->minor);

  bdbuf_disk_lock (&bdbuf_disks[tc->minor]);
  bdbuf_disks[tc->minor].driver_action = BDBUF_DISK_NOOP;
  bdbuf_disk_unlock (&bdbuf_disks[tc->minor]);

  /*
   * Read the buffer and then release it.
   */
  bdbuf_test_printf ("%s: rtems_bdbuf_read[5]: ", tc->name);
  sc = rtems_bdbuf_read (device, 5, &bd);
  if ((passed = bdbuf_test_print_sc (sc, true)))
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[5]: ", tc->name);
    sc = rtems_bdbuf_release_modified (bd);
    passed = bdbuf_test_print_sc (sc, true);
  }

  /*
   * Read the buffer again and then just release. The buffer should
   * be maintained as modified.
   */
  bdbuf_test_printf ("%s: rtems_bdbuf_read[5]: ", tc->name);
  sc = rtems_bdbuf_read (device, 5, &bd);
  if ((passed = bdbuf_test_print_sc (sc, true)))
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release[5]: ", tc->name);
    sc = rtems_bdbuf_release (bd);
    passed = bdbuf_test_print_sc (sc, true);
  }

  /*
   * Set up a disk watch and wait for the write to happen.
   */
  bdbuf_set_disk_driver_watch (tc, 1);
  passed = bdbuf_disk_driver_watch_wait (tc, BDBUF_SECONDS (5));

  tc->passed = passed;
  tc->test = 0;
}
示例#4
0
文件: init.c 项目: lanzhongheng/rtems
/**
 * Clear the disk driver watch.
 */
static void
bdbuf_clear_disk_driver_watch (bdbuf_task_control* tc)
{
  /*
   * Set up a disk watch and wait for the write to happen.
   */
  bdbuf_disk_lock (&bdbuf_disks[tc->minor]);
  bdbuf_disks[tc->minor].watcher_name = 0;
  bdbuf_disks[tc->minor].watcher = 0;
  bdbuf_disks[tc->minor].watch_count = 0;
  bdbuf_disk_unlock (&bdbuf_disks[tc->minor]);
}
示例#5
0
文件: init.c 项目: lanzhongheng/rtems
/**
 * Set up a disk driver watch.
 */
static void
bdbuf_set_disk_driver_watch (bdbuf_task_control* tc, int count)
{
  /*
   * Set up a disk watch and wait for the write to happen.
   */
  bdbuf_disk_lock (&bdbuf_disks[tc->minor]);
  bdbuf_disks[tc->minor].watcher_name = tc->name;
  bdbuf_disks[tc->minor].watcher = tc->task;
  bdbuf_disks[tc->minor].watch_count = count;
  bdbuf_disk_unlock (&bdbuf_disks[tc->minor]);
}
示例#6
0
文件: init.c 项目: lanzhongheng/rtems
/**
 * BDBuf disk IOCTL handler.
 *
 * @param dd Disk device.
 * @param req IOCTL request code.
 * @param argp IOCTL argument.
 * @retval The IOCTL return value
 */
static int
bdbuf_disk_ioctl (rtems_disk_device *dd, uint32_t req, void* argp)
{
  rtems_blkdev_request *r = argp;
  bdbuf_disk           *bdd = rtems_disk_get_driver_data (dd);

  errno = 0;

  if (!bdbuf_disk_lock (bdd))
  {
    errno = EIO;
  }
  else
  {
    switch (req)
    {
      case RTEMS_BLKIO_REQUEST:
        switch (r->req)
        {
          case RTEMS_BLKDEV_REQ_READ:
            if (!bdbuf_disk_ioctl_process (bdd, r))
              rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
            else
            {
              rtems_blkdev_sg_buffer* sg = r->bufs;
              uint32_t                block = RTEMS_BLKDEV_START_BLOCK (r);
              uint32_t                b;
              int32_t                 remains;

              remains = r->bufnum * bdd->block_size;

              for (b = 0; b < r->bufnum; b++, block++, sg++)
              {
                uint32_t length = sg->length;

                if (sg->length != bdd->block_size)
                  if (length > bdd->block_size)
                    length = bdd->block_size;

                memset (sg->buffer, block, length);

                remains -= length;
              }

              rtems_blkdev_request_done (r, RTEMS_SUCCESSFUL);
            }
            bdbuf_disk_ioctl_leave (bdd, r->bufnum);
            break;

          case RTEMS_BLKDEV_REQ_WRITE:
            if (!bdbuf_disk_ioctl_process (bdd, r))
              rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
            else
              rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
            bdbuf_disk_ioctl_leave (bdd, r->bufnum);
            break;

          default:
            errno = EINVAL;
            break;
        }
        break;

      default:
        errno = EINVAL;
        break;
    }

    if (!bdbuf_disk_unlock (bdd))
      errno = EIO;
  }

  return errno == 0 ? 0 : -1;
}