亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? sbull.c

?? Linux設備驅動程序的編寫 Linux設備驅動程序的編寫
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* * sbull.c -- the Simple Block Utility * * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet * Copyright (C) 2001 O'Reilly & Associates * * The source code in this file can be freely used, adapted, * and redistributed in source or binary form, so long as an * acknowledgment appears in derived source files.  The citation * should list that the code comes from the book "Linux Device * Drivers" by Alessandro Rubini and Jonathan Corbet, published * by O'Reilly & Associates.   No warranty is attached; * we cannot take responsibility for errors or fitness for use. * * $Id: sbull.c,v 1.32 2001/07/18 22:28:16 rubini Exp $ */#ifndef __KERNEL__#  define __KERNEL__#endif#ifndef MODULE#  define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/malloc.h> /* kmalloc() */#include <linux/fs.h>     /* everything... */#include <linux/errno.h>  /* error codes */#include <linux/timer.h>#include <linux/types.h>  /* size_t */#include <linux/fcntl.h>        /* O_ACCMODE */#include <linux/hdreg.h>  /* HDIO_GETGEO */#include <asm/system.h>   /* cli(), *_flags */#define MAJOR_NR sbull_major /* force definitions on in blk.h */static int sbull_major; /* must be declared before including blk.h */#define DEVICE_NR(device) MINOR(device)   /* sbull has no partition bits */#define DEVICE_NAME "sbull"               /* name for messaging */#define DEVICE_INTR sbull_intrptr         /* pointer to the bottom half */#define DEVICE_NO_RANDOM                  /* no entropy to contribute */#define DEVICE_REQUEST sbull_request#define DEVICE_OFF(d) /* do-nothing */#include <linux/blk.h>#include "sbull.h"        /* local definitions */#ifdef HAVE_BLKPG_H#include <linux/blkpg.h>  /* blk_ioctl() */#endif/* * Do the raw char interface in 2.4. */#ifdef LINUX_24#  define DO_RAW_INTERFACE#  include <linux/iobuf.h>static void sbullr_init();static void sbullr_release();#  define SBULLR_SECTOR 512  /* insist on this */#  define SBULLR_SECTOR_MASK (SBULLR_SECTOR - 1)#  define SBULLR_SECTOR_SHIFT 9#endif/* * Non-prefixed symbols are static. They are meant to be assigned at * load time. Prefixed symbols are not static, so they can be used in * debugging. They are hidden anyways by register_symtab() unless * SBULL_DEBUG is defined. */static int major    = SBULL_MAJOR;static int devs     = SBULL_DEVS;static int rahead   = SBULL_RAHEAD;static int size     = SBULL_SIZE;static int blksize  = SBULL_BLKSIZE;static int hardsect = SBULL_HARDSECT;MODULE_PARM(major, "i");MODULE_PARM(devs, "i");MODULE_PARM(rahead, "i");MODULE_PARM(size, "i");MODULE_PARM(blksize, "i");MODULE_PARM(hardsect, "i");MODULE_AUTHOR("Alessandro Rubini");int sbull_devs, sbull_rahead, sbull_size;int sbull_blksize, sbull_hardsect;/* The following items are obtained through kmalloc() in sbull_init() */Sbull_Dev *sbull_devices = NULL;int *sbull_blksizes = NULL;int *sbull_sizes = NULL;int *sbull_hardsects = NULL;/* * We can do without a request queue, but only in 2.4 */#if defined(LINUX_24) && !defined(SBULL_MULTIQUEUE)static int noqueue = 0;         /* Use request queue by default */MODULE_PARM(noqueue, "i");#endif#ifdef DO_RAW_INTERFACEint sbullr_major = SBULLR_MAJOR;MODULE_PARM(sbullr_major, "i");#endifint sbull_revalidate(kdev_t i_rdev);/* * Open and close */int sbull_open (struct inode *inode, struct file *filp){    Sbull_Dev *dev; /* device information */    int num = MINOR(inode->i_rdev);    if (num >= sbull_devs) return -ENODEV;    dev = sbull_devices + num;    /* kill the timer associated to the device: it might be active */    del_timer(&dev->timer);    spin_lock(&dev->lock);    /* revalidate on first open and fail if no data is there */    if (!dev->usage) {        check_disk_change(inode->i_rdev);        if (!dev->data)        {            spin_unlock (&dev->lock);            return -ENOMEM;        }    }    dev->usage++;    spin_unlock(&dev->lock);    MOD_INC_USE_COUNT;    return 0;          /* success */}int sbull_release (struct inode *inode, struct file *filp){    Sbull_Dev *dev = sbull_devices + MINOR(inode->i_rdev);    spin_lock(&dev->lock);    dev->usage--;    /*     * If the device is closed for the last time, start a timer     * to release RAM in half a minute. The function and argument     * for the timer have been setup in sbull_init()     */    if (!dev->usage) {        dev->timer.expires = jiffies + 30 * HZ;        add_timer(&dev->timer);        /* but flush it right now */        fsync_dev(inode->i_rdev);        invalidate_buffers(inode->i_rdev);    }    MOD_DEC_USE_COUNT;    spin_unlock(&dev->lock);    return 0;}/* * The timer function. As argument it receives the device */void sbull_expires(unsigned long data){    Sbull_Dev *dev = (Sbull_Dev *)data;    spin_lock(&dev->lock);    if (dev->usage || !dev->data) {        spin_unlock(&dev->lock);        printk(KERN_WARNING "sbull: timer mismatch for device %i\n",               dev - sbull_devices);        return;    }    PDEBUG("freeing device %i\n",dev - sbull_devices);    vfree(dev->data);    dev->data=0;    spin_unlock(&dev->lock);    return;}    /* * The ioctl() implementation */int sbull_ioctl (struct inode *inode, struct file *filp,                 unsigned int cmd, unsigned long arg){    int err;    long size;    struct hd_geometry geo;    PDEBUG("ioctl 0x%x 0x%lx\n", cmd, arg);    switch(cmd) {      case BLKGETSIZE:        /* Return the device size, expressed in sectors */        if (!arg) return -EINVAL; /* NULL pointer: not valid */        err = ! access_ok (VERIFY_WRITE, arg, sizeof(long));        if (err) return -EFAULT;        size = blksize*sbull_sizes[MINOR(inode->i_rdev)]		/ sbull_hardsects[MINOR(inode->i_rdev)];	if (copy_to_user((long *) arg, &size, sizeof (long)))	    return -EFAULT;        return 0;      case BLKRRPART: /* re-read partition table: can't do it */        return -ENOTTY;      case HDIO_GETGEO:        /*	 * Get geometry: since we are a virtual device, we have to make	 * up something plausible.  So we claim 16 sectors, four heads,	 * and calculate the corresponding number of cylinders.  We set the	 * start of data at sector four.         */        err = ! access_ok(VERIFY_WRITE, arg, sizeof(geo));        if (err) return -EFAULT;        size = sbull_size * blksize / sbull_hardsect;        geo.cylinders = (size & ~0x3f) >> 6;	geo.heads = 4;	geo.sectors = 16;	geo.start = 4;	if (copy_to_user((void *) arg, &geo, sizeof(geo)))	    return -EFAULT;        return 0;      default:        /*         * For ioctls we don't understand, let the block layer handle them.         */        return blk_ioctl(inode->i_rdev, cmd, arg);    }    return -ENOTTY; /* unknown command */}/* * Support for removable devices */int sbull_check_change(kdev_t i_rdev){    int minor = MINOR(i_rdev);    Sbull_Dev *dev = sbull_devices + minor;    if (minor >= sbull_devs) /* paranoid */         return 0;                                                                           PDEBUG("check_change for dev %i\n",minor);    if (dev->data)        return 0; /* still valid */    return 1; /* expired */}/* * Note no locks taken out here.  In a worst case scenario, we could drop * a chunk of system memory.  But that should never happen, since validation * happens at open or mount time, when locks are held. */int sbull_revalidate(kdev_t i_rdev){    Sbull_Dev *dev = sbull_devices + MINOR(i_rdev);    PDEBUG("revalidate for dev %i\n",MINOR(i_rdev));    if (dev->data)        return 0;    dev->data = vmalloc(dev->size);    if (!dev->data)        return -ENOMEM;    return 0;}/* * The file operations */#ifdef LINUX_24struct block_device_operations sbull_bdops = {    open:               sbull_open,    release:            sbull_release,    ioctl:              sbull_ioctl,    check_media_change: sbull_check_change,    revalidate:         sbull_revalidate,};#else#ifdef LINUX_20void sbull_release_20 (struct inode *inode, struct file *filp){        (void) sbull_release (inode, filp);}#define sbull_release sbull_release_20#endifstruct file_operations sbull_bdops = {    read:       block_read,    write:      block_write,    ioctl:      sbull_ioctl,    open:       sbull_open,    release:    sbull_release,    fsync:      block_fsync,    check_media_change: sbull_check_change,    revalidate: sbull_revalidate};# endif /* LINUX_24 *//* * Block-driver specific functions *//* * Find the device for this request. */static Sbull_Dev *sbull_locate_device(const struct request *req){    int devno;    Sbull_Dev *device;    /* Check if the minor number is in range */    devno = DEVICE_NR(req->rq_dev);    if (devno >= sbull_devs) {        static int count = 0;        if (count++ < 5) /* print the message at most five times */            printk(KERN_WARNING "sbull: request for unknown device\n");        return NULL;    }    device = sbull_devices + devno;  /* Pick it out of our device array */    return device;}/* * Perform an actual transfer. */static int sbull_transfer(Sbull_Dev *device, const struct request *req){    int size;    u8 *ptr;        ptr = device->data + req->sector * sbull_hardsect;    size = req->current_nr_sectors * sbull_hardsect;    /* Make sure that the transfer fits within the device. */    if (ptr + size > device->data + sbull_blksize*sbull_size) {        static int count = 0;        if (count++ < 5)            printk(KERN_WARNING "sbull: request past end of device\n");        return 0;    }    /* Looks good, do the transfer. */    switch(req->cmd) {        case READ:            memcpy(req->buffer, ptr, size); /* from sbull to buffer */            return 1;        case WRITE:            memcpy(ptr, req->buffer, size); /* from buffer to sbull */            return 1;        default:            /* can't happen */            return 0;    }}#ifdef LINUX_24/* * Transfer a buffer directly, without going through the request queue. */int sbull_make_request(request_queue_t *queue, int rw, struct buffer_head *bh){    u8 *ptr;    /* Figure out what we are doing */    Sbull_Dev *device = sbull_devices + MINOR(bh->b_rdev);    ptr = device->data + bh->b_rsector * sbull_hardsect;    /* Paranoid check, this apparently can really happen */    if (ptr + bh->b_size > device->data + sbull_blksize*sbull_size) {        static int count = 0;        if (count++ < 5)            printk(KERN_WARNING "sbull: request past end of device\n");        bh->b_end_io(bh, 0);        return 0;    }    /* This could be a high memory buffer, shift it down */#if CONFIG_HIGHMEM    bh = create_bounce(rw, bh);#endif    /* Do the transfer */    switch(rw) {        case READ:        case READA:  /* Readahead */            memcpy(bh->b_data, ptr, bh->b_size); /* from sbull to buffer */            bh->b_end_io(bh, 1);            break;        case WRITE:            refile_buffer(bh);            memcpy(ptr, bh->b_data, bh->b_size); /* from buffer to sbull */            mark_buffer_uptodate(bh, 1);            bh->b_end_io(bh, 1);            break;        default:            /* can't happen */            bh->b_end_io(bh, 0);            break;    }    /* Nonzero return means we're done */    return 0;}void sbull_unused_request(request_queue_t *q){    static int count = 0;    if (count++ < 5)        printk(KERN_WARNING "sbull: unused_request called\n");}        #endif /* LINUX_24 */#if defined(SBULL_EMPTY_REQUEST)/* * This empty request function just prints the interesting items * of the current request. The sectors affected by the request * are printed as <first-sector>-<number-of-sectors>. */#ifdef LINUX_24void sbull_request(request_queue_t *q)#else                                   void sbull_request()                    

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
美女在线观看视频一区二区| 亚洲乱码中文字幕| 色综合中文字幕国产 | 在线观看成人免费视频| 久久精品国产99久久6| 亚洲欧美成人一区二区三区| 久久久亚洲精品一区二区三区| 一本久久综合亚洲鲁鲁五月天| 国产真实精品久久二三区| 亚洲综合在线电影| 国产精品麻豆久久久| 精品国产乱码久久久久久图片| 欧美日韩在线电影| 99综合电影在线视频| 国内精品国产成人国产三级粉色| 亚洲成人动漫一区| 亚洲乱码一区二区三区在线观看| 国产丝袜美腿一区二区三区| 日韩一区二区三区精品视频| 欧美在线不卡一区| 色综合一区二区| 成人午夜私人影院| 国产精品一区二区不卡| 蜜桃av一区二区| 视频一区视频二区在线观看| 夜夜夜精品看看| 亚洲图片你懂的| 中文一区一区三区高中清不卡| 精品国产乱码久久久久久图片 | 国产亚洲1区2区3区| 日韩一区二区在线观看视频 | 美女视频黄 久久| 午夜影院在线观看欧美| 一区二区三区四区乱视频| 亚洲青青青在线视频| 亚洲三级久久久| 亚洲欧美日韩在线播放| 亚洲欧美日韩国产手机在线| 成人欧美一区二区三区小说| 国产精品久久久久三级| 中文字幕字幕中文在线中不卡视频| 国产精品免费av| 国产精品乱码一区二三区小蝌蚪| 国产精品久久毛片av大全日韩| 中文字幕乱码日本亚洲一区二区| 国产精品久久久久久久浪潮网站 | 欧美成人伊人久久综合网| 日韩视频在线永久播放| 精品蜜桃在线看| 久久久国产精品不卡| 中文字幕国产一区二区| 亚洲女人****多毛耸耸8| 亚洲日本欧美天堂| 亚洲二区在线观看| 人禽交欧美网站| 国模无码大尺度一区二区三区| 国产自产2019最新不卡| 国产91清纯白嫩初高中在线观看 | 91麻豆免费在线观看| 在线免费观看日本一区| 在线播放91灌醉迷j高跟美女| 91精品国产乱码久久蜜臀| 精品国产一区二区国模嫣然| 国产日韩亚洲欧美综合| 亚洲人成在线播放网站岛国| 午夜精品久久久久影视| 精品系列免费在线观看| 不卡一卡二卡三乱码免费网站| 91福利区一区二区三区| 欧美一区二区在线观看| 欧美激情艳妇裸体舞| 亚洲国产精品视频| 精品无码三级在线观看视频| 成人av手机在线观看| 欧美精品在线观看一区二区| 久久综合狠狠综合| 亚洲乱码国产乱码精品精可以看| 五月婷婷激情综合| 国产成人精品免费看| 在线亚洲高清视频| 久久久久久久国产精品影院| 一区二区在线看| 精品一区二区成人精品| 色一区在线观看| 亚洲精品在线三区| 亚洲一区二区三区爽爽爽爽爽| 国产一区日韩二区欧美三区| 欧洲av在线精品| 久久精品男人的天堂| 亚洲高清视频中文字幕| 国产精品一级二级三级| 欧美日韩精品三区| 国产精品视频线看| 麻豆免费精品视频| 色88888久久久久久影院按摩| 久久久久国产精品麻豆| 亚洲国产精品久久不卡毛片 | 久久久国产综合精品女国产盗摄| 亚洲精品国产视频| 国产经典欧美精品| 日韩欧美高清在线| 午夜精品一区二区三区电影天堂| 99视频有精品| 久久久久久久av麻豆果冻| 偷拍自拍另类欧美| 91电影在线观看| 国产精品免费视频网站| 国产在线国偷精品产拍免费yy| 欧美性大战久久久久久久| 中文字幕一区二区三区不卡在线| 精品一区二区三区视频| 欧美精品v国产精品v日韩精品| 中文字幕一区二区三区视频 | 91麻豆精品国产自产在线| 亚洲少妇中出一区| 成人小视频在线| 国产网红主播福利一区二区| 久久黄色级2电影| 日韩欧美一区电影| 五月婷婷欧美视频| 欧美精品 国产精品| 午夜久久久久久| 欧美日韩国产高清一区二区三区| 一区二区三区在线高清| 97久久超碰国产精品| 国产精品久久久久久户外露出 | 国产精品午夜在线| 黑人精品欧美一区二区蜜桃| 日韩一区二区三区四区五区六区| 日韩影视精彩在线| 欧美一区二区三区人| 日韩一级片在线播放| 国产综合色在线视频区| 国产精品麻豆视频| 亚洲高清在线精品| 欧美在线一区二区| 亚洲最大的成人av| 在线观看国产日韩| 亚洲成人tv网| 欧美一区二区三区不卡| 久久精品国产久精国产爱| 欧美一区二区久久久| 精品一区二区日韩| 久久久久久一二三区| 福利电影一区二区| 亚洲女子a中天字幕| 欧美影院一区二区| 日韩国产高清影视| 精品入口麻豆88视频| 国产精品一区二区你懂的| 国产精品福利影院| 欧美视频在线观看一区| 日本视频一区二区三区| 欧美成人video| 国产传媒久久文化传媒| 自拍偷在线精品自拍偷无码专区| 在线免费视频一区二区| 奇米色一区二区三区四区| 精品成a人在线观看| 波多野结衣精品在线| 一区二区三区.www| 日韩一级片在线观看| 成人一区二区三区| 亚洲一区二区三区在线| 制服丝袜国产精品| 国产精品综合一区二区三区| 综合av第一页| 日韩欧美亚洲另类制服综合在线| 国产麻豆精品95视频| 一区二区三区在线免费视频| 91精品国产美女浴室洗澡无遮挡| 国产福利视频一区二区三区| 亚洲免费av在线| 精品久久久久久久一区二区蜜臀| a亚洲天堂av| 久久激情五月婷婷| 尤物视频一区二区| 精品三级在线看| 欧美无砖砖区免费| 国产精品99久久久久久似苏梦涵 | 欧美一区二区三区色| 成人黄色免费短视频| 视频一区二区三区中文字幕| 国产色综合一区| 欧美男男青年gay1069videost| 国产一区三区三区| 亚洲电影你懂得| 中文无字幕一区二区三区| 欧美一a一片一级一片| 国产福利精品导航| 日韩成人免费看| 亚洲乱码日产精品bd| 国产欧美日韩亚州综合 | 国产精品国产精品国产专区不蜜| 337p亚洲精品色噜噜狠狠| 不卡视频一二三四| 韩日欧美一区二区三区| 首页综合国产亚洲丝袜| 最新日韩av在线| 国产日产欧美一区|