From b9a769d65decf20c811fdec092a956a2d0cecf66 Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Mon, 15 May 2017 07:20:32 -0600 Subject: [PATCH 1/6] drivers: fix some bad NULL checks --- drivers/audio/audio_null.c | 6 ++---- drivers/input/ajoystick.c | 10 ++++++---- drivers/input/djoystick.c | 10 ++++++---- drivers/modem/u-blox.c | 12 ++++++++---- drivers/pwm.c | 12 ++++++++---- drivers/sensors/qencoder.c | 9 ++++++--- drivers/timers/timer.c | 9 ++++++--- drivers/timers/watchdog.c | 12 ++++++++---- 8 files changed, 50 insertions(+), 30 deletions(-) diff --git a/drivers/audio/audio_null.c b/drivers/audio/audio_null.c index d6c522101a..4ed7a010a6 100644 --- a/drivers/audio/audio_null.c +++ b/drivers/audio/audio_null.c @@ -653,6 +653,8 @@ static int null_enqueuebuffer(FAR struct audio_lowerhalf_s *dev, FAR struct null_dev_s *priv = (FAR struct null_dev_s *)dev; bool done; + DEBUGASSERT(priv && apb && priv->dev.upper); + audinfo("apb=%p curbyte=%d nbytes=%d\n", apb, apb->curbyte, apb->nbytes); /* Say that we consumed all of the data */ @@ -663,10 +665,6 @@ static int null_enqueuebuffer(FAR struct audio_lowerhalf_s *dev, done = ((apb->flags & AUDIO_APB_FINAL) != 0); - /* And return the buffer to the upper level */ - - DEBUGASSERT(priv && apb && priv->dev.upper); - /* The buffer belongs to to an upper level. Just forward the event to * the next level up. */ diff --git a/drivers/input/ajoystick.c b/drivers/input/ajoystick.c index 2868e1542a..76c93e43c7 100644 --- a/drivers/input/ajoystick.c +++ b/drivers/input/ajoystick.c @@ -201,7 +201,7 @@ static inline int ajoy_takesem(sem_t *sem) #if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) static void ajoy_enable(FAR struct ajoy_upperhalf_s *priv) { - FAR const struct ajoy_lowerhalf_s *lower = priv->au_lower; + FAR const struct ajoy_lowerhalf_s *lower; FAR struct ajoy_open_s *opriv; ajoy_buttonset_t press; ajoy_buttonset_t release; @@ -210,8 +210,9 @@ static void ajoy_enable(FAR struct ajoy_upperhalf_s *priv) int i; #endif - DEBUGASSERT(priv && priv->au_lower); + DEBUGASSERT(priv); lower = priv->au_lower; + DEBUGASSERT(lower); /* This routine is called both task level and interrupt level, so * interrupts must be disabled. @@ -295,7 +296,7 @@ static void ajoy_interrupt(FAR const struct ajoy_lowerhalf_s *lower, static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv) { - FAR const struct ajoy_lowerhalf_s *lower = priv->au_lower; + FAR const struct ajoy_lowerhalf_s *lower; FAR struct ajoy_open_s *opriv; ajoy_buttonset_t sample; #if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) @@ -308,8 +309,9 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv) int i; #endif - DEBUGASSERT(priv && priv->au_lower); + DEBUGASSERT(priv); lower = priv->au_lower; + DEBUGASSERT(lower); /* This routine is called both task level and interrupt level, so * interrupts must be disabled. diff --git a/drivers/input/djoystick.c b/drivers/input/djoystick.c index 62f62fe45a..c0559208fb 100644 --- a/drivers/input/djoystick.c +++ b/drivers/input/djoystick.c @@ -201,7 +201,7 @@ static inline int djoy_takesem(sem_t *sem) #if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) static void djoy_enable(FAR struct djoy_upperhalf_s *priv) { - FAR const struct djoy_lowerhalf_s *lower = priv->du_lower; + FAR const struct djoy_lowerhalf_s *lower; FAR struct djoy_open_s *opriv; djoy_buttonset_t press; djoy_buttonset_t release; @@ -210,8 +210,9 @@ static void djoy_enable(FAR struct djoy_upperhalf_s *priv) int i; #endif - DEBUGASSERT(priv && priv->du_lower); + DEBUGASSERT(priv); lower = priv->du_lower; + DEBUGASSERT(lower); /* This routine is called both task level and interrupt level, so * interrupts must be disabled. @@ -295,7 +296,7 @@ static void djoy_interrupt(FAR const struct djoy_lowerhalf_s *lower, static void djoy_sample(FAR struct djoy_upperhalf_s *priv) { - FAR const struct djoy_lowerhalf_s *lower = priv->du_lower; + FAR const struct djoy_lowerhalf_s *lower; FAR struct djoy_open_s *opriv; djoy_buttonset_t sample; #if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS) @@ -308,8 +309,9 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv) int i; #endif - DEBUGASSERT(priv && priv->du_lower); + DEBUGASSERT(priv); lower = priv->du_lower; + DEBUGASSERT(lower); /* This routine is called both task level and interrupt level, so * interrupts must be disabled. diff --git a/drivers/modem/u-blox.c b/drivers/modem/u-blox.c index 95a7fc29d2..014dac102e 100644 --- a/drivers/modem/u-blox.c +++ b/drivers/modem/u-blox.c @@ -141,13 +141,16 @@ static int ubxmdm_ioctl(FAR struct file* filep, unsigned long arg) { FAR struct inode* inode = filep->f_inode; - FAR struct ubxmdm_upper* upper = inode->i_private; - FAR struct ubxmdm_lower* lower = upper->lower; + FAR struct ubxmdm_upper* upper; + FAR struct ubxmdm_lower* lower; int ret; FAR struct ubxmdm_status* status; m_info("cmd: %d arg: %ld\n", cmd, arg); - DEBUGASSERT(upper && lower); + upper = inode->i_private; + DEBUGASSERT(upper != NULL); + lower = upper->lower; + DEBUGASSERT(lower != NULL); switch (cmd) { @@ -320,8 +323,9 @@ void ubxmdm_unregister(FAR void *handle) FAR struct ubxmdm_lower *lower; upper = (FAR struct ubxmdm_upper*) handle; + DEBUGASSERT(upper != NULL); lower = upper->lower; - DEBUGASSERT(upper && lower); + DEBUGASSERT(lower != NULL); m_info("Unregistering: %s\n", upper->path); diff --git a/drivers/pwm.c b/drivers/pwm.c index 78b60751c0..24c5ae4105 100644 --- a/drivers/pwm.c +++ b/drivers/pwm.c @@ -318,11 +318,13 @@ static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, #ifdef CONFIG_PWM_PULSECOUNT static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) { - FAR struct pwm_lowerhalf_s *lower = upper->dev; + FAR struct pwm_lowerhalf_s *lower; irqstate_t flags; int ret = OK; - DEBUGASSERT(upper != NULL && lower->ops->start != NULL); + DEBUGASSERT(upper != NULL); + lower = upper->dev; + DEBUGASSERT(lower != NULL && lower->ops->start != NULL); /* Verify that the PWM is not already running */ @@ -385,10 +387,12 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) #else static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags) { - FAR struct pwm_lowerhalf_s *lower = upper->dev; + FAR struct pwm_lowerhalf_s *lower; int ret = OK; - DEBUGASSERT(upper != NULL && lower->ops->start != NULL); + DEBUGASSERT(upper != NULL); + lower = upper->dev; + DEBUGASSERT(lower != NULL && lower->ops->start != NULL); /* Verify that the PWM is not already running */ diff --git a/drivers/sensors/qencoder.c b/drivers/sensors/qencoder.c index 7f6edd0978..ead9ec6de7 100644 --- a/drivers/sensors/qencoder.c +++ b/drivers/sensors/qencoder.c @@ -276,12 +276,15 @@ static ssize_t qe_write(FAR struct file *filep, FAR const char *buffer, size_t b static int qe_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; - FAR struct qe_upperhalf_s *upper = inode->i_private; - FAR struct qe_lowerhalf_s *lower = upper->lower; + FAR struct qe_upperhalf_s *upper; + FAR struct qe_lowerhalf_s *lower; int ret; sninfo("cmd: %d arg: %ld\n", cmd, arg); - DEBUGASSERT(upper && lower); + upper = inode->i_private; + DEBUGASSERT(upper != NULL); + lower = upper->lower; + DEBUGASSERT(lower != NULL); /* Get exclusive access to the device structures */ diff --git a/drivers/timers/timer.c b/drivers/timers/timer.c index 667be5276d..4cfdacaac7 100644 --- a/drivers/timers/timer.c +++ b/drivers/timers/timer.c @@ -254,12 +254,15 @@ static ssize_t timer_write(FAR struct file *filep, FAR const char *buffer, static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; - FAR struct timer_upperhalf_s *upper = inode->i_private; - FAR struct timer_lowerhalf_s *lower = upper->lower; + FAR struct timer_upperhalf_s *upper; + FAR struct timer_lowerhalf_s *lower; int ret; tmrinfo("cmd: %d arg: %ld\n", cmd, arg); - DEBUGASSERT(upper && lower); + upper = inode->i_private; + DEBUGASSERT(upper != NULL); + lower = upper->lower; + DEBUGASSERT(lower != NULL); /* Handle built-in ioctl commands */ diff --git a/drivers/timers/watchdog.c b/drivers/timers/watchdog.c index e9320a9612..7ccab15a06 100644 --- a/drivers/timers/watchdog.c +++ b/drivers/timers/watchdog.c @@ -240,12 +240,15 @@ static ssize_t wdog_write(FAR struct file *filep, FAR const char *buffer, size_t static int wdog_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; - FAR struct watchdog_upperhalf_s *upper = inode->i_private; - FAR struct watchdog_lowerhalf_s *lower = upper->lower; + FAR struct watchdog_upperhalf_s *upper; + FAR struct watchdog_lowerhalf_s *lower; int ret; wdinfo("cmd: %d arg: %ld\n", cmd, arg); - DEBUGASSERT(upper && lower); + upper = inode->i_private; + DEBUGASSERT(upper != NULL); + lower = upper->lower; + DEBUGASSERT(lower != NULL); /* Get exclusive access to the device structures */ @@ -533,8 +536,9 @@ void watchdog_unregister(FAR void *handle) /* Recover the pointer to the upper-half driver state */ upper = (FAR struct watchdog_upperhalf_s *)handle; + DEBUGASSERT(upper != NULL); lower = upper->lower; - DEBUGASSERT(upper && lower); + DEBUGASSERT(lower != NULL); wdinfo("Unregistering: %s\n", upper->path); From 34e68a569b8dcbddf0501c6bb0665d7941a908e2 Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Mon, 15 May 2017 07:22:17 -0600 Subject: [PATCH 2/6] drivers: rename newly introduced up_i2creset to I2C_RESET --- drivers/sensors/Kconfig | 1 + drivers/sensors/hts221.c | 8 ++++---- drivers/sensors/lis2dh.c | 6 ++++-- drivers/sensors/lps25h.c | 8 ++++---- drivers/usbmisc/fusb301.c | 8 ++++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index b5fc76cb41..03911022b5 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -201,6 +201,7 @@ config MS58XX_I2C_FREQUENCY config MS58XX_VDD int "MEAS MS58XX VDD" default 30 + depends on MS58XX config MPL115A bool "Freescale MPL115A Barometer Sensor support" diff --git a/drivers/sensors/hts221.c b/drivers/sensors/hts221.c index 59c5790ad5..9f3138bddf 100644 --- a/drivers/sensors/hts221.c +++ b/drivers/sensors/hts221.c @@ -201,10 +201,10 @@ static int hts221_do_transfer(FAR struct hts221_dev_s *priv, break; } - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - hts221_dbg("up_i2creset failed: %d\n", ret); + hts221_dbg("I2C_RESET failed: %d\n", ret); return ret; } #endif @@ -892,7 +892,7 @@ static int hts221_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; FAR struct hts221_dev_s *priv = inode->i_private; - int32_t ret = 0; + int ret = OK; while (sem_wait(&priv->devsem) != 0) { @@ -932,7 +932,7 @@ static int hts221_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; default: - ret = -EINVAL; + ret = -ENOTTY; break; } diff --git a/drivers/sensors/lis2dh.c b/drivers/sensors/lis2dh.c index b24aa782e3..f7a982f151 100644 --- a/drivers/sensors/lis2dh.c +++ b/drivers/sensors/lis2dh.c @@ -131,9 +131,11 @@ static int lis2dh_get_reading(FAR struct lis2dh_dev_s *dev, FAR struct lis2dh_vector_s *res, bool force_read); static int lis2dh_powerdown(FAR struct lis2dh_dev_s *dev); static int lis2dh_reboot(FAR struct lis2dh_dev_s *dev); +#ifndef CONFIG_DISABLE_POLL static int lis2dh_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); static void lis2dh_notify(FAR struct lis2dh_dev_s *priv); +#endif static int lis2dh_int_handler(int irq, FAR void *context, FAR void *arg); static int lis2dh_setup(FAR struct lis2dh_dev_s *dev, @@ -1614,10 +1616,10 @@ static int lis2dh_access(FAR struct lis2dh_dev_s *dev, uint8_t subaddr, { /* Some error. Try to reset I2C bus and keep trying. */ #ifdef CONFIG_I2C_RESET - int ret = up_i2creset(dev->i2c); + int ret = I2C_RESET(dev->i2c); if (ret < 0) { - lis2dh_dbg("up_i2creset failed: %d\n", ret); + lis2dh_dbg("I2C_RESET failed: %d\n", ret); return ret; } #endif diff --git a/drivers/sensors/lps25h.c b/drivers/sensors/lps25h.c index 3ebba98285..bd35f38043 100644 --- a/drivers/sensors/lps25h.c +++ b/drivers/sensors/lps25h.c @@ -257,10 +257,10 @@ static int lps25h_do_transfer(FAR struct lps25h_dev_s *dev, break; } - ret = up_i2creset(dev->i2c); + ret = I2C_RESET(dev->i2c); if (ret < 0) { - lps25h_dbg("up_i2creset failed: %d\n", ret); + lps25h_dbg("I2C_RESET failed: %d\n", ret); return ret; } #endif @@ -708,7 +708,7 @@ static int lps25h_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; FAR struct lps25h_dev_s *dev = inode->i_private; - int ret = 0; + int ret = OK; while (sem_wait(&dev->devsem) != 0) { @@ -742,7 +742,7 @@ static int lps25h_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; default: - ret = -EINVAL; + ret = -ENOTTY; break; } diff --git a/drivers/usbmisc/fusb301.c b/drivers/usbmisc/fusb301.c index c3627fd909..f24ae78558 100644 --- a/drivers/usbmisc/fusb301.c +++ b/drivers/usbmisc/fusb301.c @@ -176,10 +176,10 @@ static int fusb301_getreg(FAR struct fusb301_dev_s *priv, uint8_t reg) break; } - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - fusb301_err("ERROR: up_i2creset failed: %d\n", ret); + fusb301_err("ERROR: I2C_RESET failed: %d\n", ret); return ret; } #endif @@ -246,10 +246,10 @@ static int fusb301_putreg(FAR struct fusb301_dev_s *priv, uint8_t regaddr, break; } - ret = up_i2creset(priv->i2c); + ret = I2C_RESET(priv->i2c); if (ret < 0) { - fusb301_err("ERROR: up_i2creset failed: %d\n", ret); + fusb301_err("ERROR: I2C_RESET failed: %d\n", ret); return ret; } #endif From 914c5dad0cd846870efd5e6b10faf5d0bbb9febe Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 15 May 2017 08:10:43 -0600 Subject: [PATCH 3/6] TCP: An RST recevied suring the 3-way handshake requires a little more clean-up --- net/tcp/tcp_input.c | 40 +++++++++++++++++++++++++++++++++++++--- net/tcp/tcp_timer.c | 2 +- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 23bec6a6e5..d1addb0bbf 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -314,10 +314,44 @@ found: if ((tcp->flags & TCP_RST) != 0) { - conn->tcpstateflags = TCP_CLOSED; - nwarn("WARNING: RESET - TCP state: TCP_CLOSED\n"); + FAR struct tcp_conn_s *listener = NULL; + + /* An RST received during the 3-way connection handshake requires + * little more clean-up. + */ + + if ((conn->tcpstateflags & TCP_STATE_MASK) == TCP_SYN_RCVD) + { + conn->tcpstateflags = TCP_CLOSED; + nwarn("WARNING: RESET in TCP_SYN_RCVD\n"); + + /* Notify the listerner for connection of the reset event */ + + listener = tcp_findlistener(conn->lport); + + /* We must free this TCP connection structure, this connection + * will never be established. + */ + + tcp_free(conn); + } + else + { + conn->tcpstateflags = TCP_CLOSED; + nwarn("WARNING: RESET TCP state: TCP_CLOSED\n"); + + /* Notify this connection of the reset event */ + + listener = conn; + } + + /* Perform the TCP_ABORT callback and drop the packet */ + + if (listener != NULL) + { + (void)tcp_callback(dev, listener, TCP_ABORT); + } - (void)tcp_callback(dev, conn, TCP_ABORT); goto drop; } diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index a9047fc478..03935c964b 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -231,7 +231,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, FAR struct tcp_conn_s *listener; conn->tcpstateflags = TCP_CLOSED; - ninfo("TCP state: TCP_CLOSED\n"); + ninfo("TCP state: TCP_SYN_RCVD->TCP_CLOSED\n"); /* Find the listener for this connection. */ From 56c8456ff037583ce5b6ea6a3e74c22b1fb34409 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 16 May 2017 07:38:57 -0600 Subject: [PATCH 4/6] Update some comments. --- net/tcp/tcp_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index d1addb0bbf..a064fb0763 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -325,11 +325,11 @@ found: conn->tcpstateflags = TCP_CLOSED; nwarn("WARNING: RESET in TCP_SYN_RCVD\n"); - /* Notify the listerner for connection of the reset event */ + /* Notify the listener for the connection of the reset event */ listener = tcp_findlistener(conn->lport); - /* We must free this TCP connection structure, this connection + /* We must free this TCP connection structure; this connection * will never be established. */ From b8e7d5c455abd98deb11edb7bf682353ba438f6f Mon Sep 17 00:00:00 2001 From: Lederhilger Martin Date: Tue, 16 May 2017 07:47:18 -0600 Subject: [PATCH 5/6] I had the problem that the transmit FIFO size (= actual elements in FIFO) was slowly increasing over time, and was full after a few hours. The reason was that the code hit the line "canerr("ERROR: No available mailbox\n");" in stm32_cansend, so can_xmit thinks it has sent the packet to the hardware, but actually has not. Therefore the transmit interrupt never happens which would call can_txdone, and so the size of the FIFO size does not decrease. The reason why the code actually hit the mentioned line above, is because stm32can_txready uses a different (incomplete) condition than stm32can_send to determine if the mailbox can be used for sending, and thus can_xmit forwards the packet to stm32can_send. stm32can_txready considered mailboxes OK for sending if the mailbox was empty, but did not consider that mailboxes may not yet be used if the request completed bit is set - stm32can_txinterrupt has to process these mailboxes first. Note that I have also modified stm32can_txinterrupt - I removed the if condition, because the CAN controller retries to send the packet until it succeeds. Also if the condition would not evaluate to true, can_txdone would not be called and the FIFO size would not decrease also. --- arch/arm/src/stm32/stm32_can.c | 102 +++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 31 deletions(-) diff --git a/arch/arm/src/stm32/stm32_can.c b/arch/arm/src/stm32/stm32_can.c index 4497dd9766..9e23a48f36 100644 --- a/arch/arm/src/stm32/stm32_can.c +++ b/arch/arm/src/stm32/stm32_can.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/stm32/stm32_can.c * - * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. @@ -74,10 +74,6 @@ #define INAK_TIMEOUT 65535 -/* Mailboxes ****************************************************************/ - -#define CAN_ALL_MAILBOXES (CAN_TSR_TME0 | CAN_TSR_TME1 | CAN_TSR_TME2) - /* Bit timing ***************************************************************/ #define CAN_BIT_QUANTA (CONFIG_CAN_TSEG1 + CONFIG_CAN_TSEG2 + 1) @@ -172,6 +168,12 @@ static int stm32can_bittiming(FAR struct stm32_can_s *priv); static int stm32can_cellinit(FAR struct stm32_can_s *priv); static int stm32can_filterinit(FAR struct stm32_can_s *priv); +/* TX mailbox status */ + +static bool stm32can_txmb0empty(uint32_t tsr_regval); +static bool stm32can_txmb1empty(uint32_t tsr_regval); +static bool stm32can_txmb2empty(uint32_t tsr_regval); + /**************************************************************************** * Private Data ****************************************************************************/ @@ -1170,15 +1172,15 @@ static int stm32can_send(FAR struct can_dev_s *dev, /* Select one empty transmit mailbox */ regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET); - if ((regval & CAN_TSR_TME0) != 0 && (regval & CAN_TSR_RQCP0) == 0) + if (stm32can_txmb0empty(regval)) { txmb = 0; } - else if ((regval & CAN_TSR_TME1) != 0 && (regval & CAN_TSR_RQCP1) == 0) + else if (stm32can_txmb1empty(regval)) { txmb = 1; } - else if ((regval & CAN_TSR_TME2) != 0 && (regval & CAN_TSR_RQCP2) == 0) + else if (stm32can_txmb2empty(regval)) { txmb = 2; } @@ -1321,7 +1323,8 @@ static bool stm32can_txready(FAR struct can_dev_s *dev) regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET); caninfo("CAN%d TSR: %08x\n", priv->port, regval); - return (regval & CAN_ALL_MAILBOXES) != 0; + return stm32can_txmb0empty(regval) || stm32can_txmb1empty(regval) || + stm32can_txmb2empty(regval); } /**************************************************************************** @@ -1352,7 +1355,8 @@ static bool stm32can_txempty(FAR struct can_dev_s *dev) regval = stm32can_getreg(priv, STM32_CAN_TSR_OFFSET); caninfo("CAN%d TSR: %08x\n", priv->port, regval); - return (regval & CAN_ALL_MAILBOXES) == CAN_ALL_MAILBOXES; + return stm32can_txmb0empty(regval) && stm32can_txmb1empty(regval) && + stm32can_txmb2empty(regval); } /**************************************************************************** @@ -1553,14 +1557,9 @@ static int stm32can_txinterrupt(int irq, FAR void *context, FAR void *arg) stm32can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP0); - /* Check for errors */ + /* Tell the upper half that the transfer is finished. */ - if ((regval & CAN_TSR_TXOK0) != 0) - { - /* Tell the upper half that the tansfer is finished. */ - - (void)can_txdone(dev); - } + (void)can_txdone(dev); } /* Check for RQCP1: Request completed mailbox 1 */ @@ -1573,14 +1572,9 @@ static int stm32can_txinterrupt(int irq, FAR void *context, FAR void *arg) stm32can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP1); - /* Check for errors */ + /* Tell the upper half that the transfer is finished. */ - if ((regval & CAN_TSR_TXOK1) != 0) - { - /* Tell the upper half that the tansfer is finished. */ - - (void)can_txdone(dev); - } + (void)can_txdone(dev); } /* Check for RQCP2: Request completed mailbox 2 */ @@ -1593,14 +1587,9 @@ static int stm32can_txinterrupt(int irq, FAR void *context, FAR void *arg) stm32can_putreg(priv, STM32_CAN_TSR_OFFSET, CAN_TSR_RQCP2); - /* Check for errors */ + /* Tell the upper half that the transfer is finished. */ - if ((regval & CAN_TSR_TXOK2) != 0) - { - /* Tell the upper half that the tansfer is finished. */ - - (void)can_txdone(dev); - } + (void)can_txdone(dev); } return OK; @@ -2111,6 +2100,57 @@ static int stm32can_delstdfilter(FAR struct stm32_can_s *priv, int arg) return -ENOTTY; } +/**************************************************************************** + * Name: stm32can_txmb0empty + * + * Input Parameter: + * tsr_regval - value of CAN transmit status register + * + * Returned Value: + * Returns true if mailbox 0 is empty and can be used for sending. + * + ****************************************************************************/ + +static bool stm32can_txmb0empty(uint32_t tsr_regval) +{ + return (tsr_regval & CAN_TSR_TME0) != 0 && + (tsr_regval & CAN_TSR_RQCP0) == 0; +} + +/**************************************************************************** + * Name: stm32can_txmb1empty + * + * Input Parameter: + * tsr_regval - value of CAN transmit status register + * + * Returned Value: + * Returns true if mailbox 1 is empty and can be used for sending. + * + ****************************************************************************/ + +static bool stm32can_txmb1empty(uint32_t tsr_regval) +{ + return (tsr_regval & CAN_TSR_TME1) != 0 && + (tsr_regval & CAN_TSR_RQCP1) == 0; +} + +/**************************************************************************** + * Name: stm32can_txmb2empty + * + * Input Parameter: + * tsr_regval - value of CAN transmit status register + * + * Returned Value: + * Returns true if mailbox 2 is empty and can be used for sending. + * + ****************************************************************************/ + +static bool stm32can_txmb2empty(uint32_t tsr_regval) +{ + return (tsr_regval & CAN_TSR_TME2) != 0 && + (tsr_regval & CAN_TSR_RQCP2) == 0; +} + /**************************************************************************** * Public Functions ****************************************************************************/ From 5ef00f0b9192749d7fb2bb28524c40558f449f60 Mon Sep 17 00:00:00 2001 From: EunBong Song Date: Tue, 16 May 2017 08:01:05 -0600 Subject: [PATCH 6/6] drivers/bch: BCH character driver bch_ioctl() always returns -ENOTTY for DIOC_GETPRIV command. It should returns OK if DIOC_GETPRIV command succeeds. --- drivers/bch/bchdev_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bch/bchdev_driver.c b/drivers/bch/bchdev_driver.c index e74ef3f7f7..438bdfd9d0 100644 --- a/drivers/bch/bchdev_driver.c +++ b/drivers/bch/bchdev_driver.c @@ -339,12 +339,13 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg) bchlib_semtake(bch); if (!bchr || bch->refs == MAX_OPENCNT) { - ret = -EINVAL; + ret = -EINVAL; } else { bch->refs++; *bchr = bch; + ret = OK; } bchlib_semgive(bch);