AlcapDAQ  1
Data Structures | Macros | Functions | Variables
CAENUSBdrvB.c File Reference
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/version.h>
#include <linux/smp_lock.h>
#include "CAENUSBdrvB.h"

Go to the source code of this file.

Data Structures

struct  v1718_usb_data
 

Macros

#define DRIVER_VERSION   "1.2"
 
#define DRIVER_AUTHOR   "CAEN Computing Division <support.computing@caen.it>"
 
#define DRIVER_DESC   "CAEN USB driver"
 
#define V1718_MINOR_BASE   178
 
#define NAK_TIMEOUT   (HZ)
 
#define IBUF_SIZE   0x10000 /* 64 kbytes */
 
#define OBUF_SIZE   0x10000 /* 64 kbytes */
 
#define MAX_DEVICES   16
 
#define VERSION(ver, rel, seq)   (((ver)<<16) | ((rel)<<8) | (seq))
 

Functions

static DECLARE_MUTEX (minor_table_mutex)
 
static void v1718_delete (struct v1718_usb_data *v1718)
 
static int open_v1718 (struct inode *inode, struct file *file)
 
static int close_v1718 (struct inode *inode, struct file *file)
 
static int ioctl_v1718 (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 
static ssize_t write_v1718 (struct file *file, const char *buffer, size_t count, loff_t *ppos)
 
static ssize_t read_v1718 (struct file *file, char *buffer, size_t count, loff_t *ppos)
 
static int probe_v1718 (struct usb_interface *intf, const struct usb_device_id *id)
 
static void disconnect_v1718 (struct usb_interface *intf)
 
 MODULE_DEVICE_TABLE (usb, v1718_table)
 
static int __init usb_v1718_init (void)
 
static void __exit usb_v1718_cleanup (void)
 
 module_init (usb_v1718_init)
 
 module_exit (usb_v1718_cleanup)
 
 MODULE_AUTHOR (DRIVER_AUTHOR)
 
 MODULE_DESCRIPTION (DRIVER_DESC)
 
 MODULE_LICENSE ("GPL")
 

Variables

static struct v1718_usb_dataminor_table [MAX_DEVICES]
 
static struct file_operations usb_v1718_fops
 
static struct usb_class_driver usb_v1718_class
 
static struct usb_device_id v1718_table []
 
static struct usb_driver v1718_driver
 

Macro Definition Documentation

#define DRIVER_AUTHOR   "CAEN Computing Division <support.computing@caen.it>"

Definition at line 42 of file CAENUSBdrvB.c.

#define DRIVER_DESC   "CAEN USB driver"

Definition at line 43 of file CAENUSBdrvB.c.

Referenced by usb_v1718_init().

#define DRIVER_VERSION   "1.2"

Definition at line 41 of file CAENUSBdrvB.c.

Referenced by ioctl_v1718(), and usb_v1718_init().

#define IBUF_SIZE   0x10000 /* 64 kbytes */

Definition at line 50 of file CAENUSBdrvB.c.

Referenced by probe_v1718(), and read_v1718().

#define MAX_DEVICES   16

Definition at line 56 of file CAENUSBdrvB.c.

Referenced by open_v1718(), probe_v1718(), and v1718_delete().

#define NAK_TIMEOUT   (HZ)

Definition at line 48 of file CAENUSBdrvB.c.

Referenced by read_v1718(), and write_v1718().

#define OBUF_SIZE   0x10000 /* 64 kbytes */

Definition at line 53 of file CAENUSBdrvB.c.

Referenced by probe_v1718(), and write_v1718().

#define V1718_MINOR_BASE   178

Definition at line 45 of file CAENUSBdrvB.c.

Referenced by open_v1718().

#define VERSION (   ver,
  rel,
  seq 
)    (((ver)<<16) | ((rel)<<8) | (seq))

Definition at line 62 of file CAENUSBdrvB.c.

Function Documentation

static int close_v1718 ( struct inode *  inode,
struct file file 
)
static

