Ingenic Driver

Posted on

Driver Delivery 3.20 Same binaries driver than the version 3.18 (IngenicoEnum). New Microsoft Windows Hardware digitals signatures for IngenicoVBus and IngenicoVCom. VBus binary driver has been updated to fix data transfer issue. Drivers USB pour connexion caisse, pour terminaux Ingenico Telium et TETRA Autonomes. Compatible Windows 2012 Server, Windows 2016 Server, Windows Vista, Windows 7, Windows 8, Windows 10. Ingenico - TETRA Telium Tools Ingenico Jungo Driver v3.22 (Vista-Win10) Verifone - MX Integration Kit Verifone Form Agent Packages Verifone MX 915 Form Agent Verifone MX 915 P2PE Forms Verifone MX 925 Form Agent Verifone MX 925 P2PE Forms Ingenico (UIA) Conversion Updates Ingenico Telium UIA 9.04 Update Ingenico Telium RBA 15.06 Update Custom.

Welcome to the LWN.net Weekly Edition for December 24, 2020

This edition contains the following feature content:
  • LWN's 2020 Retrospective: a look back at the year that was and what we thought it might be in January.
  • PureOS: freedom, privacy, and security: a company to create a secure Linux product.
  • 5.11 Merge window, part 1: the first set of patches merged for the 5.11 release.
  • Managing multifunction devices with the auxiliary bus: a new virtual bus for devices that do more than one thing.
  • Doing symbolic math with SymPy: Lee Phillips reviews a capable mathematical tool.

This week's edition also includes these inner pages:

  • Brief items: Brief news items from throughout the community.
  • Announcements: Newsletters, conferences, security updates, patches, and more.

This is the final LWN Weekly Edition for 2020; as is traditional we will betaking the last week of the year off for rest, recovery, and preparationfor the year to come. Thanks to all of you for supporting LWN though thischallenging year. Best wishes to all of you for the holidays and the newyear, and we look forward to seeing you all back here in 2021.

Please enjoy this week's edition, and, as always, thank you for supporting LWN.net.

LWN's 2020 Retrospective

Predictions are hard, as they say, especially when they are about thefuture. So perhaps your editor can be forgiven for not anticipating that2020 would be the sort of year that makes one think nostalgically abouttrips to the dentist, waiting in a crowded motor-vehicle office, orcrossing the Pacific in a row-47 middle seat. If only we had known howgood we had it. Be that as it may, this year is finally coming to an end.Read on for a look back at the year, starting with the ill-advised predictions made in January.Ingenic Driver

A look back at a look forward

The first prediction had to do with the Python project finding its path ina post-Guido world. In truth, founder Guido van Rossum has not been asabsent as one might have thought, and he continues to have a strong say inthe development direction of the language. His championing of the PEP 622 pattern-matching mechanism showsthat he still has strong ideas about where the language should go. Pythongovernance may be happening without Guido, but the project's leaders stilllisten to him.

The direction of the GNU Project was the subject of another prediction thatdid not really pan out as expected. As far as the public can see, atleast, the discussion about the future of the GNU project appears to havefaded away. Richard Stallman remains in charge (as expected), but theproject gives every indication of being mostly on autopilot.

The prediction about increasing retirements in the community explicitlysaid that little might happen in 2020, and that appears to be the case. Ifanything, things went the other way, with Van Rossum ending his retirementto take a new job in the industry.

Did the kernel workflow effort begin to bear fruit, as predicted? Thatwork has continued, and the community has gained some new infrastructurefor dealing with patches outside of email. The ripest fruit at this point,certainly, is the b4 tool, which continually gainscapabilities and has become an increasingly indispensable part of manydevelopers' workflow. One wonders how we did without it, but it only showed up (under a different name) inJanuary.

Your editor predicted that the next LTS kernel would be 5.9, released onNovember 1. There were some weasel words about how, if there were fewerten-week cycles, that kernel would actually be 5.10, released in December.And, in fact, kernel releases got a little faster in 2020, 5.9 was releasedon October 11, and the long-term-support release for 2020 will be5.10, which came out on December 13. So this prediction is a win — aslong as the fine print is taken into account.

A prediction that there will be conflict within the Debian community isrelatively safe in any year, 2020 included. Attacks on Debian from outsidethe community may have fallen off a bit, but Debian developers are good atcreating their own heat. This can be seen, for example, in ongoingdisagreements about vendoring and, ofcourse, initscripts.

As predicted, the kernel community did come close to finishing its work toaddress the year-2038 problem, though some loose ends remain. It just goesto show that if you predict something oftenenough you may eventually be able to claim victory.Another prediction was that BPF API issues would not go away. Theyarguably have not, but neither did they play a large role in thediscussions of 2020. The one exception was perhaps this libbpf issue which isn't really an issuein BPF itself. Meanwhile, BPF development continues at a furious pace.

Were there 'perturbations in the employment market' as predicted?Obviously, labor markets as a whole have had a difficult year, but it seemsthat the market for free-software developers was mostly shielded from allof that. Social distancing and working from home come naturally to us, andthe technology industry as a whole had a good year.

What was missed

Overall, it is fair to say that your editor's record as a mediocrepredictor of future events has not improved in 2020. But failure hereisn't just a matter of predicting things that did not happen; there's alsothe little problem of not predicting things that did come about.Needless to say, there's a few of those to make fun of as well.

One surprise, despite being arguably predictable, was Red Hat's decision to end support of CentOS as we knowit in favor of 'CentOS Stream'. There have been worries about what Red Hatwould do with CentOS ever since the acquisition, given that there are clearincentives to end the free ride that CentOS has been for so many users.The hard part with such predictions is always in the timing; it's hard totell which straw will break the camel's back.

A similar story played out in the LibreOffice community, where Collabora moved LibreOffice Online into a separate,Collabora-branded project. Once again, a company putting significantresources into a free-software project has felt the need to make changes inorder to get a sufficient return on that investment. Happily, CollaboraOnline remains free software, but it lives outside of the LibreOfficecommunity, for now at least.

The death of email in 2020 was not predicted, and it did not happen. Butthe movement of projects away from email-centered processes was predictableand did continue. Debian debated a move toDiscourse, and Fedora continues to move discussions in that direction,for example. Not everybody agrees that these web-based systems are animprovement over email, but there is pressure to move in that directionregardless.

That other story

