tonycai
驱动牛犊
驱动牛犊
  • 注册日期2002-07-03
  • 最后登录2003-06-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1301回复:0

为什么,我先插上USB,再加载驱动,就打不开设备,见源码

楼主#
更多 发布于:2002-12-04 22:39
  我的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;

}





最新喜欢:

jeanyejeanye
www.micreation.com 亿新软件欢迎您
游客

返回顶部