Definition at line 193 of file CAENUSBdrvB.c.

References v1718_usb_data::lock, v1718_usb_data::open_count, v1718_delete(), and v1718_usb_data::v1718_dev.

194 {
195  struct v1718_usb_data *v1718 = (struct v1718_usb_data *)file->private_data;
196  int retval = 0;
197  if( v1718 == NULL ) {
198  printk("Close: object is null\n");
199  return -ENODEV;
200  }
201  down(&minor_table_mutex);
202  down(&v1718->lock);
203 
204  if( v1718->open_count <= 0 ) {
205  printk("Device not opened\n");
206  retval = -ENODEV;
207  goto exit_not_opened;
208  }
209 
210  if( v1718->v1718_dev == NULL ) {
211  /* the device was unplugged before the file was released */
212  up(&v1718->lock);
213  v1718_delete(v1718);
214  up(&minor_table_mutex);
215  return 0;
216  }
217 
218  v1718->open_count--;
219 
220 exit_not_opened:
221  up(&(v1718->lock));
222  up(&minor_table_mutex);
223 
224  return retval;
225 }
static DECLARE_MUTEX ( minor_table_mutex  )
static
static void disconnect_v1718 ( struct usb_interface *  intf)
static

Definition at line 619 of file CAENUSBdrvB.c.

References v1718_usb_data::lock, v1718_usb_data::minor, v1718_usb_data::open_count, v1718_delete(), and v1718_usb_data::v1718_dev.

620 {
621  struct v1718_usb_data *v1718 = usb_get_intfdata (intf);
622 
623  int minor;
624 
625  down(&minor_table_mutex);
626  down(&(v1718->lock));
627 
628  minor = v1718->minor;
629 
630  usb_set_intfdata (intf, NULL);
631  if (v1718) {
632  usb_deregister_dev(intf, &usb_v1718_class);
633  if (v1718->open_count != 0) {
634  /* better let it finish - the release will do whats needed */
635  v1718->v1718_dev = NULL;
636  up(&(v1718->lock));
637  } else {
638  up(&(v1718->lock));
639  v1718_delete(v1718);
640  }
641  }
642 
643 
644  printk(KERN_INFO "CAEN #%d device disconnected\n", minor);
645 
646  up(&minor_table_mutex);
647 }
static int ioctl_v1718 ( struct inode *  inode,
struct file file,
unsigned int  cmd,
unsigned long  arg 
)
static

Definition at line 228 of file CAENUSBdrvB.c.

References DRIVER_VERSION, v1718_usb_data::lock, v1718_usb_data::present, v1718_rev_t::rev_buf, v1718_usb_data::v1718_dev, V1718_IOCTL_REBOOTB, V1718_IOCTL_REBOOTF, and V1718_IOCTL_REV.

