linux编写驱动程序,[原创]如何编写Linux 驱动程序(四)

#include

#include

#include

#include

#include

#include "usb.h"

#define MAX_USB_MINORS256

static struct file_operations *usb_minors[MAX_USB_MINORS];

static DEFINE_SPINLOCK(minor_lock);

static int usb_open(struct inode * inode, struct file * file)

{

int minor = iminor(inode);

struct file_operations *c;

int err = -ENODEV;

struct file_operations *old_fops, *new_fops = NULL;

spin_lock (&minor_lock);

c = usb_minors[minor];

if (!c || !(new_fops = fops_get(c))) {

spin_unlock(&minor_lock);

return err;

}

spin_unlock(&minor_lock);

old_fops = file->f_op;

file->f_op = new_fops;

/* Curiouser and curiouser... NULL ->open() as "no device" ? */

if (file->f_op->open)

err = file->f_op->open(inode,file);

if (err) {

fops_put(file->f_op);

file->f_op = fops_get(old_fops);

}

fops_put(old_fops);

return err;

}

static struct file_operations usb_fops = {

.owner =THIS_MODULE,

.open =usb_open,

};

static struct class *usb_class;

int usb_major_init(void)

{

int error;

error = register_chrdev(USB_MAJOR, "usb", &usb_fops);

if (error) {

err("unable to get major %d for usb devices", USB_MAJOR);

goto out;

}

usb_class = class_create(THIS_MODULE, "usb");

if (IS_ERR(usb_class)) {

error = PTR_ERR(usb_class);

err("class_create failed for usb devices");

unregister_chrdev(USB_MAJOR, "usb");

goto out;

}

out:

return error;

}

void usb_major_cleanup(void)

{

class_destroy(usb_class);

unregister_chrdev(USB_MAJOR, "usb");

}

int usb_register_dev(struct usb_interface *intf,

struct usb_class_driver *class_driver)

{

int retval = -EINVAL;

int minor_base = class_driver->minor_base;

int minor = 0;

char name[BUS_ID_SIZE];

char *temp;

#ifdef CONFIG_USB_DYNAMIC_MINORS

minor_base = 0;

#endif

intf->minor = -1;

dbg ("looking for a minor, starting at %d", minor_base);

if (class_driver->fops == NULL)

goto exit;

spin_lock (&minor_lock);

for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {

if (usb_minors[minor])

continue;

usb_minors[minor] = class_driver->fops;

retval = 0;

break;

}

spin_unlock (&minor_lock);

if (retval)

goto exit;

intf->minor = minor;

/* create a usb class device for this usb interface */

snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base);

temp = strrchr(name, '/');

if (temp && (temp[1] != 0x00))

++temp;

else

temp = name;

intf->class_dev = class_device_create(usb_class, NULL,

MKDEV(USB_MAJOR, minor),

&intf->dev, "%s", temp);

if (IS_ERR(intf->class_dev)) {

spin_lock (&minor_lock);

usb_minors[intf->minor] = NULL;

spin_unlock (&minor_lock);

retval = PTR_ERR(intf->class_dev);

}

exit:

return retval;

}

EXPORT_SYMBOL(usb_register_dev);

void usb_deregister_dev(struct usb_interface *intf,

struct usb_class_driver *class_driver)

{

int minor_base = class_driver->minor_base;

char name[BUS_ID_SIZE];

#ifdef CONFIG_USB_DYNAMIC_MINORS

minor_base = 0;

#endif

if (intf->minor == -1)

return;

dbg ("removing %d minor", intf->minor);

spin_lock (&minor_lock);

usb_minors[intf->minor] = NULL;

spin_unlock (&minor_lock);

snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);

class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor));

intf->class_dev = NULL;

intf->minor = -1;

}

EXPORT_SYMBOL(usb_deregister_dev);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值