usb_bulk_msg 在全局缓冲区上失败,但在 kmalloc 缓冲区上工作

问题描述

我正在尝试在 Linux 下开发 USB 设备驱动程序。我创建了一个简单的 USB 驱动程序来通过批量端点发送和接收数据。代码如下:

#include <linux/init.h>   // Macros used to mark up functions e.g. __init __exit
#include <linux/module.h> // Core header for loading LKMs into the kernel
#include <linux/device.h> // Header to support the kernel Driver Model
#include <linux/kernel.h> // Contains types,macros,functions for the kernel
#include <linux/fs.h>     // Header for the Linux file system support
#include <linux/usb.h>
#include <linux/uaccess.h>

#define DEVICE_VID 0x0483
#define DEVICE_PID 0xff11

struct usbd_device
{
  struct usb_device *device;
  struct usb_class_driver class;
  struct usb_interface *interface;
  __u8 buffer[64];
  __u8 bulk_in_addr;
  __u8 bulk_out_addr;
};

static struct usbd_device usbd_dev;

static int usbd_open(struct inode *i,struct file *filp)
{
  return 0;
}

static int usbd_close(struct inode *i,struct file *filp)
{
  return 0;
}

static ssize_t usbd_read(struct file *filp,char *buff,size_t len,loff_t *off)
{
  int ret,cnt;
  memset(usbd_dev.buffer,64);
  ret = usb_bulk_msg(usbd_dev.device,usb_rcvbulkpipe(usbd_dev.device,usbd_dev.bulk_in_addr),usbd_dev.buffer,64,&cnt,1000);

  if (ret) {
    printk(KERN_ALERT "USBD BULK READ Failed!,ERR: %d\n",ret);
    return ret;
  }
  if (copy_to_user(buff,2)) {
    return -EFAULT;
  }
  printk(KERN_ALERT "USBD READ %s and %d bytes\n",cnt);
  printk(KERN_ALERT "USBD LOL\n");

  return cnt;
}

static ssize_t usbd_write(struct file *filp,const char *buff,cnt;

  if (copy_from_user(usbd_dev.buffer,buff,2))
    return -EFAULT;

  ret = usb_bulk_msg(usbd_dev.device,usb_sndbulkpipe(usbd_dev.device,usbd_dev.bulk_out_addr),1000);
  if (ret) {
    printk(KERN_ALERT "USBD BULK WRITE Failed!,ret);
    return ret;
  }

  printk(KERN_ALERT "USBD WROTE %s and %d bytes\n",cnt);
  return cnt;
}

static struct file_operations usbd_fops = {
    .owner = THIS_MODULE,.open = usbd_open,.release = usbd_close,.read = usbd_read,.write = usbd_write,};

const struct usb_device_id usbd_table[] = {
    { USB_DEVICE(DEVICE_VID,DEVICE_PID)},};

MODULE_DEVICE_TABLE(usb,usbd_table);

static int usbd_probe(struct usb_interface *interface,const struct usb_device_id *id)
{
  int i,ret;
  struct usb_host_interface *iface_desc;
  struct usb_endpoint_descriptor *ep;

  usbd_dev.device = usb_get_dev(interface_to_usbdev(interface));
  usbd_dev.interface = interface;
  usbd_dev.class.name = "usbd%d";
  usbd_dev.class.fops = &usbd_fops;

  iface_desc = interface->cur_altsetting;

  for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
    ep = &iface_desc->endpoint[i].desc;
    if (usb_endpoint_is_bulk_in(ep)) {
      usbd_dev.bulk_in_addr = ep->bEndpointAddress;
      printk(KERN_ALERT "found ep in at %d",usbd_dev.bulk_in_addr);
    }
    if (usb_endpoint_is_bulk_out(ep)) {
      usbd_dev.bulk_out_addr = ep->bEndpointAddress;
      printk(KERN_ALERT "found ep out at %d",usbd_dev.bulk_out_addr);
    }
  }

  if ((ret = usb_register_dev(interface,&usbd_dev.class)) < 0)
    printk(KERN_ALERT "USBD PROBE Failed!,CANNOT REGISTER DEVICE\n");
  else
    printk(KERN_ALERT "USBD PROBE SUCCESS! minor: %d\n",interface->minor);

  return ret;
}

static void usbd_disconnect(struct usb_interface *interface)
{
  usb_deregister_dev(interface,&usbd_dev.class);
  printk(KERN_ALERT "USBD disCONNECT SUCCESS!\n");
}

static struct usb_driver usbd = {
    .name = "usbd",.probe = usbd_probe,.disconnect = usbd_disconnect,.id_table = usbd_table,};

static int __init usbd_init(void)
{
  int result;

  result = usb_register(&usbd);
  if (result < 0) {
    printk(KERN_ALERT "error registering : usbd");
    return -1;
  }
  return 0;
}

static void __exit usbd_exit(void)
{
  usb_deregister(&usbd);
}

module_init(usbd_init);
module_exit(usbd_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ankit Sharma");
MODULE_DESCRIPTION("A simple linux usb driver");
MODULE_VERSION("0.1");

问题是我无法向 USB 设备发送或接收任何数据。 usb_bulk_msg() 成功返回,但 usbd_dev.buffer 中没有数据,尽管 cnt(字节读取变量)显示已读取 64 个字节。当我从静态全局缓冲区 (usbd_dev.buffer) 切换到通过 kmalloc() 动态分配的本地缓冲区时:

  int ret,cnt = 0;
  uint8_t *b;
  b = kzalloc(64,GFP_KERNEL);

  ret = usb_bulk_msg(usbd_dev.device,b,1000);
  if (ret) {
    printk(KERN_ALERT "USBD BULK READ Failed!,min(len,64)))
    return -EFAULT;
  printk(KERN_ALERT "USBD READ %s and %d bytes\n",cnt);
  kfree(b);

一切正常。为什么会这样?为什么我不能读入结构内部初始化的静态缓冲区?为什么我需要通过 kmalloc() 从堆动态分配内存?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)