230 {
231 
232 
233  int ret= 0;
234  struct v1718_usb_data *v1718;
235 
236  v1718 = (struct v1718_usb_data *)file->private_data;
237  down(&(v1718->lock));
238  /* Sanity check to make sure v1718 is connected, powered, etc */
239  if ( v1718 == NULL ||
240  v1718->present == 0 ||
241  v1718->v1718_dev == NULL )
242  {
243  up(&(v1718->lock));
244  return -ENOTTY;
245  }
246 
247  switch (cmd) {
248  case V1718_IOCTL_REV:
249  {
250  v1718_rev_t rev;
251  if( copy_from_user(&rev, (v1718_rev_t *)arg, sizeof(rev)) > 0 ) {
252  ret = -EFAULT;
253  break;
254  }
255  strcpy( rev.rev_buf, DRIVER_VERSION);
256  if( copy_to_user((v1718_rev_t *)arg, &rev, sizeof(rev)) > 0) {
257  ret = -EFAULT;
258  break;
259  }
260  }
261  break;
262  case V1718_IOCTL_REBOOTB:
263  ret = usb_control_msg(v1718->v1718_dev, usb_sndctrlpipe(v1718->v1718_dev,0),0xB0, 0x20,1, 0, NULL, 0, 1 * HZ);
264  ret |= usb_control_msg(v1718->v1718_dev, usb_sndctrlpipe(v1718->v1718_dev,0),0xB0, 0x20,0, 0, NULL, 0, 1 * HZ);
265  break;
266  case V1718_IOCTL_REBOOTF:
267  ret = usb_control_msg(v1718->v1718_dev, usb_sndctrlpipe(v1718->v1718_dev,0),0xB0, 0x20,3, 0, NULL, 0, 1 * HZ);
268  ret |= usb_control_msg(v1718->v1718_dev, usb_sndctrlpipe(v1718->v1718_dev,0),0xB0, 0x20,2, 0, NULL, 0, 1 * HZ);
269  break;
270  default:
271  ret= -ENOTTY;
272  break;
273  }
274  up(&(v1718->lock));
275  return ret;
276 }
MODULE_AUTHOR ( DRIVER_AUTHOR  )
MODULE_DESCRIPTION ( DRIVER_DESC  )
MODULE_DEVICE_TABLE ( usb  ,
v1718_table   
)
module_exit ( usb_v1718_cleanup  )
module_init ( usb_v1718_init  )
MODULE_LICENSE ( "GPL"  )
static int open_v1718 ( struct inode *  inode,
struct file file 
)
static

Definition at line 153 of file CAENUSBdrvB.c.

References v1718_usb_data::lock, MAX_DEVICES, v1718_usb_data::minor, v1718_usb_data::open_count, V1718_MINOR_BASE, and v1718_usb_data::wait_q.

154 {
155  struct v1718_usb_data *v1718 = NULL;
156  int subminor;
157 
158 #ifndef CONFIG_USB_DYNAMIC_MINORS
159  subminor = MINOR(inode->i_rdev) - V1718_MINOR_BASE;
160 #else
161  for (subminor=0; subminor<MAX_DEVICES; subminor++) if (MINOR(inode->i_rdev) == minor_table[subminor]->minor) break;
162 #endif
163 
164  if( (subminor < 0) || (subminor > MAX_DEVICES) )
165  return -ENODEV;
166 
167  down(&minor_table_mutex);
168 
169  v1718 = minor_table[subminor];
170  if( v1718 == NULL ) {
171  up(&minor_table_mutex);
172  return -ENODEV;
173  }
174 
175  down(&v1718->lock);
176 
177  up(&minor_table_mutex);
178 
179  v1718->open_count++;
180 
181  init_waitqueue_head(&v1718->wait_q);
182 
183 
184 #if LINUX_VERSION_CODE >= VERSION(2,6,11)
185  mutex_init(&v1718->ioctl_lock);
186 #endif
187  file->private_data = v1718;
188  up(&v1718->lock);
189 
190  return 0;
191 }
static int probe_v1718 ( struct usb_interface *  intf,
const struct usb_device_id *  id 
)
static

Definition at line 534 of file CAENUSBdrvB.c.

References dev, v1718_usb_data::ibuf, IBUF_SIZE, v1718_usb_data::lock, MAX_DEVICES, v1718_usb_data::minor, v1718_usb_data::obuf, OBUF_SIZE, v1718_usb_data::present, v1718_delete(), and v1718_usb_data::v1718_dev.

