22 #include <linux/kernel.h>
23 #include <linux/slab.h>
24 #include <linux/module.h>
25 #include <linux/list.h>
36 #include <asm/uaccess.h>
43 static void blktrans_dev_release(
struct kref *
kref)
60 dev = disk->private_data;
73 kref_put(&dev->
ref, blktrans_dev_release);
85 block = blk_rq_pos(req) << 9 >> tr->
blkshift;
86 nsect = blk_rq_cur_bytes(req) >> tr->
blkshift;
90 if (req->cmd_type != REQ_TYPE_FS)
93 if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
94 get_capacity(req->rq_disk))
98 return tr->
discard(dev, block, nsect);
100 switch(rq_data_dir(req)) {
102 for (; nsect > 0; nsect--, block++, buf += tr->
blksize)
105 rq_flush_dcache_pages(req);
111 rq_flush_dcache_pages(req);
112 for (; nsect > 0; nsect--, block++, buf += tr->
blksize)
131 static int mtd_blktrans_thread(
void *
arg)
137 int background_done = 0;
139 spin_lock_irq(rq->queue_lock);
147 spin_unlock_irq(rq->queue_lock);
151 spin_lock_irq(rq->queue_lock);
156 background_done = !dev->
bg_stop;
164 spin_unlock_irq(rq->queue_lock);
166 spin_lock_irq(rq->queue_lock);
170 spin_unlock_irq(rq->queue_lock);
173 res = do_blktrans_request(dev->
tr, dev, req);
176 spin_lock_irq(rq->queue_lock);
187 spin_unlock_irq(rq->queue_lock);
222 __module_get(dev->
tr->owner);
228 ret = dev->
tr->open(dev);
241 blktrans_dev_put(dev);
245 if (dev->
tr->release)
246 dev->
tr->release(dev);
248 module_put(dev->
tr->owner);
249 kref_put(&dev->
ref, blktrans_dev_release);
251 blktrans_dev_put(dev);
255 static int blktrans_release(
struct gendisk *disk,
fmode_t mode)
268 kref_put(&dev->
ref, blktrans_dev_release);
269 module_put(dev->
tr->owner);
272 ret = dev->
tr->release ? dev->
tr->release(dev) : 0;
277 blktrans_dev_put(dev);
294 ret = dev->
tr->getgeo ? dev->
tr->getgeo(dev, geo) : 0;
297 blktrans_dev_put(dev);
302 unsigned int cmd,
unsigned long arg)
317 ret = dev->
tr->flush ? dev->
tr->flush(dev) : 0;
324 blktrans_dev_put(dev);
330 .open = blktrans_open,
331 .release = blktrans_release,
332 .ioctl = blktrans_ioctl,
333 .getgeo = blktrans_getgeo,
338 struct mtd_blktrans_ops *tr =
new->tr;
340 int last_devnum = -1;
351 if (new->devnum == -1) {
353 if (d->
devnum != last_devnum+1) {
355 new->devnum = last_devnum+1;
359 }
else if (d->
devnum == new->devnum) {
363 }
else if (d->
devnum > new->devnum) {
372 if (new->devnum == -1)
373 new->devnum = last_devnum+1;
379 (tr->
part_bits && new->devnum >= 27 * 26)) {
389 kref_init(&new->ref);
401 gd->private_data =
new;
402 gd->major = tr->
major;
403 gd->first_minor = (
new->devnum) << tr->
part_bits;
404 gd->fops = &mtd_blktrans_ops;
407 if (new->devnum < 26)
408 snprintf(gd->disk_name,
sizeof(gd->disk_name),
409 "%s%c", tr->
name,
'a' + new->devnum);
411 snprintf(gd->disk_name,
sizeof(gd->disk_name),
413 'a' - 1 + new->devnum / 26,
414 'a' + new->devnum % 26);
416 snprintf(gd->disk_name,
sizeof(gd->disk_name),
417 "%s%d", tr->
name, new->devnum);
419 set_capacity(gd, (new->size * tr->
blksize) >> 9);
428 new->rq->queuedata =
new;
431 queue_flag_set_unlocked(QUEUE_FLAG_NONROT, new->rq);
434 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, new->rq);
435 new->rq->limits.max_discard_sectors =
UINT_MAX;
442 new->thread =
kthread_run(mtd_blktrans_thread,
new,
443 "%s%d", tr->
name, new->mtd->index);
444 if (IS_ERR(new->thread)) {
445 ret = PTR_ERR(new->thread);
448 gd->driverfs_dev = &
new->mtd->dev;
455 if (new->disk_attributes) {
457 new->disk_attributes);
493 old->
rq->queuedata =
NULL;
495 spin_unlock_irqrestore(&old->
queue_lock, flags);
501 if (old->
tr->release)
502 old->
tr->release(old);
509 blktrans_dev_put(old);
513 static void blktrans_notify_remove(
struct mtd_info *mtd)
515 struct mtd_blktrans_ops *tr;
526 struct mtd_blktrans_ops *tr;
536 .
add = blktrans_notify_add,
537 .remove = blktrans_notify_remove,
548 if (!blktrans_notifier.list.next)
567 INIT_LIST_HEAD(&tr->
devs);
568 list_add(&tr->
list, &blktrans_majors);
597 static void __exit mtd_blktrans_exit(
void)
601 if (blktrans_notifier.list.next)