⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb-mininurse.c

📁 Six objects here: The document you re reading & its Chinese version Set of "HWDesign" includes
💻 C
字号:
/* * USB Mini-Nurse Driver - 0.1 * * Copyright (C) 2004 Marco (Chopin_1998@Sina.com) * *      This program is free software; you can redistribute it and/or *      modify it under the terms of the GNU General Public License as *      published by the Free Software Foundation; either version 2 of *      the License, or (at your option) any later version. * * * This driver is just to drive Mini-Nurse, Just for Fun. * * Thanks to Linus, USBCORE guys, and all Open-Source World * * BUG: *      - Yes,I canNOT run on a SMP machine or even Sigle-CPU with preemptive kernel.  *  * TODO: *      - let it running on a SMP and Linux2.6 preemptive kernel *      - enhence it to use more feature of PDIUSBD12 (and of course it should be supported by MN's FIRMWARE) *      - add it with more kernel feature (like procfs and so on) * * History: * *  2004_05_26 - 0.1.0 - the first version *  2004_05_31 - 0.1.1 - the second version *                          - serval bugs fixed *                          - full DevFS supported */#include "usb-mininurse.h"#include "usb-mn-ioctls.h"static inline void mn_delete (struct usb_mn *dev)     /* when the driver is useless, free its resource */{  info("Driver of MN will be deleted!");  minor_table[dev->minor] = NULL;  kfree (dev);}static int mn_open (struct inode *inode, struct file *file){  struct usb_mn *dev = NULL;    /* another way to get the Major/Minor, as tranditional method U can read it from inode */  int dmajor,dminor;  devfs_get_maj_min (usb_devfs_handle, &dmajor, &dminor);  dev = minor_table[dminor-1];   //U SHOULD MINUS ONE HERE !!!  if (dev == NULL)    {      info("from mn_open(): device NULL?");      return -ENODEV;    }  ++(dev->open_count);  file->private_data = dev;  info("open Mini-Nurse device now");  return 0;}static int mn_release (struct inode *inode, struct file *file){  struct usb_mn *dev;  int retval = 0;  dev = (struct usb_mn *)file->private_data;  if (dev == NULL)    return -ENODEV;	/*	usb_control_msg(dev->udev,usb_sndctrlpipe(dev->udev,0),			    LEDoff,			    USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_ENDPOINT,			    0,LEDA,			    NULL,0,.1*HZ);	*/  if (dev->open_count <= 0) {    retval = -ENODEV;    goto exit_not_opened;  }  if (dev->udev == NULL) {    mn_delete (dev);    return 0;  }  --dev->open_count;  if (dev->open_count <= 0)    dev->open_count = 0; exit_not_opened:  return retval;}static int mn_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){  struct usb_mn *dev;  dev = (struct usb_mn *)file->private_data;  if (dev->udev == NULL)    return -ENODEV;  u16 LEDnum=(u16)arg;  info("from mn_ioctl: cmd=%d arg=%d",cmd,LEDnum);  switch (cmd) {    case MN_LEDon:      usb_control_msg(dev->udev,usb_sndctrlpipe(dev->udev,0),		      LEDon,		      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_ENDPOINT,		      0,LEDnum,		      NULL,0,.1*HZ);      break;    case MN_LEDoff:      usb_control_msg(dev->udev,usb_sndctrlpipe(dev->udev,0),		      LEDoff,		      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_ENDPOINT,		      0,LEDnum,		      NULL,0,.1*HZ);      break;  default:    /* new return number to mis-understand ioctl call */    return -ENOTTY;  }  return 0;}static void * mn_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id){  struct usb_mn *dev = NULL;  int minor;  char name[10]="MiniNurse";/* file name pleaced in /dev */  struct usb_interface *interface;		  if ((udev->descriptor.idVendor != USB_MN_VENDOR_ID) ||      (udev->descriptor.idProduct != USB_MN_PRODUCT_ID)) {    return NULL;  }  for (minor = 0; minor < MAX_DEVICES; ++minor) {    if (minor_table[minor] == NULL)      break;  }  if (minor >= MAX_DEVICES) {    info ("from mn_probe: Too many devices plugged in, can not handle this device.");    mn_delete (dev);    dev=NULL;  }  dev = kmalloc (sizeof(struct usb_mn), GFP_KERNEL);  if (dev == NULL) {    err ("from mn_probe: Out of memory");    mn_delete (dev);    dev=NULL;  }    memset (dev, 0x00, sizeof (*dev));  minor_table[minor] = dev;  interface = &udev->actconfig->interface[ifnum];  dev->udev = udev;  dev->interface = interface;  dev->devfs = devfs_register (NULL, name,			       DEVFS_FL_AUTO_DEVNUM, USB_MAJOR,USB_MN_MINOR_BASE + dev->minor,			       S_IFCHR | S_IRUSR | S_IWUSR | 			       S_IRGRP | S_IWGRP | S_IROTH, 			       &mn_fops, NULL);  usb_devfs_handle = dev->devfs;		  info("%d from mn_probe-->usb_control_msg",       usb_control_msg(udev,usb_sndctrlpipe(udev,0),		       LEDon,		       USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_ENDPOINT,		       0,LEDA,		       NULL,0,.1*HZ)       );  unsigned long j = jiffies + 1.25*HZ;  while (jiffies < j)    schedule();  info("%d from mn_probe-->usb_control_msg",       usb_control_msg(udev,usb_sndctrlpipe(udev,0),		       LEDoff,		       USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_ENDPOINT,		       0,LEDA,		       NULL,0,.1*HZ)       );    return dev;}static void mn_disconnect(struct usb_device *udev, void *ptr){  struct usb_mn *dev;  dev = (struct usb_mn *)ptr;  devfs_unregister(dev->devfs);  if (!dev->open_count)    mn_delete (dev);  else    dev->udev = NULL;  info("MN now disconnected");}static int usb_mn_init(void){  if (usb_register(&mn_driver)<0) {    err("from usb_mn_init: a error on usb_register");    return -1;  }  info(DRIVER_DESC " " DRIVER_VERSION);  return 0;}static void usb_mn_exit(void){  info("ByeBye. MN out of control now.");  usb_deregister(&mn_driver);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -