* Re: [RFC V1 00/16] hci_ldisc hci_uart_tty_close() fixes
From: Marcel Holtmann @ 2017-04-03 15:51 UTC (permalink / raw)
To: Dean Jenkins; +Cc: Gustavo F. Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <ee49f939-1094-0ae0-0fa7-6c5cad112527@mentor.com>
Hi Dean,
>>> This is RFC patchset V1 which reorganises hci_uart_tty_close() to overcome a
>>> design flaw. I would like some comments on the changes.
>>>
>>> Design Flaw
>>> ===========
>>>
>>> An example callstack is as follows
>>>
>>> Have Bluetooth running using a BCSP based UART Bluetooth Radio Module.
>>>
>>> Now kill the userland hciattach program by doing
>>> killall hciattach
>> is there any chance we can convert BCSP support to run fully inside the kernel with the new parts we have put in. And with that then also use btattach. The split of some parts of BCSP in userspace seems never been a good idea.
>
> I am not aware of "the new parts we [you] have put in" to the kernel because I am working with the older 3.14 kernel with userland components that are not Bluez based but the kernel issue is observable. Is there a web page where I can find out about your design changes for the new parts ?
>
> My efforts are to improve the latest upstream kernel to eliminate this kernel design flaw in HCI UART LDISC (Note TTY LDISC is also broken but not fixed by my patchset).
>
> I see that "btattach" is at https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/tools/btattach.c, however, I am unable to identify whether Linux distributions such as Ubuntu have a bluez package that contains "btattach". Is "btattach" a replacement for "hciattach” ?
yes, we want to move towards btattach that just assigned the line discipline and selects the UART protocol. Everything else including firmware download, speed changes, recover etc. should be done inside the kernel.
And later with serdev, we would not even need btattach anymore. UART based Bluetooth devices would be enumerated via DT and the TTY not even exposed to userspace. We are slowly getting to that point.
The latest kernel has UART drivers like hci_intel.c and hci_bcm.c which do a lot of things in the kernel. And btattach is just the process that keeps the line discipline open.
>> I am a bit reluctant to change major hci_ldisc pieces because of just one broken protocol. Running BCSP fully in the kernel seems a better solution to deal with some of these issues.
>
> The kernel BCSP software in the kernel is not broken although it is not fully implemented as you already highlighted. The issue is that HCI UART LDISC (and TTY LDISC) has a broken procedure for closing down the HCI UART device via hci_uart_tty_close().
>
> This means that I don't see how your suggestion helps to resolve the kernel design flaw which is related to closing down any of the Bluetooth Data Link protocol layers such as H4, H5, and BCSP (I use BCSP). This flaw seems to me to be a long standing Bluetooth kernel Data Link protocol layer closedown issue and is unrelated to how the Data Link protocol layer is established (connected). Therefore, having BCSP partly in userland is irrelevant to this kernel design flaw. Even with BCSP fully in the kernel, the protocol closedown issue will remain present I think.
If you think there are issues, then lets fix them for all protocols. I assumed this was BCSP specific.
> I might try to build "btattach" and have a go to use it. If you look inside the source code of "btattach" and "hciattach" you can see the problem area in closing down an established Bluetooth Data Link protocol layer by the use of:
>
> if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
> perror("Failed set serial line discipline");
> close(fd);
> return -1;
> }
>
> This userland call is the problem area as this asynchronous ioctl TIOCSETD can cause hci_uart_tty_close() to run and I think it can cause trouble for ALL the Bluetooth Data Link protocol layers such as H4, H5 and BCSP.
>
> The design flaw is exposed after the Data Link protocol layer has been established (connected) and ioctl TIOCSETD is used from userland. In my example, I killed "hciattach" which is an abnormal scenario but it still needs good handling. I think I have strace evidence of TIOCSETD being used due to SIGTERM.
>
> The design flaw is because TIOCSETD can trigger the sending of a HCI RESET command during closedown of HCI UART LDISC, TTY LDISC and the Data Link protocol layer. I only have experience of BCSP but I suspect H4 and H5 have retransmission procedures similar to BCSP so would also be susceptible to this issue of trying to send a HCI RESET command whilst closing down the needed data path to the UART driver which causes sending of the HCI RESET command to be unsuccessful.
>
> I think the callstack is:
>
> Userland ioctl TIOCSETD executes causing =>
> Kernel ioctl system call which runs
> tty_ioctl()
> tiocsetd()
> tty_set_ldisc()
> tty_ldisc_close()
> hci_uart_tty_close()
> hci_unregister_dev()
> hci_dev_do_close()
> __hci_req_sync() which tries to send a HCI RESET command which depends on
> HCI_QUIRK_RESET_ON_CLOSE being enabled and that is the default condition
>
> I believe It will affect the closure of any of the Bluetooth Data Link protocol layers.
>
> Note that not enabling HCI_QUIRK_RESET_ON_CLOSE does not fully help because if Data Link protocol layer retransmissions are occurring when hci_uart_tty_close() runs then the various race conditions are still present in hci_uart_tty_close().
>
> I suspect evidence of the design flaw can be observed by measuring the execution time of the userland ioctl TIOCSETD calls. I predict that sometimes it will take 2 seconds for TIOCSETD to complete due to being blocked waiting for the unsuccessful attempt at sending the HCI RESET command because the HCI command time-out expires. I believe this will be independent of the underlying Bluetooth Data Link protocol layer.
>
> Do you have any suggestions for moving forward in accepting my proposed changes ? I will try to provide more observable evidence of the issue on kernel v.4.10 on a Linux PC.
If this is an issue in 4.10, then lets get this fixed / hardened.
Regards
Marcel
^ permalink raw reply
* Re: [RFC V1 00/16] hci_ldisc hci_uart_tty_close() fixes
From: Dean Jenkins @ 2017-04-03 15:09 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: Gustavo F. Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <AA3DD0DD-5CAC-4ADD-9B0C-4E652C93E4D6@holtmann.org>
Hi Marcel,
On 30/03/17 11:11, Marcel Holtmann wrote:
> Hi Dean,
>
>> This is RFC patchset V1 which reorganises hci_uart_tty_close() to overcome a
>> design flaw. I would like some comments on the changes.
>>
>> Design Flaw
>> ===========
>>
>> An example callstack is as follows
>>
>> Have Bluetooth running using a BCSP based UART Bluetooth Radio Module.
>>
>> Now kill the userland hciattach program by doing
>> killall hciattach
> is there any chance we can convert BCSP support to run fully inside the kernel with the new parts we have put in. And with that then also use btattach. The split of some parts of BCSP in userspace seems never been a good idea.
I am not aware of "the new parts we [you] have put in" to the kernel
because I am working with the older 3.14 kernel with userland components
that are not Bluez based but the kernel issue is observable. Is there a
web page where I can find out about your design changes for the new parts ?
My efforts are to improve the latest upstream kernel to eliminate this
kernel design flaw in HCI UART LDISC (Note TTY LDISC is also broken but
not fixed by my patchset).
I see that "btattach" is at
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/tools/btattach.c,
however, I am unable to identify whether Linux distributions such as
Ubuntu have a bluez package that contains "btattach". Is "btattach" a
replacement for "hciattach" ?
>
> I am a bit reluctant to change major hci_ldisc pieces because of just one broken protocol. Running BCSP fully in the kernel seems a better solution to deal with some of these issues.
The kernel BCSP software in the kernel is not broken although it is not
fully implemented as you already highlighted. The issue is that HCI UART
LDISC (and TTY LDISC) has a broken procedure for closing down the HCI
UART device via hci_uart_tty_close().
This means that I don't see how your suggestion helps to resolve the
kernel design flaw which is related to closing down any of the Bluetooth
Data Link protocol layers such as H4, H5, and BCSP (I use BCSP). This
flaw seems to me to be a long standing Bluetooth kernel Data Link
protocol layer closedown issue and is unrelated to how the Data Link
protocol layer is established (connected). Therefore, having BCSP partly
in userland is irrelevant to this kernel design flaw. Even with BCSP
fully in the kernel, the protocol closedown issue will remain present I
think.
I might try to build "btattach" and have a go to use it. If you look
inside the source code of "btattach" and "hciattach" you can see the
problem area in closing down an established Bluetooth Data Link protocol
layer by the use of:
if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
perror("Failed set serial line discipline");
close(fd);
return -1;
}
This userland call is the problem area as this asynchronous ioctl
TIOCSETD can cause hci_uart_tty_close() to run and I think it can cause
trouble for ALL the Bluetooth Data Link protocol layers such as H4, H5
and BCSP.
The design flaw is exposed after the Data Link protocol layer has been
established (connected) and ioctl TIOCSETD is used from userland. In my
example, I killed "hciattach" which is an abnormal scenario but it still
needs good handling. I think I have strace evidence of TIOCSETD being
used due to SIGTERM.
The design flaw is because TIOCSETD can trigger the sending of a HCI
RESET command during closedown of HCI UART LDISC, TTY LDISC and the Data
Link protocol layer. I only have experience of BCSP but I suspect H4 and
H5 have retransmission procedures similar to BCSP so would also be
susceptible to this issue of trying to send a HCI RESET command whilst
closing down the needed data path to the UART driver which causes
sending of the HCI RESET command to be unsuccessful.
I think the callstack is:
Userland ioctl TIOCSETD executes causing =>
Kernel ioctl system call which runs
tty_ioctl()
tiocsetd()
tty_set_ldisc()
tty_ldisc_close()
hci_uart_tty_close()
hci_unregister_dev()
hci_dev_do_close()
__hci_req_sync() which tries to send a HCI RESET command which depends on
HCI_QUIRK_RESET_ON_CLOSE being enabled and that is the default condition
I believe It will affect the closure of any of the Bluetooth Data Link
protocol layers.
Note that not enabling HCI_QUIRK_RESET_ON_CLOSE does not fully help
because if Data Link protocol layer retransmissions are occurring when
hci_uart_tty_close() runs then the various race conditions are still
present in hci_uart_tty_close().
I suspect evidence of the design flaw can be observed by measuring the
execution time of the userland ioctl TIOCSETD calls. I predict that
sometimes it will take 2 seconds for TIOCSETD to complete due to being
blocked waiting for the unsuccessful attempt at sending the HCI RESET
command because the HCI command time-out expires. I believe this will be
independent of the underlying Bluetooth Data Link protocol layer.
Do you have any suggestions for moving forward in accepting my proposed
changes ? I will try to provide more observable evidence of the issue on
kernel v.4.10 on a Linux PC.
Thanks for your time in looking at my proposed patches.
Best regards,
Dean
--
Dean Jenkins
Embedded Software Engineer
Linux Transportation Solutions
Mentor Embedded Software Division
Mentor Graphics (UK) Ltd.
^ permalink raw reply
* [PATCH 3/3] Bluetooth: L2CAP: Don't return -EAGAIN if out of credits
From: Luiz Augusto von Dentz @ 2017-04-03 14:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: aar, jukka.rissanen, linux-wpan
In-Reply-To: <20170403144857.4661-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Just keep queueing them into TX queue since the caller might just have
to do the same and there is no impact in adding another packet to the
TX queue even if there aren't any credits to transmit them.
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
net/bluetooth/l2cap_core.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fc7f321..3a202b0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2458,9 +2458,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
if (len > chan->omtu)
return -EMSGSIZE;
- if (!chan->tx_credits)
- return -EAGAIN;
-
__skb_queue_head_init(&seg_queue);
err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
--
2.9.3
^ permalink raw reply related
* [PATCH 2/3] Bluetooth: 6lowpan: Print errors during recv_pkt
From: Luiz Augusto von Dentz @ 2017-04-03 14:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: aar, jukka.rissanen, linux-wpan
In-Reply-To: <20170403144857.4661-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This makes should make it more clear why a packet is being dropped.
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
net/bluetooth/6lowpan.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 2063e96..5b91e85 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -337,6 +337,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
ret = iphc_decompress(local_skb, dev, peer);
if (ret < 0) {
+ BT_DBG("iphc_decompress failed: %d", ret);
kfree_skb(local_skb);
goto drop;
}
@@ -356,6 +357,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
consume_skb(local_skb);
consume_skb(skb);
} else {
+ BT_DBG("unknown packet type");
goto drop;
}
--
2.9.3
^ permalink raw reply related
* [PATCH 1/3] Bluetooth: 6lowpan: Remove unnecessary peer lookup
From: Luiz Augusto von Dentz @ 2017-04-03 14:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: aar, jukka.rissanen, linux-wpan
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
During chan_recv_cb there is already a peer lookup which can be passed
to recv_pkt directly instead of the channel.
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
net/bluetooth/6lowpan.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index b39da8d..2063e96 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -269,27 +269,20 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
}
static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
- struct l2cap_chan *chan)
+ struct lowpan_peer *peer)
{
const u8 *saddr;
struct lowpan_btle_dev *dev;
- struct lowpan_peer *peer;
dev = lowpan_btle_dev(netdev);
- rcu_read_lock();
- peer = __peer_lookup_chan(dev, chan);
- rcu_read_unlock();
- if (!peer)
- return -EINVAL;
-
saddr = peer->lladdr;
return lowpan_header_decompress(skb, netdev, netdev->dev_addr, saddr);
}
static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
- struct l2cap_chan *chan)
+ struct lowpan_peer *peer)
{
struct sk_buff *local_skb;
int ret;
@@ -342,7 +335,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
local_skb->dev = dev;
- ret = iphc_decompress(local_skb, dev, chan);
+ ret = iphc_decompress(local_skb, dev, peer);
if (ret < 0) {
kfree_skb(local_skb);
goto drop;
@@ -388,7 +381,7 @@ static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
if (!dev || !dev->netdev)
return -ENOENT;
- err = recv_pkt(skb, dev->netdev, chan);
+ err = recv_pkt(skb, dev->netdev, peer);
if (err) {
BT_DBG("recv pkt %d", err);
err = -EAGAIN;
--
2.9.3
^ permalink raw reply related
* Re: [PATCH BlueZ] build: Make btmgmt tools installable
From: Luiz Augusto von Dentz @ 2017-04-03 11:08 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
In-Reply-To: <20170331135823.21883-1-luiz.dentz@gmail.com>
Hi,
On Fri, Mar 31, 2017 at 4:58 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
> Makefile.tools | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Makefile.tools b/Makefile.tools
> index 55d392e..73b2eef 100644
> --- a/Makefile.tools
> +++ b/Makefile.tools
> @@ -348,7 +348,9 @@ EXTRA_DIST += tools/hid2hci.1
> endif
>
> if READLINE
> -noinst_PROGRAMS += tools/btmgmt tools/obex-client-tool tools/obex-server-tool \
> +bin_PROGRAMS += tools/btmgmt
> +
> +noinst_PROGRAMS += tools/obex-client-tool tools/obex-server-tool \
> tools/bluetooth-player tools/obexctl
>
> tools_obex_client_tool_SOURCES = $(gobex_sources) $(btio_sources) \
> --
> 2.9.3
Applied.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH v2] core: replace sizeof(filename) with PATH_MAX
From: Luiz Augusto von Dentz @ 2017-04-03 11:08 UTC (permalink / raw)
To: Konrad Zapalowicz
Cc: Marcel Holtmann, Luiz Augusto Von Dentz,
linux-bluetooth@vger.kernel.org
In-Reply-To: <1490971474-9719-1-git-send-email-bergo.torino@gmail.com>
Hi Konrad,
On Fri, Mar 31, 2017 at 5:44 PM, Konrad Zapalowicz
<konrad.zapalowicz@canonical.com> wrote:
> From: Konrad Zapa=C5=82owicz <konrad.zapalowicz@canonical.com>
>
> This commit replaces sizeof(filename) with PATH_MAX to match the common
> scheme which is used in other places.
> ---
> src/adapter.c | 2 +-
> src/shared/util.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/src/adapter.c b/src/adapter.c
> index 3dac7d6..3935460 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -7107,7 +7107,7 @@ static void store_csrk(struct btd_adapter *adapter,=
const bdaddr_t *peer,
>
> ba2str(peer, device_addr);
>
> - snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
> + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
> adapter_dir(adapter), device_addr=
);
>
> key_file =3D g_key_file_new();
> diff --git a/src/shared/util.c b/src/shared/util.c
> index 7878552..4b59fad 100644
> --- a/src/shared/util.c
> +++ b/src/shared/util.c
> @@ -117,7 +117,7 @@ unsigned char util_get_dt(const char *parent, const c=
har *name)
> char filename[PATH_MAX];
> struct stat st;
>
> - snprintf(filename, sizeof(filename), "%s/%s", parent, name);
> + snprintf(filename, PATH_MAX, "%s/%s", parent, name);
> if (lstat(filename, &st) =3D=3D 0 && S_ISDIR(st.st_mode))
> return DT_DIR;
>
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth=
" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Applied, thanks.
--=20
Luiz Augusto von Dentz
^ permalink raw reply
* Re: Possible crashing bug in bluez 5.44
From: Bastien Nocera @ 2017-04-03 9:24 UTC (permalink / raw)
To: Cysioland, linux-bluetooth
In-Reply-To: <05483ac0-282d-5f1d-55ed-e2dadcb60dd1@cysioland.pl>
On Sat, 2017-04-01 at 11:15 +0200, Cysioland wrote:
> Hello,
>
> I've encountered a possible bug when trying to connect my Bluetooth
> headset via A2DP. Pairing is fine, but when it tries to connect the
> bluetoothd segfaults, with the following stacktrace:
>
> #0 0x0000000000469d60 n/a (bluetoothd)
> #1 0x00000000004472d3 n/a (bluetoothd)
> #2 0x000000000047a31d n/a (bluetoothd)
> #3 0x0000000000447405 n/a (bluetoothd)
> #4 0x00007f8ac61cf45a g_main_context_dispatch (libglib-2.0.so.0)
> #5 0x00007f8ac61cf810 n/a (libglib-2.0.so.0)
> #6 0x00007f8ac61cfb32 g_main_loop_run (libglib-2.0.so.0)
> #7 0x000000000040b6b2 n/a (bluetoothd)
> #8 0x00007f8ac57a5511 __libc_start_main (libc.so.6)
> #9 0x000000000040bf0a n/a (bluetoothd)
You'll need to install debugging symbols, this is unusable
unfortunately.
> I've installed bluez via Arch Linux packages, and after downgrading
> to
> 5.43 the bug no longer appears. I recall seeing lots of work done
> between these two on A2DP, so I suspect a regression there.
>
> Relevant Arch bug, where they told me to hit here:
> https://bugs.archlinux.org/task/53442
>
> Should I report it to your Bugzilla? Do you need any more info or
> help?
Cheers
^ permalink raw reply
* [bluetooth-next:master 25/36] drivers/clocksource/timer-sun5i.c:52:21: error: field 'clksrc' has incomplete type
From: kbuild test robot @ 2017-04-02 3:39 UTC (permalink / raw)
To: Harry Morris; +Cc: kbuild-all, linux-bluetooth, Marcel Holtmann
[-- Attachment #1: Type: text/plain, Size: 44633 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
head: 733db4ccec579e027f54011573a2304c205e7b3d
commit: 3c599b249f3c6090e886bae8e7258bb6176205ef [25/36] ieee802154: Add CA8210 IEEE 802.15.4 device driver
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 3c599b249f3c6090e886bae8e7258bb6176205ef
# save the attached .config to linux build tree
make.cross ARCH=ia64
All errors (new ones prefixed by >>):
>> drivers/clocksource/timer-sun5i.c:52:21: error: field 'clksrc' has incomplete type
struct clocksource clksrc;
^~~~~~
>> drivers/clocksource/timer-sun5i.c:60:28: error: field 'clkevt' has incomplete type
struct clock_event_device clkevt;
^~~~~~
In file included from include/linux/clk.h:16:0,
from drivers/clocksource/timer-sun5i.c:13:
drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_shutdown':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_oneshot':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_periodic':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_next_event':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_clksrc_read':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clksrc, clksrc)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'cs')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clksrc, clksrc)
^~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clksrc':
>> drivers/clocksource/timer-sun5i.c:171:3: error: implicit declaration of function 'clocksource_unregister' [-Werror=implicit-function-declaration]
clocksource_unregister(&cs->clksrc);
^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:175:3: error: implicit declaration of function 'clocksource_register_hz' [-Werror=implicit-function-declaration]
clocksource_register_hz(&cs->clksrc, ndata->new_rate);
^~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_setup_clocksource':
>> drivers/clocksource/timer-sun5i.c:223:20: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
cs->clksrc.mask = CLOCKSOURCE_MASK(32);
^~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:224:21: error: 'CLOCK_SOURCE_IS_CONTINUOUS' undeclared (first use in this function)
cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:224:21: note: each undeclared identifier is reported only once for each function it appears in
drivers/clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clkevt':
>> drivers/clocksource/timer-sun5i.c:251:3: error: implicit declaration of function 'clockevents_update_freq' [-Werror=implicit-function-declaration]
clockevents_update_freq(&ce->clkevt, ndata->new_rate);
^~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: In function 'sun5i_setup_clockevent':
>> drivers/clocksource/timer-sun5i.c:291:24: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared (first use in this function)
ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:291:50: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:305:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
clockevents_config_and_register(&ce->clkevt, rate,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c: At top level:
>> drivers/clocksource/timer-sun5i.c:361:35: error: expected ')' before string constant
CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:363:35: error: expected ')' before string constant
CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/timer-sun5i.c:326:19: warning: 'sun5i_timer_init' defined but not used [-Wunused-function]
static int __init sun5i_timer_init(struct device_node *node)
^~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
>> drivers/clocksource/cadence_ttc_timer.c:92:21: error: field 'cs' has incomplete type
struct clocksource cs;
^~
>> drivers/clocksource/cadence_ttc_timer.c:100:28: error: field 'ce' has incomplete type
struct clock_event_device ce;
^~
In file included from include/linux/clk.h:16:0,
from drivers/clocksource/cadence_ttc_timer.c:18:
drivers/clocksource/cadence_ttc_timer.c: In function '__ttc_clocksource_read':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:96:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clocksource, cs)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:163:29: note: in expansion of macro 'to_ttc_timer_clksrc'
struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
^~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'timer')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:96:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clocksource, cs)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:163:29: note: in expansion of macro 'to_ttc_timer_clksrc'
struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
^~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_set_next_event':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:185:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:185:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_shutdown':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:199:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:199:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_set_periodic':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:211:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:211:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_resume':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:221:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
container_of(x, struct ttc_timer_clockevent, ce)
^~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:221:38: note: in expansion of macro 'to_ttc_timer_clkevent'
struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
^~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_setup_clocksource':
>> drivers/clocksource/cadence_ttc_timer.c:358:19: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
ttccs->cs.mask = CLOCKSOURCE_MASK(timer_width);
^~~~~~~~~~~~~~~~
>> drivers/clocksource/cadence_ttc_timer.c:359:20: error: 'CLOCK_SOURCE_IS_CONTINUOUS' undeclared (first use in this function)
ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:359:20: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/clocksource/cadence_ttc_timer.c:372:8: error: implicit declaration of function 'clocksource_register_hz' [-Werror=implicit-function-declaration]
err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE);
^~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_rate_change_clockevent_cb':
>> drivers/clocksource/cadence_ttc_timer.c:398:3: error: implicit declaration of function 'clockevents_update_freq' [-Werror=implicit-function-declaration]
clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE);
^~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_setup_clockevent':
>> drivers/clocksource/cadence_ttc_timer.c:441:23: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared (first use in this function)
ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/cadence_ttc_timer.c:441:49: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/cadence_ttc_timer.c:468:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
clockevents_config_and_register(&ttcce->ce,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c: At top level:
>> drivers/clocksource/cadence_ttc_timer.c:542:29: error: expected ')' before string constant
CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init);
^~~~~~~~~~
drivers/clocksource/cadence_ttc_timer.c:480:19: warning: 'ttc_timer_init' defined but not used [-Wunused-function]
static int __init ttc_timer_init(struct device_node *timer)
^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
drivers//clocksource/timer-sun5i.c:52:21: error: field 'clksrc' has incomplete type
struct clocksource clksrc;
^~~~~~
drivers//clocksource/timer-sun5i.c:60:28: error: field 'clkevt' has incomplete type
struct clock_event_device clkevt;
^~~~~~
In file included from include/linux/clk.h:16:0,
from drivers//clocksource/timer-sun5i.c:13:
drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_shutdown':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_oneshot':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_periodic':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_next_event':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'ce')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clkevt, clkevt)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
^~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_clksrc_read':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clksrc, clksrc)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
^~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: note: (near initialization for 'cs')
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
drivers//clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
container_of(x, struct sun5i_timer_clksrc, clksrc)
^~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
^~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clksrc':
drivers//clocksource/timer-sun5i.c:171:3: error: implicit declaration of function 'clocksource_unregister' [-Werror=implicit-function-declaration]
clocksource_unregister(&cs->clksrc);
^~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:175:3: error: implicit declaration of function 'clocksource_register_hz' [-Werror=implicit-function-declaration]
clocksource_register_hz(&cs->clksrc, ndata->new_rate);
^~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_setup_clocksource':
drivers//clocksource/timer-sun5i.c:223:20: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
cs->clksrc.mask = CLOCKSOURCE_MASK(32);
^~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:224:21: error: 'CLOCK_SOURCE_IS_CONTINUOUS' undeclared (first use in this function)
cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:224:21: note: each undeclared identifier is reported only once for each function it appears in
drivers//clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clkevt':
drivers//clocksource/timer-sun5i.c:251:3: error: implicit declaration of function 'clockevents_update_freq' [-Werror=implicit-function-declaration]
clockevents_update_freq(&ce->clkevt, ndata->new_rate);
^~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: In function 'sun5i_setup_clockevent':
drivers//clocksource/timer-sun5i.c:291:24: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared (first use in this function)
ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:291:50: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
^~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:305:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
clockevents_config_and_register(&ce->clkevt, rate,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c: At top level:
drivers//clocksource/timer-sun5i.c:361:35: error: expected ')' before string constant
CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:363:35: error: expected ')' before string constant
CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers//clocksource/timer-sun5i.c:326:19: warning: 'sun5i_timer_init' defined but not used [-Wunused-function]
static int __init sun5i_timer_init(struct device_node *node)
^~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
..
vim +/clksrc +52 drivers/clocksource/timer-sun5i.c
4a59058f Maxime Ripard 2015-03-31 46
3071efa4 Maxime Ripard 2015-03-31 47 #define to_sun5i_timer(x) \
3071efa4 Maxime Ripard 2015-03-31 48 container_of(x, struct sun5i_timer, clk_rate_cb)
3071efa4 Maxime Ripard 2015-03-31 49
4a59058f Maxime Ripard 2015-03-31 50 struct sun5i_timer_clksrc {
4a59058f Maxime Ripard 2015-03-31 51 struct sun5i_timer timer;
4a59058f Maxime Ripard 2015-03-31 @52 struct clocksource clksrc;
4a59058f Maxime Ripard 2015-03-31 53 };
4a59058f Maxime Ripard 2015-03-31 54
4a59058f Maxime Ripard 2015-03-31 55 #define to_sun5i_timer_clksrc(x) \
4a59058f Maxime Ripard 2015-03-31 @56 container_of(x, struct sun5i_timer_clksrc, clksrc)
4a59058f Maxime Ripard 2015-03-31 57
4a59058f Maxime Ripard 2015-03-31 58 struct sun5i_timer_clkevt {
4a59058f Maxime Ripard 2015-03-31 59 struct sun5i_timer timer;
4a59058f Maxime Ripard 2015-03-31 @60 struct clock_event_device clkevt;
4a59058f Maxime Ripard 2015-03-31 61 };
4a59058f Maxime Ripard 2015-03-31 62
4a59058f Maxime Ripard 2015-03-31 63 #define to_sun5i_timer_clkevt(x) \
4a59058f Maxime Ripard 2015-03-31 64 container_of(x, struct sun5i_timer_clkevt, clkevt)
67905540 Maxime Ripard 2013-11-07 65
67905540 Maxime Ripard 2013-11-07 66 /*
67905540 Maxime Ripard 2013-11-07 67 * When we disable a timer, we need to wait at least for 2 cycles of
67905540 Maxime Ripard 2013-11-07 68 * the timer source clock. We will use for that the clocksource timer
67905540 Maxime Ripard 2013-11-07 69 * that is already setup and runs at the same frequency than the other
67905540 Maxime Ripard 2013-11-07 70 * timers, and we never will be disabled.
67905540 Maxime Ripard 2013-11-07 71 */
4a59058f Maxime Ripard 2015-03-31 72 static void sun5i_clkevt_sync(struct sun5i_timer_clkevt *ce)
67905540 Maxime Ripard 2013-11-07 73 {
4a59058f Maxime Ripard 2015-03-31 74 u32 old = readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1));
67905540 Maxime Ripard 2013-11-07 75
4a59058f Maxime Ripard 2015-03-31 76 while ((old - readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
67905540 Maxime Ripard 2013-11-07 77 cpu_relax();
67905540 Maxime Ripard 2013-11-07 78 }
67905540 Maxime Ripard 2013-11-07 79
4a59058f Maxime Ripard 2015-03-31 80 static void sun5i_clkevt_time_stop(struct sun5i_timer_clkevt *ce, u8 timer)
67905540 Maxime Ripard 2013-11-07 81 {
4a59058f Maxime Ripard 2015-03-31 82 u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
4a59058f Maxime Ripard 2015-03-31 83 writel(val & ~TIMER_CTL_ENABLE, ce->timer.base + TIMER_CTL_REG(timer));
67905540 Maxime Ripard 2013-11-07 84
4a59058f Maxime Ripard 2015-03-31 85 sun5i_clkevt_sync(ce);
67905540 Maxime Ripard 2013-11-07 86 }
67905540 Maxime Ripard 2013-11-07 87
4a59058f Maxime Ripard 2015-03-31 88 static void sun5i_clkevt_time_setup(struct sun5i_timer_clkevt *ce, u8 timer, u32 delay)
67905540 Maxime Ripard 2013-11-07 89 {
4a59058f Maxime Ripard 2015-03-31 90 writel(delay, ce->timer.base + TIMER_INTVAL_LO_REG(timer));
67905540 Maxime Ripard 2013-11-07 91 }
67905540 Maxime Ripard 2013-11-07 92
4a59058f Maxime Ripard 2015-03-31 93 static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, bool periodic)
67905540 Maxime Ripard 2013-11-07 94 {
4a59058f Maxime Ripard 2015-03-31 95 u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
67905540 Maxime Ripard 2013-11-07 96
67905540 Maxime Ripard 2013-11-07 97 if (periodic)
67905540 Maxime Ripard 2013-11-07 98 val &= ~TIMER_CTL_ONESHOT;
67905540 Maxime Ripard 2013-11-07 99 else
67905540 Maxime Ripard 2013-11-07 100 val |= TIMER_CTL_ONESHOT;
67905540 Maxime Ripard 2013-11-07 101
67905540 Maxime Ripard 2013-11-07 102 writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
4a59058f Maxime Ripard 2015-03-31 103 ce->timer.base + TIMER_CTL_REG(timer));
67905540 Maxime Ripard 2013-11-07 104 }
67905540 Maxime Ripard 2013-11-07 105
7486f5ad Viresh Kumar 2015-06-18 106 static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt)
67905540 Maxime Ripard 2013-11-07 107 {
4a59058f Maxime Ripard 2015-03-31 108 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
4a59058f Maxime Ripard 2015-03-31 109
4a59058f Maxime Ripard 2015-03-31 110 sun5i_clkevt_time_stop(ce, 0);
7486f5ad Viresh Kumar 2015-06-18 111 return 0;
7486f5ad Viresh Kumar 2015-06-18 112 }
7486f5ad Viresh Kumar 2015-06-18 113
7486f5ad Viresh Kumar 2015-06-18 114 static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt)
7486f5ad Viresh Kumar 2015-06-18 115 {
7486f5ad Viresh Kumar 2015-06-18 116 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
7486f5ad Viresh Kumar 2015-06-18 117
4a59058f Maxime Ripard 2015-03-31 118 sun5i_clkevt_time_stop(ce, 0);
4a59058f Maxime Ripard 2015-03-31 119 sun5i_clkevt_time_start(ce, 0, false);
7486f5ad Viresh Kumar 2015-06-18 120 return 0;
67905540 Maxime Ripard 2013-11-07 121 }
7486f5ad Viresh Kumar 2015-06-18 122
7486f5ad Viresh Kumar 2015-06-18 123 static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt)
7486f5ad Viresh Kumar 2015-06-18 124 {
7486f5ad Viresh Kumar 2015-06-18 125 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
7486f5ad Viresh Kumar 2015-06-18 126
7486f5ad Viresh Kumar 2015-06-18 127 sun5i_clkevt_time_stop(ce, 0);
7486f5ad Viresh Kumar 2015-06-18 128 sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
7486f5ad Viresh Kumar 2015-06-18 129 sun5i_clkevt_time_start(ce, 0, true);
7486f5ad Viresh Kumar 2015-06-18 130 return 0;
67905540 Maxime Ripard 2013-11-07 131 }
67905540 Maxime Ripard 2013-11-07 132
67905540 Maxime Ripard 2013-11-07 133 static int sun5i_clkevt_next_event(unsigned long evt,
4a59058f Maxime Ripard 2015-03-31 134 struct clock_event_device *clkevt)
67905540 Maxime Ripard 2013-11-07 135 {
4a59058f Maxime Ripard 2015-03-31 136 struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
4a59058f Maxime Ripard 2015-03-31 137
4a59058f Maxime Ripard 2015-03-31 138 sun5i_clkevt_time_stop(ce, 0);
4a59058f Maxime Ripard 2015-03-31 139 sun5i_clkevt_time_setup(ce, 0, evt - TIMER_SYNC_TICKS);
4a59058f Maxime Ripard 2015-03-31 140 sun5i_clkevt_time_start(ce, 0, false);
67905540 Maxime Ripard 2013-11-07 141
67905540 Maxime Ripard 2013-11-07 142 return 0;
67905540 Maxime Ripard 2013-11-07 143 }
67905540 Maxime Ripard 2013-11-07 144
67905540 Maxime Ripard 2013-11-07 145 static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
67905540 Maxime Ripard 2013-11-07 146 {
4a59058f Maxime Ripard 2015-03-31 147 struct sun5i_timer_clkevt *ce = (struct sun5i_timer_clkevt *)dev_id;
67905540 Maxime Ripard 2013-11-07 148
4a59058f Maxime Ripard 2015-03-31 149 writel(0x1, ce->timer.base + TIMER_IRQ_ST_REG);
4a59058f Maxime Ripard 2015-03-31 150 ce->clkevt.event_handler(&ce->clkevt);
67905540 Maxime Ripard 2013-11-07 151
67905540 Maxime Ripard 2013-11-07 152 return IRQ_HANDLED;
67905540 Maxime Ripard 2013-11-07 153 }
67905540 Maxime Ripard 2013-11-07 154
a5a1d1c2 Thomas Gleixner 2016-12-21 155 static u64 sun5i_clksrc_read(struct clocksource *clksrc)
59387683 Chen-Yu Tsai 2016-10-18 156 {
59387683 Chen-Yu Tsai 2016-10-18 @157 struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
59387683 Chen-Yu Tsai 2016-10-18 158
59387683 Chen-Yu Tsai 2016-10-18 159 return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
59387683 Chen-Yu Tsai 2016-10-18 160 }
59387683 Chen-Yu Tsai 2016-10-18 161
3071efa4 Maxime Ripard 2015-03-31 162 static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
3071efa4 Maxime Ripard 2015-03-31 163 unsigned long event, void *data)
3071efa4 Maxime Ripard 2015-03-31 164 {
3071efa4 Maxime Ripard 2015-03-31 165 struct clk_notifier_data *ndata = data;
3071efa4 Maxime Ripard 2015-03-31 166 struct sun5i_timer *timer = to_sun5i_timer(nb);
3071efa4 Maxime Ripard 2015-03-31 167 struct sun5i_timer_clksrc *cs = container_of(timer, struct sun5i_timer_clksrc, timer);
3071efa4 Maxime Ripard 2015-03-31 168
3071efa4 Maxime Ripard 2015-03-31 169 switch (event) {
3071efa4 Maxime Ripard 2015-03-31 170 case PRE_RATE_CHANGE:
3071efa4 Maxime Ripard 2015-03-31 @171 clocksource_unregister(&cs->clksrc);
3071efa4 Maxime Ripard 2015-03-31 172 break;
3071efa4 Maxime Ripard 2015-03-31 173
3071efa4 Maxime Ripard 2015-03-31 174 case POST_RATE_CHANGE:
3071efa4 Maxime Ripard 2015-03-31 @175 clocksource_register_hz(&cs->clksrc, ndata->new_rate);
3071efa4 Maxime Ripard 2015-03-31 176 break;
3071efa4 Maxime Ripard 2015-03-31 177
3071efa4 Maxime Ripard 2015-03-31 178 default:
3071efa4 Maxime Ripard 2015-03-31 179 break;
3071efa4 Maxime Ripard 2015-03-31 180 }
3071efa4 Maxime Ripard 2015-03-31 181
3071efa4 Maxime Ripard 2015-03-31 182 return NOTIFY_DONE;
3071efa4 Maxime Ripard 2015-03-31 183 }
3071efa4 Maxime Ripard 2015-03-31 184
4a59058f Maxime Ripard 2015-03-31 185 static int __init sun5i_setup_clocksource(struct device_node *node,
4a59058f Maxime Ripard 2015-03-31 186 void __iomem *base,
4a59058f Maxime Ripard 2015-03-31 187 struct clk *clk, int irq)
4a59058f Maxime Ripard 2015-03-31 188 {
4a59058f Maxime Ripard 2015-03-31 189 struct sun5i_timer_clksrc *cs;
4a59058f Maxime Ripard 2015-03-31 190 unsigned long rate;
4a59058f Maxime Ripard 2015-03-31 191 int ret;
4a59058f Maxime Ripard 2015-03-31 192
4a59058f Maxime Ripard 2015-03-31 193 cs = kzalloc(sizeof(*cs), GFP_KERNEL);
4a59058f Maxime Ripard 2015-03-31 194 if (!cs)
4a59058f Maxime Ripard 2015-03-31 195 return -ENOMEM;
4a59058f Maxime Ripard 2015-03-31 196
4a59058f Maxime Ripard 2015-03-31 197 ret = clk_prepare_enable(clk);
4a59058f Maxime Ripard 2015-03-31 198 if (ret) {
4a59058f Maxime Ripard 2015-03-31 199 pr_err("Couldn't enable parent clock\n");
4a59058f Maxime Ripard 2015-03-31 200 goto err_free;
4a59058f Maxime Ripard 2015-03-31 201 }
4a59058f Maxime Ripard 2015-03-31 202
4a59058f Maxime Ripard 2015-03-31 203 rate = clk_get_rate(clk);
4a59058f Maxime Ripard 2015-03-31 204
4a59058f Maxime Ripard 2015-03-31 205 cs->timer.base = base;
4a59058f Maxime Ripard 2015-03-31 206 cs->timer.clk = clk;
3071efa4 Maxime Ripard 2015-03-31 207 cs->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clksrc;
3071efa4 Maxime Ripard 2015-03-31 208 cs->timer.clk_rate_cb.next = NULL;
3071efa4 Maxime Ripard 2015-03-31 209
3071efa4 Maxime Ripard 2015-03-31 210 ret = clk_notifier_register(clk, &cs->timer.clk_rate_cb);
3071efa4 Maxime Ripard 2015-03-31 211 if (ret) {
3071efa4 Maxime Ripard 2015-03-31 212 pr_err("Unable to register clock notifier.\n");
3071efa4 Maxime Ripard 2015-03-31 213 goto err_disable_clk;
3071efa4 Maxime Ripard 2015-03-31 214 }
4a59058f Maxime Ripard 2015-03-31 215
4a59058f Maxime Ripard 2015-03-31 216 writel(~0, base + TIMER_INTVAL_LO_REG(1));
4a59058f Maxime Ripard 2015-03-31 217 writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
4a59058f Maxime Ripard 2015-03-31 218 base + TIMER_CTL_REG(1));
4a59058f Maxime Ripard 2015-03-31 219
59387683 Chen-Yu Tsai 2016-10-18 220 cs->clksrc.name = node->name;
59387683 Chen-Yu Tsai 2016-10-18 221 cs->clksrc.rating = 340;
59387683 Chen-Yu Tsai 2016-10-18 222 cs->clksrc.read = sun5i_clksrc_read;
59387683 Chen-Yu Tsai 2016-10-18 @223 cs->clksrc.mask = CLOCKSOURCE_MASK(32);
59387683 Chen-Yu Tsai 2016-10-18 @224 cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
59387683 Chen-Yu Tsai 2016-10-18 225
59387683 Chen-Yu Tsai 2016-10-18 226 ret = clocksource_register_hz(&cs->clksrc, rate);
4a59058f Maxime Ripard 2015-03-31 227 if (ret) {
4a59058f Maxime Ripard 2015-03-31 228 pr_err("Couldn't register clock source.\n");
3071efa4 Maxime Ripard 2015-03-31 229 goto err_remove_notifier;
4a59058f Maxime Ripard 2015-03-31 230 }
4a59058f Maxime Ripard 2015-03-31 231
4a59058f Maxime Ripard 2015-03-31 232 return 0;
4a59058f Maxime Ripard 2015-03-31 233
3071efa4 Maxime Ripard 2015-03-31 234 err_remove_notifier:
3071efa4 Maxime Ripard 2015-03-31 235 clk_notifier_unregister(clk, &cs->timer.clk_rate_cb);
4a59058f Maxime Ripard 2015-03-31 236 err_disable_clk:
4a59058f Maxime Ripard 2015-03-31 237 clk_disable_unprepare(clk);
4a59058f Maxime Ripard 2015-03-31 238 err_free:
4a59058f Maxime Ripard 2015-03-31 239 kfree(cs);
4a59058f Maxime Ripard 2015-03-31 240 return ret;
4a59058f Maxime Ripard 2015-03-31 241 }
4a59058f Maxime Ripard 2015-03-31 242
3071efa4 Maxime Ripard 2015-03-31 243 static int sun5i_rate_cb_clkevt(struct notifier_block *nb,
3071efa4 Maxime Ripard 2015-03-31 244 unsigned long event, void *data)
3071efa4 Maxime Ripard 2015-03-31 245 {
3071efa4 Maxime Ripard 2015-03-31 246 struct clk_notifier_data *ndata = data;
3071efa4 Maxime Ripard 2015-03-31 247 struct sun5i_timer *timer = to_sun5i_timer(nb);
3071efa4 Maxime Ripard 2015-03-31 248 struct sun5i_timer_clkevt *ce = container_of(timer, struct sun5i_timer_clkevt, timer);
3071efa4 Maxime Ripard 2015-03-31 249
3071efa4 Maxime Ripard 2015-03-31 250 if (event == POST_RATE_CHANGE) {
3071efa4 Maxime Ripard 2015-03-31 @251 clockevents_update_freq(&ce->clkevt, ndata->new_rate);
3071efa4 Maxime Ripard 2015-03-31 252 ce->timer.ticks_per_jiffy = DIV_ROUND_UP(ndata->new_rate, HZ);
3071efa4 Maxime Ripard 2015-03-31 253 }
3071efa4 Maxime Ripard 2015-03-31 254
:::::: The code at line 52 was first introduced by commit
:::::: 4a59058f0b09682200c04b1db236b4a3b92128d7 clocksource/drivers/sun5i: Refactor the current code
:::::: TO: Maxime Ripard <maxime.ripard@free-electrons.com>
:::::: CC: Ingo Molnar <mingo@kernel.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 47639 bytes --]
^ permalink raw reply
* Possible crashing bug in bluez 5.44
From: Cysioland @ 2017-04-01 9:15 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <bbe1720b-5d67-2257-1be1-d1051790dbc4@cysioland.pl>
Hello,
I've encountered a possible bug when trying to connect my Bluetooth
headset via A2DP. Pairing is fine, but when it tries to connect the
bluetoothd segfaults, with the following stacktrace:
#0 0x0000000000469d60 n/a (bluetoothd)
#1 0x00000000004472d3 n/a (bluetoothd)
#2 0x000000000047a31d n/a (bluetoothd)
#3 0x0000000000447405 n/a (bluetoothd)
#4 0x00007f8ac61cf45a g_main_context_dispatch (libglib-2.0.so.0)
#5 0x00007f8ac61cf810 n/a (libglib-2.0.so.0)
#6 0x00007f8ac61cfb32 g_main_loop_run (libglib-2.0.so.0)
#7 0x000000000040b6b2 n/a (bluetoothd)
#8 0x00007f8ac57a5511 __libc_start_main (libc.so.6)
#9 0x000000000040bf0a n/a (bluetoothd)
I've installed bluez via Arch Linux packages, and after downgrading to
5.43 the bug no longer appears. I recall seeing lots of work done
between these two on A2DP, so I suspect a regression there.
Relevant Arch bug, where they told me to hit here:
https://bugs.archlinux.org/task/53442
Should I report it to your Bugzilla? Do you need any more info or help?
--
Yours Faithfully,
Cysioland
https://cysioland.pl
^ permalink raw reply
* [PATCH v2] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 14:44 UTC (permalink / raw)
To: marcel; +Cc: luiz.von.dentz, linux-bluetooth, Konrad Zapałowicz
In-Reply-To: <1490958237-9299-1-git-send-email-bergo.torino@gmail.com>
From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
This commit replaces sizeof(filename) with PATH_MAX to match the common
scheme which is used in other places.
---
src/adapter.c | 2 +-
src/shared/util.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 3dac7d6..3935460 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -7107,7 +7107,7 @@ static void store_csrk(struct btd_adapter *adapter, const bdaddr_t *peer,
ba2str(peer, device_addr);
- snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
adapter_dir(adapter), device_addr);
key_file = g_key_file_new();
diff --git a/src/shared/util.c b/src/shared/util.c
index 7878552..4b59fad 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -117,7 +117,7 @@ unsigned char util_get_dt(const char *parent, const char *name)
char filename[PATH_MAX];
struct stat st;
- snprintf(filename, sizeof(filename), "%s/%s", parent, name);
+ snprintf(filename, PATH_MAX, "%s/%s", parent, name);
if (lstat(filename, &st) == 0 && S_ISDIR(st.st_mode))
return DT_DIR;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 14:15 UTC (permalink / raw)
To: Von Dentz, Luiz
Cc: Bastien Nocera, Marcel Holtmann, linux-bluetooth@vger.kernel.org
In-Reply-To: <CACumGOK1ZvY87+Y-XKLRVPN_JGGvpJMcaOHQ0tCWdXyGh4Nb1A@mail.gmail.com>
On 03/31, Von Dentz, Luiz wrote:
> Hi Konrad,
>
> On Fri, Mar 31, 2017 at 2:32 PM, Konrad Zapalowicz
> <konrad.zapalowicz@canonical.com> wrote:
> > On 03/31, Bastien Nocera wrote:
> >> On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
> >> > From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
> >> >
> >> > This commit replaces sizeof(filename) with PATH_MAX to match the
> >> > common
> >> > scheme which is used in other places.
> >>
> >> I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
> >> PATH_MAX.
> >
> > I guess it is because it is easier. With g_strdup_printf() one would
> > have to take care about freeing memory. This is not a case with having
> > filename as an atomatic variable.
>
> Patch looks fine, but we don't use Signed-off-by in userspace tree
Ok, will resend.
Thanks,
K
^ permalink raw reply
* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Von Dentz, Luiz @ 2017-03-31 14:00 UTC (permalink / raw)
To: Konrad Zapalowicz
Cc: Bastien Nocera, Marcel Holtmann, linux-bluetooth@vger.kernel.org
In-Reply-To: <20170331113218.GA28779@annapurna>
Hi Konrad,
On Fri, Mar 31, 2017 at 2:32 PM, Konrad Zapalowicz
<konrad.zapalowicz@canonical.com> wrote:
> On 03/31, Bastien Nocera wrote:
>> On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
>> > From: Konrad Zapa=C5=82owicz <konrad.zapalowicz@canonical.com>
>> >
>> > This commit replaces sizeof(filename) with PATH_MAX to match the
>> > common
>> > scheme which is used in other places.
>>
>> I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
>> PATH_MAX.
>
> I guess it is because it is easier. With g_strdup_printf() one would
> have to take care about freeing memory. This is not a case with having
> filename as an atomatic variable.
Patch looks fine, but we don't use Signed-off-by in userspace tree.
^ permalink raw reply
* [PATCH BlueZ] build: Make btmgmt tools installable
From: Luiz Augusto von Dentz @ 2017-03-31 13:58 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
Makefile.tools | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Makefile.tools b/Makefile.tools
index 55d392e..73b2eef 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -348,7 +348,9 @@ EXTRA_DIST += tools/hid2hci.1
endif
if READLINE
-noinst_PROGRAMS += tools/btmgmt tools/obex-client-tool tools/obex-server-tool \
+bin_PROGRAMS += tools/btmgmt
+
+noinst_PROGRAMS += tools/obex-client-tool tools/obex-server-tool \
tools/bluetooth-player tools/obexctl
tools_obex_client_tool_SOURCES = $(gobex_sources) $(btio_sources) \
--
2.9.3
^ permalink raw reply related
* Re: [PATCHv3 00/10] Nokia H4+ support
From: Greg Kroah-Hartman @ 2017-03-31 13:33 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Rob Herring, Sebastian Reichel, Gustavo F. Padovan, Johan Hedberg,
Samuel Thibault, Pavel Machek, Tony Lindgren, Jiri Slaby,
Mark Rutland, open list:BLUETOOTH DRIVERS,
linux-serial@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, David S. Miller
In-Reply-To: <C1A408F2-1DF8-4F49-B399-B936542DE6BC@holtmann.org>
On Wed, Mar 29, 2017 at 11:33:26PM +0200, Marcel Holtmann wrote:
> Hi Rob,
>
> >> Here is PATCHv3 for the Nokia bluetooth patchset. I addressed all comments from
> >> Rob and Pavel regarding the serdev patches and dropped the *.dts patches, since
> >> they were queued by Tony. I also changed the patch order, so that the serdev
> >> patches come first. All of them have Acked-by from Rob, so I think it makes
> >> sense to merge them to serdev subsystem (now) and provide an immutable branch
> >> for the bluetooth subsystem.
> >
> > Greg doesn't read cover letters generally and since the serdev patches
> > are Cc rather than To him, he's probably not planning to pick them up.
>
> I wonder actually if we should merge all of these via bluetooth-next
> tree with proper Ack from Greg. However it would be good to also get
> buy in from Dave for merging this ultimately through net-next.
I don't really care where it goes. I can take the whole thing in my
tty/serial tree now if no one objects and I get an ack from the relevant
maintainers {hint...}
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 11:32 UTC (permalink / raw)
To: Bastien Nocera; +Cc: marcel, luiz.von.dentz, linux-bluetooth
In-Reply-To: <1490959289.13868.12.camel@hadess.net>
On 03/31, Bastien Nocera wrote:
> On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
> > From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
> >
> > This commit replaces sizeof(filename) with PATH_MAX to match the
> > common
> > scheme which is used in other places.
>
> I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
> PATH_MAX.
I guess it is because it is easier. With g_strdup_printf() one would
have to take care about freeing memory. This is not a case with having
filename as an atomatic variable.
^ permalink raw reply
* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Bastien Nocera @ 2017-03-31 11:21 UTC (permalink / raw)
To: Konrad Zapalowicz, marcel; +Cc: luiz.von.dentz, linux-bluetooth
In-Reply-To: <1490958237-9299-1-git-send-email-bergo.torino@gmail.com>
On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
> From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
>
> This commit replaces sizeof(filename) with PATH_MAX to match the
> common
> scheme which is used in other places.
I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
PATH_MAX.
^ permalink raw reply
* [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 11:03 UTC (permalink / raw)
To: marcel; +Cc: luiz.von.dentz, linux-bluetooth, Konrad Zapałowicz
From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
This commit replaces sizeof(filename) with PATH_MAX to match the common
scheme which is used in other places.
Signed-off-by: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
---
src/adapter.c | 2 +-
src/shared/util.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 3dac7d6..3935460 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -7107,7 +7107,7 @@ static void store_csrk(struct btd_adapter *adapter, const bdaddr_t *peer,
ba2str(peer, device_addr);
- snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
adapter_dir(adapter), device_addr);
key_file = g_key_file_new();
diff --git a/src/shared/util.c b/src/shared/util.c
index 7878552..4b59fad 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -117,7 +117,7 @@ unsigned char util_get_dt(const char *parent, const char *name)
char filename[PATH_MAX];
struct stat st;
- snprintf(filename, sizeof(filename), "%s/%s", parent, name);
+ snprintf(filename, PATH_MAX, "%s/%s", parent, name);
if (lstat(filename, &st) == 0 && S_ISDIR(st.st_mode))
return DT_DIR;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v3 1/2] Bluetooth: btmrvl: disable platform wakeup interrupt in suspend failure path
From: Marcel Holtmann @ 2017-03-31 10:11 UTC (permalink / raw)
To: Xinming Hu; +Cc: Linux Bluetooth, Amitkumar Karwar, Cathy Luo
In-Reply-To: <1490941952-9048-1-git-send-email-huxm@marvell.com>
Hi Xinming,
> Host sleep handshake with device might been fail, disable platform wakeup
> interrupt in this case.
>
> Reported-by: Guenter Roeck <groeck@chromium.org>
> Signed-off-by: Xinming Hu <huxm@marvell.com>
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> ---
> v2: same as v1
> v3: use Reported-by (Guenter)
> ---
> drivers/bluetooth/btmrvl_sdio.c | 7 +++++++
> 1 file changed, 7 insertions(+)
both patches have been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] bluetooth: 6lowpan: fix delay work init in add_peer_chan()
From: Marcel Holtmann @ 2017-03-31 10:10 UTC (permalink / raw)
To: Michael Scott
Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
Jukka Rissanen, linux-bluetooth, linux-wpan, netdev, linux-kernel
In-Reply-To: <20170329061054.4300-1-michael.scott@linaro.org>
Hi Michael,
> When adding 6lowpan devices very rapidly we sometimes see a crash:
> [23122.306615] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.9.0-43-arm64 #1 Debian 4.9.9.linaro.43-1
> [23122.315400] Hardware name: HiKey Development Board (DT)
> [23122.320623] task: ffff800075443080 task.stack: ffff800075484000
> [23122.326551] PC is at expire_timers+0x70/0x150
> [23122.330907] LR is at run_timer_softirq+0xa0/0x1a0
> [23122.335616] pc : [<ffff000008142dd8>] lr : [<ffff000008142f58>] pstate: 600001c5
>
> This was due to add_peer_chan() unconditionally initializing the
> lowpan_btle_dev->notify_peers delayed work structure, even if the
> lowpan_btle_dev passed into add_peer_chan() had previously been
> initialized.
>
> Normally, this would go unnoticed as the delayed work timer is set for
> 100 msec, however when calling add_peer_chan() faster than 100 msec it
> clears out a previously queued delay work causing the crash above.
>
> To fix this, let add_peer_chan() know when a new lowpan_btle_dev is passed
> in so that it only performs the delay work initialization when needed.
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] bluetooth: 6lowpan: fix use after free in chan_suspend/resume
From: Marcel Holtmann @ 2017-03-31 10:10 UTC (permalink / raw)
To: Michael Scott
Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
Jukka Rissanen, linux-bluetooth, linux-wpan, netdev, linux-kernel
In-Reply-To: <20170329061018.4243-1-michael.scott@linaro.org>
Hi Michael,
> A status field in the skb_cb struct was storing a channel status
> based on channel suspend/resume events. This stored status was
> then used to return EAGAIN if there were packet sending issues
> in snd_pkt().
>
> The issue is that the skb has been freed by the time the callback
> to 6lowpan's suspend/resume was called. So, this generates a
> "use after free" issue that was noticed while running kernel tests
> with KASAN debug enabled.
>
> Let's eliminate the status field entirely as we can use the channel
> tx_credits to indicate whether we should return EAGAIN when handling
> packets.
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 21 +++------------------
> 1 file changed, 3 insertions(+), 18 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] bluetooth: 6lowpan: fix delay work init in add_peer_chan()
From: Jukka Rissanen @ 2017-03-31 9:37 UTC (permalink / raw)
To: Michael Scott, Marcel Holtmann, Gustavo Padovan, Johan Hedberg
Cc: David S . Miller, linux-bluetooth, linux-wpan, netdev,
linux-kernel
In-Reply-To: <20170329061054.4300-1-michael.scott@linaro.org>
Hi Michael,
On Tue, 2017-03-28 at 23:10 -0700, Michael Scott wrote:
> When adding 6lowpan devices very rapidly we sometimes see a crash:
> [23122.306615] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.9.0-43-
> arm64 #1 Debian 4.9.9.linaro.43-1
> [23122.315400] Hardware name: HiKey Development Board (DT)
> [23122.320623] task: ffff800075443080 task.stack: ffff800075484000
> [23122.326551] PC is at expire_timers+0x70/0x150
> [23122.330907] LR is at run_timer_softirq+0xa0/0x1a0
> [23122.335616] pc : [<ffff000008142dd8>] lr : [<ffff000008142f58>]
> pstate: 600001c5
>
> This was due to add_peer_chan() unconditionally initializing the
> lowpan_btle_dev->notify_peers delayed work structure, even if the
> lowpan_btle_dev passed into add_peer_chan() had previously been
> initialized.
>
> Normally, this would go unnoticed as the delayed work timer is set
> for
> 100 msec, however when calling add_peer_chan() faster than 100 msec
> it
> clears out a previously queued delay work causing the crash above.
>
> To fix this, let add_peer_chan() know when a new lowpan_btle_dev is
> passed
> in so that it only performs the delay work initialization when
> needed.
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index e27be3ca0a0c..c282482edc2c 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -754,7 +754,8 @@ static void set_ip_addr_bits(u8 addr_type, u8
> *addr)
> }
>
> static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
> - struct lowpan_btle_dev *dev)
> + struct lowpan_btle_dev *dev,
> + bool new_netdev)
> {
> struct lowpan_peer *peer;
>
> @@ -785,7 +786,8 @@ static struct l2cap_chan *add_peer_chan(struct
> l2cap_chan *chan,
> spin_unlock(&devices_lock);
>
> /* Notifying peers about us needs to be done without locks
> held */
> - INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers);
> + if (new_netdev)
> + INIT_DELAYED_WORK(&dev->notify_peers,
> do_notify_peers);
> schedule_delayed_work(&dev->notify_peers,
> msecs_to_jiffies(100));
>
> return peer->chan;
> @@ -842,6 +844,7 @@ static int setup_netdev(struct l2cap_chan *chan,
> struct lowpan_btle_dev **dev)
> static inline void chan_ready_cb(struct l2cap_chan *chan)
> {
> struct lowpan_btle_dev *dev;
> + bool new_netdev = false;
>
> dev = lookup_dev(chan->conn);
>
> @@ -852,12 +855,13 @@ static inline void chan_ready_cb(struct
> l2cap_chan *chan)
> l2cap_chan_del(chan, -ENOENT);
> return;
> }
> + new_netdev = true;
> }
>
> if (!try_module_get(THIS_MODULE))
> return;
>
> - add_peer_chan(chan, dev);
> + add_peer_chan(chan, dev, new_netdev);
> ifup(dev->netdev);
> }
>
Good catch!
Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Cheers,
Jukka
^ permalink raw reply
* Re: [PATCH] bluetooth: 6lowpan: fix use after free in chan_suspend/resume
From: Jukka Rissanen @ 2017-03-31 9:35 UTC (permalink / raw)
To: Michael Scott, Marcel Holtmann, Gustavo Padovan, Johan Hedberg,
Luiz Augusto von Dentz
Cc: David S . Miller, linux-bluetooth, linux-wpan, netdev,
linux-kernel
In-Reply-To: <20170329061018.4243-1-michael.scott@linaro.org>
Hi Michael,
On Tue, 2017-03-28 at 23:10 -0700, Michael Scott wrote:
> A status field in the skb_cb struct was storing a channel status
> based on channel suspend/resume events. This stored status was
> then used to return EAGAIN if there were packet sending issues
> in snd_pkt().
>
> The issue is that the skb has been freed by the time the callback
> to 6lowpan's suspend/resume was called. So, this generates a
> "use after free" issue that was noticed while running kernel tests
> with KASAN debug enabled.
>
> Let's eliminate the status field entirely as we can use the channel
> tx_credits to indicate whether we should return EAGAIN when handling
> packets.
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 21 +++------------------
> 1 file changed, 3 insertions(+), 18 deletions(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index d491529332f4..e27be3ca0a0c 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -38,7 +38,6 @@ struct skb_cb {
> struct in6_addr addr;
> struct in6_addr gw;
> struct l2cap_chan *chan;
> - int status;
> };
> #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
>
> @@ -528,7 +527,7 @@ static int send_pkt(struct l2cap_chan *chan,
> struct sk_buff *skb,
> }
>
> if (!err)
> - err = lowpan_cb(skb)->status;
> + err = (!chan->tx_credits ? -EAGAIN : 0);
>
> if (err < 0) {
> if (err == -EAGAIN)
> @@ -964,26 +963,12 @@ static struct sk_buff *chan_alloc_skb_cb(struct
> l2cap_chan *chan,
>
> static void chan_suspend_cb(struct l2cap_chan *chan)
> {
> - struct sk_buff *skb = chan->data;
> -
> - BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> - if (!skb)
> - return;
> -
> - lowpan_cb(skb)->status = -EAGAIN;
> + BT_DBG("chan %p suspend", chan);
> }
>
> static void chan_resume_cb(struct l2cap_chan *chan)
> {
> - struct sk_buff *skb = chan->data;
> -
> - BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> - if (!skb)
> - return;
> -
> - lowpan_cb(skb)->status = 0;
> + BT_DBG("chan %p resume", chan);
> }
>
> static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
Good catch! If we can avoid using the status variable, that is very
good. We could probably also remove the resume and suspend callbacks as
they are now empty functions (unless we need the debug info for
something).
Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Cheers,
Jukka
^ permalink raw reply
* Re: [PATCH] bluetooth: 6lowpan: fix use after free in chan_suspend/resume
From: Luiz Augusto von Dentz @ 2017-03-31 8:33 UTC (permalink / raw)
To: Michael Scott
Cc: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, David S . Miller,
Jukka Rissanen, linux-bluetooth@vger.kernel.org, linux-wpan,
open list:NETWORKING [GENERAL], Linux Kernel Mailing List
In-Reply-To: <20170329061018.4243-1-michael.scott@linaro.org>
Hi Michael,
On Wed, Mar 29, 2017 at 9:10 AM, Michael Scott <michael.scott@linaro.org> wrote:
> A status field in the skb_cb struct was storing a channel status
> based on channel suspend/resume events. This stored status was
> then used to return EAGAIN if there were packet sending issues
> in snd_pkt().
>
> The issue is that the skb has been freed by the time the callback
> to 6lowpan's suspend/resume was called. So, this generates a
> "use after free" issue that was noticed while running kernel tests
> with KASAN debug enabled.
>
> Let's eliminate the status field entirely as we can use the channel
> tx_credits to indicate whether we should return EAGAIN when handling
> packets.
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 21 +++------------------
> 1 file changed, 3 insertions(+), 18 deletions(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index d491529332f4..e27be3ca0a0c 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -38,7 +38,6 @@ struct skb_cb {
> struct in6_addr addr;
> struct in6_addr gw;
> struct l2cap_chan *chan;
> - int status;
> };
> #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
>
> @@ -528,7 +527,7 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
> }
>
> if (!err)
> - err = lowpan_cb(skb)->status;
> + err = (!chan->tx_credits ? -EAGAIN : 0);
>
> if (err < 0) {
> if (err == -EAGAIN)
> @@ -964,26 +963,12 @@ static struct sk_buff *chan_alloc_skb_cb(struct l2cap_chan *chan,
>
> static void chan_suspend_cb(struct l2cap_chan *chan)
> {
> - struct sk_buff *skb = chan->data;
> -
> - BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> - if (!skb)
> - return;
> -
> - lowpan_cb(skb)->status = -EAGAIN;
> + BT_DBG("chan %p suspend", chan);
> }
>
> static void chan_resume_cb(struct l2cap_chan *chan)
> {
> - struct sk_buff *skb = chan->data;
> -
> - BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> - if (!skb)
> - return;
> -
> - lowpan_cb(skb)->status = 0;
> + BT_DBG("chan %p resume", chan);
> }
>
> static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
> --
> 2.11.0
It should be possible to queue the packets on l2cap_chan_send, Im not
sure why we have this suspend logic in the first place so perhaps
Jukka can shed some light here.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH v3 2/2] Bluetooth: btmrvl: remove unnecessary wakeup interrupt number sanity check
From: Xinming Hu @ 2017-03-31 6:32 UTC (permalink / raw)
To: Linux Bluetooth; +Cc: Marcel Holtmann, Amitkumar Karwar, Cathy Luo, Xinming Hu
In-Reply-To: <1490941952-9048-1-git-send-email-huxm@marvell.com>
Sanity check of interrupt number in interrupt handler is unnecessary and
confusion, remove it.
Reported-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
v2: fix apply error in v1
v3: use Reported-by (Guenter)
---
drivers/bluetooth/btmrvl_sdio.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 95e40ec..eb794f0 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -64,11 +64,9 @@ static irqreturn_t btmrvl_wake_irq_bt(int irq, void *priv)
struct btmrvl_sdio_card *card = priv;
struct btmrvl_plt_wake_cfg *cfg = card->plt_wake_cfg;
- if (cfg->irq_bt >= 0) {
- pr_info("%s: wake by bt", __func__);
- cfg->wake_by_bt = true;
- disable_irq_nosync(irq);
- }
+ pr_info("%s: wake by bt", __func__);
+ cfg->wake_by_bt = true;
+ disable_irq_nosync(irq);
pm_wakeup_event(&card->func->dev, 0);
pm_system_wakeup();
--
1.8.1.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox