wait_queue_head_t & wait_queue_t(MTD)

本文介绍了Linux中NAND闪存的擦除操作流程。通过ioctl命令触发擦除过程,并利用wait_queue_head_t与wait_queue_t实现进程等待与唤醒机制。详细展示了从用户请求到设备擦除完成的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值