Then, there is that one other little surprise.Some comfort can be taken in the fact that few others predicted that theworld would be thoroughly disrupted by a global pandemic, even though thefirst reports were showing up by the time the predictions article waswritten. Over the year, the pandemic has brought a few interesting thingsto light.

It is worth pointing out, for example, that as soon as discussion ofcontact-tracing apps took off, a consensus formed that these apps should beopen source. Given the sensitive nature of the information handled, theneed to be able to inspect the operation of contact-tracing apps and ensurethat privacy was protected was easy to see. We have, over the years,raised some awareness of that advantage of free and open-source software,it seems.

Of course, weather and solitaire apps can still follow your every move andreport everything back to the mothership. Oh well.

One other thing is worth a mention. Free software famously built theInternet. When in-person meetings became an unwise thing to do, there wasan immediate, pressing need for the Internet to support activities likevideo conferencing, and the free-software community had no real answer togive. There are good video-conferencing applications, and many of us put them to good use this year, but there wasnothing that could work on the scale needed. Thus, even free-softwarecompanies — and free-software events — ended up depending on highlyproprietary platforms, some of which arenot necessarily designed with privacy or freedom in mind. This was ahuge missed opportunity; freesoftware, it seems, is still far from world domination.

We were certainly hurt by the end of in-person conferences; they are necessary for the smooth functioning of our global, electronicallyconnected community. Thatsituation seems likely to continue well into 2021. But how did thepandemic affect the development of the code?One way of answering that would be to point out that two of the threebusiest kernel development cycles ever happened in 2020. Another way wouldbe this set of plots:

The upper plot shows a count of patches merged into the mainline kernel by thedate they were posted; the lower one counts by commit date instead. Theshaded areas indicate the merge windows. If there is any signal to beseen there at all, it suggests that activity may have picked up ever soslightly during the peak of the lockdowns in March and April. Certainlythere is no decline in activity over the course of the year. The pandemiccontinues to cause untold grief and harm worldwide, but it has beenrelatively gentle with the development community.

In the same vein, the community has been gentle with LWN. At the beginningof the pandemic it was hard indeed to predict how things would go and easyto fear the worst. At the end of the year, LWN's staff is healthy, and sois its financial footing. We can only offer our deepest thanks to all ofyou who have supported us over the years, and who continued to support usthrough this difficult year as well, many at higher levels than before.You all are the reason LWN has been here since 1998.

We wish the best of the holidays for all of our readers and a happybeginning to what will hopefully be a better year than 2020.

PureOS: freedom, privacy, and security

By Jake Edge
December 23, 2020

A recent blogpost from Purism—the company that developed PureOS to run on its security-focusedhardware—celebrates three years of FSF endorsementof the Linux distribution. While this endorsement is an achievement that is not ashighly valued by our communities as one might think, the work done toobtain and maintain that endorsement is useful even to those who disdainthe FSF or disagree with its definition of what makes a distribution 'free'. WhilePurism and PureOS have been on our radarfor a few years now, it seems worth a look at where things have gone withthe distribution—and the company behind it.

The blog post notes that PureOS and Purism 'sit on a three-leggedstool of Freedom, Privacy and Security'. The three are intertwined,of course, since PureOS consisting of only free software allows users toensure there are no antifeatures being slipped into the OS or applicationsthat would impact their privacy or security. Beyond that, free software isan excellent defense against various software supply-chain attacks; in additionthe scrutiny of the code afforded to free software, it can also be built ina manner that provides more security:

Finally, free software has a gigantic advantage over proprietary softwarein supply chain security due to Reproducible Builds. WithReproducible Builds you can download the source code used to build your software, buildit yourself, and compare your output with the output you get from avendor. If the output matches, you can be assured that no malicious codewas injected somewhere in the software supply chain and it 100% matches thepublic code that can be audited for back doors. Because proprietarysoftware can’t be reproducibly built by third parties (because they don’tshare the code), you are left relying on the package signature for all yoursupply chain security.

PureOS is a Debian derivative that consists of a stable 'Amber' release, as well as arolling 'Byzantium' release. Amber is based on Debian 10 ('Buster'),while Byzantium pulls packages from Debian testing. Because PureOS onlyincludes free software, it only pulls from the 'main' archive, not'contrib' or 'non-free' because they contain packages that do not complywith the DebianFree Software Guidelines (DFSG).

The system is customized to makevarious tweaks, including adding kernel patches for security, enablingAppArmor, and defaulting to a Wayland-based GNOME desktop. It alsoinstalls a browser that is configured for better privacy and security;originally it was Firefox-based, but that has changedto GNOME Web (formerly knownas Epiphany) more recently. It also comes with DuckDuckGo as the default search engine, rather than alternatives that hoover up vast amounts ofinformation about searches and clicks to enable 'better' advertising.

PureOS will run on most desktops and laptops that will run Linux, which isnot really a surprise. Some hardware may not work (e.g. laptop WiFi)because it needs a proprietary binary blob, but users can install thosepieces from elsewhere if desired. But the mobile version ofPureOS is not likely to run on existing phone hardware, which, as the PureOS FAQ notes, generallyrequires binary blobs. Those blobs typically onlywork with specific older kernels that are not supported by Mobile PureOS,which uses recent mainline kernels.

For PureOS on phones, Purism now offers its Librem 5 phone. It wasoriginally crowdfunded, and has taken a somewhat circuitous route to massproduction (leaving some ratherunhappy with Purism), but it is designedwith the three legs of the stool in mind. For example, it has hardware kill switches todisconnect various peripherals, such as the cellular modem, microphone,camera, and WiFi. Naturally, it does not need any binary blobs for itsfunctionality either.

Other hardware, such as laptops(Librem 14 and 15), mini-PC, and servers, have also been designedwith privacy and security in mind. The laptops feature hardware killswitches for the camera and microphone, for example. Kobo driver download for windows 7. Any of the hardwarecan be ordered with the company's anti-interdictionservice that provides customized mechanisms to enable recipients todetect hardware tampering during shipping. These include tamper-evidenttape on the system and its box, glitter nail polish on screws, and picturesof all of that sent separately, encrypted with GPG.

Ingenico Drivers

Beyond that, users can also order the PureBootBundle that couples the PureBootsecurity-oriented firmwarewith a pre-installed LibremKey, which is a tamper-resistant USB OpenPGP smart card. The Key willcome with a GPG key that will be installed as the secure boot key for the system; it will be shipped separately,perhaps to a different address, to the new owner before the system is shipped. The Librem Key isconfigured such that it will blink its LED to indicate if the firmware hasbeen tampered with en route.

