阅读:1302回复:0
为什么,我先插上USB,再加载驱动,就打不开设备,见源码
我的usb设备好怪,如果,我先插上USB设备,再加载驱动,就打不开设备,但是如果这时,我如果重新拔掉USB,然后插上,就能OPEN设备,而且一切其它程序允许成功。如果现在,再卸载驱动,然后加载,设备有打不开。
程序跟踪显示,probe()函数都正确,也能找到设备,建立控制通道连接。只有到了OPEN函数里的if (dev == NULL)就发现dev是空的,这是为什么呢?(注:没有使用Devfs系统)是在红帽子7.3下操作的。 static int open_mms500usb(struct inode * inode, struct file * file) { struct usb_mms500 *dev = NULL; int subminor; int retval = 0; dbg(__FUNCTION__); subminor = MINOR (inode->i_rdev) - MMS500USB_MINOR_BASE; if ((subminor < 0) || (subminor >= MAX_MMS500USB)) { return -ENODEV; } MOD_INC_USE_COUNT; /* lock our minor table and get our local data for this minor */ down (&minor_table_lock); dev = minor_table[subminor]; if (dev == NULL) { up (&minor_table_lock); MOD_DEC_USE_COUNT; return -ENODEV; } /* lock this device */ down (&dev->lock); /* unlock the minor table */ up (&minor_table_lock); /* increment our usage count for the driver */ ++dev->open_count; /* save our object in the file\'s private structure */ file->private_data = dev; /* unlock this device */ up (&dev->lock); info(\"mms500 usb device #%d opened.\", subminor); return retval; } static int close_mms500usb(struct inode * inode, struct file * file) { struct usb_mms500 *dev; int retval = 0; dev = (struct usb_mms500 *)file->private_data; if (dev == NULL) { dbg(__FUNCTION__ \" - object is NULL\"); return -ENODEV; } dbg(__FUNCTION__ \" - minor %d\", dev->minor); /* lock our minor table */ down (&minor_table_lock); /* lock our device */ down (&dev->lock); if (dev->open_count <= 0) { dbg(__FUNCTION__ \" - device not opened\"); retval = -ENODEV; goto exit_not_opened; } if (dev->dev == NULL) { /* the device was unplugged before the file was released */ up (&dev->lock); mms500_delete (dev); up (&minor_table_lock); MOD_DEC_USE_COUNT; return 0; } /* decrement our usage count for the device */ --dev->open_count; if (dev->open_count <= 0) { /* shutdown any bulk writes that might be going on */ usb_unlink_urb (dev->out_urb); usb_unlink_urb (dev->in_urb); dev->open_count = 0; } /* decrement our usage count for the module */ MOD_DEC_USE_COUNT; exit_not_opened: up (&dev->lock); up (&minor_table_lock); return retval; } static void * probe_mms500usb(struct usb_device* dev, unsigned int ifnum, const struct usb_device_id * id) { struct usb_mms500 * mms500_dev = NULL; struct usb_interface *interface; struct usb_interface_descriptor *iface_desc; struct usb_endpoint_descriptor *endpoint; int minor, i; char name[8]; int notify; info (__FUNCTION__); /* Check PID&VID */ if ( (dev->descriptor.idVendor != MMS500USB_VID) || (dev->descriptor.idProduct != MMS500USB_PID) ) { return NULL; } /* Lock minor table */ down(&minor_table_lock); /* Find an empty minor number. */ for ( minor = 0; minor < MAX_MMS500USB; minor++ ) { if ( minor_table[minor] == NULL ) break; } if ( minor >= MAX_MMS500USB ) { info (\"Too many mms devices plugged in, can not handle this device.\"); goto exit; } /* Allocate device */ mms500_dev = kmalloc( sizeof(struct usb_mms500), GFP_KERNEL ); if ( mms500_dev == NULL ) { err (\"Memory low.\"); goto exit; } memset((char*)mms500_dev, 0, sizeof(struct usb_mms500)); minor_table[minor] = mms500_dev; interface = &dev->actconfig->interface[ifnum]; mms500_dev->dev = dev; mms500_dev->interface = interface; mms500_dev->minor = minor; mms500_dev->in_size = IN_BUFFER_SIZE; mms500_dev->out_size = OUT_BUFFER_SIZE; init_MUTEX (&mms500_dev->lock); init_waitqueue_head (&mms500_dev->read_wait); init_waitqueue_head (&mms500_dev->write_wait); /* Check endpoints */ iface_desc = &interface->altsetting[0]; for ( i =0; i < iface_desc->bNumEndpoints; i++ ) { endpoint = &iface_desc->endpoint; if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) { /* we found a bulk in endpoint */ mms500_dev->in_endpoint = endpoint->bEndpointAddress; } if (((endpoint->bEndpointAddress & 0x80) == 0x00) && ((endpoint->bmAttributes & 3) == 0x02)) { /* we found a bulk out endpoint */ mms500_dev->out_endpoint = endpoint->bEndpointAddress; } } /* Found bulk in and bulk out endpoints ? */ if ( (mms500_dev->in_endpoint == 0) || (mms500_dev->out_endpoint == 0) ) { err (\"endpoint check error.\"); goto error; } info (\"Endpoint in = %d, Endpoint out = %d.\", mms500_dev->in_endpoint, mms500_dev->out_endpoint); /* Allocate buffer for bulk in and out */ mms500_dev->in_buf = kmalloc(mms500_dev->in_size, GFP_KERNEL); if ( mms500_dev->in_buf == NULL ) { err (\"memory low.\"); goto error; } mms500_dev->out_buf = kmalloc(mms500_dev->out_size, GFP_KERNEL); if ( mms500_dev->out_buf == NULL ) { err (\"memory low.\"); goto error; } mms500_dev->in_urb = usb_alloc_urb(0); if ( mms500_dev->in_urb == NULL ) { err (\"urb allocate fail.\"); goto error; } mms500_dev->out_urb = usb_alloc_urb(0); if ( mms500_dev->out_urb == NULL ) { err (\"urb allocate fail.\"); goto error; } FILL_BULK_URB ( mms500_dev->out_urb, mms500_dev->dev, usb_sndbulkpipe (mms500_dev->dev, mms500_dev->out_endpoint), mms500_dev->out_buf, 64, write_mms500usb_callback, mms500_dev ); FILL_BULK_URB ( mms500_dev->in_urb, mms500_dev->dev, usb_rcvbulkpipe (mms500_dev->dev, mms500_dev->in_endpoint), mms500_dev->in_buf, 64, read_mms500usb_callback, mms500_dev ); /* notify mms500 usb it\'s an new connect */ /* * bRequest = MMS500_VENDOR_CMD * bRequestType = ignore * wValue = MMS500USB_RECONNECT * wIndex = ignore */ notify = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MMS500_VENDOR_CMD, 0, MMS500USB_RECONNECT, 0, NULL, 0, HZ*5); if ( notify != 0 ) { err (\"mms500 usb reconnect command fail.\"); } info (\"mms500 usb reconnect command success.\"); mms500_dev->connectted = 1; /* if we have devfs , register devfs node */ sprintf(name, \"mms500.%d\", mms500_dev->minor); mms500_dev->devfs = devfs_register(usb_devfs_handle, name, DEVFS_FL_DEFAULT, USB_MAJOR, MMS500USB_MINOR_BASE + mms500_dev->minor, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ,/*| S_IROTH*/ &mms500usb_fops, NULL); dbg(\"usb_devfs_handle = %p\", usb_devfs_handle); if ( mms500_dev->devfs != NULL ) { info (\"devfs node register succeed, minor = %d.\", MMS500USB_MINOR_BASE + mms500_dev->minor); } else { info (\"devfs node register failed, maybe devfs not configured into the kernel.\"); } goto exit; error: mms500_delete(mms500_dev); mms500_dev = NULL; exit: up (&minor_table_lock); return mms500_dev; } |
|
最新喜欢:![]()
|