diff options
author | jfornal <jakub.fornal@intel.com> | 2016-09-02 14:04:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-02 14:04:57 +0200 |
commit | 10309b48d18740e11736be69d92e069450ac673b (patch) | |
tree | 22786fda76caddf56d825f1a83e7a3a357052bbd | |
parent | e880a5e652e6c88d5b0665ec209039a30781346a (diff) | |
parent | a86a949a6ceef5ed884dba5bb18edf1d64a72d49 (diff) | |
download | Open-AVB-10309b48d18740e11736be69d92e069450ac673b.tar.gz |
Merge pull request #1 from AVnu/open-avb-next
Merge of AVnu/Open-AVB/open-avb-next into jfornal/Open-AVB/open-avb-next
-rw-r--r-- | daemons/gptp/common/avbts_message.hpp | 6 | ||||
-rw-r--r-- | daemons/gptp/common/ieee1588port.cpp | 9 | ||||
-rw-r--r-- | daemons/gptp/linux/build/Makefile | 13 | ||||
-rw-r--r-- | daemons/gptp/linux/src/daemon_cl.cpp | 9 | ||||
-rw-r--r-- | daemons/gptp/linux/src/linux_hal_generic.cpp | 51 | ||||
-rw-r--r-- | daemons/gptp/linux/src/linux_hal_generic.hpp | 3 | ||||
-rw-r--r-- | daemons/mrpd/mrp.c | 1 | ||||
-rw-r--r-- | kmod/igb/igb.h | 10 | ||||
-rw-r--r-- | kmod/igb/igb_main.c | 304 | ||||
-rw-r--r-- | lib/avtp_pipeline/platform/Linux/tl/openavb_tl_osal.c | 14 | ||||
-rw-r--r-- | lib/avtp_pipeline/tl/openavb_talker.c | 2 |
11 files changed, 313 insertions, 109 deletions
diff --git a/daemons/gptp/common/avbts_message.hpp b/daemons/gptp/common/avbts_message.hpp index 661e88c9..1e8220a1 100644 --- a/daemons/gptp/common/avbts_message.hpp +++ b/daemons/gptp/common/avbts_message.hpp @@ -1059,16 +1059,16 @@ class SignallingTLV { */ SignallingTLV() { tlvType = PLAT_htons(0x3); - lengthField = PLAT_htons(28); + lengthField = PLAT_htons(12); organizationId[0] = '\x00'; organizationId[1] = '\x80'; organizationId[2] = '\xC2'; organizationSubType_ms = 0; - organizationSubType_ls = PLAT_htons(1); + organizationSubType_ls = PLAT_htons(2); linkDelayInterval = 0; timeSyncInterval = 0; announceInterval = 0; - flags = 0; + flags = 3; reserved = PLAT_htons(0); } diff --git a/daemons/gptp/common/ieee1588port.cpp b/daemons/gptp/common/ieee1588port.cpp index dac87a75..34edf4d1 100644 --- a/daemons/gptp/common/ieee1588port.cpp +++ b/daemons/gptp/common/ieee1588port.cpp @@ -582,7 +582,7 @@ void IEEE1588Port::processEvent(Event e) // Send an initial signalling message PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this); if (sigMsg) { - sigMsg->setintervals(log_min_mean_pdelay_req_interval, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoSend); + sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoSend); sigMsg->sendPort(this, NULL); delete sigMsg; } @@ -732,7 +732,7 @@ void IEEE1588Port::processEvent(Event e) // Send an initial signaling message PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this); if (sigMsg) { - sigMsg->setintervals(log_min_mean_pdelay_req_interval, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoSend); + sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoSend); sigMsg->sendPort(this, NULL); delete sigMsg; } @@ -1202,7 +1202,10 @@ void IEEE1588Port::processEvent(Event e) // Send operational signalling message PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this); if (sigMsg) { - sigMsg->setintervals(log_min_mean_pdelay_req_interval, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoChange); + if (automotive_profile) + sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoChange, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoChange); + else + sigMsg->setintervals(log_min_mean_pdelay_req_interval, log_mean_sync_interval, PTPMessageSignalling::sigMsgInterval_NoChange); sigMsg->sendPort(this, NULL); delete sigMsg; } diff --git a/daemons/gptp/linux/build/Makefile b/daemons/gptp/linux/build/Makefile index 02d082f1..21048c06 100644 --- a/daemons/gptp/linux/build/Makefile +++ b/daemons/gptp/linux/build/Makefile @@ -33,6 +33,19 @@ ALTERNATE_LINUX_INCPATH=$(HOME)/header/include/ CFLAGS_G = -Wall -std=c++0x -g -I. -I../../common -I../src \ -I$(ALTERNATE_LINUX_INCPATH) +# Check to see if PTP cross-timestamping is supported in hardware/driver +# and, if so, add flag to compile in support + +PRECISE_TIME_TEST = "\#include <linux/ptp_clock.h>\\n\ +\#ifdef PTP_SYS_OFFSET_PRECISE\\nint main(){return 0;}\\n\#endif" + +HAS_PRECISE_TIME = $(shell echo $(PRECISE_TIME_TEST) | gcc -xc - \ +-I$(ALTERNATE_LINUX_INCPATH) -o /dev/null > /dev/null 2>&1 ; echo $$?) + +ifeq ($(HAS_PRECISE_TIME),0) + CFLAGS_G += -DPTP_HW_CROSSTSTAMP +endif + CPPFLAGS_G = $(CFLAGS_G) -Wnon-virtual-dtor LDFLAGS_G = -lpthread -lrt diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp index 35282e9b..b5b46a10 100644 --- a/daemons/gptp/linux/src/daemon_cl.cpp +++ b/daemons/gptp/linux/src/daemon_cl.cpp @@ -363,10 +363,6 @@ int main(int argc, char **argv) portInit.lock_factory = lock_factory; pPort = new IEEE1588Port(&portInit); - if (!pPort->init_port(phy_delay)) { - printf("failed to initialize port \n"); - return -1; - } if(use_config_file) { @@ -408,6 +404,11 @@ int main(int argc, char **argv) } + if (!pPort->init_port(phy_delay)) { + printf("failed to initialize port \n"); + return -1; + } + if( restoredataptr != NULL ) { if( !restorefailed ) { restorefailed = !pPort->restoreSerializedState( restoredataptr, &restoredatacount ); diff --git a/daemons/gptp/linux/src/linux_hal_generic.cpp b/daemons/gptp/linux/src/linux_hal_generic.cpp index b1dc2485..1dbcbc18 100644 --- a/daemons/gptp/linux/src/linux_hal_generic.cpp +++ b/daemons/gptp/linux/src/linux_hal_generic.cpp @@ -222,7 +222,9 @@ bool LinuxTimestamperGeneric::HWTimestamper_init cross_stamp_good = false; int phc_index; char ptp_device[] = PTP_DEVICE; - +#ifdef PTP_HW_CROSSTSTAMP + struct ptp_clock_caps ptp_capability; +#endif _private = new LinuxTimestamperGenericPrivate; pthread_mutex_init( &_private->cross_stamp_lock, NULL ); @@ -244,6 +246,16 @@ bool LinuxTimestamperGeneric::HWTimestamper_init return false; } +#ifdef PTP_HW_CROSSTSTAMP + // Query PTP stack for availability of HW cross-timestamp + if( ioctl( phc_fd, PTP_CLOCK_GETCAPS, &ptp_capability ) == -1 ) + { + GPTP_LOG_ERROR( "Failed to query PTP clock capabilities" ); + return false; + } + precise_timestamp_enabled = ptp_capability.cross_timestamping; +#endif + if( !resetFrequencyAdjustment() ) { GPTP_LOG_ERROR( "Failed to reset (zero) frequency adjustment" ); return false; @@ -411,20 +423,39 @@ static inline Timestamp pctTimestamp( struct ptp_clock_time *t ) { return result; } +// Use HW cross-timestamp if available bool LinuxTimestamperGeneric::HWTimestamper_gettime ( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, uint32_t *nominal_clock_rate ) { - unsigned i; - struct ptp_sys_offset offset; - struct ptp_clock_time *pct; - struct ptp_clock_time *system_time_l, *device_time_l; + if( phc_fd == -1 ) + return false; - int64_t interval = LLONG_MAX; +#ifdef PTP_HW_CROSSTSTAMP + if( precise_timestamp_enabled ) + { + struct ptp_sys_offset_precise offset; + memset( &offset, 0, sizeof(offset)); + if( ioctl( phc_fd, PTP_SYS_OFFSET_PRECISE, &offset ) == 0 ) + { + *device_time = pctTimestamp( &offset.device ); + *system_time = pctTimestamp( &offset.sys_realtime ); + + return true; + } + } +#endif + + { + unsigned i; + struct ptp_clock_time *pct; + struct ptp_clock_time *system_time_l, *device_time_l; + int64_t interval = LLONG_MAX; + struct ptp_sys_offset offset; - if( phc_fd != -1 ) { memset( &offset, 0, sizeof(offset)); offset.n_samples = PTP_MAX_SAMPLES; - ioctl( phc_fd, PTP_SYS_OFFSET, &offset ); + if( ioctl( phc_fd, PTP_SYS_OFFSET, &offset ) == -1 ) + return false; pct = &offset.ts[0]; for( i = 0; i < offset.n_samples; ++i ) { @@ -439,9 +470,7 @@ bool LinuxTimestamperGeneric::HWTimestamper_gettime *device_time = pctTimestamp( device_time_l ); *system_time = pctTimestamp( system_time_l ); - - return true; } - return false; + return true; } diff --git a/daemons/gptp/linux/src/linux_hal_generic.hpp b/daemons/gptp/linux/src/linux_hal_generic.hpp index 5b33dad5..abe1f276 100644 --- a/daemons/gptp/linux/src/linux_hal_generic.hpp +++ b/daemons/gptp/linux/src/linux_hal_generic.hpp @@ -62,6 +62,9 @@ private: bool cross_stamp_good; std::list<Timestamp> rxTimestampList; LinuxNetworkInterfaceList iface_list; +#ifdef PTP_HW_CROSSTSTAMP + bool precise_timestamp_enabled; +#endif TicketingLock *net_lock; diff --git a/daemons/mrpd/mrp.c b/daemons/mrpd/mrp.c index 1537facf..3a162b37 100644 --- a/daemons/mrpd/mrp.c +++ b/daemons/mrpd/mrp.c @@ -665,7 +665,6 @@ int mrp_applicant_fsm(struct mrp_database *mrp_db, optional = 1; tx = 1; sndmsg = MRP_SND_IN; - mrp_state = MRP_VO_STATE; break; default: break; diff --git a/kmod/igb/igb.h b/kmod/igb/igb.h index edd858b3..1da12050 100644 --- a/kmod/igb/igb.h +++ b/kmod/igb/igb.h @@ -575,7 +575,6 @@ struct igb_adapter { /* OS defined structs */ struct pci_dev *pdev; /* user-dma specific variables */ - struct igb_user_page *userpages; u32 uring_tx_init; u32 uring_rx_init; #ifndef HAVE_NETDEV_STATS_IN_NETDEV @@ -895,4 +894,13 @@ struct igb_link_cmd { u32 duplex; }; +struct igb_private_data { + struct igb_adapter *adapter; + /* user-dma specific variable for buffer */ + struct igb_user_page *userpages; + /* user-dma specific variable for TX and RX */ + u32 uring_tx_init; + u32 uring_rx_init; +}; + #endif /* _IGB_H_ */ diff --git a/kmod/igb/igb_main.c b/kmod/igb/igb_main.c index f1534180..79dead8f 100644 --- a/kmod/igb/igb_main.c +++ b/kmod/igb/igb_main.c @@ -2686,7 +2686,6 @@ static int igb_probe(struct pci_dev *pdev, adapter->msg_enable = (1 << debug) - 1; /* AVB specific */ - adapter->userpages = NULL; adapter->uring_tx_init = 0; adapter->uring_rx_init = 0; mutex_init(&adapter->lock); @@ -10137,6 +10136,7 @@ static struct igb_adapter *igb_lookup(char *id) static int igb_bind(struct file *file, void __user *argp) { + struct igb_private_data *igb_priv = file->private_data; struct igb_adapter *adapter; struct igb_bind_cmd req; int err = 0; @@ -10146,13 +10146,18 @@ static int igb_bind(struct file *file, void __user *argp) printk("bind to iface %s\n", req.iface); + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + adapter = igb_lookup(req.iface); if (adapter == NULL) { printk("lookup failed to iface %s\n", req.iface); return -ENOENT; } - file->private_data = adapter; + igb_priv->adapter = adapter; req.mmap_size = 0; req.mmap_size = pci_resource_len(adapter->pdev, 0); @@ -10166,30 +10171,41 @@ static int igb_bind(struct file *file, void __user *argp) return 0; failed: - file->private_data = NULL; + igb_priv->adapter = NULL; return err; } static int igb_unbind(struct file *file) { struct igb_adapter *adapter; + struct igb_private_data *igb_priv = file->private_data; - adapter = file->private_data; + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + adapter = igb_priv->adapter; if (adapter == NULL) return -EBADFD; - file->private_data = NULL; + igb_priv->adapter = NULL; return 0; } static long igb_getspeed(struct file *file, void __user *arg) { + struct igb_private_data *igb_priv = file->private_data; struct igb_adapter *adapter; struct igb_link_cmd req; u32 link; - adapter = file->private_data; + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + + adapter = igb_priv->adapter; if (adapter == NULL) { printk("map to unbound device!\n"); return -ENOENT; @@ -10213,16 +10229,118 @@ static long igb_getspeed(struct file *file, void __user *arg) return 0; } +static long igb_mapbuf_user(struct file *file, void __user *arg, int ring) +{ + struct igb_private_data *igb_priv = file->private_data; + struct igb_adapter *adapter; + struct igb_buf_cmd req; + int err = 0; + struct page *page; + dma_addr_t page_dma; + struct igb_user_page *userpage; + + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + + adapter = igb_priv->adapter; + if (adapter == NULL) { + printk("map to unbound device!\n"); + return -ENOENT; + } + + if (copy_from_user(&req, arg, sizeof(req))) + return -EFAULT; + + userpage = vzalloc(sizeof(struct igb_user_page)); + if (unlikely(!userpage)) { + err = -ENOMEM; + goto failed; + } + + mutex_lock(&adapter->lock); + if (igb_priv->userpages == NULL) { + igb_priv->userpages = userpage; + } else { + userpage->next = igb_priv->userpages; + igb_priv->userpages->prev = userpage; + igb_priv->userpages = userpage; + } + +#if defined(CONFIG_IGB_SUPPORT_32BIT_IOCTL) +#if defined(CONFIG_ZONE_DMA32) + page = alloc_page(GFP_ATOMIC | __GFP_COLD | GFP_DMA32); +#else /* defined(CONFIG_ZONE_DMA32) */ + page = alloc_page(GFP_ATOMIC | __GFP_COLD | GFP_DMA); +#endif /* defined(CONFIG_ZONE_DMA32) */ +#else /* defined(CONFIG_IGB_SUPPORT_32BIT_IOCTL) */ + page = alloc_page(GFP_ATOMIC | __GFP_COLD); +#endif /* defined(CONFIG_IGB_SUPPORT_32BIT_IOCTL) */ + if (unlikely(!page)) { + err = -ENOMEM; + goto page_failed; + } + + page_dma = dma_map_page(pci_dev_to_dev(adapter->pdev), page, + 0, PAGE_SIZE, DMA_FROM_DEVICE); + + if (dma_mapping_error(pci_dev_to_dev(adapter->pdev), page_dma)) { + err = -ENOMEM; + goto map_failed; + } + + igb_priv->userpages->page = page; + igb_priv->userpages->page_dma = page_dma; + + req.physaddr = page_dma; + req.mmap_size = PAGE_SIZE; + mutex_unlock(&adapter->lock); + + if (copy_to_user(arg, &req, sizeof(req))) { + printk("copyout to user failed\n"); + err = -EFAULT; + mutex_lock(&adapter->lock); + goto copy_failed; + } + + return 0; + +copy_failed: + dma_unmap_page(pci_dev_to_dev(adapter->pdev), + userpage->page_dma, PAGE_SIZE, + DMA_FROM_DEVICE); +map_failed: + put_page(userpage->page); +page_failed: + if (userpage->prev) + userpage->prev->next = userpage->next; + if (userpage->next) + userpage->next->prev = userpage->prev; + if (userpage == igb_priv->userpages) + igb_priv->userpages = userpage->next; + vfree(userpage); + mutex_unlock(&adapter->lock); +failed: + return err; +} + static long igb_mapbuf(struct file *file, void __user *arg, int ring) { + struct igb_private_data *igb_priv = file->private_data; struct igb_adapter *adapter; struct igb_buf_cmd req; int err = 0; + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - adapter = file->private_data; + adapter = igb_priv->adapter; if (adapter == NULL) { printk("map to unbound device!\n"); return -ENOENT; @@ -10235,15 +10353,19 @@ static long igb_mapbuf(struct file *file, void __user *arg, int ring) return -EINVAL; } + mutex_lock(&adapter->lock); if (adapter->uring_tx_init & (1 << req.queue)) { + mutex_unlock(&adapter->lock); printk("mapring:queue in use (%d)\n", req.queue); return -EBUSY; } adapter->uring_tx_init |= (1 << req.queue); + igb_priv->uring_tx_init |= (1 << req.queue); req.physaddr = adapter->tx_ring[req.queue]->dma; req.mmap_size = adapter->tx_ring[req.queue]->size; + mutex_unlock(&adapter->lock); } else if (ring == IGB_MAP_RX_RING) { if (req.queue >= 3) { printk("mapring:invalid queue specified(%d)\n", @@ -10251,66 +10373,22 @@ static long igb_mapbuf(struct file *file, void __user *arg, int ring) return -EINVAL; } + mutex_lock(&adapter->lock); if (adapter->uring_rx_init & (1 << req.queue)) { + mutex_unlock(&adapter->lock); printk("mapring:queue in use (%d)\n", req.queue); return -EBUSY; } adapter->uring_rx_init |= (1 << req.queue); + igb_priv->uring_rx_init |= (1 << req.queue); req.physaddr = adapter->rx_ring[req.queue]->dma; req.mmap_size = adapter->rx_ring[req.queue]->size; - } else { - struct page *page; - dma_addr_t page_dma; - struct igb_user_page *userpage; - - userpage = vzalloc(sizeof(struct igb_user_page)); - if (unlikely(!userpage)) { - err = -ENOMEM; - goto failed; - } - - mutex_lock(&adapter->lock); - if (adapter->userpages == NULL) { - adapter->userpages = userpage; - } else { - userpage->next = adapter->userpages; - adapter->userpages->prev = userpage; - adapter->userpages = userpage; - } - -#if defined(CONFIG_IGB_SUPPORT_32BIT_IOCTL) -#if defined(CONFIG_ZONE_DMA32) - page = alloc_page(GFP_ATOMIC | __GFP_COLD | GFP_DMA32); -#else /* defined(CONFIG_ZONE_DMA32) */ - page = alloc_page(GFP_ATOMIC | __GFP_COLD | GFP_DMA); -#endif /* defined(CONFIG_ZONE_DMA32) */ -#else /* defined(CONFIG_IGB_SUPPORT_32BIT_IOCTL) */ - page = alloc_page(GFP_ATOMIC | __GFP_COLD); -#endif /* defined(CONFIG_IGB_SUPPORT_32BIT_IOCTL) */ - if (unlikely(!page)) { - err = -ENOMEM; - mutex_unlock(&adapter->lock); - goto failed; - } - - page_dma = dma_map_page(pci_dev_to_dev(adapter->pdev), page, - 0, PAGE_SIZE, DMA_FROM_DEVICE); - - if (dma_mapping_error(pci_dev_to_dev(adapter->pdev), page_dma)) { - put_page(page); - err = -ENOMEM; - mutex_unlock(&adapter->lock); - goto failed;; - } - - adapter->userpages->page = page; - adapter->userpages->page_dma = page_dma; - - req.physaddr = page_dma; - req.mmap_size = PAGE_SIZE; mutex_unlock(&adapter->lock); + } else { + printk("mapring: invalid ioctl %d\n", _IOC_NR(ring)); + return -EINVAL; } if (copy_to_user(arg, &req, sizeof(req))) { @@ -10328,13 +10406,19 @@ failed: static long igb_unmapbuf(struct file *file, void __user *arg, int ring) { int err = 0; + struct igb_private_data *igb_priv = file->private_data; struct igb_adapter *adapter; struct igb_buf_cmd req; + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; - adapter = file->private_data; + adapter = igb_priv->adapter; if (adapter == NULL) { printk("map to unbound device!\n"); return -ENOENT; @@ -10345,25 +10429,43 @@ static long igb_unmapbuf(struct file *file, void __user *arg, int ring) if (req.queue >= 3) return -EINVAL; - if (0 == (adapter->uring_tx_init & (1 << req.queue))) + mutex_lock(&adapter->lock); + if (0 == (igb_priv->uring_tx_init & (1 << req.queue))) { + mutex_unlock(&adapter->lock); return -EINVAL; + } else { + if (0 == (adapter->uring_tx_init & (1 << req.queue))) { + printk("Warning: invalid tx ring buffer state!\n"); + } + } adapter->uring_tx_init &= ~(1 << req.queue); + igb_priv->uring_tx_init &= ~(1 << req.queue); + mutex_unlock(&adapter->lock); } else if (ring == IGB_UNMAP_RX_RING) { /* its easy to figure out what to free on the rings ... */ if (req.queue >= 3) return -EINVAL; - if (0 == (adapter->uring_rx_init & (1 << req.queue))) + mutex_lock(&adapter->lock); + if (0 == (igb_priv->uring_rx_init & (1 << req.queue))) { + mutex_unlock(&adapter->lock); return -EINVAL; + } else { + if (0 == (adapter->uring_rx_init & (1 << req.queue))) { + printk("Warning: invalid rx ring buffer state!\n"); + } + } adapter->uring_rx_init &= ~(1 << req.queue); + igb_priv->uring_rx_init &= ~(1 << req.queue); + mutex_unlock(&adapter->lock); } else { /* have to find the corresponding page to free */ - struct igb_user_page *userpage; + struct igb_user_page *userpage; mutex_lock(&adapter->lock); - userpage = adapter->userpages; + userpage = igb_priv->userpages; while (userpage != NULL) { if (req.physaddr == userpage->page_dma) @@ -10390,8 +10492,8 @@ static long igb_unmapbuf(struct file *file, void __user *arg, int ring) if (userpage->next) userpage->next->prev = userpage->prev; - if (userpage == adapter->userpages) - adapter->userpages = userpage->next; + if (userpage == igb_priv->userpages) + igb_priv->userpages = userpage->next; vfree(userpage); mutex_unlock(&adapter->lock); @@ -10414,9 +10516,11 @@ static long igb_ioctl_file(struct file *file, unsigned int cmd, break; case IGB_MAP_TX_RING: case IGB_MAP_RX_RING: - case IGB_MAPBUF: err = igb_mapbuf(file, argp, cmd); break; + case IGB_MAPBUF: + err = igb_mapbuf_user(file, argp, cmd); + break; case IGB_UNMAP_TX_RING: case IGB_UNMAP_RX_RING: case IGB_UNMAPBUF: @@ -10435,37 +10539,67 @@ static long igb_ioctl_file(struct file *file, unsigned int cmd, static int igb_open_file(struct inode *inode, struct file *file) { - file->private_data = NULL; - return 0; + struct igb_private_data *igb_priv = NULL; + int ret = 0; + + igb_priv = kzalloc(sizeof(struct igb_private_data *), GFP_KERNEL); + if (igb_priv == NULL) { + ret = -ENOMEM; + goto out; + } + igb_priv->uring_tx_init = 0; + igb_priv->uring_rx_init = 0; + igb_priv->userpages = NULL; + igb_priv->adapter = NULL; +out: + file->private_data = igb_priv; + return ret; } static int igb_close_file(struct inode *inode, struct file *file) { - struct igb_adapter *adapter = file->private_data; - int err; + struct igb_private_data *igb_priv = file->private_data; + struct igb_adapter *adapter = NULL; + int err = 0; int i; struct igb_user_page *userpage; + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + + adapter = igb_priv->adapter; if (adapter == NULL) - return 0; + goto out; + mutex_lock(&adapter->lock); /* free up any rings and user-mapped pages */ for (i = 0; i < 3; i++) { - if (adapter->uring_tx_init & (1 << i)) { - igb_free_tx_resources(adapter->tx_ring[i]); + if (igb_priv->uring_tx_init & (1 << i)) { + if (adapter->uring_tx_init & (1 << i)) { + igb_free_tx_resources(adapter->tx_ring[i]); + } else { + printk("Warning: invalid tx ring buffer state!\n"); + } adapter->uring_tx_init &= ~(1 << i); + igb_priv->uring_tx_init &= ~(1 << i); } } for (i = 0; i < 3; i++) { - if (adapter->uring_rx_init & (1 << i)) { - igb_free_rx_resources(adapter->rx_ring[i]); + if (igb_priv->uring_rx_init & (1 << i)) { + if (adapter->uring_rx_init & (1 << i)) { + igb_free_rx_resources(adapter->rx_ring[i]); + } else { + printk("Warning: invalid rx ring buffer state!\n"); + } adapter->uring_rx_init &= ~(1 << i); + igb_priv->uring_rx_init &= ~(1 << i); } } - mutex_lock(&adapter->lock); - userpage = adapter->userpages; + userpage = igb_priv->userpages; while (userpage != NULL) { dma_unmap_page(pci_dev_to_dev(adapter->pdev), @@ -10482,15 +10616,18 @@ static int igb_close_file(struct inode *inode, struct file *file) if (userpage->next) userpage->next->prev = userpage->prev; - if (userpage == adapter->userpages) - adapter->userpages = userpage->next; + if (userpage == igb_priv->userpages) + igb_priv->userpages = userpage->next; vfree(userpage); - userpage = adapter->userpages; + userpage = igb_priv->userpages; } mutex_unlock(&adapter->lock); err = igb_unbind(file); +out: + file->private_data = NULL; + kfree(igb_priv); return err; } @@ -10509,11 +10646,18 @@ static int igb_vm_fault(struct vm_area_struct *area, struct vm_fault *fdata) static int igb_mmap(struct file *file, struct vm_area_struct *vma) { - struct igb_adapter *adapter = file->private_data; + struct igb_private_data *igb_priv = file->private_data; + struct igb_adapter *adapter = NULL; unsigned long size = vma->vm_end - vma->vm_start; dma_addr_t pgoff = vma->vm_pgoff; dma_addr_t physaddr; + if (igb_priv == NULL) { + printk("cannot find private data!\n"); + return -ENOENT; + } + + adapter = igb_priv->adapter; if (adapter == NULL) return -ENODEV; diff --git a/lib/avtp_pipeline/platform/Linux/tl/openavb_tl_osal.c b/lib/avtp_pipeline/platform/Linux/tl/openavb_tl_osal.c index d6ca4264..d10ab6b8 100644 --- a/lib/avtp_pipeline/platform/Linux/tl/openavb_tl_osal.c +++ b/lib/avtp_pipeline/platform/Linux/tl/openavb_tl_osal.c @@ -297,11 +297,8 @@ static int openavbTLCfgCallback(void *user, const char *tlSection, const char *n } } else if (MATCH(name, "ifname")) { - if_info_t ifinfo; - if (openavbCheckInterface(value, &ifinfo)) { - strncpy(pCfg->ifname, value, IFNAMSIZ - 1); - valOK = TRUE; - } + strncpy(pCfg->ifname, value, IFNAMSIZ - 1); + valOK = TRUE; } else if (MATCH(name, "vlan_id")) { errno = 0; @@ -405,6 +402,13 @@ EXTERN_DLL_EXPORT bool openavbTLReadIniFileOsal(tl_handle_t TLhandle, const char parseIniData.pNVCfg = pNVCfg; int result = ini_parse(fileName, openavbTLCfgCallback, &parseIniData); + if (result == 0) { + if_info_t ifinfo; + if (!openavbCheckInterface(&parseIniData.pCfg->ifname, &ifinfo)) { + AVB_LOGF_ERROR("Invalid value: name=%s, value=%s", "ifname", parseIniData.pCfg->ifname); + return FALSE; + } + } if (result < 0) { AVB_LOGF_ERROR("Couldn't parse INI file: %s", fileName); return FALSE; diff --git a/lib/avtp_pipeline/tl/openavb_talker.c b/lib/avtp_pipeline/tl/openavb_talker.c index 8bc6ca42..ed623a26 100644 --- a/lib/avtp_pipeline/tl/openavb_talker.c +++ b/lib/avtp_pipeline/tl/openavb_talker.c @@ -170,7 +170,7 @@ void talkerStopStream(tl_state_t *pTLState) openavbTalkerGetStat(pTLState, TL_STAT_TX_FRAMES), openavbTalkerGetStat(pTLState, TL_STAT_TX_LATE), openavbTalkerGetStat(pTLState, TL_STAT_TX_BYTES), - openavbRawsockGetTXOutOfBuffers(rawsock) + rawsock ? openavbRawsockGetTXOutOfBuffers(rawsock) : 0 ); if (pTLState->bStreaming) { |