PureBoot is based on coreboot and has neutralizedand disabled the IntelManagement Engine (IME), which is an intrusive part of the firmware that has had a number of security flaws identified in it over the years.Users wanting to fully control their systems will want to get rid of asmuch of IME as possible. The Heads boot software is used to detecttampering with the firmware as well.

It all adds up to a pretty impressive story for those who are concernedabout their security and privacy.That story, painted via the huge number of blog posts and otherdocumentation available from Purism, may besomewhat off the mark, however. There have been other complaints aboutthe company, its products, and its behavior, beyond those that werementioned here as well. There are clearly some problems to be addressed,but the ideas and conceptsbehind the hardware and software seem sound.

As might be guessed, security and privacy features donot come for free—or even inexpensively. The Purism hardware products aregenerally quite a bit more expensive than their less secure competitors,but the availability of the systems and services is a boon for those whoneed that level of assurance.

Ingenic

To a large extent, we humans have sacrificed our freedom, privacy, and security onthe altar of convenience—and low cost. Over the years, LWN has looked atvarious aspects of these problems, including the recent efforts by Mozilla to 'take back' the internetfrom the forces of surveillancecapitalism (inspired, in part, by The Social Dilemmamovie). In early December, we also looked at the movement awayfrom allowing general-purpose computing on our devices; hardware likethat provided by Purism is a way around that problem—at least for now.

But the bottom line is that these options will only exist if at least some consumers areinterested in buying them. Purism looks to have a lot of the rightanswers, but, with any luck, the market will be large enough to supportmultiple options for hardware and software of this sort. PureOS andPureBoot are all free software that can be adopted and improved by othersas needed. In order for that to go anywhere, though, people are going tohave to start changing their thinking and prioritize freedom, privacy,and security over convenience and price. In truth, that all seems ratherunlikely, sadly.

Ingenico Driver Usb

5.11 Merge window, part 1

When Linus Torvalds releasedthe 5.10 kernel, he noted that the 5.11 merge window would run upagainst the holidays. He indicated strongly that maintainers should sendhim pull requests early as a result. Maintainers appear to have listened;over 10,000 non-merge changesets were pulled into the mainline in the firstthree days of the 5.11 merge window. Read on for a summary of the mostsignificant changes in that flood of patches.

Architecture-specific

  • Support for Intel's software guard extensions (SGX) finally made it into the kernel after 41 revisions on the mailing lists. Some information can be found in this documentation commit.
  • In the ongoing effort to crack down on user-space access to x86 model-specific registers (MSRs), writes to MSR_IA32_ENERGY_PERF_BIAS are no longer allowed. There is a document being constructed with a list of tools that perform writes to MSRs, with the eventual goal of finding better solutions for all of them.
  • The arm64 architecture can now expose tag bits on addresses (the uppermost bits that are not used as part of the virtual address) to signal handlers if the SA_EXPOSE_TAGBITS option has been set with sigaction(). This provides access to, among other things, memory type extension keys in pointers.
  • Support for Microblaze systems without a memory-management unit has been removed; it would seem that there are no longer any users of such systems.
  • The MIPS architecture has gained support for coverage testing with gcov.

Core kernel

  • There is a new system-call interception mechanism, based on prctl(), that allows user space to trap and emulate system calls. The target use case is running Windows games, but other applications seem likely as well.
  • The userfaultfd() system call now provides the ability to disable handling of kernel-mode faults as a security-enhancing measure.
  • The BPF subsystem has gained support for task-local storage — data that lives with a given task. The first user is the BPF Linux security module (formerly KRSI).
  • The accounting of memory used by BPF programs has changed completely. There is now a control-group controller providing fine-grained management of memory use; see this merge commit for (some) information.
  • The BTF mechanism, providing information about kernel types for BPF programs (and more), has been extended to kernel modules.
  • The io_uring subsystem has gained support for the shutdown(), renameat2(), and unlinkat() system calls.
  • Calls to io_uring_enter() can now specify a timeout value. Adding this feature requires changing the API of that system call; this was done by adding a new flag (IORING_FEAT_EXT_ARG) to indicate the presence of the timeout argument.

Filesystems and block I/O

  • The Btrfs filesystem has a couple of new mount options intended to help with the unwelcome task of rescuing data off a corrupted filesystem. Using rescue=ignorebadroots will cause a mount to try to proceed with a corrupted extent root, while rescue=ignoredatacsums turns off data checksum verification.
  • Re-exporting a filesystem mounted over NFS is now considered to be a supported operation.
  • The close_range() system call has gained a new CLOSE_RANGE_CLOEXEC option. When that option is specified, the indicated file descriptors are marked close-on-exec rather than closed immediately.

Hardware support

  • Crypto: Intel QAT_4xxx crypto accelerators and Intel Keem Bay OCS AES/SM4 accelerators.
  • Graphics: Novatek NT36672A DSI panels, TDO TL070WSH30 DSI panels, Analogix Anx7625 MIPI to DP interfaces, AMD 'Van Gogh' and 'Dimgrey cavefish' graphics processors, Lontium LT9611UXC DSI/HDMI bridges, Samsung sofef00/s6e3fc2x01 OnePlus 6/6T DSI cmd mode panels, and ABT Y030XX067A 320x480 LCD panels.
  • Hardware monitoring: Corsair power-supply HID controllers, Maxim MAX127 12-bit 8-channel data acquisition systems, STMicroelectronics pm6764 voltage regulators, Delta Q54SJ108A2 power supplies, and Linear Technology LTC2992 I2C system monitors.
  • Media: OmniVision OV9734 sensors, OmniVision OV02A10 sensors, and Amlogic 2D graphic acceleration units.
  • Miscellaneous: Modtronix lcd2s 20x4 character displays, Arm DMC-620 memory controllers, Samsung Exynos generic interconnects, Intel Keem Bay USB PHYs, MediaTek MT7621 PCI PHYs, Ingenic USB PHYs, Mediatek MT6360 analog-to-digital converters, Dialog Semiconductor DA9121 regulators, NXP PF8100/PF8121A/PF8200 regulators, Mellanox BlueField performance monitoring counters, Dell Wyse 3020 power buttons, Dialog Semiconductor DA7280 haptic interfaces, TI PRU remote processors, Intel LGM SoC NAND controllers, and AMD sensor fusion hubs.
  • Networking: Hirschmann Hellcreek TSN switches, Samsung S3FWRN82 UARTs, and OpenCompute TimeCard clocks.
  • Pin control and GPIO: Qualcomm LPASS LPI, 8953, SC7280, and SDX55 pin controllers, Intel Lakefield, Elkhart Lake, and Alder Lake-S pin controllers, and Microsemi/Microchip serial GPIO controllers.
  • Sound: NXP audio transceivers, Mediatek MT8192 audio interfaces, Nuvoton NAU8315 class-D amplifiers, Analog Devices ADAU1372 codecs, and Realtek RT715 SDCA codecs.
  • It's also worth noting that there has been more than the usual number of obsolete drivers removed during this merge window. Quite a bit of cleanup has been happening across the driver subsystem.

