我正在为USB设备编写自己的字符驱动程序,需要使用ctrl传输进行简单写入并使用中断传输进行读取。我的设备有2个接口,其中对于零接口我可以获得中断端点,所以基本上我不需要处理包含批量ISCO的第二个接口,所以我在bInterfaceNumber时从探测器函数返回-ENODEV是1。以下是代码段
static int USBTestMode_Probe(struct usb_interface *interface, const struct usb_device_id *id)
{
if(interface->cur_altsetting->desc.bInterfaceNumber != 0)
{
return -ENODEV;
}
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_test_mode_dev * testModeDev = NULL;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int i, int_end_size;
int retval = -ENODEV;
TestModeclass.name = "testmode%d";
TestModeclass.fops = &USBTestModefops;
testModeDev = kzalloc(sizeof(struct usb_test_mode_dev),GFP_KERNEL);
strcpy(testModeDev->buffer , "mydata");
printk("size::%d\n", sizeof(struct usb_test_mode_dev));
printk("testModeDev size::%d\n", sizeof(testModeDev));
printk("name :%s\n",testModeDev->buffer);
if(testModeDev == NULL)
{
printk("No Memory ):");
goto exit;
}
testModeDev->udev = usb_get_dev(udev);
testModeDev->interface = interface;
iface_desc = interface->cur_altsetting;
testModeDev->int_in_endpoint = kzalloc(sizeof(struct usb_endpoint_descriptor),GFP_KERNEL);
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
== USB_DIR_IN)
&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_INT))
memcpy(testModeDev->int_in_endpoint , endpoint ,sizeof(endpoint));
}
if (! testModeDev->int_in_endpoint) {
printk("could not find interrupt in endpoint");
goto error;
}
printk("endpoint packetSize :%d\n",testModeDev->int_in_endpoint->wMaxPacketSize);
printk("endpoint value :%d\n",testModeDev->int_in_endpoint->bEndpointAddress);
int_end_size = le16_to_cpu(testModeDev->int_in_endpoint->wMaxPacketSize);
testModeDev->int_in_buffer = kzalloc(int_end_size, GFP_KERNEL);
printk("endpoint packetSize :%d\n",testModeDev->int_in_endpoint->wMaxPacketSize);
printk("endpoint value :%d\n",testModeDev->int_in_endpoint->bEndpointAddress);
if (! testModeDev->int_in_buffer) {
printk("could not allocate int_in_buffer");
retval = -ENOMEM;
goto error;
}
testModeDev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
if (! testModeDev->int_in_urb) {
printk("could not allocate int_in_urb");
retval = -ENOMEM;
goto error;
}
printk("endpoint packetSize :%d\n",testModeDev->int_in_endpoint->wMaxPacketSize);
printk("endpoint value :%d\n",testModeDev->int_in_endpoint->bEndpointAddress);
// Save our data pointer in this interface device.
usb_set_intfdata(interface, testModeDev);
printk("endpoint packetSize :%d\n",testModeDev->int_in_endpoint->wMaxPacketSize);
printk("endpoint value :%d\n",testModeDev->int_in_endpoint->bEndpointAddress);
// We can register the device now, as it is ready.
retval = usb_register_dev(interface, &TestModeclass);
if (retval) {
printk("not able to get a minor for this device.");
usb_set_intfdata(interface, NULL);
goto error;
}
testModeDev->minor = interface->minor;
printk("TestUSB now attached to /dev/TestMode%d\n",
interface->minor - 0);
error:
TestMode_delete(testModeDev);
exit:
return retval;
return 0;
}
当我试图在下面的open方法中访问探针中保存的usb_test_mode_dev数据时,我收到BUG:无法在0000000000000048处理内核NULL指针取消引用
static int TestMode_open(struct inode *inode, struct file *file)
{
struct usb_test_mode_dev *dev = NULL;
struct usb_interface *interface;
int subminor;
int retval = 0;
subminor = iminor(inode);
printk(" i came here %d\n" , subminor);
interface = usb_find_interface(&USBTestMode_driver, subminor);
printk("interface->cur_altsetting->desc.bInterfaceNumber : %d \n" ,interface->cur_altsetting->desc.bInterfaceNumber);
if (! interface) {
printk("can't find device for minor %d", subminor);
retval = -ENODEV;
return retval;
}
printk(" i came here .....1\n");
dev = usb_get_intfdata(interface);
printk("name :%s\n",dev->buffer);
if (! dev) {
retval = -ENODEV;
return retval;
}
printk("Dev size::%d\n", sizeof(*dev));
printk(" i came here .....2\n");
//dev->int_in_endpoint->bEndpointAddress = 129;
//dev->int_in_endpoint->wMaxPacketSize = 64;
if( dev->int_in_endpoint != NULL)
{
printk(" i came here .....8\n");
printk("endpoint value :%d\n",dev->int_in_endpoint->bEndpointAddress);
printk("endpoint value :%d\n",dev->int_in_endpoint->wMaxPacketSize);
}
printk(" i came here .....7\n");
if(!dev->int_in_endpoint->bEndpointAddress || !dev->int_in_endpoint->wMaxPacketSize )
return -1;
/* Initialize interrupt URB. */
usb_fill_int_urb(dev->int_in_urb, dev->udev,
usb_rcvintpipe(dev->udev,
dev->int_in_endpoint->bEndpointAddress),
dev->int_in_buffer,
le16_to_cpu(dev->int_in_endpoint->wMaxPacketSize),
TestMode_init_callback,
dev,
dev->int_in_endpoint->bInterval);
printk(" i came here .....3\n");
mb();
printk(" i came here .....6\n");
retval = usb_submit_urb(dev->int_in_urb, GFP_KERNEL);
if (retval) {
printk("submitting int urb failed (%d)", retval);
return retval;
}
printk(" i came here .....4\n");
/* Save our object in the file's private structure. */
file->private_data = dev;
printk(" i came here .....5\n");
return retval;
}
当我尝试访问dev-&gt; int_in_endpoint时模块崩溃,即使缓冲区继续为空。为什么保存在探针中的数据结构被覆盖。这是由于我的设备的多个接口。请帮我。如果您希望下面我的char设备的数据结构是代码。
struct usb_test_mode_dev {
struct usb_device *udev;
unsigned char *int_in_buffer;
struct usb_interface *interface;
struct usb_endpoint_descriptor *int_in_endpoint;
struct urb *int_in_urb;
unsigned char minor;
char buffer[20];
};
提前致谢。
答案 0 :(得分:0)
usb_set_intfdata(interface, testModeDev); is at wrong place , should be called before return in probe method