wait_queue_head_t & wait_queue_t(MTD)

wait_queue_head_t & wait_queue_t使用

 

文件:Linux/drivers/mtd/mtdchar.c +526

 

 case MEMERASE:                //Nand擦除IOCTL
 case MEMERASE64:
 {
  struct erase_info *erase;

  if(!(file->f_mode & FMODE_WRITE))
   return -EPERM;

  erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL);
  if (!erase)
   ret = -ENOMEM;
  else {
   wait_queue_head_t waitq;     //定义等待队列头
   DECLARE_WAITQUEUE(wait, current);       //声明等待队列

   init_waitqueue_head(&waitq);                   //初始化等待队列头

   if (cmd == MEMERASE64) {
    struct erase_info_user64 einfo64;

    if (copy_from_user(&einfo64, argp,
         sizeof(struct erase_info_user64))) {
     kfree(erase);
     return -EFAULT;
    }
    erase->addr = einfo64.start;
    erase->len = einfo64.length;
   } else {
    struct erase_info_user einfo32;

    if (copy_from_user(&einfo32, argp,
         sizeof(struct erase_info_user))) {
     kfree(erase);
     return -EFAULT;
    }
    erase->addr = einfo32.start;
    erase->len = einfo32.length;
   }
   erase->mtd = mtd;
   erase->callback = mtdchar_erase_callback;      //定义擦除唤醒的callback函数
   erase->priv = (unsigned long)&waitq;                //将等待队列的地址作为参数传递

   /*
     FIXME: Allow INTERRUPTIBLE. Which means
     not having the wait_queue head on the stack.

     If the wq_head is on the stack, and we
     leave because we got interrupted, then the
     wq_head is no longer there when the
     callback routine tries to wake us up.
   */
   ret = mtd->erase(mtd, erase);
   if (!ret) {
    set_current_state(TASK_UNINTERRUPTIBLE);
    add_wait_queue(&waitq, &wait);  //将当前进程加入等待队列
    if (erase->state != MTD_ERASE_DONE &&
        erase->state != MTD_ERASE_FAILED)
     schedule();  //判断擦除是否完成,没有的话睡眠,知道callback函数唤醒该进程
    remove_wait_queue(&waitq, &wait);
    set_current_state(TASK_RUNNING);

    ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0;
   }
   kfree(erase);
  }
  break;

-------------------------------------------------------------------------------

static void mtdchar_erase_callback (struct erase_info *instr)
{
 wake_up((wait_queue_head_t *)instr->priv);
}

文件:linux/drivers/mtd/nand/nand_base.c +2495

int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
      int allowbbt)
{

......

 /* Do call back function */
 if (!ret)
  mtd_erase_callback(instr); //唤醒睡眠进程

......

}

nanjing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值