Miscellaneous

  • Support for the auxiliary bus, a virtual bus for multi-function devices, has been added.

Networking

  • The 802.1Q 'connectivity fault management' mechanism is now supported. See this merge message for (a bit) more information.
  • Support for the WiMAX protocol has been moved to staging with the intent of removing it altogether in the near future. It would appear that this support has not actually worked for some time, so the number of users is thought to be zero.
  • RFC 6951 — UDP encapsulation of the SCTP protocol — is now supported.
  • Zero-copy TCP receives have seen a number of performance improvements, making this feature worthwhile for much smaller payloads; see this merge message for more information.
  • There is a pair of new ioctl() calls to facilitate the bridging of PPP channels; see this commit for some documentation.

Security-related

  • The seccomp() system call has gained support for constant-action bitmaps. This is a mechanism allowing seccomp() to determine that specific system calls are always allowed or denied and short out much of the processing work for those calls.

Internal kernel changes

  • The arm64 and s390 architectures have removed set_fs().
  • The migration disable functionality has been merged. The realtime tree has had this capability for years, but there is increasing need for it in the mainline as well.
  • One user of migration disable is the kmap_local() API, which has also been merged.

By the normal schedule, the 5.11 merge window should close onDecember 27, but Torvalds has indicated that he might delay the 5.11-rc1release if he falls behind on pull requests due to the holidays. The paceof merging thus far suggests, though, that nobody should count on the mergewindow lasting any longer than usual. As always, we'll post anothersummary once the merge window closes, whenever that may be.

Managing multifunction devices with the auxiliary bus

December 17, 2020

This article was contributed by Marta Rybczyńska

Device drivers usually live within a single kernel subsystem. Sometimes,however, developers need to handle functionalities outside of this model.Consider, for example, a network interface card (NIC) exposing both Ethernet andRDMA functionalities. There is one hardware block, but two drivers for thetwo functions. Those drivers need to work within their respectivesubsystems, but they must also share access to the same hardware. There isno standard way in current kernels to connect those drivers together, sodevelopers invent ad-hoc methods to handle the interaction betweenthem. Recently, Dave Ertman posteda patch set introducing a new type of a bus, called the 'auxiliary bus', toaddress this problem.

Complex devices

Linux already includes a number of drivers for multi-functiondevices. One of the ways to support them is the Multi-FunctionDevices (MFD) subsystem. It handles independent devices 'glued'together into one hardware block which may contain some sharedresources. MFD allows access to device registers either directly, or usinga common bus. In this second case, it conveniently multiplexes accesses onInter-Integrated Circuit(I2C) or SerialPeripheral Interface (SPI) buses. As the MFD sub-devices are separate,MFD drivers do not share a common state.

The devices Ertman addresses do not fit well into the MFD model.Devices using the auxiliary bus provide subsets of the capabilities of asingle hardware device. They do not expose separate register sets for eachfunction; thus they cannot be described by devicetrees or discovered byACPI. Their drivers need to share access to the hardware. Events concerning allsub-functionalities (like power management) need to be properly handled byall drivers. These devices will often be specialized processors runningfirmware and communicating with the host system (and the Linux drivers) bymessaging. The available functions may not be known in advance, and thusmust be discovered at run time.

The documentationpatch in the auxiliary bus series cites a number of examples. The SoundOpen Firmware (SOF) driver interacts with a single device exposinginterfaces like HDMI output, microphones, speakers, testing, and debughooks. NICs implementing both Ethernet and RDMA may need a driversupporting a common part of the functionalities, and then the specificEthernet and RDMA drivers can implement specific parts on top of that.

Current kernels do not have a generic way to describe dependenciesbetween drivers for this kind of device. A solution to the problem could beto have a way to attach secondary drivers to the primaryone; this is exactly what the auxiliary bus implements.

Auxiliary devices and drivers

The patch set introduces two main concepts: The 'auxiliary device' and'auxiliary driver'. These implement the relationship between the main andthe secondary drivers. The main driver maintains the device state, allocating and managing all shared data. It also unregisters all secondarydrivers when shutting down. Secondary drivers, instead, handle theinteractions with the specific subsystem they are implementing a devicefor.

Each main driver may expose a number of functionalities (devices) forsecondary drivers. Only one secondary driver can attach to each of thosefunctionalities.

The main driver creates an auxiliary device, represented by structauxiliary_device:

The combination of name and id must be unique; thecomplete device name is a combination of the module name and those twofields, connected by dots (.). That yields a result likemodname.device_name.id.

The developer embeds this structure in the device structure ofthe main driver, with all shared data necessary for the communicationbetween the main driver and secondary drivers. They may also addsupplementary callbacks.

The sequence to initialize the main driver contains two steps. The firstone is to call auxiliary_device_init():

It verifies the arguments and returns anerror code if need be; in such case the initialization of the deviceshould be aborted.If the first call succeeds, the second step is to call the macroauxiliary_device_add() with the initialized device; this willset up the device name and register the deviceitself.

The unregistration procedure also has two steps, consisting of calls toauxiliary_device_uninit() (necessary from the point whenauxiliary_device_init() has succeeded) andauxiliary_device_delete(). Those functions have the followingprototypes:

This two-step approach was implemented inresponse to comments on earlier versions of the patch set. It allows the driver to allocate itsown data between auxiliary_device_init() andauxiliary_device_add() with a possibility to free it correctly inthe case of a failure.

The secondary devices, which will connect to the main driver,are represented by struct auxiliary_driver:

This structure includes a number of callbacks to manage thedevice's life cycle, and the id_table containing names of thedevices the driver can bind with. All callbacks receive pointers to theparent's auxiliary_device, allowing access to the shareddata.

