在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ARM的嵌入式Linux移植體驗之設備驅動

            ARM的嵌入式Linux移植體驗之設備驅動

            作者: 時間:2012-11-13 來源:網絡 收藏

            static int write_cached_data (struct mtdblk_dev *mtdblk)
            {
             struct mtd_info *mtd = mtdblk->mtd;
             int ret;

             if (mtdblk->cache_state != STATE_DIRTY)
              return 0;

             DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for /"%s/" "
            "at 0x%lx, size 0x%x/n", mtd->name,
            mtdblk->cache_offset, mtdblk->cache_size);

             ret = erase_write (mtd, mtdblk->cache_offset,
            mtdblk->cache_size, mtdblk->cache_data);
             if (ret)
              return ret;

             mtdblk->cache_state = STATE_EMPTY;
             return 0;
            }

            static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
            int len, const char *buf)
            {
             …
            }

            static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
            int len, char *buf)
            {
             …
            }

            static int mtdblock_open(struct inode *inode, struct file *file)
            {
             …
            }

            static release_t mtdblock_release(struct inode *inode, struct file *file)
            {
             int dev;
             struct mtdblk_dev *mtdblk;
             DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release/n");

             if (inode == NULL)
              release_return(-ENODEV);

             dev = minor(inode->i_rdev);
             mtdblk = mtdblks[dev];

             down(mtdblk->cache_sem);
             write_cached_data(mtdblk);
             up(mtdblk->cache_sem);

             spin_lock(mtdblks_lock);
             if (!--mtdblk->count) {
              /* It was the last usage. Free the device */
              mtdblks[dev] = NULL;
              spin_unlock(mtdblks_lock);
              if (mtdblk->mtd->sync)
               mtdblk->mtd->sync(mtdblk->mtd);
               put_mtd_device(mtdblk->mtd);
               vfree(mtdblk->cache_data);
               kfree(mtdblk);
             } else {
              spin_unlock(mtdblks_lock);
             }

             DEBUG(MTD_DEBUG_LEVEL1, "ok/n");
             
             BLK_DEC_USE_COUNT;
             release_return(0);
            }

            /*
            * This is a special request_fn because it is executed in a process context
            * to be able to sleep independently of the caller. The
            * io_request_lock (for 2.5) or queue_lock (for >=2.5) is held upon entry
            * and exit. The head of our request queue is considered active so there is
            * no need to dequeue requests before we are done.
            */
            static void handle_mtdblock_request(void)
            {
             struct request *req;
             struct mtdblk_dev *mtdblk;
             unsigned int res;

             for (;;) {
              INIT_REQUEST;
              req = CURRENT;
              spin_unlock_irq(QUEUE_LOCK(QUEUE));
              mtdblk = mtdblks[minor(req->rq_dev)];
              res = 0;

              if (minor(req->rq_dev) >= MAX_MTD_DEVICES)
               panic("%s : minor out of bound", __FUNCTION__);

              if (!IS_REQ_CMD(req))
               goto end_req;

              if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9))
               goto end_req;

              // Handle the request
              switch (rq_data_dir(req))
              {
               int err;

               case READ:
                down(mtdblk->cache_sem);
                err = do_cached_read (mtdblk, req->sector 9,
            req->current_nr_sectors 9,
            req->buffer);
                up(mtdblk->cache_sem);
                if (!err)
                 res = 1;
                break;

               case WRITE:
                // Read only device
                if ( !(mtdblk->mtd->flags MTD_WRITEABLE) )
                 break;

                // Do the write
                down(mtdblk->cache_sem);
                err = do_cached_write (mtdblk, req->sector 9,req->current_nr_sectors 9, req->buffer);
                up(mtdblk->cache_sem);
                if (!err)
                 res = 1;
                break;
              }

             end_req:
             spin_lock_irq(QUEUE_LOCK(QUEUE));
             end_request(res);
            }
            }

            static volatile int leaving = 0;
            static DECLARE_MUTEX_LOCKED(thread_sem);
            static DECLARE_WAIT_QUEUE_HEAD(thr_wq);

            int mtdblock_thread(void *dummy)
            {
             …
            }

            #define RQFUNC_ARG request_queue_t *q

            static void mtdblock_request(RQFUNC_ARG)
            {
             /* Don't do anything, except wake the thread if necESSary */
             wake_up(thr_wq);
            }

            static int mtdblock_ioctl(struct inode * inode, struct file * file,
            unsigned int CMd, unsigned long arg)
            {
             struct mtdblk_dev *mtdblk;
             mtdblk = mtdblks[minor(inode->i_rdev)];
             switch (cMD) {
              case BLKGETSIZE: /* Return device size */
               return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);

              case BLKFLSBUF:
               if(!capable(CAP_SYS_ADMIN))
                return -EACCES;
               fsync_dev(inode->i_rdev);
               invalidate_buffers(inode->i_rdev);
               down(mtdblk->cache_sem);
               write_cached_data(mtdblk);
               up(mtdblk->cache_sem);
               if (mtdblk->mtd->sync)
                mtdblk->mtd->sync(mtdblk->mtd);
                return 0;
              default:
               return -EINVAL;
             }
            }

            linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

            linux相關文章:linux教程




            關鍵詞: ARM 嵌入式 Linux移植

            評論


            相關推薦

            技術專區(qū)

            關閉