blkmtd.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:36k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  * $Id: blkmtd.c,v 1.7 2001/11/10 17:06:30 spse Exp $
  3.  *
  4.  * blkmtd.c - use a block device as a fake MTD
  5.  *
  6.  * Author: Simon Evans <spse@secret.org.uk>
  7.  *
  8.  * Copyright (C) 2001 Simon Evans
  9.  * 
  10.  * Licence: GPL
  11.  *
  12.  * How it works:
  13.  *       The driver uses raw/io to read/write the device and the page
  14.  *       cache to cache access. Writes update the page cache with the
  15.  *       new data but make a copy of the new page(s) and then a kernel
  16.  *       thread writes pages out to the device in the background. This
  17.  *       ensures that writes are order even if a page is updated twice.
  18.  *       Also, since pages in the page cache are never marked as dirty,
  19.  *       we dont have to worry about writepage() being called on some 
  20.  *       random page which may not be in the write order.
  21.  * 
  22.  *       Erases are handled like writes, so the callback is called after
  23.  *       the page cache has been updated. Sync()ing will wait until it is 
  24.  *       all done.
  25.  *
  26.  *       It can be loaded Read-Only to prevent erases and writes to the 
  27.  *       medium.
  28.  *
  29.  * Todo:
  30.  *       Make the write queue size dynamic so this it is not too big on
  31.  *       small memory systems and too small on large memory systems.
  32.  * 
  33.  *       Page cache usage may still be a bit wrong. Check we are doing
  34.  *       everything properly.
  35.  * 
  36.  *       Somehow allow writes to dirty the page cache so we dont use too
  37.  *       much memory making copies of outgoing pages. Need to handle case
  38.  *       where page x is written to, then page y, then page x again before
  39.  *       any of them have been committed to disk.
  40.  * 
  41.  *       Reading should read multiple pages at once rather than using 
  42.  *       readpage() for each one. This is easy and will be fixed asap.
  43.  */
  44. #include <linux/config.h>
  45. #include <linux/module.h>
  46. #include <linux/fs.h>
  47. #include <linux/pagemap.h>
  48. #include <linux/iobuf.h>
  49. #include <linux/slab.h>
  50. #include <linux/pagemap.h>
  51. #include <linux/mtd/compatmac.h>
  52. #include <linux/mtd/mtd.h>
  53. #ifdef CONFIG_MTD_DEBUG
  54. #ifdef CONFIG_PROC_FS
  55. #  include <linux/proc_fs.h>
  56. #  define BLKMTD_PROC_DEBUG
  57.    static struct proc_dir_entry *blkmtd_proc;
  58. #endif
  59. #endif
  60. /* Default erase size in K, always make it a multiple of PAGE_SIZE */
  61. #define CONFIG_MTD_BLKDEV_ERASESIZE 128
  62. #define VERSION "1.7"
  63. extern int *blk_size[];
  64. extern int *blksize_size[];
  65. /* Info for the block device */
  66. typedef struct mtd_raw_dev_data_s {
  67.   struct block_device *binding;
  68.   int sector_size, sector_bits;
  69.   int partial_last_page;   // 0 if device ends on page boundary, else page no of last page
  70.   int last_page_sectors;   // Number of sectors in last page if partial_last_page != 0
  71.   size_t totalsize;
  72.   int readonly;
  73.   struct address_space as;
  74.   struct mtd_info mtd_info;
  75. } mtd_raw_dev_data_t;
  76. /* Info for each queue item in the write queue */
  77. typedef struct mtdblkdev_write_queue_s {
  78.   mtd_raw_dev_data_t *rawdevice;
  79.   struct page **pages;
  80.   int pagenr;
  81.   int pagecnt;
  82.   int iserase;
  83. } mtdblkdev_write_queue_t;
  84. /* Our erase page - always remains locked. */
  85. static struct page *erase_page;
  86. /* Static info about the MTD, used in cleanup_module */
  87. static mtd_raw_dev_data_t *mtd_rawdevice;
  88. /* Write queue fixed size */
  89. #define WRITE_QUEUE_SZ 512
  90. /* Storage for the write queue */
  91. static mtdblkdev_write_queue_t *write_queue;
  92. static int write_queue_sz = WRITE_QUEUE_SZ;
  93. static int volatile write_queue_head;
  94. static int volatile write_queue_tail;
  95. static int volatile write_queue_cnt;
  96. static spinlock_t mbd_writeq_lock = SPIN_LOCK_UNLOCKED;
  97. /* Tell the write thread to finish */
  98. static volatile int write_task_finish;
  99. /* ipc with the write thread */
  100. #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
  101. static DECLARE_MUTEX_LOCKED(thread_sem);
  102. static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
  103. static DECLARE_WAIT_QUEUE_HEAD(mtbd_sync_wq);
  104. #else
  105. static struct semaphore thread_sem = MUTEX_LOCKED;
  106. DECLARE_WAIT_QUEUE_HEAD(thr_wq);
  107. DECLARE_WAIT_QUEUE_HEAD(mtbd_sync_wq);
  108. #endif
  109. /* Module parameters passed by insmod/modprobe */
  110. char *device;    /* the block device to use */
  111. int erasesz;     /* optional default erase size */
  112. int ro;          /* optional read only flag */
  113. int bs;          /* optionally force the block size (avoid using) */
  114. int count;       /* optionally force the block count (avoid using) */
  115. int wqs;         /* optionally set the write queue size */
  116. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
  117. MODULE_LICENSE("GPL");
  118. MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
  119. MODULE_DESCRIPTION("Emulate an MTD using a block device");
  120. MODULE_PARM(device, "s");
  121. MODULE_PARM_DESC(device, "block device to use");
  122. MODULE_PARM(erasesz, "i");
  123. MODULE_PARM_DESC(erasesz, "optional erase size to use in KB. eg 4=4K.");
  124. MODULE_PARM(ro, "i");
  125. MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors");
  126. MODULE_PARM(bs, "i");
  127. MODULE_PARM_DESC(bs, "force the block size in bytes");
  128. MODULE_PARM(count, "i");
  129. MODULE_PARM_DESC(count, "force the block count");
  130. MODULE_PARM(wqs, "i");
  131. #endif
  132. /* Page cache stuff */
  133. /* writepage() - should never be called - catch it anyway */
  134. static int blkmtd_writepage(struct page *page)
  135. {
  136.   printk("blkmtd: writepage called!!!n");
  137.   return -EIO;
  138. }
  139. /* readpage() - reads one page from the block device */                 
  140. static int blkmtd_readpage(mtd_raw_dev_data_t *rawdevice, struct page *page)
  141. {  
  142.   int err;
  143.   int sectornr, sectors, i;
  144.   struct kiobuf *iobuf;
  145.   kdev_t dev;
  146.   unsigned long *blocks;
  147.   if(!rawdevice) {
  148.     printk("blkmtd: readpage: PANIC file->private_data == NULLn");
  149.     return -EIO;
  150.   }
  151.   dev = to_kdev_t(rawdevice->binding->bd_dev);
  152.   DEBUG(2, "blkmtd: readpage called, dev = `%s' page = %p index = %ldn",
  153. bdevname(dev), page, page->index);
  154.   if(Page_Uptodate(page)) {
  155.     DEBUG(2, "blkmtd: readpage page %ld is already upto daten", page->index);
  156.     UnlockPage(page);
  157.     return 0;
  158.   }
  159.   ClearPageUptodate(page);
  160.   ClearPageError(page);
  161.   /* see if page is in the outgoing write queue */
  162.   spin_lock(&mbd_writeq_lock);
  163.   if(write_queue_cnt) {
  164.     int i = write_queue_tail;
  165.     while(i != write_queue_head) {
  166.       mtdblkdev_write_queue_t *item = &write_queue[i];
  167.       if(page->index >= item->pagenr && page->index < item->pagenr+item->pagecnt) {
  168. /* yes it is */
  169. int index = page->index - item->pagenr;
  170. DEBUG(2, "blkmtd: readpage: found page %ld in outgoing write queuen",
  171.       page->index);
  172. if(item->iserase) {
  173.   memset(page_address(page), 0xff, PAGE_SIZE);
  174. } else {
  175.   memcpy(page_address(page), page_address(item->pages[index]), PAGE_SIZE);
  176. }
  177. SetPageUptodate(page);
  178. flush_dcache_page(page);
  179. UnlockPage(page);
  180. spin_unlock(&mbd_writeq_lock);
  181. return 0;
  182.       }
  183.       i++;
  184.       i %= write_queue_sz;
  185.     }
  186.   }
  187.   spin_unlock(&mbd_writeq_lock);
  188.   DEBUG(3, "blkmtd: readpage: getting kiovecn");
  189.   err = alloc_kiovec(1, &iobuf);
  190.   if (err) {
  191.     printk("blkmtd: cant allocate kiobufn");
  192.     SetPageError(page);
  193.     return err;
  194.   }
  195.   /* Pre 2.4.4 doesn't have space for the block list in the kiobuf */ 
  196. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
  197.   blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long));
  198.   if(blocks == NULL) {
  199.     printk("blkmtd: cant allocate iobuf blocksn");
  200.     free_kiovec(1, &iobuf);
  201.     SetPageError(page);
  202.     return -ENOMEM;
  203.   }
  204. #else 
  205.   blocks = iobuf->blocks;
  206. #endif
  207.   iobuf->offset = 0;
  208.   iobuf->nr_pages = 1;
  209.   iobuf->length = PAGE_SIZE;
  210.   iobuf->locked = 1;
  211.   iobuf->maplist[0] = page;
  212.   sectornr = page->index << (PAGE_SHIFT - rawdevice->sector_bits);
  213.   sectors = 1 << (PAGE_SHIFT - rawdevice->sector_bits);
  214.   if(rawdevice->partial_last_page && page->index == rawdevice->partial_last_page) {
  215.     DEBUG(3, "blkmtd: handling partial last pagen");
  216.     sectors = rawdevice->last_page_sectors;
  217.   }
  218.   DEBUG(3, "blkmtd: readpage: sectornr = %d sectors = %dn", sectornr, sectors);
  219.   for(i = 0; i < sectors; i++) {
  220.     blocks[i] = sectornr++;
  221.   }
  222.   /* If only a partial page read in, clear the rest of the page */
  223.   if(rawdevice->partial_last_page && page->index == rawdevice->partial_last_page) {
  224.     int offset = rawdevice->last_page_sectors << rawdevice->sector_bits;
  225.     int count = PAGE_SIZE-offset;
  226.     DEBUG(3, "blkmtd: clear last partial page: offset = %d count = %dn", offset, count);
  227.     memset(page_address(page)+offset, 0, count);
  228.     sectors = rawdevice->last_page_sectors;
  229.   }
  230.   DEBUG(3, "bklmtd: readpage: starting brw_kiovecn");
  231.   err = brw_kiovec(READ, 1, &iobuf, dev, blocks, rawdevice->sector_size);
  232.   DEBUG(3, "blkmtd: readpage: finished, err = %dn", err);
  233.   iobuf->locked = 0;
  234.   free_kiovec(1, &iobuf);
  235. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
  236.   kfree(blocks);
  237. #endif
  238.   if(err != PAGE_SIZE) {
  239.     printk("blkmtd: readpage: error reading page %ldn", page->index);
  240.     memset(page_address(page), 0, PAGE_SIZE);
  241.     SetPageError(page);
  242.     err = -EIO;
  243.   } else {
  244.     DEBUG(3, "blkmtd: readpage: setting page upto daten");
  245.     SetPageUptodate(page);
  246.     err = 0;
  247.   }
  248.   flush_dcache_page(page);
  249.   UnlockPage(page);
  250.   DEBUG(2, "blkmtd: readpage: finished, err = %dn", err);
  251.   return 0;
  252. }
  253.                     
  254. static struct address_space_operations blkmtd_aops = {
  255.   writepage:     blkmtd_writepage,
  256.   readpage:      NULL,
  257. }; 
  258. /* This is the kernel thread that empties the write queue to disk */
  259. static int write_queue_task(void *data)
  260. {
  261.   int err;
  262.   struct task_struct *tsk = current;
  263.   struct kiobuf *iobuf;
  264.   unsigned long *blocks;
  265.   DECLARE_WAITQUEUE(wait, tsk);
  266.   DEBUG(1, "blkmtd: writetask: starting (pid = %d)n", tsk->pid);
  267.   daemonize();
  268.   strcpy(tsk->comm, "blkmtdd");
  269.   tsk->tty = NULL;
  270.   spin_lock_irq(&tsk->sigmask_lock);
  271.   sigfillset(&tsk->blocked);
  272.   recalc_sigpending(tsk);
  273.   spin_unlock_irq(&tsk->sigmask_lock);
  274.   exit_sighand(tsk);
  275.   if(alloc_kiovec(1, &iobuf)) {
  276.     printk("blkmtd: write_queue_task cant allocate kiobufn");
  277.     return 0;
  278.   }
  279.   /* Pre 2.4.4 doesn't have space for the block list in the kiobuf */ 
  280. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
  281.   blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long));
  282.   if(blocks == NULL) {
  283.     printk("blkmtd: write_queue_task cant allocate iobuf blocksn");
  284.     free_kiovec(1, &iobuf);
  285.     return 0;
  286.   }
  287. #else 
  288.   blocks = iobuf->blocks;
  289. #endif
  290.   DEBUG(2, "blkmtd: writetask: entering main loopn");
  291.   add_wait_queue(&thr_wq, &wait);
  292.   while(1) {
  293.     spin_lock(&mbd_writeq_lock);
  294.     if(!write_queue_cnt) {
  295.       /* If nothing in the queue, wake up anyone wanting to know when there
  296.  is space in the queue then sleep for 2*HZ */
  297.       spin_unlock(&mbd_writeq_lock);
  298.       DEBUG(4, "blkmtd: writetask: queue emptyn");
  299.       if(waitqueue_active(&mtbd_sync_wq))
  300.  wake_up(&mtbd_sync_wq);
  301.       interruptible_sleep_on_timeout(&thr_wq, 2*HZ);
  302.       DEBUG(4, "blkmtd: writetask: woken upn");
  303.       if(write_task_finish)
  304. break;
  305.     } else {
  306.       /* we have stuff to write */
  307.       mtdblkdev_write_queue_t *item = &write_queue[write_queue_tail];
  308.       struct page **pages = item->pages;
  309.       int i;
  310.       int sectornr = item->pagenr << (PAGE_SHIFT - item->rawdevice->sector_bits);
  311.       int sectorcnt = item->pagecnt << (PAGE_SHIFT - item->rawdevice->sector_bits);
  312.       int max_sectors = KIO_MAX_SECTORS >> (item->rawdevice->sector_bits - 9);
  313.       kdev_t dev = to_kdev_t(item->rawdevice->binding->bd_dev);
  314.       /* If we are writing to the last page on the device and it doesn't end
  315.        * on a page boundary, subtract the number of sectors that dont exist.
  316.        */
  317.       if(item->rawdevice->partial_last_page && 
  318.  (item->pagenr + item->pagecnt -1) == item->rawdevice->partial_last_page) {
  319. sectorcnt -= (1 << (PAGE_SHIFT - item->rawdevice->sector_bits));
  320. sectorcnt += item->rawdevice->last_page_sectors;
  321.       }
  322.       DEBUG(3, "blkmtd: writetask: got %d queue itemsn", write_queue_cnt);
  323.       set_current_state(TASK_RUNNING);
  324.       spin_unlock(&mbd_writeq_lock);
  325.       DEBUG(2, "blkmtd: writetask: writing pagenr = %d pagecnt = %d sectornr = %d sectorcnt = %dn", 
  326.     item->pagenr, item->pagecnt, sectornr, sectorcnt);
  327.       iobuf->offset = 0;
  328.       iobuf->locked = 1;
  329.       /* Loop through all the pages to be written in the queue item, remembering
  330.  we can only write KIO_MAX_SECTORS at a time */
  331.  
  332.       while(sectorcnt) {
  333. int cursectors = (sectorcnt < max_sectors) ? sectorcnt : max_sectors;
  334. int cpagecnt = (cursectors << item->rawdevice->sector_bits) + PAGE_SIZE-1;
  335. cpagecnt >>= PAGE_SHIFT;
  336. for(i = 0; i < cpagecnt; i++) {
  337.   if(item->iserase) {
  338.     iobuf->maplist[i] = erase_page;
  339.   } else {
  340.     iobuf->maplist[i] = *(pages++);
  341.   }
  342. }
  343. for(i = 0; i < cursectors; i++) {
  344.   blocks[i] = sectornr++;
  345. }
  346. iobuf->nr_pages = cpagecnt;
  347. iobuf->length = cursectors << item->rawdevice->sector_bits;
  348. DEBUG(3, "blkmtd: write_task: about to kiovecn");
  349. err = brw_kiovec(WRITE, 1, &iobuf, dev, blocks, item->rawdevice->sector_size);
  350. DEBUG(3, "bklmtd: write_task: done, err = %dn", err);
  351. if(err != (cursectors << item->rawdevice->sector_bits)) {
  352.   /* if an error occured - set this to exit the loop */
  353.   sectorcnt = 0;
  354. } else {
  355.   sectorcnt -= cursectors;
  356. }
  357.       }
  358.       /* free up the pages used in the write and list of pages used in the write
  359.  queue item */
  360.       iobuf->locked = 0;
  361.       spin_lock(&mbd_writeq_lock);
  362.       write_queue_cnt--;
  363.       write_queue_tail++;
  364.       write_queue_tail %= write_queue_sz;
  365.       if(!item->iserase) {
  366. for(i = 0 ; i < item->pagecnt; i++) {
  367.   UnlockPage(item->pages[i]);
  368.   __free_pages(item->pages[i], 0);
  369. }
  370. kfree(item->pages);
  371.       }
  372.       item->pages = NULL;
  373.       spin_unlock(&mbd_writeq_lock);
  374.       /* Tell others there is some space in the write queue */
  375.       if(waitqueue_active(&mtbd_sync_wq))
  376. wake_up(&mtbd_sync_wq);
  377.     }
  378.   }
  379.   remove_wait_queue(&thr_wq, &wait);
  380.   DEBUG(1, "blkmtd: writetask: exitingn");
  381.   free_kiovec(1, &iobuf);
  382. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
  383.   kfree(blocks);
  384. #endif
  385.   /* Tell people we have exitd */
  386.   up(&thread_sem);
  387.   return 0;
  388. }
  389. /* Add a range of pages into the outgoing write queue, making copies of them */
  390. static int queue_page_write(mtd_raw_dev_data_t *rawdevice, struct page **pages,
  391.     int pagenr, int pagecnt, int iserase)
  392. {
  393.   struct page *outpage;
  394.   struct page **new_pages = NULL;
  395.   mtdblkdev_write_queue_t *item;
  396.   int i;
  397.   DECLARE_WAITQUEUE(wait, current);
  398.   DEBUG(2, "blkmtd: queue_page_write: adding pagenr = %d pagecnt = %dn", pagenr, pagecnt);
  399.   if(!pagecnt)
  400.     return 0;
  401.   if(pages == NULL && !iserase)
  402.     return -EINVAL;
  403.   /* create a array for the list of pages */
  404.   if(!iserase) {
  405.     new_pages = kmalloc(pagecnt * sizeof(struct page *), GFP_KERNEL);
  406.     if(new_pages == NULL)
  407.       return -ENOMEM;
  408.     /* make copies of the pages in the page cache */
  409.     for(i = 0; i < pagecnt; i++) {
  410.       outpage = alloc_pages(GFP_KERNEL, 0);
  411.       if(!outpage) {
  412. while(i--) {
  413.   UnlockPage(new_pages[i]);
  414.   __free_pages(new_pages[i], 0);
  415. }
  416. kfree(new_pages);
  417. return -ENOMEM;
  418.       }
  419.       lock_page(outpage);
  420.       memcpy(page_address(outpage), page_address(pages[i]), PAGE_SIZE);
  421.       new_pages[i] = outpage;
  422.     }
  423.   }
  424.   /* wait until there is some space in the write queue */
  425.  test_lock:
  426.   spin_lock(&mbd_writeq_lock);
  427.   if(write_queue_cnt == write_queue_sz) {
  428.     spin_unlock(&mbd_writeq_lock);
  429.     DEBUG(3, "blkmtd: queue_page: Queue fulln");
  430.     current->state = TASK_UNINTERRUPTIBLE;
  431.     add_wait_queue(&mtbd_sync_wq, &wait);
  432.     wake_up_interruptible(&thr_wq);
  433.     schedule();
  434.     current->state = TASK_RUNNING;
  435.     remove_wait_queue(&mtbd_sync_wq, &wait);
  436.     DEBUG(3, "blkmtd: queue_page_write: Queue has %d items in itn", write_queue_cnt);
  437.     goto test_lock;
  438.   }
  439.   DEBUG(3, "blkmtd: queue_page_write: qhead: %d qtail: %d qcnt: %dn", 
  440. write_queue_head, write_queue_tail, write_queue_cnt);
  441.   /* fix up the queue item */
  442.   item = &write_queue[write_queue_head];
  443.   item->pages = new_pages;
  444.   item->pagenr = pagenr;
  445.   item->pagecnt = pagecnt;
  446.   item->rawdevice = rawdevice;
  447.   item->iserase = iserase;
  448.   write_queue_head++;
  449.   write_queue_head %= write_queue_sz;
  450.   write_queue_cnt++;
  451.   DEBUG(3, "blkmtd: queue_page_write: qhead: %d qtail: %d qcnt: %dn", 
  452. write_queue_head, write_queue_tail, write_queue_cnt);
  453.   spin_unlock(&mbd_writeq_lock);
  454.   DEBUG(2, "blkmtd: queue_page_write: finishedn");
  455.   return 0;
  456. }
  457. /* erase a specified part of the device */
  458. static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr)
  459. {
  460.   mtd_raw_dev_data_t *rawdevice = mtd->priv;
  461.   struct mtd_erase_region_info *einfo = mtd->eraseregions;
  462.   int numregions = mtd->numeraseregions;
  463.   size_t from;
  464.   u_long len;
  465.   int err = 0;
  466.   /* check readonly */
  467.   if(rawdevice->readonly) {
  468.     printk("blkmtd: error: trying to erase readonly device %sn", device);
  469.     instr->state = MTD_ERASE_FAILED;
  470.     goto erase_callback;
  471.   }
  472.   instr->state = MTD_ERASING;
  473.   from = instr->addr;
  474.   len = instr->len;
  475.   /* check erase region has valid start and length */
  476.   DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%x len = 0x%lxn",
  477. bdevname(rawdevice->binding->bd_dev), from, len);
  478.   while(numregions) {
  479.     DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%xn",
  480.   einfo->offset, einfo->erasesize, einfo->numblocks);
  481.     if(from >= einfo->offset && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) {
  482.       if(len == einfo->erasesize && ( (from - einfo->offset) % einfo->erasesize == 0))
  483. break;
  484.     }
  485.     numregions--;
  486.     einfo++;
  487.   }
  488.   if(!numregions) {
  489.     /* Not a valid erase block */
  490.     printk("blkmtd: erase: invalid erase request 0x%lX @ 0x%08Xn", len, from);
  491.     instr->state = MTD_ERASE_FAILED;
  492.     err = -EIO;
  493.   }
  494.   
  495.   if(instr->state != MTD_ERASE_FAILED) {
  496.     /* start the erase */
  497.     int pagenr, pagecnt;
  498.     struct page *page, **pages;
  499.     int i = 0;
  500.     /* Handle the last page of the device not being whole */
  501.     if(len < PAGE_SIZE)
  502.       len = PAGE_SIZE;
  503.     pagenr = from >> PAGE_SHIFT;
  504.     pagecnt = len >> PAGE_SHIFT;
  505.     DEBUG(3, "blkmtd: erase: pagenr = %d pagecnt = %dn", pagenr, pagecnt);
  506.     pages = kmalloc(pagecnt * sizeof(struct page *), GFP_KERNEL);
  507.     if(pages == NULL) {
  508.       err = -ENOMEM;
  509.       instr->state = MTD_ERASE_FAILED;
  510.       goto erase_out;
  511.     }
  512.     while(pagecnt) {
  513.       /* get the page via the page cache */
  514.       DEBUG(3, "blkmtd: erase: doing grab_cache_page() for page %dn", pagenr);
  515.       page = grab_cache_page(&rawdevice->as, pagenr);
  516.       if(!page) {
  517. DEBUG(3, "blkmtd: erase: grab_cache_page() failed for page %dn", pagenr);
  518. kfree(pages);
  519. err = -EIO;
  520. instr->state = MTD_ERASE_FAILED;
  521. goto erase_out;
  522.       }
  523.       memset(page_address(page), 0xff, PAGE_SIZE);
  524.       pages[i] = page;
  525.       pagecnt--;
  526.       pagenr++;
  527.       i++;
  528.     }
  529.     DEBUG(3, "blkmtd: erase: queuing page writen");
  530.     err = queue_page_write(rawdevice, NULL, from >> PAGE_SHIFT, len >> PAGE_SHIFT, 1);
  531.     pagecnt = len >> PAGE_SHIFT;
  532.     if(!err) {
  533.       while(pagecnt--) {
  534. SetPageUptodate(pages[pagecnt]);
  535. UnlockPage(pages[pagecnt]);
  536. page_cache_release(pages[pagecnt]);
  537. flush_dcache_page(pages[pagecnt]);
  538.       }
  539.       kfree(pages);
  540.       instr->state = MTD_ERASE_DONE;
  541.     } else {
  542.       while(pagecnt--) {
  543. SetPageError(pages[pagecnt]);
  544. page_cache_release(pages[pagecnt]);
  545.       }
  546.       kfree(pages);
  547.       instr->state = MTD_ERASE_FAILED;
  548.     }
  549.   }
  550.  erase_out:
  551.   DEBUG(3, "blkmtd: erase: checking callbackn");
  552.  erase_callback:
  553.   if (instr->callback) {
  554.     (*(instr->callback))(instr);
  555.   }
  556.   DEBUG(2, "blkmtd: erase: finished (err = %d)n", err);
  557.   return err;
  558. }
  559. /* read a range of the data via the page cache */
  560. static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len,
  561.      size_t *retlen, u_char *buf)
  562. {
  563.   mtd_raw_dev_data_t *rawdevice = mtd->priv;
  564.   int err = 0;
  565.   int offset;
  566.   int pagenr, pages;
  567.   *retlen = 0;
  568.   DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %pn",
  569. bdevname(rawdevice->binding->bd_dev), (long int)from, len, buf);
  570.   pagenr = from >> PAGE_SHIFT;
  571.   offset = from - (pagenr << PAGE_SHIFT);
  572.   
  573.   pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT;
  574.   DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %dn", pagenr, offset, pages);
  575.   /* just loop through each page, getting it via readpage() - slow but easy */
  576.   while(pages) {
  577.     struct page *page;
  578.     int cpylen;
  579.     DEBUG(3, "blkmtd: read: looking for page: %dn", pagenr);
  580.     page = read_cache_page(&rawdevice->as, pagenr, (filler_t *)blkmtd_readpage, rawdevice);
  581.     if(IS_ERR(page)) {
  582.       return PTR_ERR(page);
  583.     }
  584.     wait_on_page(page);
  585.     if(!Page_Uptodate(page)) {
  586.       /* error reading page */
  587.       printk("blkmtd: read: page not uptodaten");
  588.       page_cache_release(page);
  589.       return -EIO;
  590.     }
  591.     cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE;
  592.     if(offset+cpylen > PAGE_SIZE)
  593.       cpylen = PAGE_SIZE-offset;
  594.     
  595.     memcpy(buf + *retlen, page_address(page) + offset, cpylen);
  596.     offset = 0;
  597.     len -= cpylen;
  598.     *retlen += cpylen;
  599.     pagenr++;
  600.     pages--;
  601.     page_cache_release(page);
  602.   }
  603.   
  604.   DEBUG(2, "blkmtd: end read: retlen = %d, err = %dn", *retlen, err);
  605.   return err;
  606. }
  607.     
  608. /* write a range of the data via the page cache.
  609.  *
  610.  * Basic operation. break the write into three parts. 
  611.  *
  612.  * 1. From a page unaligned start up until the next page boundary
  613.  * 2. Page sized, page aligned blocks
  614.  * 3. From end of last aligned block to end of range
  615.  *
  616.  * 1,3 are read via the page cache and readpage() since these are partial
  617.  * pages, 2 we just grab pages from the page cache, not caring if they are
  618.  * already in memory or not since they will be completly overwritten.
  619.  *
  620.  */
  621.  
  622. static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len,
  623.       size_t *retlen, const u_char *buf)
  624. {
  625.   mtd_raw_dev_data_t *rawdevice = mtd->priv;
  626.   int err = 0;
  627.   int offset;
  628.   int pagenr;
  629.   size_t len1 = 0, len2 = 0, len3 = 0;
  630.   struct page **pages;
  631.   int pagecnt = 0;
  632.   *retlen = 0;
  633.   DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %pn",
  634. bdevname(rawdevice->binding->bd_dev), (long int)to, len, buf);
  635.   /* handle readonly and out of range numbers */
  636.   if(rawdevice->readonly) {
  637.     printk("blkmtd: error: trying to write to a readonly device %sn", device);
  638.     return -EROFS;
  639.   }
  640.   if(to >= rawdevice->totalsize) {
  641.     return -ENOSPC;
  642.   }
  643.   if(to + len > rawdevice->totalsize) {
  644.     len = (rawdevice->totalsize - to);
  645.   }
  646.   pagenr = to >> PAGE_SHIFT;
  647.   offset = to - (pagenr << PAGE_SHIFT);
  648.   /* see if we have to do a partial write at the start */
  649.   if(offset) {
  650.     if((offset + len) > PAGE_SIZE) {
  651.       len1 = PAGE_SIZE - offset;
  652.       len -= len1;
  653.     } else {
  654.       len1 = len;
  655.       len = 0;
  656.     }
  657.   }
  658.   /* calculate the length of the other two regions */
  659.   len3 = len & ~PAGE_MASK;
  660.   len -= len3;
  661.   len2 = len;
  662.   if(len1)
  663.     pagecnt++;
  664.   if(len2)
  665.     pagecnt += len2 >> PAGE_SHIFT;
  666.   if(len3)
  667.     pagecnt++;
  668.   DEBUG(3, "blkmtd: write: len1 = %d len2 = %d len3 = %d pagecnt = %dn", len1, len2, len3, pagecnt);
  669.   
  670.   /* get space for list of pages */
  671.   pages = kmalloc(pagecnt * sizeof(struct page *), GFP_KERNEL);
  672.   if(pages == NULL) {
  673.     return -ENOMEM;
  674.   }
  675.   pagecnt = 0;
  676.   if(len1) {
  677.     /* do partial start region */
  678.     struct page *page;
  679.     
  680.     DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %d offset = %dn", pagenr, len1, offset);
  681.     page = read_cache_page(&rawdevice->as, pagenr, (filler_t *)blkmtd_readpage, rawdevice);
  682.     if(IS_ERR(page)) {
  683.       kfree(pages);
  684.       return PTR_ERR(page);
  685.     }
  686.     memcpy(page_address(page)+offset, buf, len1);
  687.     pages[pagecnt++] = page;
  688.     buf += len1;
  689.     *retlen = len1;
  690.     err = 0;
  691.     pagenr++;
  692.   }
  693.   /* Now do the main loop to a page aligned, n page sized output */
  694.   if(len2) {
  695.     int pagesc = len2 >> PAGE_SHIFT;
  696.     DEBUG(3, "blkmtd: write: whole pages start = %d, count = %dn", pagenr, pagesc);
  697.     while(pagesc) {
  698.       struct page *page;
  699.       /* see if page is in the page cache */
  700.       DEBUG(3, "blkmtd: write: grabbing page %d from page cachen", pagenr);
  701.       page = grab_cache_page(&rawdevice->as, pagenr);
  702.       DEBUG(3, "blkmtd: write: got page %d from page cachen", pagenr);
  703.       if(!page) {
  704. printk("blkmtd: write: cant grab cache page %dn", pagenr);
  705. err = -EIO;
  706. goto write_err;
  707.       }
  708.       memcpy(page_address(page), buf, PAGE_SIZE);
  709.       pages[pagecnt++] = page;
  710.       UnlockPage(page);
  711.       SetPageUptodate(page);
  712.       pagenr++;
  713.       pagesc--;
  714.       buf += PAGE_SIZE;
  715.       *retlen += PAGE_SIZE;
  716.     }
  717.   }
  718.   if(len3) {
  719.     /* do the third region */
  720.     struct page *page;
  721.     DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %dn", pagenr, len3);
  722.     page = read_cache_page(&rawdevice->as, pagenr, (filler_t *)blkmtd_readpage, rawdevice);
  723.     if(IS_ERR(page)) {
  724.       err = PTR_ERR(page);
  725.       goto write_err;
  726.     }
  727.     memcpy(page_address(page), buf, len3);
  728.     DEBUG(3, "blkmtd: write: writing out partial endn");
  729.     pages[pagecnt++] = page;
  730.     *retlen += len3;
  731.     err = 0;
  732.   }
  733.   DEBUG(2, "blkmtd: write: end, retlen = %d, err = %dn", *retlen, err);
  734.   /* submit it to the write task */
  735.   err = queue_page_write(rawdevice, pages, to >> PAGE_SHIFT, pagecnt, 0);
  736.   if(!err) {
  737.     while(pagecnt--) {
  738.       SetPageUptodate(pages[pagecnt]);
  739.       flush_dcache_page(pages[pagecnt]);
  740.       page_cache_release(pages[pagecnt]);
  741.     }
  742.     kfree(pages);
  743.     return 0;
  744.   }
  745.  write_err:
  746.   while(--pagecnt) {
  747.     SetPageError(pages[pagecnt]);
  748.     page_cache_release(pages[pagecnt]);
  749.   }
  750.   kfree(pages);
  751.   return err;
  752. }
  753. /* sync the device - wait until the write queue is empty */
  754. static void blkmtd_sync(struct mtd_info *mtd)
  755. {
  756.   DECLARE_WAITQUEUE(wait, current);
  757.   mtd_raw_dev_data_t *rawdevice = mtd->priv;
  758.   if(rawdevice->readonly)
  759.     return;
  760.   DEBUG(2, "blkmtd: sync: calledn");
  761.  stuff_inq:
  762.   spin_lock(&mbd_writeq_lock);
  763.   if(write_queue_cnt) {
  764.     spin_unlock(&mbd_writeq_lock);
  765.     current->state = TASK_UNINTERRUPTIBLE;
  766.     add_wait_queue(&mtbd_sync_wq, &wait);
  767.     DEBUG(3, "blkmtd: sync: waking up taskn");
  768.     wake_up_interruptible(&thr_wq);
  769.     schedule();
  770.     current->state = TASK_RUNNING;
  771.     remove_wait_queue(&mtbd_sync_wq, &wait);
  772.     DEBUG(3, "blkmtd: sync: waking up after write taskn");
  773.     goto stuff_inq;
  774.   }
  775.   spin_unlock(&mbd_writeq_lock);
  776.   DEBUG(2, "blkmtd: sync: finishedn");
  777. }
  778. #ifdef BLKMTD_PROC_DEBUG
  779. /* procfs stuff */
  780. static int blkmtd_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
  781. {
  782.   int clean = 0, dirty = 0, locked = 0;
  783.   struct list_head *temp;
  784.   int i, len, pages = 0, cnt;
  785.   MOD_INC_USE_COUNT;
  786.   spin_lock(&mbd_writeq_lock);
  787.   cnt = write_queue_cnt;
  788.   i = write_queue_tail;
  789.   while(cnt) {
  790.     if(!write_queue[i].iserase)
  791.       pages += write_queue[i].pagecnt;
  792.     i++;
  793.     i %= write_queue_sz;
  794.     cnt--;
  795.   }
  796.   /* Count the size of the page lists */
  797.   list_for_each(temp, &mtd_rawdevice->as.clean_pages) {
  798.     clean++;
  799.   }
  800.   list_for_each(temp, &mtd_rawdevice->as.dirty_pages) {
  801.     dirty++;
  802.   }
  803.   list_for_each(temp, &mtd_rawdevice->as.locked_pages) {
  804.     locked++;
  805.   }
  806.   len = sprintf(page, "Write queue head: %dnWrite queue tail: %dn"
  807. "Write queue count: %dnPages in queue: %d (%dK)n"
  808. "Clean Pages: %dnDirty Pages: %dnLocked Pages: %dn"
  809. "nrpages: %ldn",
  810. write_queue_head, write_queue_tail, write_queue_cnt,
  811. pages, pages << (PAGE_SHIFT-10), clean, dirty, locked,
  812. mtd_rawdevice->as.nrpages);
  813.   if(len <= count)
  814.     *eof = 1;
  815.   spin_unlock(&mbd_writeq_lock);
  816.   MOD_DEC_USE_COUNT;
  817.   return len;
  818. }
  819. #endif
  820. /* Cleanup and exit - sync the device and kill of the kernel thread */
  821. static void __exit cleanup_blkmtd(void)
  822. {
  823. #ifdef BLKMTD_PROC_DEBUG
  824.   if(blkmtd_proc) {
  825.     remove_proc_entry("blkmtd_debug", NULL);
  826.   }
  827. #endif
  828.   if (mtd_rawdevice) {
  829.     /* sync the device */
  830.     if (!mtd_rawdevice->readonly) {
  831.       blkmtd_sync(&mtd_rawdevice->mtd_info);
  832.       write_task_finish = 1;
  833.       wake_up_interruptible(&thr_wq);
  834.       down(&thread_sem);
  835.     }
  836.     del_mtd_device(&mtd_rawdevice->mtd_info);
  837.     if(mtd_rawdevice->binding != NULL)
  838.       blkdev_put(mtd_rawdevice->binding, BDEV_RAW);
  839.     if(mtd_rawdevice->mtd_info.eraseregions)
  840.       kfree(mtd_rawdevice->mtd_info.eraseregions);
  841.     if(mtd_rawdevice->mtd_info.name)
  842.       kfree(mtd_rawdevice->mtd_info.name);
  843.     kfree(mtd_rawdevice);
  844.   }
  845.   if(write_queue)
  846.     kfree(write_queue);
  847.   if(erase_page) {
  848.     UnlockPage(erase_page);
  849.     __free_pages(erase_page, 0);
  850.   }
  851.   printk("blkmtd: unloaded for %sn", device);
  852. }
  853. extern struct module __this_module;
  854. #ifndef MODULE
  855. /* Handle kernel boot params */
  856. static int __init param_blkmtd_device(char *str)
  857. {
  858.   device = str;
  859.   return 1;
  860. }
  861. static int __init param_blkmtd_erasesz(char *str)
  862. {
  863.   erasesz = simple_strtol(str, NULL, 0);
  864.   return 1;
  865. }
  866. static int __init param_blkmtd_ro(char *str)
  867. {
  868.   ro = simple_strtol(str, NULL, 0);
  869.   return 1;
  870. }
  871. static int __init param_blkmtd_bs(char *str)
  872. {
  873.   bs = simple_strtol(str, NULL, 0);
  874.   return 1;
  875. }
  876. static int __init param_blkmtd_count(char *str)
  877. {
  878.   count = simple_strtol(str, NULL, 0);
  879.   return 1;
  880. }
  881. __setup("blkmtd_device=", param_blkmtd_device);
  882. __setup("blkmtd_erasesz=", param_blkmtd_erasesz);
  883. __setup("blkmtd_ro=", param_blkmtd_ro);
  884. __setup("blkmtd_bs=", param_blkmtd_bs);
  885. __setup("blkmtd_count=", param_blkmtd_count);
  886. #endif
  887. /* for a given size and initial erase size, calculate the number and size of each
  888.    erase region */
  889. static int __init calc_erase_regions(struct mtd_erase_region_info *info, size_t erase_size, size_t total_size)
  890. {
  891.   int count = 0;
  892.   int offset = 0;
  893.   int regions = 0;
  894.    while(total_size) {
  895.      count = total_size / erase_size;
  896.      if(count) {
  897.        total_size = total_size % erase_size;
  898.        if(info) {
  899.  info->offset = offset;
  900.  info->erasesize = erase_size;
  901.  info->numblocks = count;
  902.  info++;
  903.        }
  904.        offset += (count * erase_size);
  905.        regions++;
  906.      }
  907.      while(erase_size > total_size)
  908.        erase_size >>= 1;
  909.    }
  910.    return regions;
  911. }
  912. extern kdev_t name_to_kdev_t(char *line) __init;
  913. /* Startup */
  914. static int __init init_blkmtd(void)
  915. {
  916. #ifdef MODULE
  917.   struct file *file = NULL;
  918.   struct inode *inode;
  919. #endif
  920.   int maj, min;
  921.   int i, blocksize, blocksize_bits;
  922.   loff_t size = 0;
  923.   int readonly = 0;
  924.   int erase_size = CONFIG_MTD_BLKDEV_ERASESIZE;
  925.   kdev_t rdev;
  926.   int err;
  927.   int mode;
  928.   int regions;
  929.   /* Check args */
  930.   if(device == 0) {
  931.     printk("blkmtd: error, missing `device' namen");
  932.     return -EINVAL;
  933.   }
  934.   if(ro)
  935.     readonly = 1;
  936.   if(erasesz)
  937.     erase_size = erasesz;
  938.   if(wqs) {
  939.     if(wqs < 16) 
  940.       wqs = 16;
  941.     if(wqs > 4*WRITE_QUEUE_SZ)
  942.       wqs = 4*WRITE_QUEUE_SZ;
  943.     write_queue_sz = wqs;
  944.   }
  945.   DEBUG(1, "blkmtd: device = `%s' erase size = %dK readonly = %s queue size = %dn",
  946. device, erase_size, readonly ? "yes" : "no", write_queue_sz);
  947.   /* Get a handle on the device */
  948.   mode = (readonly) ? O_RDONLY : O_RDWR;
  949. #ifdef MODULE
  950.   file = filp_open(device, mode, 0);
  951.   if(IS_ERR(file)) {
  952.     printk("blkmtd: error, cant open device %sn", device);
  953.     DEBUG(2, "blkmtd: filp_open returned %ldn", PTR_ERR(file));
  954.     return 1;
  955.   }
  956.   
  957.   /* determine is this is a block device and if so get its major and minor
  958.      numbers */
  959.   inode = file->f_dentry->d_inode;
  960.   if(!S_ISBLK(inode->i_mode)) {
  961.     printk("blkmtd: %s not a block devicen", device);
  962.     filp_close(file, NULL);
  963.     return 1;
  964.   }
  965.   rdev = inode->i_rdev;
  966.   filp_close(file, NULL);
  967. #else
  968.   rdev = name_to_kdev_t(device);
  969. #endif
  970.   maj = MAJOR(rdev);
  971.   min = MINOR(rdev);
  972.   DEBUG(1, "blkmtd: found a block device major = %d, minor = %dn", maj, min);
  973.   if(!rdev) {
  974.     printk("blkmtd: bad block device: `%s'n", device);
  975.     return 1;
  976.   }
  977.   if(maj == MTD_BLOCK_MAJOR) {
  978.     printk("blkmtd: attempting to use an MTD device as a block devicen");
  979.     return 1;
  980.   }
  981.   DEBUG(1, "blkmtd: devname = %sn", bdevname(rdev));
  982.   blocksize = BLOCK_SIZE;
  983.   if(bs) {
  984.     blocksize = bs;
  985.   } else {
  986.     if (blksize_size[maj] && blksize_size[maj][min]) {
  987.       DEBUG(2, "blkmtd: blksize_size = %dn", blksize_size[maj][min]);
  988.       blocksize = blksize_size[maj][min];
  989.     }
  990.   }
  991.   i = blocksize;
  992.   blocksize_bits = 0;
  993.   while(i != 1) {
  994.     blocksize_bits++;
  995.     i >>= 1;
  996.   }
  997.   if(count) {
  998.     size = count;
  999.   } else {
  1000.     if (blk_size[maj]) {
  1001.       size = ((loff_t) blk_size[maj][min] << BLOCK_SIZE_BITS) >> blocksize_bits;
  1002.     }
  1003.   }
  1004.   size *= blocksize;
  1005.   DEBUG(1, "blkmtd: size = %ldn", (long int)size);
  1006.   if(size == 0) {
  1007.     printk("blkmtd: cant determine sizen");
  1008.     return 1;
  1009.   }
  1010.   mtd_rawdevice = (mtd_raw_dev_data_t *)kmalloc(sizeof(mtd_raw_dev_data_t), GFP_KERNEL);
  1011.   if(mtd_rawdevice == NULL) {
  1012.     err = -ENOMEM;
  1013.     goto init_err;
  1014.   }
  1015.   memset(mtd_rawdevice, 0, sizeof(mtd_raw_dev_data_t));
  1016.   /* get the block device */
  1017.   mtd_rawdevice->binding = bdget(kdev_t_to_nr(MKDEV(maj, min)));
  1018.   err = blkdev_get(mtd_rawdevice->binding, mode, 0, BDEV_RAW);
  1019.   if (err) {
  1020.     goto init_err;
  1021.   }
  1022.   mtd_rawdevice->totalsize = size;
  1023.   mtd_rawdevice->sector_size = blocksize;
  1024.   mtd_rawdevice->sector_bits = blocksize_bits;
  1025.   mtd_rawdevice->readonly = readonly;
  1026.   /* See if device ends on page boundary */
  1027.   if(size % PAGE_SIZE) {
  1028.     mtd_rawdevice->partial_last_page = size >> PAGE_SHIFT;
  1029.     mtd_rawdevice->last_page_sectors = (size & (PAGE_SIZE-1)) >> blocksize_bits;
  1030.   }
  1031.   DEBUG(2, "sector_size = %d, sector_bits = %d, partial_last_page = %d last_page_sectors = %dn", 
  1032. mtd_rawdevice->sector_size, mtd_rawdevice->sector_bits,
  1033. mtd_rawdevice->partial_last_page, mtd_rawdevice->last_page_sectors);
  1034.   /* Setup the MTD structure */
  1035.   /* make the name contain the block device in */
  1036.   mtd_rawdevice->mtd_info.name = kmalloc(9 + strlen(device), GFP_KERNEL);
  1037.   if(mtd_rawdevice->mtd_info.name == NULL)
  1038.     goto init_err;
  1039.   sprintf(mtd_rawdevice->mtd_info.name, "blkmtd: %s", device);
  1040.   if(readonly) {
  1041.     mtd_rawdevice->mtd_info.type = MTD_ROM;
  1042.     mtd_rawdevice->mtd_info.flags = MTD_CAP_ROM;
  1043.     mtd_rawdevice->mtd_info.erasesize = erase_size << 10;
  1044.   } else {
  1045.     mtd_rawdevice->mtd_info.type = MTD_RAM;
  1046.     mtd_rawdevice->mtd_info.flags = MTD_CAP_RAM;
  1047.     mtd_rawdevice->mtd_info.erasesize = erase_size << 10;
  1048.   }
  1049.   mtd_rawdevice->mtd_info.size = size;
  1050.   mtd_rawdevice->mtd_info.erase = blkmtd_erase;
  1051.   mtd_rawdevice->mtd_info.read = blkmtd_read;
  1052.   mtd_rawdevice->mtd_info.write = blkmtd_write;
  1053.   mtd_rawdevice->mtd_info.sync = blkmtd_sync;
  1054.   mtd_rawdevice->mtd_info.point = 0;
  1055.   mtd_rawdevice->mtd_info.unpoint = 0;
  1056.   mtd_rawdevice->mtd_info.priv = mtd_rawdevice;
  1057.   regions = calc_erase_regions(NULL, erase_size << 10, size);
  1058.   DEBUG(1, "blkmtd: init: found %d erase regionsn", regions);
  1059.   mtd_rawdevice->mtd_info.eraseregions = kmalloc(regions * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
  1060.   if(mtd_rawdevice->mtd_info.eraseregions == NULL) {
  1061.     err = -ENOMEM;
  1062.     goto init_err;
  1063.   }
  1064.   mtd_rawdevice->mtd_info.numeraseregions = regions;
  1065.   calc_erase_regions(mtd_rawdevice->mtd_info.eraseregions, erase_size << 10, size);
  1066.   /* setup the page cache info */
  1067.   
  1068.   mtd_rawdevice->as.nrpages = 0;
  1069.   INIT_LIST_HEAD(&mtd_rawdevice->as.clean_pages);
  1070.   INIT_LIST_HEAD(&mtd_rawdevice->as.dirty_pages);
  1071.   INIT_LIST_HEAD(&mtd_rawdevice->as.locked_pages);
  1072.   mtd_rawdevice->as.host = NULL;
  1073.   spin_lock_init(&(mtd_rawdevice->as.i_shared_lock));
  1074.   mtd_rawdevice->as.a_ops = &blkmtd_aops;
  1075.   mtd_rawdevice->as.i_mmap = NULL;
  1076.   mtd_rawdevice->as.i_mmap_shared = NULL;
  1077.   mtd_rawdevice->as.gfp_mask = GFP_KERNEL;
  1078. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
  1079.   mtd_rawdevice->mtd_info.module = THIS_MODULE;
  1080. #endif
  1081.   if (add_mtd_device(&mtd_rawdevice->mtd_info)) {
  1082.     err = -EIO;
  1083.     goto init_err;
  1084.   }
  1085.   if(!mtd_rawdevice->readonly) {
  1086.     /* Allocate the write queue */
  1087.     write_queue = kmalloc(write_queue_sz * sizeof(mtdblkdev_write_queue_t), GFP_KERNEL);
  1088.     if(!write_queue) {
  1089.       err = -ENOMEM;
  1090.       goto init_err;
  1091.     }
  1092.     /* Set up the erase page */
  1093.     erase_page = alloc_pages(GFP_KERNEL, 0);
  1094.     if(erase_page == NULL) {
  1095.       err = -ENOMEM;
  1096.       goto init_err;
  1097.     }
  1098.     memset(page_address(erase_page), 0xff, PAGE_SIZE);
  1099.     lock_page(erase_page);
  1100.     init_waitqueue_head(&thr_wq);
  1101.     init_waitqueue_head(&mtbd_sync_wq);
  1102.     DEBUG(3, "blkmtd: init: kernel task @ %pn", write_queue_task);
  1103.     DEBUG(2, "blkmtd: init: starting kernel taskn");
  1104.     kernel_thread(write_queue_task, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
  1105.     DEBUG(2, "blkmtd: init: startedn");
  1106.     printk("blkmtd loaded: version = %s using %s erase_size = %dK %sn",
  1107.    VERSION, device, erase_size, (readonly) ? "(read-only)" : "");
  1108.   }
  1109. #ifdef BLKMTD_PROC_DEBUG
  1110.   /* create proc entry */
  1111.   DEBUG(2, "Creating /proc/blkmtd_debugn");
  1112.   blkmtd_proc = create_proc_read_entry("blkmtd_debug", 0444,
  1113.        NULL, blkmtd_proc_read, NULL);
  1114.   if(blkmtd_proc == NULL) {
  1115.     printk("Cant create /proc/blkmtd_debugn");
  1116.   } else {
  1117.     blkmtd_proc->owner = THIS_MODULE;
  1118.   }
  1119. #endif
  1120.   
  1121.   /* Everything is ok if we got here */
  1122.   return 0;
  1123.   
  1124.  init_err:
  1125.   if(mtd_rawdevice) {
  1126.     if(mtd_rawdevice->mtd_info.eraseregions)
  1127.       kfree(mtd_rawdevice->mtd_info.eraseregions);
  1128.     if(mtd_rawdevice->mtd_info.name)
  1129.       kfree(mtd_rawdevice->mtd_info.name);
  1130.     if(mtd_rawdevice->binding) 
  1131.       blkdev_put(mtd_rawdevice->binding, BDEV_RAW);
  1132.     kfree(mtd_rawdevice);
  1133.   }
  1134.   if(write_queue) {
  1135.     kfree(write_queue);
  1136.     write_queue = NULL;
  1137.   }
  1138.   if(erase_page) 
  1139.     __free_pages(erase_page, 0);
  1140.   return err;
  1141. }
  1142. module_init(init_blkmtd);
  1143. module_exit(cleanup_blkmtd);