The secondary devices are set up with auxiliary_driver_register():

This function requires the probe() callback and theid_table to be filled in. When successful, it causes aprobe() callback call for any matching devices. The secondarydevices can access the shared data using container_of() and theauxiliary_device structure.

When unregistering a driver, the developer should callauxiliary_driver_unregister():

First users

Together with the auxiliary bus implementation, Ertman postedchanges to the SOF driver. The modified driver uses thisinfrastructure to implementa test driver, and aprobes driver, allowing the creation of a new virtual audio device thatcan tap into the pipeline and allow listening in at any point.

Another user can be found in the networking subsystem; Leon Romanovskyposteda conversion of the mlx5 driver to use the auxiliary bus. The updateddriver creates network, VDPA, and RDMAdrivers for one physical device. Those changes allowthe removal of a bunch of custom driver code. Parav Pandit followed upby using this functionality to implement device sub-functions.

The patch set has come to its fourth iteration in its current form, andwitnessed a number of earlier ones under the names of ancillaryand virtualbus.The development of the auxiliary bus patch set took time, and it createddependencies in other work. This caused a fair amount of pressure to get itupstream, and that led to some pushing on thelist. In an attempt to push things forward, Dan Williams repostedthe patch set, stating that 'it looks good to me and several otherstakeholders'. After a review from GregKroah-Hartman, the auxiliary bus code was merged into the mainline for the5.11 kernel release.

Doing symbolic math with SymPy

December 22, 2020

This article was contributed by Lee Phillips

On November 29, version 1.7 of SymPy, a Python library forsymbolic mathematics, was released. The new version brings a large numberof enhancements and bug fixes, and some minor backwardincompatibilities. While these are enumerated in detail in the releasenotes, we will take advantage of this opportunity to look at some ofthe things that can be done with SymPy and explore its interface optionsthrough several detailed examples.

What is SymPy?

SymPy performs symbolic mathematicalmanipulations using Python. Like others of its kind, it can solve algebraic anddifferential equations, simplify expressions, apply trigonometricidentities, differentiate, and integrate; SymPy knows things about sets,manifolds, tensors, and many other mathematical objects. It offers aconvenient interface to Matplotlib,the Python plotting library that I looked at back in 2015; this allowsa seamless graphical exploration of results.

Although they are not limited to algebra, members of this category ofsoftware are universally called computer algebra systems (abbreviated CAS),so I will adopt this term here. Computer algebra systems are not usedprimarily for numerical work, as is a program such as Octave, which I reviewedrecently. They combine the encoded knowledge of specialists indiverse mathematical fields with strategies of expression transformation toperform actual symbolic mathematical manipulations. These programs do notreplace a human mathematician in creating new mathematical knowledge, but theycan solve problems that can be reduced to a set of rules and mechanicalprocedures, such as finding an integral or factoring a polynomial.

Who uses SymPy?

Anyone who needs to carry out non-trivial mathematical manipulations canpotentially benefit from a computer algebra system. It can be used to checkwork done by hand, to replace weighty tomes offormulas, to solve large systems of equations that cannot (or shouldnot) be done with pencil and paper, or to explore, symbolically andgraphically, a mathematical landscape.

There are manycomputer algebra systems available, both of the free-software varietyand proprietary offerings. The most well-known of the commercial programsis certainly Mathematica, while SymPyis one of the most popular free-software computer algebra systems. Theirpredecessors go back decades. The first system of this kind was Macsyma, which arrived in the1960s, and is still offered as a commercial product, though apparently onlyfor Windows. I wrote about its free-software offshoot, Maxima, in a 2017 LWN article where I surveyed programsfor symbolic mathematics available for Linux.

Maxima was for many years the standard general-purpose, free-softwarecomputer algebra system. Although it is still the preferred such programfor many practitioners, the comparatively young SymPy has become aprominent choice over the past decade. This is due to several factors, suchas its inclusion in other packages, in particular Sage, which is a large system that bundles andprovides a unified interface to many numerical, graphical, and symbolicsoftware packages. Another reason behind SymPy's wide adoption is that itis a Python library, so the large population familiar with Python's syntaxwill not be tripped up when using SymPy. In contrast, Maxima is written inLisp and has its own syntax that the user is obligated to master.

Many who use SymPy do so within Sage; however, for those who don'tneed the other things that come with Sage, installing standalone SymPymakes more sense. For one, Sage takes up over a gigabyte of storage space,due to the large number of packages that it bundles, while my SymPyinstallation takes up just 63 megabytes, including its 45 standardmodules. SymPy can be included in other Python code with a single importstatement, and its liberal BSD license presents no obstacles to any form ofdistribution.

SymPy's only dependency is mpmath,which is alibrary for arbitrary precision arithmetic that is also BSD-licensed. Usersinstalling from source will have to install mpmath before installing SymPy,but pip will install it automatically. SymPy and mpmath are included in projects suchas the Anacondahttps:>

Let's first try the IPython interface. After typing ipython ina terminal and getting the IPython startup message, the user types twocommands, shown in the figure below, to start up the SymPy environment. Thefirst command imports one function from SymPy, which is then run tobootstrap the rest. This function, init_session(), imports therest of SymPy and then invokes the SymPy symbols() function threetimes.

The purpose of the calls to symbols() is to define some names for variables that can beused in mathematical expressions. This is necessary because, in Python, youmay not use undefined symbols in expressions, but in a computer algebrasystem you need to refer to variables somehow—symbols that, by definition,have not been assigned a value. init_session() establishes ahandful of variables with conventional names, and of course the user isfree to define as many more as required. Finally, init_printing()sets up any defaults for printing results to the terminal.

If the terminal in use supports Unicode, SymPy will form mathematicaloutput from Unicode glyphs. To see what this looks like, we'll ask it tosimply represent an integral for us, using the Integral()function, which returns an unevaluated integral. The figure below shows howthe integral sign is built up to the required height using line segmentglyphs, how Greek letters are used for mathematical constants, and theinfinity symbol, which is entered on the command line using a double 'o'.

Now let's do a little math. As mentioned above, SymPy comes with a goodnumber of specialized modules. In the following figure we import thegeometry module, which knows about a variety of planar geometricalobjects. We define a point at the origin, and a circle centered there, with aradius of one. Then we define two more points, and a line connectingthem. This line should be horizontal and touch the circle at its highestpoint. The next two commands check on that.

