- 04 Mar, 2016 40 commits
-
-
Douglas Anderson authored
In commit 94dfd7ed ("USB: HCD: support giveback of URB in tasklet context") support was added to give back the URB in tasklet context. Let's take advantage of this in dwc2. This speeds up the dwc2 interrupt handler considerably. Note that this requires the change ("usb: dwc2: host: Add a delay before releasing periodic bandwidth") to come first. Note that, as per Alan Stern in <https://patchwork.kernel.org/patch/7555771/>, we also need to make sure that the extra delay before the device drivers submit more data doesn't break the scheduler. At the moment the scheduler is pretty broken (see future patches) so it's hard to be 100% certain, but I have yet to see any new breakage introduced by this delay. ...and speeding up interrupt processing for dwc2 is a huge deal because it means we've got a better chance of not missing SOF interrupts. That means we've got an overall win here. Note that when playing USB audio and using a USB webcam and having several USB keyboards plugged in, the crackling on the USB audio device is noticably reduced with this patch. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
We'd like to be able to use HCD_BH in order to speed up the dwc2 host interrupt handler quite a bit. However, according to the kernel doc for usb_submit_urb() (specifically the part about "Reserved Bandwidth Transfers"), we need to keep a reservation active as long as a device driver keeps submitting. That was easy to do when we gave back the URB in the interrupt context: we just looked at when our queue was empty and released the reserved bandwidth then. ...but now we need a little more complexity. We'll follow EHCI's lead in commit 9118f9eb ("USB: EHCI: improve interrupt qh unlink") and add a 5ms delay. Since we don't have a whole timer infrastructure in dwc2, we'll just add a timer per QH. The overhead for this is very small. Note that the dwc2 scheduler is pretty broken (see future patches to fix it). This patch attempts to replicate all old behavior and just add the proper delay. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
In preparation for future changes to the scheduler let's add some tracing that makes it easy for us to see what's happening. By default this tracing will be off. By changing "core.h" you can easily trace to ftrace, the console, or nowhere. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
We're supposed to keep outstanding splits in order. Keep track of a list of the order of splits and process channel interrupts in that order. Without this change and the following setup: * Rockchip rk3288 Chromebook, using port ff540000 -> Pluggable 7-port Hub with Charging (powered) -> Microsoft Wireless Keyboard 2000 in port 1. -> Das Keyboard in port 2. ...I find that I get dropped keys on the Microsoft keyboard (I'm sure there are other combinations that fail, but this documents my test). Specifically I've been typing "hahahahahahaha" on the keyboard and often see keys dropped or repeated. After this change the above setup works properly. This patch is based on a previous patch proposed by Yunzhi Li ("usb: dwc2: hcd: fix periodic transfer schedule sequence") Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Yunzhi Li <lyz@rock-chips.com> Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
The queues the the dwc2 host controller used are truly queues. That means FIFO or first in first out. Unfortunately though the code was iterating through these queues starting from the head, some places in the code was adding things to the queue by adding at the head instead of the tail. That means last in first out. Doh. Go through and just always add to the tail. Doing this makes things much happier when I've got: * 7-port USB 2.0 Single-TT hub * - Microsoft 2.4 GHz Transceiver v7.0 dongle * - Jabra speakerphone playing music Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
When poking around with USB devices with slub_debug enabled, I found another obvious use after free. Turns out that in dwc2_hc_n_intr() I was in a state when the contents of chan->qh was filled with 0x6b, indicating that chan->qh was freed but chan still had a reference to it. Let's make sure that whenever we free qh we also make sure we remove a reference from its channel. The bug fixed here doesn't appear to be new--I believe I just got lucky and happened to see it while stress testing. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
As documented in dwc2_calculate_dynamic_fifo(), host_rx_fifo_size should really be: 2 * ((Largest Packet size / 4) + 1 + 1) + n with n = number of host channel. We have 9 host channels, so 2 * ((1024/4) + 2) + 9 = 516 + 9 = 525 We've got 960 / 972 total_fifo_size on rk3288 (and presumably on rk3066) and 525 + 128 + 256 = 909 so we're still under on both ports even when we increment by 5. In the future, it would be nice if dwc2_calculate_dynamic_fifo() could handle the "too small" FIFO case and come up with something more dynamically. When we do that we can figure out how to allocate the extra 48 / 60 bytes of FIFO that we're currently wasting. NOTE: no known bugs are fixed by this patch, but it seems like a simple fix and ought to fix someone. Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
All other host controllers who want aligned buffers for DMA do it a certain way. Let's do that too instead of working behind the USB core's back. This makes our interrupt handler not take forever and also rips out a lot of code, simplifying things a bunch. This also has the side effect of removing the 65535 max transfer size limit. NOTE: The actual code to allocate the aligned buffers is ripped almost completely from the tegra EHCI driver. At some point in the future we may want to add this functionality to the USB core to share more code everywhere. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: John Youn <johnyoun@synopsys.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: John Youn <johnyoun@synopsys.com> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Douglas Anderson authored
Previously we needed to set the max_transfer_size to explicitly be 65535 because the old driver would detect that our hardware could support much bigger transfers and then would try to do them. This wouldn't work since the DMA alignment code couldn't support it. Later in commit e8f8c14d ("usb: dwc2: clip max_transfer_size to 65535") upstream added support for clipping this automatically. Since that commit it has been OK to just use "-1" (default), but nobody bothered to change it. Let's change it to default now for two reasons: - It's nice to use autodetected params. - If we can remove the 65535 limit, we can transfer more! Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: John Youn <johnyoun@synopsys.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
John Youn authored
Check that dwc->maximum_speed is set to a valid value. Also add an error when we use it later if we encounter an invalid value. Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Emilio López authored
MODULE_DEVICE_TABLE() is missing, so the module isn't auto-loading on sunxi systems using the OTG controller. This commit adds the missing line so it loads automatically when building it as a module and running on a system with an USB OTG port. Signed-off-by: Emilio López <emilio.lopez@collabora.co.uk> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
B-device detects that bus is idle for more than TB_AIDL_BDIS min and begins HNP by turning off pullup on DP, this allows the bus to discharge to the SE0 state. This timer was missed and failed with PET test: 6.8.5 B-UUT HNP of USB OTG and EH automated compliance plan v1.2, this patch is to fix this timing issue. Acked-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Add A-idle to B-disconnect timer, B-device detects that bus is idle for more than TB_AIDL_BDIS min and begins HNP by turning off pullup on D+. This allows the bus to discharge to the SE0 state. Acked-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Update HNP test procedure as HNP polling is supported. Acked-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Enable HNP polling support for chipidea gadget and allocate memory for host request flag when otg fsm init. Acked-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Set host_request_flag if the current peripheral wants to take host role via changing a_bus_req or b_bus_req by user application. Acked-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
If gadget with HNP polling support receives GetStatus request of otg status selector, it feedback to host with host request flag to indicate if it wants to take host role. Acked-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Since gadget driver will handle this request, so controller driver bypass it. Acked-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Adds HNP polling timer when transits to host state, the OTG status request will be sent to peripheral after timeout, if host request flag is set, it will switch to peripheral state, otherwise it will repeat HNP polling every 1.5s and maintain the current session. Acked-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
A host is required to use the GetStatus command, with wIndex set to the OTG status selector(F000H) to request the Host request flag from the peripheral. Acked-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Li Jun authored
Add 2 flags for USB OTG HNP polling, hnp_polling_support is to indicate if the gadget can support HNP polling, host_request_flag is used for gadget to store host request information from application, which can be used to respond to HNP polling from host. Acked-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Li Jun <jun.li@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Marek Szyprowski authored
Since commit 855ed04a ("usb: gadget: udc-core: independent registration of gadgets and gadget drivers") gadget drivers can not assume that UDC drivers are already available on their initialization. This broke the HACK, which was used in gadgetfs driver, to get UDC controller name. This patch removes this hack and replaces it by additional function in the UDC core (which is usefully only for legacy drivers, please don't use it in the new code). Reported-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
For every in_substream, there must be a corresponding gmidi_in_port structure so it is perfectly viable and some might argue sensible to stash pointer to the input substream in the gmidi_in_port structure. This has an added benefit that if in_ports < MAX_PORTS, the whole f_midi structure takes up less space because only in_ports number of pointers for in_substream are allocated instead of MAX_PORTS lots of them. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Dan Carpenter authored
We added a new error path to this function and we forgot to drop the lock. Fixes: e1e3d7ec ('usb: gadget: f_midi: pre-allocate IN requests') Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> [mina86@mina86.com: rebased on top of refactoring commit] Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
Reduce number of allocations, simplify memory management and reduce memory usage by stacking the gmidi_in_port elements at the end of the f_midi structure using a flexible array. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
In general case, all of midi->in_port pointers may be non-NULL which implies that the ‘if (\!port)’ condition will never execute thus never zeroing midi->in_last_port. Fix by rewriting the loop such that the field is set to zero if \!port or end of loop has been reached. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
Move some of the f_midi_transmit to a separate f_midi_do_transmit function so the massive indention levels are not so jarring. This introduces no changes in behaviour. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Felipe F. Tonello authored
remove a field which is unnecessary. No functional changes. Signed-off-by: Felipe F. Tonello <eu@felipetonello.com> Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Du, Changbin authored
ffs_epfile_io and ffs_epfile_io_complete runs in different context, but there is no synchronization between them. consider the following scenario: 1) ffs_epfile_io interrupted by sigal while wait_for_completion_interruptible 2) then ffs_epfile_io set ret to -EINTR 3) just before or during usb_ep_dequeue, the request completed 4) ffs_epfile_io return with -EINTR In this case, ffs_epfile_io tell caller no transfer success but actually it may has been done. This break the caller's pipe. Below script can help test it (adbd is the process which lies on f_fs). while true do pkill -19 adbd #SIGSTOP pkill -18 adbd #SIGCONT sleep 0.1 done To avoid this, just dequeue the request first. After usb_ep_dequeue, the request must be done or canceled. With this change, we can ensure no race condition in f_fs driver. But actually I found some of the udc driver has analogical issue in its dequeue implementation. For example, 1) the dequeue function hold the controller's lock. 2) before driver request controller to stop transfer, a request completed. 3) the controller trigger a interrupt, but its irq handler need wait dequeue function to release the lock. 4) dequeue function give back the request with negative status, and release lock. 5) irq handler get lock but the request has already been given back. So, the dequeue implementation should take care of this case. IMO, it can be done as below steps to dequeue a already started request, 1) request controller to stop transfer on the given ep. HW know the actual transfer status. 2) after hw stop transfer, driver scan if there are any completed one. 3) if found, process it with real status. if no, the request can canceled. Signed-off-by: "Du, Changbin" <changbin.du@intel.com> [mina86@mina86.com: rebased on top of refactoring commits] Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
Eliminate one of the return paths by using a ‘goto error_mutex’ and rearrange some if-bodies which results in reduction of the indention level and thus hopefully makes the function easier to read and reason about. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
In ffs_epfile_io error label points to a return path which includes a kfree(data) call. However, at the beginning of the function data is always NULL so some of the early ‘goto error’ can safely be replaced with a trivial return statement. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
In the AIO path, if allocating of a request failse, the function simply goes to the error_lock path whose end result is returning value of ret. However, at this point ret’s value is zero (assigned as return value from ffs_mutex_lock). Fix by adding ‘ret = -ENOMEM’ statement. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Michal Nazarewicz authored
In the ffs_epfile_io function, data buffer is allocated for non-halt requests. Later, after grabing a mutex, the function checks that epfile->ep is still ep and if it’s not, it set ret to -ESHUTDOWN and follow a path including spin_unlock_irq (just after ‘ret = -ESHUTDOWN’), mutex_unlock (after if-else-if-else chain) and returns ret. Noticeably, this does not include freeing of the data buffer. Fix by introducing a goto which moves control flow to the the end of the function where spin_unlock_irq, mutex_unlock and kfree are all called. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Bjorn Helgaas authored
phy-am335x.c doesn't use any interfaces from linux/regulator/consumer.h, so stop including it. Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Arnd Bergmann authored
When I wrote the cleanup patch series, it was not clear how exactly big-endian mode works on ixp4xx, and whether the driver was doing this correctly. After discussing with Krzysztof Hałasa, this has been clarified, so I can update the comment let pxa25x big-endian (which we don't support) work the same way as ixp4xx. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Arnd Bergmann authored
When dma_addr_t is 64-bit, we get a warning about an invalid cast in the call to ux500_dma_is_compatible() from ux500_dma_channel_program(): drivers/usb/musb/ux500_dma.c: In function 'ux500_dma_channel_program': drivers/usb/musb/ux500_dma.c:210:51: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast] if (!ux500_dma_is_compatible(channel, packet_sz, (void *)dma_addr, len)) The problem is that ux500_dma_is_compatible() is called from the main musb driver on the virtual address, but here we pass in a DMA address, so the types are fundamentally different but it works because the function only checks the alignment of the buffer and that is the same. We could work around this by adding another cast, but I have checked that the buffer we get passed here is already checked before it gets mapped, so the second check seems completely unnecessary and removing it must be the cleanest solution. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Arnd Bergmann authored
The musb driver prints DMA addresses in a few places, using the 0x%x format string. This is wrong on 64-bit architectures (which need %lx) and 32-bit ARM with CONFIG_LPAE set (which needs %llx), otherwise we print the wrong data, as gcc warns: musb/musbhsdma.c: In function 'configure_channel': musb/musbhsdma.c:120:53: error: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t {aka long long unsigned int}' [-Werror=format=] dev_dbg(musb->controller, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n", musb/musbhsdma.c: In function 'dma_channel_program': musb/musbhsdma.c:155:53: error: format '%x' expects argument of type 'unsigned int', but argument 7 has type 'dma_addr_t {aka long long unsigned int}' [-Werror=format=] dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n", musb/tusb6010_omap.c: In function 'tusb_omap_dma_program': musb/tusb6010_omap.c:313:53: error: format '%x' expects argument of type 'unsigned int', but argument 7 has type 'dma_addr_t {aka long long unsigned int}' [-Werror=format=] dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %08x len: %u(%u) packet_sz: %i(%i)\n", This uses the %pad format string, which prints a dma_addr_t that gets passed by reference, which works for all combinations. Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Arnd Bergmann authored
The power_up function is used for otg or udc mode, but nost when the driver is only configured for host mode: drivers/usb/phy/phy-isp1301-omap.c:261:13: error: 'power_up' defined but not used [-Werror=unused-function] This marks the function __maybe_unused to avoid the warning and silently drop the definition when it is unused. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Arnd Bergmann authored
The USB_FSL_MPH_DR_OF symbol is used to ensure the code that interprets the DR device node is built whenever one of the two drivers (EHCI or UDC) for the platform is enabled. However, if CONFIG_USB is disabled and we only support gadget mode, this causes a Kconfig warning: warning: (USB_FSL_USB2) selects USB_FSL_MPH_DR_OF which has unmet direct dependencies (USB_SUPPORT && USB) We can avoid this warning by simply no longer using the symbol, and making sure we enter the drivers/usb/host/ directory when the UDC driver is enabled that needs the file, and then we use Makefile syntax to ensure the file is built-in if needed. There is currently a dependency on CONFIG_OF, but this is redundant, as we already know that this is set unconditionally for the platforms that use this driver. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-
Arnd Bergmann authored
This converts the pxa25x udc driver to use readl/writel as normal driver should do, rather than dereferencing __iomem pointers themselves. Based on the earlier preparation work, we can now also pass the register start in the device pointer so we no longer need the global variable. The unclear part here is for IXP4xx, which supports both big-endian and little-endian configurations. So far, the driver has done no byteswap in either case. I suspect that is wrong and it would actually need to swap in one or the other case, but I don't know which. It's also possible that there is some magic setting in the chip that makes the endianess of the MMIO register match the CPU, and in that case, the code actually does the right thing for all configurations, both before and after this patch. Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Felipe Balbi <balbi@kernel.org>
-