536 {
537  struct usb_device *dev = interface_to_usbdev(intf);
538  int retval= 0;
539  struct v1718_usb_data *v1718 = NULL;
540 // Rev 0.2
541 // char name[12];
542  int minor;
543  switch(id->idProduct) {
544  case 0x0000:
545  printk(KERN_INFO "CAEN Desktop Waveform Digitizers Carrier found at address %d\n", dev->devnum);
546  break;
547  case 0x0001:
548  printk(KERN_INFO "CAEN NIM Waveform Digitizers Carrier found at address %d\n", dev->devnum);
549  break;
550  case 0x1002:
551  printk(KERN_INFO "CAEN V1718 found at address %d\n", dev->devnum);
552  break;
553  default:
554  printk(KERN_INFO "CAEN V1718 found at address %d\n", dev->devnum);
555  break;
556  }
557  down(&minor_table_mutex);
558  for( minor = 0; minor < MAX_DEVICES; ++minor ) {
559  if( minor_table[minor] == NULL )
560  break;
561  }
562  if( minor >= MAX_DEVICES ) {
563  printk(KERN_INFO "Too many devices\n");
564  goto exit;
565  }
566 
567  v1718 = kmalloc(sizeof(struct v1718_usb_data), GFP_KERNEL);
568  if (v1718 == NULL) {
569  printk("Out of memory\n");
570  goto exit;
571  }
572  memset(v1718, 0x00, sizeof(*v1718));
573  minor_table[minor] = v1718;
574 
575  if( usb_register_dev(intf, &usb_v1718_class))
576  {
577  printk("probe: Not able to get a minor for this device.\n");
578  goto error;
579  }
580 #ifdef CONFIG_USB_DYNAMIC_MINORS
581  minor = intf->minor;
582 #endif
583  v1718->present = 1;
584  v1718->v1718_dev = dev;
585  v1718->minor = minor;
586 
587  if (!(v1718->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
588  printk("probe: Not enough memory for the output buffer\n");
589  goto error;
590  }
591  dbg("probe: obuf address:%p", v1718->obuf);
592 
593  if (!(v1718->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
594  printk("probe: Not enough memory for the input buffer\n");
595  goto error;
596  }
597  dbg("probe: ibuf address:%p", v1718->ibuf);
598 
599  usb_set_intfdata (intf, v1718);
600 #if LINUX_VERSION_CODE <= VERSION(2,6,32)
601  init_MUTEX(&(v1718->lock));
602 #else
603  sema_init(&(v1718->lock),1);
604 #endif
605  goto exit;
606 
607 error:
608  usb_deregister_dev(intf, &usb_v1718_class);
609  retval= -ENOMEM;
610  v1718_delete(v1718);
611  v1718 = NULL;
612 
613 exit:
614  up(&minor_table_mutex);
615  return retval;
616 
617 }
static ssize_t read_v1718 ( struct file file,
char *  buffer,
size_t  count,
loff_t *  ppos 
)
static

Definition at line 397 of file CAENUSBdrvB.c.

References v1718_usb_data::ibuf, IBUF_SIZE, v1718_usb_data::lock, NAK_TIMEOUT, v1718_usb_data::present, v1718_usb_data::v1718_dev, and v1718_usb_data::wait_q.

398 {
399  struct v1718_usb_data *v1718;
400  ssize_t read_count;
401  unsigned int partial;
402  int this_read;
403  int result;
404  int maxretry = 1;
405  char *ibuf;
406 
407  v1718 = (struct v1718_usb_data *)file->private_data;
408 
409  down(&(v1718->lock));
410  /* Sanity check to make sure v1718 is connected, powered, etc */
411  if ( v1718 == NULL ||
412  v1718->present == 0 ||
413  v1718->v1718_dev == NULL )
414  {
415  up(&(v1718->lock));
416  return -ENODEV;
417  }
418 
419  ibuf = v1718->ibuf;
420 
421  read_count = 0;
422 
423  while (count > 0) {
424 
425  if (!v1718->v1718_dev) {
426  up(&(v1718->lock));
427  return -ENODEV;
428  }
429  this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
430 
431  result = usb_bulk_msg(v1718->v1718_dev,
432  usb_rcvbulkpipe(v1718->v1718_dev, 6),
433  ibuf, this_read, &partial,
434  (int) (HZ * 1));
435 
436  dbg("read stats: result:%d this_read:%u partial:%u",
437  result, this_read, partial);
438  if (partial) {
439  count = this_read = partial;
440  } else {
441  switch( result){
442  case USB_ST_BUFFERUNDERRUN:
443  printk( "DBG read_v1718 USB_ST_BUFFERUNDERRUN ...\n" );
444  usb_clear_halt( v1718->v1718_dev, 6);
445  up(&(v1718->lock));
446  return (0);
447  case USB_ST_TIMEOUT:
448  case 15:
449  if (!maxretry--) {
450  up(&(v1718->lock));
451  printk("read: maxretry timeout\n");
452  return -ETIME;
453  }
454 
455  wait_event_interruptible_timeout(v1718-> wait_q,1,NAK_TIMEOUT);
456  this_read= 0;
457  break;
458  case USB_ST_DATAOVERRUN:
459  {
460  int count_retry= 100;
461  do {
462  printk( "DATAOVERRUN\n");
463  usb_clear_halt( v1718->v1718_dev, 6);
464  if( usb_bulk_msg(v1718->v1718_dev,
465  usb_rcvbulkpipe(v1718->v1718_dev, 6),
466  ibuf, IBUF_SIZE, &partial,
467  (int) (HZ * 1))!= USB_ST_DATAOVERRUN){
468  break;
469  }
470  } while( count_retry--);
471  }
472  up(&(v1718->lock));
473  return -EIO;
474  case USB_ST_SHORT_PACKET:
475  case USB_ST_PARTIAL_ERROR:
476  case USB_ST_URB_KILLED:
477  case USB_ST_URB_PENDING:
478  case USB_ST_REMOVED:
479  case USB_ST_CRC:
480  case USB_ST_BITSTUFF:
481  case USB_ST_BUFFEROVERRUN:
482  case USB_ST_NOTSUPPORTED:
483  case USB_ST_BANDWIDTH_ERROR:
484  case USB_ST_URB_INVALID_ERROR:
485  case USB_ST_URB_REQUEST_ERROR:
486  case USB_ST_STALL:
487  default:
488  usb_clear_halt( v1718->v1718_dev, 6);
489  up(&(v1718->lock));
490  printk("Read Whoops - result:0x%08x partial:%u this_read:%u\n",
491  result, partial, this_read);
492  return -EIO;
493  }
494  }
495  if (this_read) {
496  if (copy_to_user(buffer, ibuf, this_read)) {
497  up(&(v1718->lock));
498  return -EFAULT;
499  }
500  count -= this_read;
501  read_count += this_read;
502  buffer += this_read;
503  }
504  }
505  up(&(v1718->lock));
506  return read_count;
507 }
static void __exit usb_v1718_cleanup ( void  )
static

Definition at line 679 of file CAENUSBdrvB.c.

681 {
682  usb_deregister(&v1718_driver);
683 }
static int __init usb_v1718_init ( void  )
static

Definition at line 669 of file CAENUSBdrvB.c.

References DRIVER_DESC, and DRIVER_VERSION.

671 {
672  if (usb_register(&v1718_driver) < 0)
673  return -1;
674  printk(DRIVER_DESC " version " DRIVER_VERSION "\n");
675 
676  return 0;
677 }
static void v1718_delete ( struct v1718_usb_data v1718)
static

Definition at line 132 of file CAENUSBdrvB.c.

References i, v1718_usb_data::ibuf, MAX_DEVICES, v1718_usb_data::minor, and v1718_usb_data::obuf.

Referenced by close_v1718(), disconnect_v1718(), and probe_v1718().

133 {
134 #ifndef CONFIG_USB_DYNAMIC_MINORS
135  minor_table[v1718->minor] = NULL;
136 #else
137  int i = 0;
138  for (; i < MAX_DEVICES; i++) if (v1718->minor == minor_table[i]->minor) break;
139  if (i < MAX_DEVICES) minor_table[i] = NULL;
140 #endif
141  if( v1718->ibuf != NULL )
142  kfree(v1718->ibuf);
143  if( v1718->obuf != NULL )
144  kfree(v1718->obuf);
145  kfree(v1718);
146 }
static ssize_t write_v1718 ( struct file file,
const char *  buffer,
size_t  count,
loff_t *  ppos 
)
static

Definition at line 310 of file CAENUSBdrvB.c.

References v1718_usb_data::lock, NAK_TIMEOUT, v1718_usb_data::obuf, OBUF_SIZE, v1718_usb_data::present, v1718_usb_data::v1718_dev, and v1718_usb_data::wait_q.

312 {
313  struct v1718_usb_data *v1718;
314 
315  unsigned long copy_size;
316  unsigned long bytes_written = 0;
317  unsigned int partial;
318 
319  int result = 0;
320  int maxretry;
321  int errn = 0;
322 
323  v1718 = (struct v1718_usb_data *)file->private_data;
324 
325  down(&(v1718->lock));
326  /* Sanity check to make sure v1718 is connected, powered, etc */
327  if ( v1718 == NULL ||
328  v1718->present == 0 ||
329  v1718->v1718_dev == NULL )
330  {
331  up(&(v1718->lock));
332  return -ENODEV;
333  }
334 
335  do {
336  unsigned long thistime;
337  char *obuf = v1718->obuf;
338 
339  thistime = copy_size =
340  (count >= OBUF_SIZE) ? OBUF_SIZE : count;
341  if (copy_from_user(v1718->obuf, buffer, copy_size)) {
342  errn = -EFAULT;
343  goto error;
344  }
345  maxretry = 1;
346  while (thistime) {
347  if (!v1718->v1718_dev) {
348  errn = -ENODEV;
349  goto error;
350  }
351  if (signal_pending(current)) {
352  up(&(v1718->lock));
353  return bytes_written ? bytes_written : -EINTR;
354  }
355 
356  result = usb_bulk_msg(v1718->v1718_dev,
357  usb_sndbulkpipe(v1718->v1718_dev, 2),
358  obuf, thistime, &partial, 1 * HZ); // TEMP - 1 sec basta?
359 
360  dbg("write stats: result:%d thistime:%lu partial:%u",
361  result, thistime, partial);
362 
363  if (result == USB_ST_TIMEOUT) {
364  if (!maxretry--) {
365  errn = -ETIME;
366  goto error;
367  }
368 
369  wait_event_interruptible_timeout(v1718-> wait_q,(result == USB_ST_TIMEOUT),NAK_TIMEOUT);
370  continue;
371  } else if (!result && partial) {
372  obuf += partial;
373  thistime -= partial;
374  } else
375  break;
376  };
377  if (result) {
378  printk("Write Whoops - %x\n", result);
379  errn = -EIO;
380  goto error;
381  }
382  bytes_written += copy_size;
383  count -= copy_size;
384  buffer += copy_size;
385  } while (count > 0);
386 
387  up(&(v1718->lock));
388 
389  return bytes_written ? bytes_written : -EIO;
390 
391 error:
392  up(&(v1718->lock));
393  return errn;
394 }

Variable Documentation

struct v1718_usb_data* minor_table[MAX_DEVICES]
static

Definition at line 123 of file CAENUSBdrvB.c.

struct usb_class_driver usb_v1718_class
static
Initial value:
= {
.name = "usb/v1718_%d",
.fops = &usb_v1718_fops ,
.mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ,
.minor_base = V1718_MINOR_BASE ,
}

Definition at line 525 of file CAENUSBdrvB.c.

struct file_operations usb_v1718_fops
static
Initial value:
= {
owner: THIS_MODULE,
read: read_v1718,
write: write_v1718,
ioctl: ioctl_v1718,
open: open_v1718,
release: close_v1718,
}

Definition at line 510 of file CAENUSBdrvB.c.

struct usb_driver v1718_driver
static
Initial value:
= {
owner: THIS_MODULE,
name: "v1718",
disconnect: disconnect_v1718,
id_table: v1718_table,
}

Definition at line 659 of file CAENUSBdrvB.c.

struct usb_device_id v1718_table[]
static
Initial value:
= {
{ USB_DEVICE(0x0547, 0x1002) },
{ USB_DEVICE(0x21e1, 0x0000) },
{ USB_DEVICE(0x21e1, 0x0001) },
{ }
}

Definition at line 649 of file CAENUSBdrvB.c.