First we ask SymPy whether theline is tangent to the circle, and it confirms that it is. Then we askwhere the line and circle intersect. The answer, at x = 0 and y = 1, iswhat we expected.

The qtconsoleinterface for SymPy has several advantages over the IPythoninterface. The most significant is that it can typeset math using LaTeX,which helps immensely in reading complicated expressions in theoutput. Other nice features are embedded graphs and automatic functiondocumentation: when typing an open-parenthesis after a function name, theqtconsole will immediately pop up a box with the function signature, if itrecognizes the name, and some documentation about the function, as shown inthe figure below:

Hitting escape or clicking anywhere in the window dismisses thedocumentation box. Tab-completion works in qtconsole, as does accessingcommand history with the arrow keys, which is the same as it is in the IPython interface. At leaston my machine, qtconsole is deaf to control-C, but I was able to cancel anypending input with the escape key.

The disadvantages of using the qtconsole are that it involves extrainstalls; on my machine I had to install the PyQt5 package withpip. It also did not, at first, handle my screen resolution correctly.Those with screen resolutions larger than 72 dots per inch will need toenter the command:

That will create larger LaTeX output. The scale factor can be set as desired, and thecolor setting creates more legible output than the default medium grey.

If using inline plots, which you get with the'%matplotlib inline' command, Matplotlib also needs to knowabout the screen resolution:

The number need not match the actual resolution, but can be set as aconvenient way to get the desired figure size. All of the above commandsare entered at the interactive prompt within the qtconsole session. Afterthis is done, the interface performs well and is a pleasure to use.

The following figure is designed to convince the user of the advantageof LaTeX output. Simple-looking problems often lead to hairy expressions;the result of solving this innocent-looking integral would be difficultto parse using ASCII or even SymPy's well-executed Unicode output.

Ingenico Driver Ipp320

The next example includes an embedded line graph and shows off SymPy'sknowledge of special functions and integrals. It asks for the integral of aGaussian,which is called the error function, written as erf(). Theplot command uses _ in the argument, which stands for themost recently returned result. The basic plotting functions are importedautomatically with SymPy.

Our last example demonstrates multiple integration and surfaceplotting. Before using this plotting function, plot3d must beimported from sympy.plotting. The plot command again refers tothe previous result, and defines limits for the x and ycoordinates.

The new release

The 1.7 release brings a few backward-incompatible changes. Some ofthese involve the naming of modules, so the import statements in existingscripts may need to be updated. Another possible disruption for some usersis the dropping of support for Python 3.5; the minimum version now requiredby SymPy is Python 3.6.

The new version brings a handful of improvements to SymPy'sunderstanding of trigonometric functions, absolute values, and othermathematical objects, which improve its ability to simplify expressions.Translation of the output to LaTeX now works better in some situations, and itis more convenient to substitute another plotting library for Matplotlib.

New capabilities were added to several modules, including physics,statistics, and the ordinary differential equation solver; the relevantsections of the release notes contain links to the issue tracker entriesfor each of these, which users of these packages may want to consult.

Documentation and assistance

The starting place to learn how to use SymPy is the documentation based on thecurrent release, which covers the various methods of installation,includes a nicely done tutorial aimed at people who might not know what acomputer algebra system is, has a detailed reference to all the standard SymPymodules, and contains information about the SymPy project. This manual is mostlyup-to-date and quite good, although it contains a few corners with obsoleteinformation.

One wonderful feature of the documentation is that every code blockcomes with a button that opens a window where a live notebook interfacecalled SymPy Live is running; the code in the block is copied to the windowand executed.

There are some glitches, however. The documentation is up todate, covering, as of this writing, version 1.7.1; but the SymPy Live instance isstill on 1.5. The consequence of that is that some code blocks in thedocumentation produce errors in the SymPy Live window. Another problem,unavoidable in a service such as this, is that the response is much slowerin general than what a user will experience with a locally installed SymPy.Direct access to SymPy Live is also provided here, free for anyone toexperiment with the software.

Users seeking help from others may want to turn to the general mailing list, hosted onGoogle Groups, or the Gitterchannel; there is also an IRC channel called #sympy.

SymPy Gamma is an interestingproject with SymPy at its core. It aspires to offer something similar to Wolfram Alpha, which is an onlinemathematical knowledge engine. SymPy Gamma presents several example topicsin mathematics and the user can type in problems or questions. It has made impressive progress,but it not yet in the same league as Wolfram Alpha, in general failing toanswer open-ended questions about mathematical objects, but presenting anice variety of information in response to a more focused query.

If theuser simply types a mathematical expression, the engine will reply with itstypeset form, graph (only of single-variable expressions), roots,derivative, antiderivative, series expansion, and sometimes more,depending on the type of expression entered. This is all provided withoutthe user needing to know the syntax for calculating these things, so thisis a way to make some use of SymPy without having to learn anything aboutit, or even about Python, aside from the basic syntax related tomathematics.

Anyone in need of a general environment for computer-assistedmathematics will be well-served by either Maxima or SymPy. Which one to usedepends on several factors, which include the availability and maturity ofmodules for any needed specialized areas of math or science. Lisp expertsinterested in possibly adding to the system or improving existing routines,while occasionally dropping down into the Lisp subsystem, will naturallygravitate towards Maxima. SymPy is a good choice for those alreadyexperienced with Python or who are interested in adding mathematicalintelligence to a Python project.

Vivante Corporation
Founded2004; 17 years ago
Headquarters,
ProductsSemiconductor intellectual property
Websitewww.vivantecorp.com

Vivante Corporation is a fablesssemiconductor company headquartered in Sunnyvale, California, with an R&D center in Shanghai, China. The company was founded in 2004 as GiQuila and focused on the portable gaming market. The company's first product was a DirectX-compatible graphics processing unit (GPU) capable of playing PC games. In 2007, GiQuila changed its name to Vivante and changed the direction of the company to focus on the design and licensing of embeddedgraphics processing unit designs. The company is licensing its Mobile Visual Reality to semiconductor solution providers that serve embedded computing markets for mobile gaming, high-definition home entertainment, image processing, and automotive display and entertainment.

Vivante is named as a contributor to the HSA (Heterogeneous System Architecture) Foundation.[1]

In 2015, VeriSilicon Holdings Co., Ltd. acquired Vivante Corporation in an all-stock transaction.[2]

Products[edit]

