diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2011-05-13 12:00:00 +0200 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2011-05-13 12:00:00 +0200 |
commit | 9fc4a73b3b75b4e9b68397d3d79e539366ff530e (patch) | |
tree | 950e27fe5a3725bd7534529258afc60f35243681 | |
parent | 89b44c58a33547e6bd2e202b6a031e3c94bbcbb6 (diff) | |
download | mbgtools-fbsd-9fc4a73b3b75b4e9b68397d3d79e539366ff530e.tar.gz mbgtools-fbsd-9fc4a73b3b75b4e9b68397d3d79e539366ff530e.zip |
Improve IOCTL handlermbgtools-fbsd-dev-2011-05-13
Remove NetBSD-specific code from FreeBSD-specific files.
Check privileges and return proper error codes in IOCTL handler.
Update some source files.
-rwxr-xr-x | mbgclock/mbgclock_main.c | 185 | ||||
-rwxr-xr-x | mbglib/common/macioctl.h | 6 | ||||
-rwxr-xr-x | mbglib/common/mbgdevio.c | 6 | ||||
-rwxr-xr-x | mbglib/common/mbgioctl.h | 229 | ||||
-rwxr-xr-x | mbglib/common/pcpsirq.h | 55 |
5 files changed, 320 insertions, 161 deletions
diff --git a/mbgclock/mbgclock_main.c b/mbgclock/mbgclock_main.c index bde66cc..584b303 100755 --- a/mbgclock/mbgclock_main.c +++ b/mbgclock/mbgclock_main.c @@ -55,9 +55,7 @@ #include <sys/malloc.h> #include <sys/bus.h> /* structs, prototypes for pci bus stuff */ -#if defined( MBG_TGT_FREEBSD ) - #include <sys/rman.h> -#endif +#include <sys/rman.h> #include <dev/pci/pcivar.h> /* For pci_get macros! */ #include <dev/pci/pcireg.h> @@ -105,43 +103,24 @@ struct mbgclock_softc /* Function prototypes */ -#if defined( MBG_TGT_NETBSD ) - static int mbgclock_open( dev_t, int, int, struct proc * ); - static int mbgclock_close( dev_t, int, int, struct proc * ); - static int mbgclock_read( dev_t dev, struct uio *, int ); -#else // FreeBSD - static d_open_t mbgclock_open; - static d_close_t mbgclock_close; - static d_read_t mbgclock_read; - static d_write_t mbgclock_write; - static d_ioctl_t mbgclock_ioctl; -#endif +static d_open_t mbgclock_open; +static d_close_t mbgclock_close; +static d_read_t mbgclock_read; +static d_write_t mbgclock_write; +static d_ioctl_t mbgclock_ioctl; /* Character device entry points */ static struct cdevsw mbgclock_cdevsw = { -#if defined( MBG_TGT_NETBSD ) - -#if 0 //##+++++++ - .d_open = mbgclock_open, - .d_close = mbgclock_close, - .d_read = mbgclock_read, - .d_write = mbgclock_write, - .d_ioctl = mbgclock_ioctl, - .d_name = "mbgclock" -#endif - -#else // FreeBSD .d_version = D_VERSION, - .d_open = mbgclock_open, - .d_close = mbgclock_close, - .d_read = mbgclock_read, - .d_write = mbgclock_write, - .d_ioctl = mbgclock_ioctl, - .d_name = "mbgclock" -#endif + .d_open = mbgclock_open, + .d_close = mbgclock_close, + .d_read = mbgclock_read, + .d_write = mbgclock_write, + .d_ioctl = mbgclock_ioctl, + .d_name = "mbgclock" }; @@ -163,17 +142,6 @@ void set_dev_connected( PCPS_DDEV *pddev, int state ) * of struct cdev. We set this variable to point to our softc in our * attach routine when we create the /dev entry. */ -#if defined( MBG_TGT_NETBSD ) - -#if 0 //##++++ -int -mbgclock_open( dev_t, int, int, struct proc * ) -{ -} // mbgclock_open -#endif - -#else // FreeBSD - int mbgclock_open( struct cdev *dev, int oflags, int devtype, d_thread_t *td ) { @@ -189,12 +157,7 @@ mbgclock_open( struct cdev *dev, int oflags, int devtype, d_thread_t *td ) } // mbgclock_open -#endif - - -#if defined( MBG_TGT_NETBSD ) -#else // FreeBSD int mbgclock_close( struct cdev *dev, int fflag, int devtype, d_thread_t *td ) @@ -211,12 +174,7 @@ mbgclock_close( struct cdev *dev, int fflag, int devtype, d_thread_t *td ) } // mbgclock_close -#endif - -#if defined( MBG_TGT_NETBSD ) - -#else // FreeBSD int mbgclock_read( struct cdev *dev, struct uio *uio, int ioflag ) @@ -234,12 +192,7 @@ mbgclock_read( struct cdev *dev, struct uio *uio, int ioflag ) } // mbgclock_read -#endif - - -#if defined( MBG_TGT_NETBSD ) -#else // FreeBSD int mbgclock_write( struct cdev *dev, struct uio *uio, int ioflag ) @@ -257,36 +210,51 @@ mbgclock_write( struct cdev *dev, struct uio *uio, int ioflag ) } // mbgclock_write -#endif - - - -#if defined( MBG_TGT_NETBSD ) //##++++++++++++ - -// Below there are some dummy declarations to make the IOCTL handler -// for FreeBSD *compile* without errors under NetBSD. -// This is mainly to see if ioctl_switch() compiles without errors. - -#define caddr_t void * - -struct thread -{ - int dummy; -}; -#endif int mbgclock_ioctl( struct cdev *dev, u_long cmd, caddr_t data, int32_t flag, struct thread *td ) { -#if defined( MBG_TGT_NETBSD ) - struct mbgclock_softc *psc = NULL; //##++++ dummy, just to avoid build error -#else // FreeBSD struct mbgclock_softc *psc = dev->si_drv1; -#endif PCPS_DDEV *pddev = psc->pddev; int rc; + int priv_lvl; + + // Find out which privilege level is required + // to execute this IOCTL command. + priv_lvl = ioctl_get_required_privilege( cmd ); + + // Check if the calling process has the required privilege. + switch ( priv_lvl ) + { + case MBG_REQ_PRIVL_NONE: + // Always allow. + break; + + case MBG_REQ_PRIVL_EXT_STATUS: + case MBG_REQ_PRIVL_CFG_READ: + // This may require some privilege for the calling process. + // Anyway, always allow for now. + break; + + case MBG_REQ_PRIVL_CFG_WRITE: + case MBG_REQ_PRIVL_SYSTEM: + #if 0 // TODO Check if required privileges are available, e.g.: + if ( !capable( CAP_SYS_ADMIN ) ) // don't allow if no root privileges + { + _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: permission denied, dev %s_%s", + pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); + return EPERM; + } + #endif + break; + + default: + _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: unknown, permission denied, dev %s_%s", + pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); + return EPERM; + } rc = ioctl_switch( pddev, cmd, (void *) data, (void *) data ); @@ -294,7 +262,7 @@ mbgclock_ioctl( struct cdev *dev, u_long cmd, caddr_t data, if ( rc == MBG_SUCCESS ) { - _mbgddmsg_5( MBG_DBG_INFO, "%s: %p IOCTL 0x%02lX: success, dev %s_%s", + _mbgddmsg_5( MBG_DBG_DETAIL, "%s: %p IOCTL 0x%02lX: success, dev %s_%s", pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); goto out; } @@ -310,28 +278,28 @@ mbgclock_ioctl( struct cdev *dev, u_long cmd, caddr_t data, _mbgddmsg_6( MBG_DBG_WARN, "%s: %p ioctl 0x%02lX: invalid cmd %04lX, dev %s_%s", pcps_driver_name, dev, cmd, IOCBASECMD( cmd ), _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); - rc = -EINVAL; + rc = EINVAL; break; case MBG_ERR_NOT_SUPP_BY_DEV: _mbgddmsg_5( MBG_DBG_WARN, "%s: %p ioctl 0x%02lX: not supported by dev %s_%s", pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); - rc = -EIO; + rc = EIO; break; case MBG_ERR_NO_MEM: _mbgddmsg_5( MBG_DBG_WARN, "%s: %p ioctl 0x%02lX: unable to allocate buffer for dev %s_%s", pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); - rc = -EFAULT; + rc = EFAULT; break; case MBG_ERR_IRQ_UNSAFE: _mbgddmsg_5( MBG_DBG_DETAIL, "%s: %p ioctl 0x%02lX: busy since unsafe IRQ enabled, dev %s_%s", pcps_driver_name, dev, cmd, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); - rc = -EBUSY; + rc = EBUSY; break; @@ -339,7 +307,7 @@ mbgclock_ioctl( struct cdev *dev, u_long cmd, caddr_t data, // or copying from or to user space _mbgddmsg_6( MBG_DBG_WARN, "%s: %p ioctl 0x%02lX: error %i accessing dev %s_%s", pcps_driver_name, dev, cmd, rc, _pcps_ddev_type_name( pddev ), _pcps_ddev_sernum( pddev ) ); - rc = -EFAULT; + rc = EFAULT; } // switch error rc @@ -358,14 +326,10 @@ mbg_deallocate_resource( device_t device, BSD_RSRC_INFO *p_ri, int type ) { if ( p_ri->res ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD bus_deactivate_resource( device, type, p_ri->rid, p_ri->res ); bus_release_resource( device, type, p_ri->rid, p_ri->res ); -#endif p_ri->res = NULL; } @@ -379,9 +343,6 @@ mbg_deallocate_resource( device_t device, BSD_RSRC_INFO *p_ri, int type ) static void mbg_dealloc_rsrcs( device_t device ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD struct mbgclock_softc *psc = device_get_softc( device ); PCPS_DDEV *pddev = psc->pddev; PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info; @@ -394,7 +355,6 @@ mbg_dealloc_rsrcs( device_t device ) for ( i = 0; i < N_PCPS_PORT_RSRC; i++ ) mbg_deallocate_resource( device, &prsrci->port[i].bsd, SYS_RES_IOPORT ); -#endif } // mbg_dealloc_rsrcs @@ -403,9 +363,6 @@ mbg_dealloc_rsrcs( device_t device ) static void mbg_alloc_rsrc( device_t device, int rid, BSD_RSRC_INFO *p_ri, int type, int flags ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD p_ri->rid = rid; p_ri->res = bus_alloc_resource_any( device, type, &p_ri->rid, flags ); @@ -415,7 +372,6 @@ mbg_alloc_rsrc( device_t device, int rid, BSD_RSRC_INFO *p_ri, int type, int fla p_ri->bst = rman_get_bustag( p_ri->res ); p_ri->bsh = rman_get_bushandle( p_ri->res ); } -#endif } // mbg_alloc_rsrc @@ -424,9 +380,6 @@ mbg_alloc_rsrc( device_t device, int rid, BSD_RSRC_INFO *p_ri, int type, int fla static void mbg_alloc_rsrcs( device_t device ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD struct mbgclock_softc *psc = device_get_softc( device ); PCPS_DDEV *pddev = psc->pddev; PCPS_RSRC_INFO *prsrci = &pddev->rsrc_info; @@ -477,8 +430,6 @@ mbg_alloc_rsrcs( device_t device ) } #endif -#endif - } // mbg_alloc_rsrcs @@ -490,9 +441,6 @@ mbg_alloc_rsrcs( device_t device ) static int mbgclock_probe( device_t device ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD uint16_t vend_id = pci_get_vendor( device ); uint16_t dev_id = pci_get_device( device ); PCPS_DEV_TYPE *pdt; @@ -519,8 +467,6 @@ fail: pcps_driver_name, vend_id, dev_id ); return ENXIO; -#endif - } // mbgclock_probe @@ -531,9 +477,6 @@ fail: static int mbgclock_attach( device_t device ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD uint16_t dev_id = pci_get_device( device ); struct mbgclock_softc *psc = device_get_softc( device ); int rc; @@ -610,7 +553,6 @@ fail: _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: failed to attach device 0x%04X", pcps_driver_name, dev_id ); return rc; -#endif } // mbgclock_attach @@ -622,9 +564,6 @@ fail: static int mbgclock_detach( device_t device ) { -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD #if defined( DEBUG ) uint16_t dev_id = pci_get_device( device ); #endif @@ -641,14 +580,17 @@ mbgclock_detach( device_t device ) set_dev_connected( pddev, 0 ); // pcps_free_ddev( pddev ); //##++++++ should wait for outstanding requests - mbg_dealloc_rsrcs( device ); + if ( psc->pddev ) + pcps_free_ddev( psc->pddev ); + + psc->pddev = NULL; + destroy_dev( psc->cdev ); _mbgddmsg_2( MBG_DBG_INIT_DEV, "%s: device 0x%04X detached", pcps_driver_name, dev_id ); -#endif return 0; @@ -698,9 +640,6 @@ mbgclock_resume( device_t device ) -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD static device_method_t mbgclock_methods[] = { /* Device interface */ @@ -712,14 +651,10 @@ static device_method_t mbgclock_methods[] = DEVMETHOD( device_resume, mbgclock_resume ), { 0, 0 } }; -#endif -#if defined( MBG_TGT_NETBSD ) - //##++++++ -#else // FreeBSD + static devclass_t mbgclock_devclass; DEFINE_CLASS_0( mbgclock, mbgclock_driver, mbgclock_methods, sizeof( struct mbgclock_softc ) ); DRIVER_MODULE( mbgclock, pci, mbgclock_driver, mbgclock_devclass, 0, 0 ); -#endif diff --git a/mbglib/common/macioctl.h b/mbglib/common/macioctl.h index 172fcfe..03cfa9d 100755 --- a/mbglib/common/macioctl.h +++ b/mbglib/common/macioctl.h @@ -1507,12 +1507,12 @@ int ioctl_switch( PCPS_DDEV *pddev, int ioctl_code, break; - case IOCTL_HAS_PCI_ASIC_FEATURES: + case IOCTL_DEV_HAS_PCI_ASIC_FEATURES: _report_cond( _pcps_ddev_has_asic_features( pddev ), pout ); break; - case IOCTL_HAS_PCI_ASIC_VERSION: + case IOCTL_DEV_HAS_PCI_ASIC_VERSION: _report_cond( _pcps_ddev_has_asic_version( pddev ), pout ); break; @@ -1556,7 +1556,7 @@ int ioctl_switch( PCPS_DDEV *pddev, int ioctl_code, break; - case IOCTL_HAS_FAST_HR_TIMESTAMP: + case IOCTL_DEV_HAS_FAST_HR_TIMESTAMP: _report_cond( _pcps_ddev_has_fast_hr_timestamp( pddev ), pout ); break; diff --git a/mbglib/common/mbgdevio.c b/mbglib/common/mbgdevio.c index b058f07..f23f394 100755 --- a/mbglib/common/mbgdevio.c +++ b/mbglib/common/mbgdevio.c @@ -4194,7 +4194,7 @@ _MBG_API_ATTR int _MBG_API mbg_get_synth_state( MBG_DEV_HANDLE dh, SYNTH_STATE * */ _MBG_API_ATTR int _MBG_API mbg_dev_has_fast_hr_timestamp( MBG_DEV_HANDLE dh, int *p ) { - _mbgdevio_query_cond( dh, _pcps_ddev_has_fast_hr_timestamp, IOCTL_HAS_FAST_HR_TIMESTAMP, p ); + _mbgdevio_query_cond( dh, _pcps_ddev_has_fast_hr_timestamp, IOCTL_DEV_HAS_FAST_HR_TIMESTAMP, p ); } // mbg_dev_has_fast_hr_timestamp @@ -4857,7 +4857,7 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_generic_io( MBG_DEV_HANDLE dh, int *p ) */ _MBG_API_ATTR int _MBG_API mbg_dev_has_asic_version( MBG_DEV_HANDLE dh, int *p ) { - _mbgdevio_query_cond( dh, _pcps_ddev_has_asic_version, IOCTL_HAS_PCI_ASIC_VERSION, p ); + _mbgdevio_query_cond( dh, _pcps_ddev_has_asic_version, IOCTL_DEV_HAS_PCI_ASIC_VERSION, p ); } // mbg_dev_has_asic_version @@ -4876,7 +4876,7 @@ _MBG_API_ATTR int _MBG_API mbg_dev_has_asic_version( MBG_DEV_HANDLE dh, int *p ) */ _MBG_API_ATTR int _MBG_API mbg_dev_has_asic_features( MBG_DEV_HANDLE dh, int *p ) { - _mbgdevio_query_cond( dh, _pcps_ddev_has_asic_features, IOCTL_HAS_PCI_ASIC_FEATURES, p ); + _mbgdevio_query_cond( dh, _pcps_ddev_has_asic_features, IOCTL_DEV_HAS_PCI_ASIC_FEATURES, p ); } // mbg_dev_has_asic_features diff --git a/mbglib/common/mbgioctl.h b/mbglib/common/mbgioctl.h index 4e5fb94..1c7718e 100755 --- a/mbglib/common/mbgioctl.h +++ b/mbglib/common/mbgioctl.h @@ -351,8 +351,8 @@ #define IOCTL_GET_PCI_ASIC_FEATURES _MBG_IOR( IOTYPE, 0x61, PCI_ASIC_FEATURES ) -#define IOCTL_HAS_PCI_ASIC_FEATURES _MBG_IOR( IOTYPE, 0x62, int ) -#define IOCTL_HAS_PCI_ASIC_VERSION _MBG_IOR( IOTYPE, 0x63, int ) +#define IOCTL_DEV_HAS_PCI_ASIC_FEATURES _MBG_IOR( IOTYPE, 0x62, int ) +#define IOCTL_DEV_HAS_PCI_ASIC_VERSION _MBG_IOR( IOTYPE, 0x63, int ) #define IOCTL_DEV_IS_MSF _MBG_IOR( IOTYPE, 0x64, int ) #define IOCTL_DEV_IS_LWR _MBG_IOR( IOTYPE, 0x65, int ) @@ -361,7 +361,7 @@ #define IOCTL_GET_IRQ_STAT_INFO _MBG_IOR( IOTYPE, 0x67, PCPS_IRQ_STAT_INFO ) #define IOCTL_GET_CYCLES_FREQUENCY _MBG_IOR( IOTYPE, 0x68, MBG_PC_CYCLES_FREQUENCY ) -#define IOCTL_HAS_FAST_HR_TIMESTAMP _MBG_IOR( IOTYPE, 0x69, int ) +#define IOCTL_DEV_HAS_FAST_HR_TIMESTAMP _MBG_IOR( IOTYPE, 0x69, int ) #define IOCTL_GET_FAST_HR_TIMESTAMP_CYCLES _MBG_IOR( IOTYPE, 0x6A, PCPS_TIME_STAMP_CYCLES ) #define IOCTL_GET_FAST_HR_TIMESTAMP _MBG_IOR( IOTYPE, 0x6B, PCPS_TIME_STAMP ) @@ -418,6 +418,229 @@ #endif +/** + * @brief Privilege levels for IOCTL codes. + * + * IOCTLs can be used to do different things ranging from simply + * reading a timestamp up to forcing a GPS receiver into boot mode + * which may completely mess up the time keeping on the PC. + * + * These codes are used to determine a privilege level required + * to execute a specific IOCTL command. + * + * How to determine if a calling process has sufficient privileges + * depends strongly on the rights management features provided + * by the underlying OS (e.g simple user/group rights, ACLs, + * Linux capabilities, Windows privileges) so this needs to be + * implemented in the OS-specific code of a driver. + * + * Implementation should be done in a way which introduces as low + * latency as possible when reading time stamps from a device. + */ +enum +{ + MBG_REQ_PRIVL_NONE, //< e.g. read date/time/sync status + MBG_REQ_PRIVL_EXT_STATUS, //< e.g. read receiver position + MBG_REQ_PRIVL_CFG_READ, //< read device config data + MBG_REQ_PRIVL_CFG_WRITE, //< write config data to the device + MBG_REQ_PRIVL_SYSTEM, //< operations which may affect system operation + N_MBG_REQ_PRIVL //< the number of supported privilege levels +}; + + +#if defined( __GNUC__ ) +// Avoid "no previous prototype" with some gcc versions. +__mbg_inline +int ioctl_get_required_privilege( ulong ioctl_code ) __attribute__((always_inline)); +#endif + +/** + * @brief Determine the privilege level required to execute a specific IOCTL command. + * + * @param ioctl_code The IOCTL code for which to return the privilege level + * + * @return One of the enumerated privilege levels + * @return -1 for unknown IOCTL codes + */ +__mbg_inline +int ioctl_get_required_privilege( ulong ioctl_code ) +{ + switch ( ioctl_code ) + { + // Commands requiring lowest latency: + case IOCTL_GET_FAST_HR_TIMESTAMP: + case IOCTL_GET_PCPS_HR_TIME: + case IOCTL_GET_FAST_HR_TIMESTAMP_CYCLES: + case IOCTL_GET_PCPS_HR_TIME_CYCLES: + case IOCTL_GET_PCPS_UCAP_EVENT: + // Other low latency commands: + case IOCTL_GET_PCPS_TIME: + case IOCTL_GET_PCPS_TIME_CYCLES: + case IOCTL_GET_PCPS_STATUS_PORT: + case IOCTL_GET_PCPS_TIME_SEC_CHANGE: + case IOCTL_GET_GPS_TIME: + case IOCTL_GET_GPS_UCAP: + case IOCTL_GET_TIME_INFO_HRT: + case IOCTL_GET_TIME_INFO_TSTAMP: + return MBG_REQ_PRIVL_NONE; + + // Commands returning public status information: + case IOCTL_GET_PCPS_DRVR_INFO: + case IOCTL_GET_PCPS_DEV: + case IOCTL_GET_PCPS_SYNC_TIME: + case IOCTL_GET_GPS_SW_REV: + case IOCTL_GET_GPS_BVAR_STAT: + case IOCTL_GET_GPS_ANT_INFO: + case IOCTL_GET_GPS_STAT_INFO: + case IOCTL_GET_GPS_IDENT: + case IOCTL_GET_GPS_RECEIVER_INFO: + case IOCTL_GET_PCI_ASIC_VERSION: + case IOCTL_GET_SYNTH_STATE: + case IOCTL_GET_PCPS_UCAP_ENTRIES: + case IOCTL_GET_PCI_ASIC_FEATURES: + case IOCTL_GET_IRQ_STAT_INFO: + case IOCTL_GET_CYCLES_FREQUENCY: + case IOCTL_GET_IRIG_CTRL_BITS: + case IOCTL_GET_IP4_STATE: + case IOCTL_GET_PTP_STATE: + return MBG_REQ_PRIVL_NONE; + + // Commands returning device capabilities and features: + case IOCTL_DEV_IS_GPS: + case IOCTL_DEV_IS_DCF: + case IOCTL_DEV_IS_MSF: + case IOCTL_DEV_IS_LWR: + case IOCTL_DEV_IS_WWVB: + case IOCTL_DEV_IS_IRIG_RX: + case IOCTL_DEV_HAS_HR_TIME: + case IOCTL_DEV_HAS_CAB_LEN: + case IOCTL_DEV_HAS_TZDL: + case IOCTL_DEV_HAS_PCPS_TZDL: + case IOCTL_DEV_HAS_TZCODE: + case IOCTL_DEV_HAS_TZ: + case IOCTL_DEV_HAS_EVENT_TIME: + case IOCTL_DEV_HAS_RECEIVER_INFO: + case IOCTL_DEV_CAN_CLR_UCAP_BUFF: + case IOCTL_DEV_HAS_UCAP: + case IOCTL_DEV_HAS_IRIG_TX: + case IOCTL_DEV_HAS_SERIAL_HS: + case IOCTL_DEV_HAS_SIGNAL: + case IOCTL_DEV_HAS_MOD: + case IOCTL_DEV_HAS_IRIG: + case IOCTL_DEV_HAS_REF_OFFS: + case IOCTL_DEV_HAS_OPT_FLAGS: + case IOCTL_DEV_HAS_GPS_DATA: + case IOCTL_DEV_HAS_SYNTH: + case IOCTL_DEV_HAS_GENERIC_IO: + case IOCTL_DEV_HAS_PCI_ASIC_FEATURES: + case IOCTL_DEV_HAS_PCI_ASIC_VERSION: + case IOCTL_DEV_HAS_FAST_HR_TIMESTAMP: + case IOCTL_DEV_HAS_GPS_TIME_SCALE: + case IOCTL_DEV_HAS_GPS_UTC_PARM: + case IOCTL_DEV_HAS_IRIG_CTRL_BITS: + case IOCTL_DEV_HAS_LAN_INTF: + case IOCTL_DEV_IS_PTP: + case IOCTL_DEV_HAS_PTP: + case IOCTL_DEV_HAS_IRIG_TIME: + case IOCTL_DEV_HAS_RAW_IRIG_DATA: + case IOCTL_DEV_HAS_PTP_UNICAST: + return MBG_REQ_PRIVL_NONE; + + // This ones are somewhat special since they change something + // on the board but do not affect basic operation: + case IOCTL_PCPS_CLR_UCAP_BUFF: + case IOCTL_SET_PCPS_EVENT_TIME: // supported by some customized firmware only + return MBG_REQ_PRIVL_NONE; + + // Status information which may not be available for everybody: + case IOCTL_GET_GPS_POS: + return MBG_REQ_PRIVL_EXT_STATUS; + + // Reading device configuration: + case IOCTL_GET_PCPS_SERIAL: + case IOCTL_GET_PCPS_TZCODE: + case IOCTL_GET_PCPS_TZDL: + case IOCTL_GET_REF_OFFS: + case IOCTL_GET_MBG_OPT_INFO: + case IOCTL_GET_PCPS_IRIG_RX_INFO: + case IOCTL_GET_GPS_TZDL: + case IOCTL_GET_GPS_PORT_PARM: + case IOCTL_GET_GPS_ENABLE_FLAGS: + case IOCTL_GET_GPS_ANT_CABLE_LEN: + case IOCTL_GET_GPS_ALL_STR_TYPE_INFO: + case IOCTL_GET_GPS_ALL_PORT_INFO: + case IOCTL_GET_PCPS_IRIG_TX_INFO: + case IOCTL_GET_SYNTH: + case IOCTL_GET_GPS_ALL_POUT_INFO: + case IOCTL_GET_GPS_TIME_SCALE_INFO: + case IOCTL_GET_GPS_UTC_PARM: + case IOCTL_GET_LAN_IF_INFO: + case IOCTL_GET_IP4_SETTINGS: + case IOCTL_GET_PTP_CFG_INFO: + case IOCTL_GET_IRIG_TIME: + case IOCTL_GET_RAW_IRIG_DATA: + case IOCTL_PTP_UC_MASTER_CFG_LIMITS: + case IOCTL_GET_ALL_PTP_UC_MASTER_INFO: + return MBG_REQ_PRIVL_CFG_READ; + + // Writing device configuration: + case IOCTL_SET_PCPS_SERIAL: + case IOCTL_SET_PCPS_TZCODE: + case IOCTL_SET_PCPS_TZDL: + case IOCTL_SET_REF_OFFS: + case IOCTL_SET_MBG_OPT_SETTINGS: + case IOCTL_SET_PCPS_IRIG_RX_SETTINGS: + case IOCTL_SET_GPS_TZDL: + case IOCTL_SET_GPS_PORT_PARM: + case IOCTL_SET_GPS_ENABLE_FLAGS: + case IOCTL_SET_GPS_ANT_CABLE_LEN: + case IOCTL_SET_GPS_PORT_SETTINGS_IDX: + case IOCTL_SET_PCPS_IRIG_TX_SETTINGS: + case IOCTL_SET_SYNTH: + case IOCTL_SET_GPS_POUT_SETTINGS_IDX: + case IOCTL_SET_IP4_SETTINGS: + case IOCTL_SET_PTP_CFG_SETTINGS: + case IOCTL_SET_PTP_UC_MASTER_SETTINGS_IDX: + return MBG_REQ_PRIVL_CFG_WRITE; + + // Operations which may affect system operation: + case IOCTL_SET_PCPS_TIME: + case IOCTL_SET_GPS_TIME: + case IOCTL_SET_GPS_POS_XYZ: + case IOCTL_SET_GPS_POS_LLA: + case IOCTL_SET_GPS_TIME_SCALE_SETTINGS: + case IOCTL_SET_GPS_UTC_PARM: + case IOCTL_SET_GPS_CMD: + // generic read/write operations can do anything + case IOCTL_PCPS_GENERIC_READ: + case IOCTL_PCPS_GENERIC_WRITE: + case IOCTL_PCPS_GENERIC_READ_GPS: + case IOCTL_PCPS_GENERIC_WRITE_GPS: + case IOCTL_PCPS_GENERIC_IO: + return MBG_REQ_PRIVL_SYSTEM; + + // These codes are somewhat special and normally + // not used by the driver software: + case IOCTL_GET_MAPPED_MEM_ADDR: + case IOCTL_UNMAP_MAPPED_MEM: + return MBG_REQ_PRIVL_SYSTEM; + + // The codes below are used for debugging only. + // Unrestricted usage may cause system malfunction !! + case IOCTL_MBG_DBG_GET_PORT_ADDR: + case IOCTL_MBG_DBG_SET_PORT_ADDR: + case IOCTL_MBG_DBG_SET_BIT: + case IOCTL_MBG_DBG_CLR_BIT: + case IOCTL_MBG_DBG_CLR_ALL: + return MBG_REQ_PRIVL_SYSTEM; + + } // switch + + return -1; // unsupported code, should always be denied + +} // ioctl_get_required_privilege + + // The structure below is used by the IOCTL_PCPS_GENERIC_... calls. typedef struct diff --git a/mbglib/common/pcpsirq.h b/mbglib/common/pcpsirq.h index 7bb2b1f..21c5bc5 100755 --- a/mbglib/common/pcpsirq.h +++ b/mbglib/common/pcpsirq.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pcpsirq.h 1.7 2008/12/05 12:20:36 martin REL_M $ + * $Id: pcpsirq.h 1.7.1.1 2011/02/09 17:22:36 martin TRASH $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -11,6 +11,7 @@ * * ----------------------------------------------------------------------- * $Log: pcpsirq.h $ + * Revision 1.7.1.1 2011/02/09 17:22:36 martin * Revision 1.7 2008/12/05 12:20:36 martin * Protect HW access to enable/disable IRQ by mutex. * Support mapped I/O resources. @@ -42,10 +43,10 @@ #define _set_port_bit( _d, _adr, _msk ) \ - _mbg_outp8( (_d), _adr, _mbg_inp8( (_d), _adr ) | (_msk) ) + _mbg_outp8( (_d), 0, _adr, _mbg_inp8( (_d), 0, _adr ) | (_msk) ) #define _clear_port_bit( _d, _adr, _msk ) \ - _mbg_outp8( (_d), _adr, _mbg_inp8( (_d), _adr ) & ~(_msk) ) + _mbg_outp8( (_d), 0, _adr, _mbg_inp8( (_d), 0, _adr ) & ~(_msk) ) // Each of the macros below expects a parameter _d which is @@ -110,34 +111,34 @@ // 2.) Clear interrupt source, deassert INTA# signal // and leave interrupt enabled by writing '1's to // the interrupt flag and interrupt enable bits. - #define _pcps_ddev_ack_irq_pci( _d ) \ - if ( (_d)->irq_ack_mask ) \ - { \ - if ( _pcps_ddev_is_pci_amcc( _d ) ) \ - _mbg_inp32( (_d), _pcps_ddev_io_base_mapped( _d, 0 ) \ - + AMCC_OP_REG_IMB4 ); \ - \ - _mbg_outp32( (_d), (_d)->irq_ack_port, (_d)->irq_ack_mask ); \ + #define _pcps_ddev_ack_irq_pci( _d ) \ + if ( (_d)->irq_ack_mask ) \ + { \ + if ( _pcps_ddev_is_pci_amcc( _d ) ) \ + _mbg_inp32( (_d), 0, _pcps_ddev_io_base_mapped( _d, 0 ) \ + + AMCC_OP_REG_IMB4 ); \ + \ + _mbg_outp32( (_d), 0, (_d)->irq_ack_port, (_d)->irq_ack_mask ); \ } // In IRQ init function, enable IRQ on the // interface chip. - #define _pcps_ddev_enb_irq_pci( _d ) \ - if ( (_d)->irq_enb_mask ) \ - { \ - uint32_t intcsr = _mbg_inp32_to_cpu( (_d), (_d)->irq_enb_disb_port ); \ - _mbg_outp32( (_d), (_d)->irq_enb_disb_port, \ - intcsr | (_d)->irq_enb_mask ); \ + #define _pcps_ddev_enb_irq_pci( _d ) \ + if ( (_d)->irq_enb_mask ) \ + { \ + uint32_t intcsr = _mbg_inp32_to_cpu( (_d), 0, (_d)->irq_enb_disb_port ); \ + _mbg_outp32( (_d), 0, (_d)->irq_enb_disb_port, \ + intcsr | (_d)->irq_enb_mask ); \ } // In IRQ de-init function, disable IRQ on the // interface chip. - #define _pcps_ddev_disb_irq_pci( _d ) \ - if ( (_d)->irq_disb_mask ) \ - { \ - uint32_t intcsr = _mbg_inp32_to_cpu( (_d), (_d)->irq_enb_disb_port ); \ - _mbg_outp32( (_d), (_d)->irq_enb_disb_port, \ - intcsr & ~(_d)->irq_disb_mask ); \ + #define _pcps_ddev_disb_irq_pci( _d ) \ + if ( (_d)->irq_disb_mask ) \ + { \ + uint32_t intcsr = _mbg_inp32_to_cpu( (_d), 0, (_d)->irq_enb_disb_port ); \ + _mbg_outp32( (_d), 0, (_d)->irq_enb_disb_port, \ + intcsr & ~(_d)->irq_disb_mask ); \ } #else @@ -155,10 +156,10 @@ // For non-PCI devices check the IRQ flag of the clock's // status port. #if ( _PCPS_USE_PCI ) - #define _pcps_ddev_has_gen_irq( _d ) \ - ( ( (_d)->irq_flag_mask ) ? \ - ( _mbg_inp32( (_d), (_d)->irq_flag_port ) & (_d)->irq_flag_mask ) : \ - ( _pcps_ddev_read_status_port( _d ) & PCPS_ST_IRQF ) \ + #define _pcps_ddev_has_gen_irq( _d ) \ + ( ( (_d)->irq_flag_mask ) ? \ + ( _mbg_inp32( (_d), 0, (_d)->irq_flag_port ) & (_d)->irq_flag_mask ) : \ + ( _pcps_ddev_read_status_port( _d ) & PCPS_ST_IRQF ) \ ) #else |