170 #define EXPORT_SYMTAB 183 #include <linux/termios.h> 184 #include <linux/pci.h> 187 #include <linux/devfs_fs_kernel.h> 190 #define MBG_COPYRIGHT "(c) Meinberg 2001-" MBG_CURRENT_COPYRIGHT_YEAR_STR 192 #define MBG_DRVR_NAME "mbgclock" 194 #if !defined( MBGCLOCK_MAX_DEVS ) 195 #define MBGCLOCK_MAX_DEVS 20 199 #if !defined( DEBUG_IRQ_LATENCY ) 200 #if ( defined( DEBUG ) ) 201 #define DEBUG_IRQ_LATENCY 0 203 #define DEBUG_IRQ_LATENCY 0 207 #if !defined( DEBUG_IRQ_TIMING ) 208 #if ( defined( DEBUG ) ) 209 #define DEBUG_IRQ_TIMING 0 211 #define DEBUG_IRQ_TIMING 0 215 #if !defined( DEBUG_SYS_IRQS ) 216 #if ( defined( DEBUG ) ) 217 #define DEBUG_SYS_IRQS 0 219 #define DEBUG_SYS_IRQS 0 224 #if !defined( OMIT_PRIV_CHECKING ) 225 #define OMIT_PRIV_CHECKING 0 245 #endif // USE_DEBUG_PORT 263 MODULE_AUTHOR(
"Martin Burnicki <martin.burnicki@meinberg.de>" );
264 MODULE_DESCRIPTION(
"Driver for Meinberg plug-in and USB radio clocks." );
265 #ifdef MODULE_VERSION 268 #ifdef MODULE_LICENSE 269 MODULE_LICENSE(
"GPL" );
271 MODULE_SUPPORTED_DEVICE(
"mbgclock" );
273 #if defined( module_param_array ) 275 #if defined( __MODULE_PARM_TYPE ) 276 module_param_array(
io,
int, &n_io, 0444 );
278 module_param_array(
io,
int, n_io, 0444 );
280 #elif defined( MODULE_PARM ) 283 MODULE_PARM_DESC(
io,
"port address(es) of ISA card(s)" );
285 #if defined( module_param_array ) 287 #if defined( __MODULE_PARM_TYPE ) 288 module_param_array(
irq,
int, &n_irq, 0444 );
290 module_param_array(
irq,
int, n_irq, 0444 );
292 #elif defined( MODULE_PARM ) 295 MODULE_PARM_DESC(
irq,
"IRQ line(s) used by ISA card(s)" );
297 #if defined( module_param ) 298 module_param(
major,
int, S_IRUGO );
299 module_param(
minor,
int, S_IRUGO );
300 module_param(
max_devs,
int, S_IRUGO );
301 #elif defined( MODULE_PARM ) 302 MODULE_PARM(
major,
"i" );
303 MODULE_PARM(
minor,
"i" );
306 MODULE_PARM_DESC(
major,
"major device number, dynamic by default" );
307 MODULE_PARM_DESC(
minor,
"first minor device number, dynamic by default" );
308 MODULE_PARM_DESC(
max_devs,
"max number of supported devices" );
311 #if defined( module_param ) 313 #elif defined( MODULE_PARM ) 316 MODULE_PARM_DESC(
pretend_sync,
"pretend to NTP to be always sync'ed" );
319 #if defined( module_param ) 322 #elif defined( MODULE_PARM ) 326 MODULE_PARM_DESC(
force_io_access,
"force I/O port access even if a device supports memory mapped access." );
327 MODULE_PARM_DESC(
force_mm16_access,
"force 16 bit memory mapped access for devices which support this." );
331 #if defined( module_param ) 332 module_param( debug_msg_sleep,
int, 0444 );
333 #elif defined( MODULE_PARM ) 334 MODULE_PARM( debug_msg_sleep,
"i" );
336 MODULE_PARM_DESC( debug_msg_sleep,
"debug only, msleep by this amount of ms after each message." );
340 #if defined( module_param ) 341 module_param(
debug,
int, 0444 );
342 #elif defined( MODULE_PARM ) 343 MODULE_PARM(
debug,
"i" );
345 MODULE_PARM_DESC(
debug,
"debug level, only if compiled with DEBUG" );
357 #define mbgclock_init_module init_module 358 #define mbgclock_cleanup_module cleanup_module 363 #define DRV_NAME MBG_DRVR_NAME 365 #define MBG_SIZE_TLG 33 367 #define _min( _a, _b ) ( ( (_b) < (_a) ) ? (_b) : (_a) ) 369 #define CYCLIC_TIMEOUT ( (ulong) 2 * HZ ) // 2 seconds 372 #define _kill_fasync( _fa, _sig, _band ) \ 373 kill_fasync( _fa, _sig, _band ) 375 #define _kill_fasync( _fa, _sig, _band ) \ 376 kill_fasync( *(_fa), _sig, _band ) 378 #define _kill_fasync( _fa, _sig, _band ) \ 379 kill_fasync( *(_fa), _sig ) 394 #if !defined( DEBUG_HW_LPT ) 395 #define DEBUG_HW_LPT 0 399 static spinlock_t hwdbg_lock = SPIN_LOCK_UNLOCKED;
401 #define MBG_BIT_OPEN 0x03 402 #define MBG_BIT_RELEASE 0x01 403 #define MBG_BIT_IRQ 0x04 404 #define MBG_BIT_TEST 0x08 407 #define _mbg_dbg_hw_lpt_vars \ 408 unsigned long hwdbg_flags; 410 #define _mbg_dbg_hw_lpt_set_bit( _b ) \ 412 spin_lock_irqsave( &hwdbg_lock, hwdbg_flags ); \ 413 _mbg_dbg_set_bit( pddev, _b ); \ 414 spin_unlock_irqrestore( &hwdbg_lock, hwdbg_flags ); \ 417 #define _mbg_dbg_hw_lpt_clr_bit( _b ) \ 419 spin_lock_irqsave( &hwdbg_lock, hwdbg_flags ); \ 420 _mbg_dbg_clr_bit( pddev, _b ); \ 421 spin_unlock_irqrestore( &hwdbg_lock, hwdbg_flags ); \ 426 #define _mbg_dbg_hw_lpt_vars 427 #define _mbg_dbg_hw_lpt_set_bit( _b ); 428 #define _mbg_dbg_hw_lpt_clr_bit( _b ); 434 #if _PCPS_HAVE_LINUX_CLASS 435 static char mbgclock_class_name[] =
"mbgclock";
436 static char mbg_clk_dev_node_fmt[] =
"mbgclock%d";
438 #if _PCPS_HAVE_LINUX_CLASS_CREATE 439 static struct class *mbgclock_class;
440 #elif _PCPS_HAVE_LINUX_CLASS_SIMPLE 441 static struct class_simple *mbgclock_class;
446 #if DEBUG_IRQ_LATENCY 447 static unsigned long long tsc_irq_1;
448 static unsigned long long tsc_irq_2;
449 static unsigned long long tsc_usb_1;
450 static unsigned long long tsc_usb_2;
458 void list_system_irqs(
void )
461 struct irq_desc *desc;
468 for_each_irq_desc( i, desc )
474 i, (
u32) desc->status, (
u32) desc->chip, (
u32) desc->handle_irq );
482 #if _PCPS_USE_LINUX_KTHREAD 484 #define _usb_read_thread_should_stop() \ 485 kthread_should_stop() 487 #define _usb_read_thread_exit( _pddev, _v ) \ 490 #define _usb_read_thread_started( _pddev ) \ 491 ( (_pddev)->usb_read_thread != NULL ) 493 #define _usb_read_thread_start( _fnc, _pddev ) \ 494 (_pddev)->usb_read_thread = kthread_run( (_fnc), (_pddev), \ 495 "%s%d", driver_name, MINOR( (_pddev)->lx_dev ) ) 497 #define _usb_read_thread_failed_to_start( _pddev ) \ 498 ( IS_ERR( (_pddev)->usb_read_thread ) ) 500 #define _usb_read_thread_set_unused( _pddev ) \ 501 (_pddev)->usb_read_thread = NULL; 503 #define _usb_read_thread_stop( _pddev ) \ 504 kthread_stop( (_pddev)->usb_read_thread ) 507 #define _usb_read_thread_daemonize( _pddev ) \ 512 #define _usb_read_thread_should_stop() \ 513 signal_pending( current ) 515 #define _usb_read_thread_exit( _pddev, _v ) \ 516 complete_and_exit( &pddev->usb_read_thread.exit, (_v) ) 518 #define _usb_read_thread_started( _pddev ) \ 519 ( (_pddev)->usb_read_thread.pid != 0 ) 521 #define _usb_read_thread_start( _fnc, _pddev ) \ 522 init_completion( &(_pddev)->usb_read_thread.exit ); \ 523 (_pddev)->usb_read_thread.pid = kernel_thread( (_fnc), (_pddev), CLONE_KERNEL ); 525 #define _usb_read_thread_failed_to_start( _pddev ) \ 526 ( (_pddev)->usb_read_thread.pid == 0 ) 528 #define _usb_read_thread_set_unused( _pddev ) \ 529 (_pddev)->usb_read_thread.pid = 0; 531 #define _usb_read_thread_stop( _pddev ) \ 532 kill_proc( (_pddev)->usb_read_thread.pid, SIGKILL, 1 ); \ 533 wait_for_completion( &(_pddev)->usb_read_thread.exit ) 535 #define _usb_read_thread_daemonize( _pddev ) \ 536 snprintf( (_pddev)->usb_read_thread.name, sizeof( (_pddev)->usb_read_thread.name ), \ 537 "%s%d", driver_name, MINOR( (_pddev)->lx_dev ) ); \ 538 daemonize( (_pddev)->usb_read_thread.name ); \ 539 allow_signal( SIGKILL ) 569 if ( ddev_list == NULL )
596 if ( minor == MINOR( (*ppddev)->lx_dev ) )
656 if ( *ppddev == pddev )
681 if ( *ppddev == NULL )
707 scnprintf( s, max_len,
"%cD:%02i.%02i.%02i;T:%i;U:%02i.%02i.%02i;%c%c%c%c%c",
728 #if REQUEST_IRQ_WO_REGS 736 int curr_access_in_progress;
737 #if defined( IRQ_RETVAL ) 741 unsigned long prv_jiffies_at_irq;
762 spin_lock_irqsave( &pddev->irq_lock, flags );
764 curr_access_in_progress = atomic_read( &pddev->access_in_progress );
767 prv_jiffies_at_irq = pddev->jiffies_at_irq;
769 pddev->jiffies_at_irq =
jiffies;
771 #if DEBUG_IRQ_LATENCY 772 rdtscll( tsc_irq_1 );
775 if ( !curr_access_in_progress )
778 #if DEBUG_IRQ_LATENCY 779 rdtscll( tsc_irq_2 );
785 if ( !curr_access_in_progress )
789 atomic_set( &pddev->data_avail, 1 );
791 wake_up_interruptible( &pddev->wait_queue );
793 if ( pddev->fasyncptr )
798 spin_unlock_irqrestore( &pddev->irq_lock, flags );
805 if ( !curr_access_in_progress )
814 info =
"** access in progress";
815 rc = curr_access_in_progress;
820 (
long) pddev->jiffies_at_irq - (
long) prv_jiffies_at_irq,
826 #if defined( IRQ_RETVAL ) 833 #if defined( IRQ_RETVAL ) 852 spin_lock_irqsave( &pddev->irq_lock, *p_flags );
865 _up_pddev( &pddev->sem_usb_cyclic,
"sem_usb_cyclic", fnc_name, pddev );
868 spin_unlock_irqrestore( &pddev->irq_lock, *p_flags );
882 int mbgdrvr_read_usb_cyclic(
void *p )
887 MBGUSB_TIMEOUT_SEND, MBGUSB_TIMEOUT_RECEIVE,
888 MBGUSB_TIMEOUT_RECEIVE_CYCLIC, HZ );
913 rc = _pcps_direct_usb_read_var_cyclic( pddev, &pddev->t_cyc );
919 #if ( 1 && defined( DEBUG ) ) // TODO DEBUG_CYCLIC 936 if ( rc !=
sizeof( pddev->t_cyc ) )
944 #if DEBUG_IRQ_LATENCY 945 rdtscll( tsc_usb_1 );
951 #if DEBUG_IRQ_LATENCY 952 rdtscll( tsc_usb_2 );
956 pddev->
t = pddev->t_cyc;
959 _up_pddev( &pddev->sem_usb_cyclic,
"sem_usb_cyclic", __func__, pddev );
990 rc = _pcps_direct_usb_write_var( pddev, &pddev->
cmd_info.
cmd );
992 _up( &pddev->
dev_mutex,
"dev_mutex",
"ctrl_usb_cyclic", pddev );
1001 #endif // _PCPS_USE_USB 1042 free_irq( irq_num, pddev );
1077 usb_reset_device( pddev->udev );
1110 unsigned long flags = 0;
1128 #if defined( IRQF_DISABLED ) 1129 flags |= IRQF_DISABLED;
1130 #elif defined( SA_INTERRUPT ) 1131 flags |= SA_INTERRUPT;
1141 #if defined( IRQF_SHARED ) 1142 flags |= IRQF_SHARED;
1143 #elif defined( SA_SHIRQ ) 1172 #if DEBUG_IRQ_TIMING 1175 void report_irq_timing(
int lvl,
const PCPS_DDEV *pddev,
1176 unsigned long jiffies_now,
1177 unsigned long jiffies_at_irq,
1178 long delta_jiffies )
1183 #endif // DEBUG_IRQ_TIMING 1190 unsigned int poll_retval = 0;
1196 poll_retval = POLLERR | POLLHUP;
1205 poll_retval = POLLIN | POLLRDNORM;
1208 unsigned long flags = 0;
1209 unsigned long jiffies_now =
jiffies;
1210 unsigned long jiffies_at_irq;
1214 return -ERESTARTSYS;
1220 delta_jiffies = (long) jiffies_now - (
long) jiffies_at_irq;
1227 jiffies_now, jiffies_at_irq,
1230 #if DEBUG_IRQ_TIMING 1231 report_irq_timing(
MBG_LOG_DEBUG, pddev, jiffies_now, jiffies_at_irq, delta_jiffies );
1238 #if DEBUG_IRQ_TIMING 1241 jiffies_now, jiffies_at_irq,
1270 sys_rc = fasync_helper( fd, filp, on, &pddev->
fasyncptr );
1280 #if FLUSH_WITH_LOCK_OWNER_ID 1306 int minor = iminor( inode );
1323 retval = -ERESTARTSYS;
1329 if ( ppddev == NULL )
1334 if ( pddev == NULL )
1341 filp->private_data = ppddev;
1346 filp, atomic_read( &pddev->
open_count ), pddev );
1348 #if _PCPS_MUST_UPDATE_USE_COUNT 1352 goto out_up_sem_fops;
1386 retval = -ERESTARTSYS;
1392 pddev = *( (
PCPS_DDEV **) filp->private_data );
1394 if ( pddev == NULL )
1397 filp, iminor( inode ) );
1399 goto out_up_sem_fops;
1403 filp, iminor( inode ) );
1405 if ( atomic_dec_and_test( &pddev->
open_count ) )
1410 filp, iminor( inode ),
1417 filp, iminor( inode ),
1426 filp, iminor( inode ), atomic_read( &pddev->
open_count ),
1429 #if _PCPS_MUST_UPDATE_USE_COUNT 1436 filp, iminor( inode ));
1437 fasync_helper( -1, filp, 0, &pddev->
fasyncptr );
1453 #if DEBUG_IRQ_LATENCY 1458 return (
long) ( delta_cyc / cpu_khz / 1000 );
1468 size_t count, loff_t *ppos )
1471 unsigned long flags = 0;
1475 ssize_t sys_rc =
mbgdrvr_get_pddev( &pddev, filp, ( filp->f_flags & O_NONBLOCK ) ?
1476 "read (non-blocking)" :
"read (blocking)" );
1483 if ( atomic_read( &pddev->
open_count ) == 0 )
1492 if ( ppos != &filp->f_pos )
1501 if ( buffer == NULL )
1510 if ( count <
sizeof( timestr ) )
1512 filp, (
int) count, (
int)
sizeof( timestr ) );
1518 if ( filp->f_flags & O_NONBLOCK )
1529 int dev_connected = 0;
1530 int this_rc = wait_event_interruptible_timeout( pddev->
wait_queue,
1534 goto out_interrupted_wait;
1536 if ( !dev_connected )
1540 sys_rc = -ERESTARTSYS;
1557 interruptible_sleep_on_timeout( &pddev->
wait_queue );
1559 if ( signal_pending( current ) )
1560 goto out_interrupted_wait;
1566 return -ERESTARTSYS;
1576 #if DEBUG_IRQ_LATENCY 1579 unsigned long long tsc;
1585 tsc, dt( tsc - tsc_usb_2 ), dt( tsc_usb_2 - tsc_usb_1 ),
1586 dt( tsc_usb_1 - tsc_irq_1 ) );
1589 tsc, dt( tsc - tsc_irq_2 ), dt( tsc_irq_2 - tsc_irq_1 ) );
1593 bytes_to_copy =
_min( count,
sizeof( timestr ) - 1 );
1595 if ( copy_to_user( buffer, timestr, bytes_to_copy ) )
1603 sys_rc = bytes_to_copy;
1609 out_interrupted_wait:
1612 sys_rc = -ERESTARTSYS;
1623 size_t count, loff_t *ppos )
1628 if ( ppos != &filp->f_pos )
1647 struct termios termios = { 0 };
1651 termios.c_iflag = IGNBRK|IGNPAR|ISTRIP;
1652 termios.c_oflag = 0;
1653 termios.c_cflag = B9600|CS7|PARENB|CREAD|HUPCL|CLOCAL;
1654 termios.c_lflag = 0;
1657 if ( copy_to_user( (
struct termios *) arg, &termios,
sizeof( termios ) ) )
1669 struct winsize winsize = { 0, 0, 0, 0 };
1671 if ( copy_to_user( (
struct winsize *) arg, &winsize,
sizeof( winsize ) ) )
1701 void decode_ioctl(
const char *s,
ulong cmd )
1704 s, cmd, (
ulong) _IOC_TYPE( cmd ), (
ulong) _IOC_NR( cmd ), (
ulong) _IOC_SIZE( cmd ) );
1722 #if defined( DEBUG ) 1752 #if !OMIT_PRIV_CHECKING // this is the default case 1756 if ( !capable( CAP_SYS_ADMIN ) )
1760 return IOCTL_RC_ERR_PERM;
1783 filp, ioctl_name, cmd,
1786 decode_ioctl(
"ioctl", cmd );
1794 decode_ioctl(
"ioctl", cmd );
1796 return IOCTL_RC_ERR_UNSUPP_IOCTL;
1801 sys_rc =
ioctl_switch( pddev, cmd, (
void *) arg, (
void *) arg );
1815 #if defined( HAVE_COMPAT_IOCTL ) && defined( CONFIG_COMPAT ) 1818 long mbgclock_compat_ioctl(
struct file *filp,
unsigned int cmd,
unsigned long arg )
1838 #if !defined( HAVE_UNLOCKED_IOCTL ) 1841 int mbgclock_ioctl(
struct inode *not_used,
struct file *filp,
unsigned int cmd,
unsigned long arg )
1869 #if VMA_HAS_VM_PGOFF 1870 if ( ( ( vma->vm_end - vma->vm_start ) != PAGE_SIZE ) || vma->vm_pgoff )
1872 if ( ( ( vma->vm_end - vma->vm_start ) != PAGE_SIZE ) )
1876 vma->vm_end, vma->vm_start, (
unsigned long) PAGE_SIZE );
1881 #if VMA_HAS_VM_PGOFF 1883 "vm_end (0x%08lX) - vm_start (0x%08lX) == PAGE_SIZE (0x%08lX), pg_off: 0x%08lX",
1884 vma->vm_end, vma->vm_start, (
unsigned long) PAGE_SIZE, vma->vm_pgoff );
1887 vma->vm_end, vma->vm_start, (
unsigned long) PAGE_SIZE );
1890 vma->vm_flags |= VM_IO;
1892 #if defined( pgprot_noncached ) 1893 vma->vm_page_prot = pgprot_noncached( vma->vm_page_prot );
1896 #if _PCPS_HAS_REMAP_PFN 1897 rc = io_remap_pfn_range( vma, vma->vm_start, addr >> PAGE_SHIFT, PAGE_SIZE, vma->vm_page_prot );
1899 rc = io_remap_page_range( vma, vma->vm_start, addr, PAGE_SIZE, vma->vm_page_prot );
1926 #if defined( HAVE_UNLOCKED_IOCTL ) 1931 #if defined( HAVE_COMPAT_IOCTL ) && defined( CONFIG_COMPAT ) 1932 compat_ioctl: mbgclock_compat_ioctl,
1944 #if _PCPS_USE_PCI_PNP 1970 cdev_init( &pddev->
cdev, &mbgclock_fops );
1971 pddev->
cdev.owner = THIS_MODULE;
1973 rc = cdev_add( &pddev->
cdev, dev, 1 );
1982 MAJOR( pddev->
cdev.dev ), MINOR( pddev->
cdev.dev ), dev_idx );
1984 #if _PCPS_HAVE_LINUX_CLASS 1985 if ( !IS_ERR( mbgclock_class ) )
1987 #if _PCPS_CLASS_DEV_OBSOLETED 1988 struct device *device;
1989 device = device_create( mbgclock_class, NULL, dev,
1993 mbg_clk_dev_node_fmt,
minor + dev_idx );
1994 #elif _PCPS_HAVE_LINUX_CLASS_CREATE 1995 struct class_device *device;
1996 device = class_device_create( mbgclock_class,
2000 dev, NULL, mbg_clk_dev_node_fmt,
minor + dev_idx );
2001 #elif _PCPS_HAVE_LINUX_CLASS_SIMPLE 2002 struct class_device *device;
2003 device = class_simple_device_add( mbgclock_class, dev, NULL, mbg_clk_dev_node_fmt,
minor + dev_idx );
2006 if ( IS_ERR( device ) )
2016 #if _USE_LINUX_DEVFS 2017 devfs_mk_cdev( MKDEV( pddev->major, 0 ),
2037 #if 0 //##++++++++++ 2038 pddev->remove_lock = ATOMIC_INIT( 0 );
2044 _sema_init_pddev( &pddev->sem_usb_cyclic, 1,
"sem_usb_cyclic", __func__, pddev );
2047 if ( default_fast_hr_time_pddev == NULL )
2050 default_fast_hr_time_pddev = pddev;
2055 if ( default_ucap_pddev == NULL )
2058 default_ucap_pddev = pddev;
2087 if ( pddev == default_fast_hr_time_pddev )
2091 default_fast_hr_time_pddev = NULL;
2094 if ( pddev == default_ucap_pddev )
2098 default_ucap_pddev = NULL;
2101 #if _USE_LINUX_DEVFS 2106 cdev_del( &pddev->
cdev );
2108 #if _PCPS_HAVE_LINUX_CLASS 2109 if ( !IS_ERR( mbgclock_class ) )
2111 #if _PCPS_CLASS_DEV_OBSOLETED 2112 device_destroy( mbgclock_class, pddev->
lx_dev );
2113 #elif _PCPS_HAVE_LINUX_CLASS_CREATE 2114 class_device_destroy( mbgclock_class, pddev->
lx_dev );
2115 #elif _PCPS_HAVE_LINUX_CLASS_SIMPLE 2116 class_simple_device_remove( pddev->
lx_dev );
2141 #if _PCPS_USE_ISA && !_PCPS_USE_ISA_PNP //##++ this needs cleanup 2146 int rc = mbgdrvr_create_device( pddev );
2160 int __devinit mbgclock_probe_pci_device(
struct pci_dev *pci_dev,
2161 const struct pci_device_id *ent )
2169 rc = pci_enable_device( pci_dev );
2174 pci_dev->device, (
ulong) pci_resource_start( pci_dev, 0 ), rc );
2195 for ( i = 0; i < 5; i++ )
2197 ulong flags = pci_resource_flags( pci_dev, i );
2199 if ( flags & IORESOURCE_IO )
2200 pcps_add_rsrc_io( pddev, pci_resource_start( pci_dev, i ), pci_resource_len( pci_dev, i ) );
2202 if ( flags & IORESOURCE_MEM )
2203 pcps_add_rsrc_mem( pddev, pci_resource_start( pci_dev, i ), pci_resource_len( pci_dev, i ) );
2216 pci_set_drvdata( pci_dev, pddev );
2218 rc = mbgdrvr_create_device( pddev );
2242 void __devexit mbgclock_remove_pci_device(
struct pci_dev *pci_dev )
2253 pci_set_drvdata( pci_dev, NULL );
2259 static struct pci_device_id mbgclock_pci_tbl[] __devinitdata =
2265 MODULE_DEVICE_TABLE( pci, mbgclock_pci_tbl );
2267 static struct pci_driver mbgclock_pci_driver =
2270 id_table: mbgclock_pci_tbl,
2271 probe: mbgclock_probe_pci_device,
2275 #endif // _PCPS_USE_PCI_PNP 2282 int __devinit mbgclock_probe_usb_device(
struct usb_interface *pintf,
2283 const struct usb_device_id *ent )
2289 struct usb_device *usb_device;
2299 usb_device = interface_to_usbdev( pintf );
2300 dev_id = le16_to_cpu( usb_device->descriptor.idProduct );
2304 #if STRUCT_USB_DEVICE_HAS_SERIAL 2306 #elif STRUCT_USB_DEVICE_HAS_STATIC_SERIAL 2309 if ( usb_device->descriptor.iSerialNumber )
2313 if ( usb_string( usb_device, usb_device->descriptor.iSerialNumber, buf,
sizeof( buf ) ) > 0 )
2327 goto fail_free_up_sem_fops;
2331 pddev->udev = usb_device;
2338 goto fail_free_up_sem_fops;
2341 pddev->intf = pintf;
2343 usb_set_intfdata( pintf, pddev );
2353 goto fail_free_up_sem_fops;
2358 if ( ppddev == NULL )
2360 rc = mbgdrvr_create_device( pddev );
2363 goto fail_free_up_sem_fops;
2377 fail_free_up_sem_fops:
2393 void __devexit mbgclock_remove_usb_device(
struct usb_interface *intf )
2416 usb_set_intfdata( intf, NULL );
2421 _up( &
sem_fops,
"sem_fops",
"remove_usb_device", NULL );
2427 static struct usb_device_id mbgclock_usb_tbl[] __devinitdata =
2443 MODULE_DEVICE_TABLE( usb, mbgclock_usb_tbl );
2445 static struct usb_driver mbgclock_usb_driver =
2448 id_table: mbgclock_usb_tbl,
2449 probe: mbgclock_probe_usb_device,
2450 disconnect: mbgclock_remove_usb_device
2453 #endif // _PCPS_USE_USB 2463 void mbgclock_cleanup_module(
void )
2470 #if _PCPS_USE_PCI_PNP 2471 pci_unregister_driver( &mbgclock_pci_driver );
2476 usb_deregister( &mbgclock_usb_driver );
2494 unregister_chrdev_region( MKDEV(
major,
minor ), max_devs );
2498 #if _PCPS_HAVE_LINUX_CLASS 2499 if ( !IS_ERR( mbgclock_class ) )
2501 #if _PCPS_HAVE_LINUX_CLASS_CREATE 2502 class_destroy( mbgclock_class );
2503 #elif _PCPS_HAVE_LINUX_CLASS_SIMPLE 2504 class_simple_destroy( mbgclock_class );
2527 #if _PCPS_USE_PCI_PNP 2528 static const char info[] =
"";
2530 static const char info[] =
" (non-PNP)";
2533 #ifdef EXPORT_NO_SYMBOLS 2549 #if _DEFAULT_PCPS_USE_MM_IO 2602 major = MAJOR( dev );
2607 #if _PCPS_HAVE_LINUX_CLASS 2608 #if _PCPS_HAVE_LINUX_CLASS_CREATE 2609 mbgclock_class = class_create( THIS_MODULE, mbgclock_class_name );
2610 #elif _PCPS_HAVE_LINUX_CLASS_SIMPLE 2611 mbgclock_class = class_simple_create( THIS_MODULE, mbgclock_class_name );
2614 if ( !IS_ERR( mbgclock_class ) )
2617 mbgclock_class_name );
2621 mbgclock_class_name );
2630 goto fail_with_cleanup;
2633 #if _USE_LINUX_DEVFS 2634 #error devfs support needs cleanup!! 2635 devfs_mk_cdev( MKDEV( pddev->major, 0 ),
2640 #if _PCPS_USE_ISA && !_PCPS_USE_ISA_PNP //##++ this needs cleanup 2644 #if _PCPS_USE_PCI_PNP 2645 rc = pci_register_driver( &mbgclock_pci_driver );
2648 #endif // _PCPS_USE_PCI_PNP 2650 #if _PCPS_USE_USB //##++ 2651 rc = usb_register( &mbgclock_usb_driver );
2654 #endif // _PCPS_USE_USB 2661 if ( drvr_info.
n_devs == 0 )
2665 goto fail_with_cleanup;
2676 mbgclock_cleanup_module();
2688 module_exit( mbgclock_cleanup_module );
2710 if ( default_fast_hr_time_pddev == NULL )
2747 if ( default_fast_hr_time_pddev == NULL )
2785 if ( default_ucap_pddev == NULL )
2797 err_busy_irq_unsafe:
2827 if ( default_ucap_pddev == NULL )
2839 __func__, p->
used, p->
max, rc );
2842 err_busy_irq_unsafe:
2875 if ( default_ucap_pddev == NULL )
2890 err_busy_irq_unsafe:
2900 #if defined( DEBUG ) 2916 #if !MBG_PC_CYCLES_SUPPORTED 2917 #warning No cycles support to compute latencies on this platform. 2920 #if OMIT_PRIV_CHECKING 2921 #warning IOCTL privilege checking is omitted on your own risk! #define USB_DEV_WWVB51USB
#define _usb_read_thread_started(_pddev)
#define _pcps_ddev_sernum(_p)
invalid time because battery had been disconnected, or absolute time can't be decoded safely ...
#define PCPS_IRQ_STAT_ENABLE_CALLED
static irqreturn_t mbgclock_irq_handler(int hw_irq, void *arg, struct pt_regs *regs)
static void mbgdrvr_delete_device(PCPS_DDEV *pddev)
PCPS_RSRC_INFO rsrc_info
Summary of resources used by the device.
uint8_t year
year of the century, 0..99
#define _up(_s, _sn, _fn, _fp)
#define _pcps_sem_dec(_pddev)
#define _pcps_fw_rev_num_minor(_v)
MBGCLOCK_DEFAULT_GET_FAST_HR_TIMESTAMP_FNC get_fast_hr_timestamp_fnc
const char * mbgioctl_get_name(long code)
#define _pcps_ddev_disb_irq(_d)
#define _pcps_fw_rev_num_major(_v)
uint32_t used
the number of saved capture events
#define _mbgddmsg_fnc_entry()
#define _mbg_kdd_msg_4(_lvl, _fmt, _p1, _p2, _p3, _p4)
struct fasync_struct * fasyncptr
Used for asynchronous signalling when data is available.
#define _pcps_ddev_is_usb(_p)
#define MBG_MICRO_VERSION_CODE
uint8_t cmd
In case of small data we just need one of the PCPS_CMD_CODES.
uint8_t mday
day of month, 0..31
#define PCPS_IRQ_STAT_UNSAFE
uint8_t sec100
hundredths of seconds, 0..99, 10 ms resolution
#define _pcps_asic_version_major(_v)
Extract the major part of an ASIC version number.
int mbgclock_default_get_ucap_entries(PCPS_UCAP_ENTRIES *p)
Read user capture FIFO information.
#define _mbgddmsg_3(_f, _lvl, _fmt, _p1, _p2, _p3)
PCPS_TIME t
Date and time read by IRQ handler.
int mbgclock_default_get_fast_hr_timestamp(PCPS_TIME_STAMP *p_ts)
Read a high resolution PCPS_TIME_STAMP structure via memory mapped access.
#define USB_DEV_TCR600USB
static int mbgclock_flush(struct file *filp)
PCPS_IRQ_STAT_INFO irq_stat_info
#define PCPS_CLR_UCAP_BUFF
(-w) No param., clear on-board capture FIFO, only if _pcps_has_ucap
MBGCLOCK_DEFAULT_GET_UCAP_EVENT_FNC get_ucap_event_fnc
unsigned long jiffies_at_irq
Set by IRQ handler, used to check if cyclic IRQs still occur.
static PCPS_DDEV ** ddev_list_locate_minor(unsigned int minor)
static int mbgdrvr_enable_cyclic(PCPS_DDEV *pddev, unsigned int force)
static int ddev_list_alloc(void)
#define _down_interruptible_pddev(_s, _sn, _fn, _fp)
ulong MBG_IOPORT_ADDR_MAPPED
static int mbgclock_ioctl(struct inode *not_used, struct file *filp, unsigned int cmd, unsigned long arg)
#define PCI_VENDOR_MEINBERG
#define PCPS_IRQ_1_SEC
(-w) Enable IRQ per 1 second
static PCPS_DDEV * default_fast_hr_time_pddev
#define _sema_init_pddev(_s, _n, _sn, _fn, _fp)
PCPS_SECONDS sec
seconds since 1970, usually UTC scale
#define _mbgddmsg_fnc_exit_str(_s)
#define _mbg_swab_pcps_time_stamp_cycles(_p)
#define _usb_read_thread_failed_to_start(_pddev)
#define MBG_DEV_NAME_FMT
A string format specifier for MBG_DEV_NAME.
#define MBG_MAIN_VERSION_CODE
#define _mbgddmsg_6(_f, _lvl, _fmt, _p1, _p2, _p3, _p4, _p5, _p6)
#define _mbgddmsg_fnc_exit_success()
static PCPS_DDEV * default_ucap_pddev
#define _kill_fasync(_fa, _sig, _band)
#define _usb_read_thread_should_stop()
void pcps_cleanup_ddev(PCPS_DDEV *pddev)
Clean up and free a previously initialized device info structure.
#define _mbgddmsg_0(_f, _lvl, _fmt)
int pcps_init_ddev(PCPS_DDEV **ppddev)
Allocate and initialize a device info structure.
#define mbg_rc_is_success(_rc)
#define _mbg_dbg_hw_lpt_clr_bit(_b)
static int ddev_list_alloc_size
#define _pcps_ddev_fw_rev_num(_p)
void mbg_kdd_msg(int lvl, const char *fmt,...)
#define _mbg_dbg_hw_lpt_vars
MBGCLOCK_DEFAULT_GET_UCAP_ENTRIES_FNC get_ucap_entries_fnc
#define PCPS_ASIC_STR_FMT
#define PCPS_IRQ_NONE
(-w) Disable IRQs
#define _mbgddmsg_5(_f, _lvl, _fmt, _p1, _p2, _p3, _p4, _p5)
#define _pcps_ddev_enb_irq(_d, _cmd)
__mbg_inline int get_cyclic_lock(PCPS_DDEV *pddev, unsigned long *p_flags, const char *fnc_name)
static int mbgclock_open(struct inode *inode, struct file *filp)
High resolution time stamp plus associated system cycles count.
Status of the time capture FIFO buffer.
int pcps_add_rsrc_mem(PCPS_DDEV *pddev, MBG_IOMEM_ADDR_RAW start, ulong len)
Add a memory address range resource to the device structure.
static __mbg_inline void do_get_fast_hr_timestamp_safe(PCPS_DDEV *pddev, PCPS_TIME_STAMP *p_ts)
static __mbg_inline void do_get_fast_hr_timestamp_cycles_safe(PCPS_DDEV *pddev, PCPS_TIME_STAMP_CYCLES *p_ts_cyc)
atomic_t open_count
Number of processes that have opened this device.
#define MBG_MINOR_VERSION_CODE
#define _mbgddmsg_fnc_exit_err_dec(_errnum)
static PCPS_DDEV ** ddev_list_locate_device(PCPS_BUS_FLAGS bus_flags, PCPS_DEV_ID dev_id, PCPS_SN_STR sernum)
#define _PCPS_DEVICE_CREATE_WITH_DEV_DATA
static __mbg_inline int ioctl_switch(PCPS_DDEV *pddev, unsigned int ioctl_code, void *pin, void *pout)
Decode and handle IOCTL commands.
#define PCPS_GIVE_UCAP_ENTRIES
(r-) Read PCPS_UCAP_ENTRIES, only if _pcps_has_ucap
#define _mbgddmsg_1(_f, _lvl, _fmt, _p1)
uint16_t n_devs
the number of devices handled by the driver
MBGCLOCK_DEFAULT_GET_FAST_HR_TIMESTAMP_CYCLES_FNC get_fast_hr_timestamp_cycles_fnc
#define _pcps_sem_inc_safe(_pddev)
#define MBG_ERR_IRQ_UNSAFE
Enabled IRQ of bus-level device is unsafe with this firmware/ASIC version.
#define _mbg_swab_pcps_hr_time(_p)
int(* MBGCLOCK_DEFAULT_GET_FAST_HR_TIMESTAMP_FNC)(PCPS_TIME_STAMP *p_ts)
#define MBG_ERR_TIMEOUT
Timeout accessing the device.
MBG_IOMEM_RSRC mem[2]
Info on actually assigned memory ranges.
uint32_t max
capture buffer size
uint64_t MBG_IOMEM_ADDR_RAW
struct file_operations mbgclock_fops
#define _pcps_read_var(_pddev, _cmd, _s)
#define _pcps_ddev_ack_irq(_d)
#define _mbgddmsg_fnc_exit()
#define _pcps_ddev_has_gen_irq(_d)
#define _mbg_dbg_hw_lpt_set_bit(_b)
static int irq[PCPS_MAX_ISA_CARDS]
#define PCPS_GIVE_UCAP_EVENT
(r-) Return oldest event as PCPS_HR_TIME, only if _pcps_has_ucap
#define PCPS_GIVE_TIME
Command codes used to communicate with bus level devices.
static __mbg_inline int ioctl_get_required_privilege(ulong ioctl_code)
Determine the privilege level required to execute a specific IOCTL command.
#define _pcps_ddev_is_isa(_p)
PCPS_FRAC_32 frac
binary fractions of second, see PCPS_FRAC_32
daylight saving currently enabled
void pcps_cleanup_device(PCPS_DDEV *pddev)
Clean up function called by pcps_probe_device on error.
static __mbg_inline int mbgdrvr_get_pddev(PCPS_DDEV **ppddev, struct file *filp, const char *info)
static PCPS_DDEV ** ddev_list
char PCPS_SN_STR[(16+1)]
A buffer for a serial number string, including terminating 0.
dev_t lx_dev
Linux device associated with this device.
PCPS_TIME_STAMP tstamp
High resolution time stamp (UTC)
int(* MBGCLOCK_DEFAULT_GET_UCAP_ENTRIES_FNC)(PCPS_UCAP_ENTRIES *p)
long wave or time code receiver has sync'ed at least once after pwr up, sat receiver is synchronized ...
#define _usb_read_thread_start(_fnc, _pddev)
#define _usb_read_thread_exit(_pddev, _v)
#define _up_pddev(_s, _sn, _fn, _fp)
static __mbg_inline void set_dev_connected(PCPS_DDEV *pddev, int state)
int mbgclock_default_clr_ucap_buff(void)
Clear the on-board user capture FIFO buffer.
#define PCPS_IRQ_STAT_ENABLED
static int mbgdrvr_disable_cyclic(PCPS_DDEV *pddev)
int(* MBGCLOCK_DEFAULT_GET_FAST_HR_TIMESTAMP_CYCLES_FNC)(PCPS_TIME_STAMP_CYCLES *p_ts_cyc)
#define USB_DEV_DCF600USB
#define _pcps_ddev_irq_num(_p)
#define _usb_read_thread_stop(_pddev)
#define MBG_LOG_FMT_LEAVING
#define _usb_read_thread_daemonize(_pddev)
#define _pcps_ddev_has_ucap(_p)
static __mbg_inline int get_dev_connected(PCPS_DDEV *pddev)
int8_t offs_utc
[hours], 0 if not _pcps_has_utc_offs
#define _mbg_swab_pcps_time_stamp(_p)
int(* MBGCLOCK_DEFAULT_CLR_UCAP_BUFF_FNC)(void)
#define IOCTL_PCPS_GENERIC_READ_GPS
#define _pcps_kmalloc(_sz)
static ssize_t mbgclock_write(struct file *filp, const char *buffer, size_t count, loff_t *ppos)
#define _pcps_ddev_asic_version(_p)
#define MBG_SUCCESS
Error codes used with Meinberg devices and drivers.
#define _mbgddmsg_4(_f, _lvl, _fmt, _p1, _p2, _p3, _p4)
#define _PCPS_CLASS_DEVICE_CREATE_WITH_PARENT
#define _pcps_ddev_has_fast_hr_timestamp(_p)
#define _mbgddmsg_2(_f, _lvl, _fmt, _p1, _p2)
static unsigned int mbgclock_poll(struct file *filp, poll_table *pt)
#define MBGCLOCK_MAX_DEVS
MBGCLOCK_DEFAULT_CLR_UCAP_BUFF_FNC clr_ucap_buff_fnc
static int io[PCPS_MAX_ISA_CARDS]
a change in daylight saving status is announced
#define USB_DEV_WVB600USB
#define _pcps_kfree(_p, _sz)
static ssize_t mbgclock_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
#define USB_DEV_MSF600USB
__mbg_inline void release_cyclic_lock(PCPS_DDEV *pddev, unsigned long *p_flags, const char *fnc_name)
static int ddev_list_remove_entry(PCPS_DDEV *pddev)
int(* MBGCLOCK_DEFAULT_GET_UCAP_EVENT_FNC)(PCPS_HR_TIME *p)
#define _pcps_ddev_type_name(_p)
atomic_t access_in_progress
Flag indicating if device access is currently in progress.
static void ddev_list_free(void)
EXPORT_SYMBOL(mbgclock_default_get_fast_hr_timestamp)
High resolution time including status and local time offset.
int pcps_probe_device(PCPS_DDEV *pddev, PCPS_BUS_NUM bus_num, PCPS_SLOT_NUM dev_fnc_num)
Probe if a device is supported, and allocate and setup the device structure.
static int mbgclock_release(struct inode *inode, struct file *filp)
#define _down_interruptible(_s, _sn, _fn, _fp)
#define _pcps_write_byte(_pddev, _b)
union PCPS_DDEV_s::@9 cmd_info
static int mbgclock_mmap(struct file *filp, struct vm_area_struct *vma)
int pcps_setup_ddev(PCPS_DDEV *pddev, PCPS_BUS_FLAGS bus_mask, PCPS_DEV_ID dev_id)
Initialize an allocated device structure for a specific device.
static long mbgclock_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
Local calendar date and time, plus sync status.
int pcps_add_rsrc_io(PCPS_DDEV *pddev, MBG_IOPORT_ADDR_RAW base, ulong num)
Add an I/O address range resource to the device structure.
#define _pcps_ddev_dev_id(_p)
static void pcps_time_to_time_str(const PCPS_TIME *t, char *s, size_t max_len)
atomic_t data_avail
Flag indicating if data has been made available by IRQ handler.
void _MBG_INIT_CODE_ATTR pcps_detect_devices(int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS])
Detect all bus-level devices in a non-PnP system.
unsigned long volatile jiffies
A high resolution time stamp.
#define _pcps_asic_version_minor(_v)
Extract the minor part of an ASIC version number.
#define _down(_s, _sn, _fn, _fp)
#define MBG_ERR_NOT_SUPP_BY_DEV
Command or feature not supported by device.
#define PCPS_MAX_ISA_CARDS
MBG_IOMEM_ADDR_RAW start_raw
A raw I/O memory start address.
#define mbg_rc_is_error(_rc)
uint8_t min
minutes, 0..59
int __init mbgclock_init_module(void)
void pcps_detect_isa_devices(PCPS_DDEV_INIT_FNC *ddev_init_fnc, PCPS_DDEV_CLEANUP_FNC *ddev_cleanup_fnc, PCPS_DDEV_REGISTER_FNC *ddev_register_fnc, int isa_ports[PCPS_MAX_ISA_CARDS], int isa_irqs[PCPS_MAX_ISA_CARDS])
Detect and initialize ISA devices in a non-PnP system.
const char * mbg_strerror(int mbg_errno)
Return an error string associated with the MBG_ERROR_CODES.
#define _mbg_swab_pcps_ucap_entries(_p)
MBG_MUTEX dev_mutex
Mutex used for device access serialization.
Device driver information.
#define USB_DEV_TCR180USB
uint8_t PCPS_TIME_STATUS
Time synchronization status.
static struct semaphore sem_fops
struct cdev cdev
Linux device class.
#define USB_VENDOR_MEINBERG
int pcps_add_rsrc_irq(PCPS_DDEV *pddev, int16_t irq_num)
Add an IRQ number resource to the device structure.
static int mbgclock_fasync(int fd, struct file *filp, int on)
long wave or time code receiver running on xtal, satellite receiver has not verified its position ...
#define MBG_MAJOR_VERSION_CODE
int mbgclock_default_get_ucap_event(PCPS_HR_TIME *p)
Retrieve single time capture event.
#define _usb_read_thread_set_unused(_pddev)
struct wait_queue * wait_queue
Used for asynchronous I/O (older kernel API)
static int mbgdrvr_ioctl_emu_serial(struct file *filp, unsigned int cmd, unsigned long arg)
uint8_t month
month, 1..12
PCPS_TIME_STATUS status
status bits, see PCPS_TIME_STATUS_FLAGS_COMMON
int mbgclock_default_get_fast_hr_timestamp_cycles(PCPS_TIME_STAMP_CYCLES *p_ts_cyc)
Read a high resolution PCPS_TIME_STAMP_CYCLES structure via memory mapped access. ...
uint8_t sec
seconds, 0..59, or 60 if leap second
leap second announced, for very old clocks see REV_PCPS_LS_ANN_PC31PS31
uint8_t wday
day of week, 1..7, 1 = Monday
static int ddev_list_add_entry(PCPS_DDEV *pddev)
#define MBG_FULL_VERSION_STR