Since changing directions Vivante has developed a range of GPU cores that are compliant with the OpenGL ES 1.1 and 2.0 standards as well as the OpenVG standard. Created by VeriSilicon support for the Vulkan API 1.0 and for OpenVX 1.0 is provided for at least 6 major desktop and embedded operating systems.[3]

2D graphics products & Vector GPUs, summarized by the vendor under the term 'Composition Processing Cores' (CPC),[4] sometimes mentioned with the feature of single pass composition blending capability of 8 or higher, are the GC300,[5] GC320, GC350[6] and GP355 (OpenVG core[7])with the additional listing of GC200 and GC420.[8]NXP further mentions GC255 in a presentation for their i.MX models.[9]The NXP i.MX8 series will come with 2 units of the GC7000Lite or GC7000 vector processor.[10]For 3D graphics products please see the table below.

Ingenico Usb Drivers

Legend for the notes in below listing:

  • Pipelined FP/INT double (64-bit), single/high (32-bit) and half precision/medium (16-bit) precision IEEE formats for GPU Compute and HDR graphics, Source:[11]
SeriesModelDateShader Cores
SP/Half (mode)
Silicon area (mm2)Core Clock
Max in MHz
Shader Clock
Max in MHz
FillrateBus width
(bit)
API (version)Shader GFLOPS
(High=SP / Medium=Half)
Usage
M triangles/sG vertices/s(GP/s)(GT/s)OpenGL ESOpenVGOpenCLOpenGLDirect3D
GCNanoGCNano Lite1 (VEC-4)0.3 @ 28 nm100–200

@ 28HPM

100–200

@ 28HPM

400.10.2N/A1.1N/AN/AN/A3.2?
GCNano1 (VEC-4)0.5 @ 28 nm200 @ 28HPM200 @ 28HPM400.10.22.03.2[12]STM32MP157
GCNano Ultra
(Vega-Lite)
GCNano Ultra1 (VEC-4)1 @ 28 nm400 @ 28HPM800 @ 28HPM800.20.41.2

optional

6.4NXP i.MX8M Mini
GCNano Ultra31 (VEC-4)1.6 @ 28 nm400 @ 28HPM800 @ 28HPM800.20.4?3.06.4?
GC200GC2000.57 @ 65 nm[13]250 @ 65nmLP
375 @ 65nmG+
0.37532/16N/AN/AN/AN/AJz4760[14]
GC400GC4001 (VEC-4)
4 (VEC-1)
1.4
2 @ 65 nm[15]
250 @ 65nmLP
375 @ 65nmG+
190.0940.18832/162.0[16]1.1 EP[16]N/A113[16]NXP i.MX6 SoloX: GC400T
GC500[17]32/16PXA920: GC530
GC600GC6001 (VEC-4)
4 (VEC-1)
32/161.2/1.13.0/2.111CuBox
GC800GC8001 (VEC-4)
4 (VEC-1)
2.5
3.38 @ 65 nm[18]
800 @ 28HPM
250 @ 65nmLP
375 @ 65nmG+
1000 @ 28HPM38 @ 65nmG+0.188 @ 65nmG+0.375 @ 65nmG+32/163.0[19]1.2

optional

3.0/2.1118 / 16[20]RK291x,
ATM7013, ATM7019
GC8601 (VEC-4)
4 (VEC-1)
32/163.0/2.111Jz4770: GCW ZeroNOVO7
GC8801 (VEC-4)
4 (VEC-1)
350.10.26632/163.0/2.1113.2[21]NXP i.MX6 Solo and DualLite
GCx000GC1000
(Vega-Lite)
2 (VEC-4)
8 (VEC-1)
3.5
4.26 @ 65 nm[22]
800 @ 28HPM
500 @ 65nmLP
750 @ 65nmG+
1000 @ 28HPM123
58 @ 65nmG+
0.5
0.375 @ 65nmG+
0.8
0.75 @ 65nmG+
32/163.0/2.11116ATM7029: GC1000+,
Marvell PXA986,[23]
PXA988, PXA1088[14]
GC20004 (VEC-4)
16 (VEC-1)
6.9800 @ 28HPM1000 @ 28HPM26711.632/161.23.0/2.11132NXP i.MX6 Dual and Quad
GC40008 (VEC-4)
32 (VEC-1)
12.4[8]800 @ 28HPM1000 @ 28HPM26721.683.0/2.11164HiSilicon K3V2
Vega xXGC3000
(Vega 1X)
4/8 (VEC-4)
16/32 (VEC-1)
800 @ 28HPM1000 @ 28HPM26711.68/43.0/2.11132 / 64[24]NXP S32V234[25]
GC5000
(Vega 2X)
8/16 (VEC-4)
32/64 (VEC-1)
800 @ 28HPM1000 @ 28HPM26711.632/163.0/2.11164 / 128Marvell PXA1928[26]
GC6000
(Vega 4X)
GC6400?
16/32 (VEC-4)
64/128 (VEC-1)
800 @ 28HPM1000 @ 28HPM53343.232/163.0/2.111128 / 256
GC7000
(Vega 8X)
[27]
GC7000 UltraLite
GC1500?[28]
8 Vega0.50.832/163.0/2.11116 / 32Marvell PXA1908[29]NXP i.MX8M Nano[30]
GC7000 Lite
GC7000L?
16 Vega11.632/163.0/2.11132 / 64Marvel PXA1936[28]
NXP i.MX 8QuadPlus
NXP i.MX 8Quad
GC700032 Vega800 @ 28HPM1000 @ 28HPM106726.43.232/163.0/2.11164 / 128NXP i.MX 8QuadMax
GC720064 Vega46.432/163.0/2.111128 / 256
GC7400128 Vega812.832/163.0/2.111256 / 512
GC7600256 Vega1625.632/163.0/2.111512 / 1024
GC8000GC8000
SeriesModelDateShader Cores
SP/Half (mode)
Silicon area (mm2)Core Clock
Max in MHz
Shader Clock
Max in MHz
FillrateBus width
(bit)
API (version)Shader GFLOPS
(High=SP / Medium=Half)
Usage
M triangles/sG vertices/s(GP/s)(GT/s)OpenGL ESOpenVGOpenCLOpenGLDirect3D

Adoption[edit]

