cregit-Linux how code gets into the kernel

Release 4.14 arch/m68k/emu/nfblock.c

Directory: arch/m68k/emu
/*
 * ARAnyM block device driver
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/slab.h>

#include <asm/natfeat.h>


static long nfhd_id;

enum {
	/* emulation entry points */
	
NFHD_READ_WRITE = 10,
	
NFHD_GET_CAPACITY = 14,

	/* skip ACSI devices */
	
NFHD_DEV_OFFSET = 8,
};


static inline s32 nfhd_read_write(u32 major, u32 minor, u32 rwflag, u32 recno, u32 count, u32 buf) { return nf_call(nfhd_id + NFHD_READ_WRITE, major, minor, rwflag, recno, count, buf); }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel45100.00%1100.00%
Total45100.00%1100.00%


static inline s32 nfhd_get_capacity(u32 major, u32 minor, u32 *blocks, u32 *blocksize) { return nf_call(nfhd_id + NFHD_GET_CAPACITY, major, minor, virt_to_phys(blocks), virt_to_phys(blocksize)); }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel3786.05%150.00%
Geert Uytterhoeven613.95%150.00%
Total43100.00%2100.00%

static LIST_HEAD(nfhd_list); static int major_num; module_param(major_num, int, 0); struct nfhd_device { struct list_head list; int id; u32 blocks, bsize; int bshift; struct request_queue *queue; struct gendisk *disk; };
static blk_qc_t nfhd_make_request(struct request_queue *queue, struct bio *bio) { struct nfhd_device *dev = queue->queuedata; struct bio_vec bvec; struct bvec_iter iter; int dir, len, shift; sector_t sec = bio->bi_iter.bi_sector; dir = bio_data_dir(bio); shift = dev->bshift; bio_for_each_segment(bvec, bio, iter) { len = bvec.bv_len; len >>= 9; nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift, bvec_to_phys(&bvec)); sec += len; } bio_endio(bio); return BLK_QC_T_NONE; }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel10689.08%125.00%
Kent Overstreet97.56%250.00%
Jens Axboe43.36%125.00%
Total119100.00%4100.00%


static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo) { struct nfhd_device *dev = bdev->bd_disk->private_data; geo->cylinders = dev->blocks >> (6 - dev->bshift); geo->heads = 4; geo->sectors = 16; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel58100.00%1100.00%
Total58100.00%1100.00%

static const struct block_device_operations nfhd_ops = { .owner = THIS_MODULE, .getgeo = nfhd_getgeo, };
static int __init nfhd_init_one(int id, u32 blocks, u32 bsize) { struct nfhd_device *dev; int dev_id = id - NFHD_DEV_OFFSET; pr_info("nfhd%u: found device with %u blocks (%u bytes)\n", dev_id, blocks, bsize); if (bsize < 512 || (bsize & (bsize - 1))) { pr_warn("nfhd%u: invalid block size\n", dev_id); return -EINVAL; } dev = kmalloc(sizeof(struct nfhd_device), GFP_KERNEL); if (!dev) goto out; dev->id = id; dev->blocks = blocks; dev->bsize = bsize; dev->bshift = ffs(bsize) - 10; dev->queue = blk_alloc_queue(GFP_KERNEL); if (dev->queue == NULL) goto free_dev; dev->queue->queuedata = dev; blk_queue_make_request(dev->queue, nfhd_make_request); blk_queue_logical_block_size(dev->queue, bsize); dev->disk = alloc_disk(16); if (!dev->disk) goto free_queue; dev->disk->major = major_num; dev->disk->first_minor = dev_id * 16; dev->disk->fops = &nfhd_ops; dev->disk->private_data = dev; sprintf(dev->disk->disk_name, "nfhd%u", dev_id); set_capacity(dev->disk, (sector_t)blocks * (bsize / 512)); dev->disk->queue = dev->queue; add_disk(dev->disk); list_add_tail(&dev->list, &nfhd_list); return 0; free_queue: blk_cleanup_queue(dev->queue); free_dev: kfree(dev); out: return -ENOMEM; }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel302100.00%1100.00%
Total302100.00%1100.00%


static int __init nfhd_init(void) { u32 blocks, bsize; int i; nfhd_id = nf_get_id("XHDI"); if (!nfhd_id) return -ENODEV; major_num = register_blkdev(major_num, "nfhd"); if (major_num <= 0) { pr_warn("nfhd: unable to get major number\n"); return major_num; } for (i = NFHD_DEV_OFFSET; i < 24; i++) { if (nfhd_get_capacity(i, 0, &blocks, &bsize)) continue; nfhd_init_one(i, blocks, bsize); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel101100.00%1100.00%
Total101100.00%1100.00%


static void __exit nfhd_exit(void) { struct nfhd_device *dev, *next; list_for_each_entry_safe(dev, next, &nfhd_list, list) { list_del(&dev->list); del_gendisk(dev->disk); put_disk(dev->disk); blk_cleanup_queue(dev->queue); kfree(dev); } unregister_blkdev(major_num, "nfhd"); }

Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel70100.00%1100.00%
Total70100.00%1100.00%

module_init(nfhd_init); module_exit(nfhd_exit); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
Roman Zippel85697.83%120.00%
Kent Overstreet91.03%240.00%
Geert Uytterhoeven60.69%120.00%
Jens Axboe40.46%120.00%
Total875100.00%5100.00%
Directory: arch/m68k/emu
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.