They have announced that as of 2009 they have at least fifteen licensees who have used their GPUs in twenty embedded designs.[31] Application processors using Vivante GPU technology:

  • Marvell ARMADA range of SoCs[32]
  • Freescale i.MX6 Series[33]
  • Ingenic Semiconductor Jz4770[34]
  • ICT Godson-2H[35][36]
  • Actions Semiconductor ATM7029
  • HiSilicon K3V2
  • InfoTM iMAP×210[37]

GC8000 Series[edit]

After Vivante was sold to Verisilicon the Arcturus GC8000 series was released by Verisilicon, which supports newer technologies such as OpenCL 2.0, OpenVX 1.1, OpenVG 1.1, OpenGL ES 3.2, OpenGL 4.0 and Vulkan 1.0.[38]

Linux support[edit]

There are no plans on writing a new DRM/KMS driver kernel driver for the Vivante hardware, since Vivante previously put out their Linux kernel component under the GNU General Public License (GPL), instead of maintaining it as a proprietary blob. The free Gallium3D-style device driver etna_viv has surpassed Vivante's own proprietary user-space driver in some benchmarks.[39] It supports Vivante's product line of GC400 Series, GC800 Series, GC1000 Series, GC2000 Series, GC3000 Series, GC4000 Series, and GC7000lite.[40]

See also[edit]

  • PowerVR – available as SIP block to 3rd parties
  • Mali – available as SIP block to 3rd parties
  • Adreno – found only on Qualcomm Snapdragon, could be available as SIP block to 3rd parties
  • Tegra – family of SoCs for mobile computers, the graphics core could be available as SIP block to 3rd parties
  • Atom family of SoCs – with Intel graphics core, not licensed to 3rd parties
  • AMD mobile APUs – with AMD graphics core, not licensed to 3rd parties

References[edit]

Ingenico Driver Update

  1. ^http://hsafoundation.com/ HSA (Heterogeneous System Architecture) Foundation
  2. ^'VeriSilicon to Acquire Vivante Corporation in All-Stock Transaction'. Vivante Corporation. October 12, 2015. Archived from the original on October 14, 2015. Retrieved October 14, 2015.
  3. ^VeriSilicon: Embedded Vivante Dedicated Vision IP
  4. ^'Composition Processing Cores (CPC)'.
  5. ^'Vivante GC300 - ChipEstimate.com IP Catalog'. www.chipestimate.com.
  6. ^'Vivante GC350 - ChipEstimate.com IP Catalog'. www.chipestimate.com.
  7. ^'Recording Not Found'. cc.readytalk.com.
  8. ^ abcnxsoft (January 19, 2013). 'GPUs Comparison: ARM Mali vs Vivante GCxxx vs PowerVR SGX vs Nvidia Geforce ULP'.
  9. ^2D and 3D Graphics in Freescale Devices
  10. ^'i.MX8 Factsheet'(PDF). NXP. NXP. Retrieved October 6, 2016.
  11. ^''Vivante Vega 3D Technology', section 'Unified Shader Architecture''.
  12. ^'Vivante GPU « GPU Talk'.
  13. ^'Vivante GC200 - ChipEstimate.com IP Catalog'. www.chipestimate.com.
  14. ^ abMobile GPU (Vivante Graphics ..)
  15. ^'Vivante GC400 - ChipEstimate.com IP Catalog'. www.chipestimate.com.
  16. ^ abcVivante Product Brief
  17. ^'Company Profile for Vivante Corporation'. www.businesswire.com. August 1, 2008.
  18. ^'Vivante GC800 - ChipEstimate.com IP Catalog'. www.chipestimate.com.
  19. ^'Vivante shipping GPU cores designed to support the latest OpenGL ES 3.0 specification'. Retrieved September 13, 2014.
  20. ^'Vivante GPU (Freescale i.MX6)'.
  21. ^'i.MX6SDL GC880 performance. - NXP Community'. community.nxp.com.
  22. ^'Vivante GC1000 - ChipEstimate.com IP Catalog'. www.chipestimate.com.
  23. ^'Archived copy'. Archived from the original on September 25, 2013. Retrieved September 25, 2013.CS1 maint: archived copy as title (link)
  24. ^'GPGPU - Vivante Corporation'. www.vivantecorp.com.
  25. ^'S32V234 Vision and Sensor Fusion Processor Family-NXP'. www.nxp.com.
  26. ^cnxsoft (February 26, 2014). 'Marvell ARMADA Mobile PXA1928 SoC Features Four Cortex A53 Cores, Vivante GC5000 GPU, and LTE'.
  27. ^cnxsoft (April 19, 2014). 'Vivante Unveils Details About GC7000 Series GPU IP Family'.
  28. ^ ab'The Linley Group - Marvell Extends LTE Lineup'. www.linleygroup.com.
  29. ^'GFXBench - Unified cross-platform 3D graphics benchmark database'. The cross-platform performance site.
  30. ^Inc, NXP USA (February 26, 2019). 'NXP Accelerates Edge Computing Revolution'. GlobeNewswire News Room. Retrieved September 6, 2019.
  31. ^'Vivante Corporation Signs 15th GPU Licensee' (Press release). June 8, 2009. Retrieved July 8, 2009.
  32. ^'Vivante GPUs Power Marvell ARMADA Application Processors' (Press release). October 27, 2009. Retrieved February 1, 2010.
  33. ^'Vivante GPU IP Cores Power the Latest Freescale i.MX 6 Series of Application Processors' (Press release). April 26, 2011. Retrieved July 31, 2011.
  34. ^'Vivante GPU Core Brings Android 3.0 Honeycomb Support to Ingenic's Latest JZ4770 Application Processor' (Press release). June 13, 2011. Archived from the original on January 19, 2013. Retrieved December 13, 2011.
  35. ^'Chinese Academy of Sciences Selects Vivante as GPU Partner for Netbooks' (Press release). June 29, 2009. Retrieved December 13, 2011.
  36. ^'Guess what is ready for tape out: It has a MIPS core and a GPU from Vivante'. April 28, 2011. Retrieved December 13, 2011.
  37. ^'盈方微电子股份有限公司'. InfoTM. Retrieved October 6, 2015.
  38. ^'Verisilicon Arcturus GC8000 series'.
  39. ^'Open-Source Vivante Driver In Some Cases Outperforming Proprietary Driver'.
  40. ^'etna_pipe is currently compatible with at least the following GC chips'.

External links[edit]

Retrieved from 'https://en.wikipedia.org/w/index.php?title=Vivante_Corporation&oldid=1003728683'