When acpi_device_install_notify_handler() failed in acpi_device_probe(),
it calls acpi_drv->ops.remove() and fails the probe. However, the ACPI
driver is left bound to the acpi_device. Fix it by clearing the driver
and driver_data fields.
Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Changed sysfs eject, acpi_eject_store(), so that it doesn't return
error codes for devices nodes with ACPI scan handlers attached and
no ACPI drivers.
[rjw: Changelog]
Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The IDs of ACPI device nodes stored in their pnp.ids member arrays
are sorted by decreasing priority (i.e. the highest-priority ID is
the first entry). This means that when matching scan handlers to
device nodes, the namespace scanning code should walk the list of
scan handlers for each device node ID instead of walking the list
of device node IDs for each handler (the latter causes the first
handler matching any of the device node IDs to be chosen, although
there may be another handler matching an ID of a higher priority
which should be preferred). Make the code follow this observation.
This change has been suggested and justified by Toshi Kani.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Make acpi_bus_get_parent() more straightforward and remove an
unnecessary local variable ret from it.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Currently, the ACPI namespace scanning code creates platform device
objects for ACPI device nodes whose IDs match the contents of the
acpi_platform_device_ids[] table. However, this adds a superfluous
special case into acpi_bus_device_attach() and makes it more
difficult to follow than it has to be. It also will make it more
difficult to implement removal code for those platform device objects
in the future.
For the above reasons, introduce a struct acpi_scan_handler object
for creating platform devices and move the code related to that from
acpi_bus_device_attach() to the .attach() callback of that object.
Also move the acpi_platform_device_ids[] table to acpi_platform.c.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Make the ACPI PCI IRQ link driver use struct acpi_scan_handler
for representing the object used to set up ACPI interrupt links and
to remove data structures used for this purpose before unregistering
the corresponding ACPI device nodes.
This simplifies the code slightly and reduces the kernel's memory
footprint by avoiding the registration of a struct device_driver
object with the driver core and creation of its sysfs directory
which is unnecessary.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Introduce struct acpi_scan_handler for representing objects that
will do configuration tasks depending on ACPI device nodes'
hardware IDs (HIDs).
Currently, those tasks are done either directly by the ACPI namespace
scanning code or by ACPI device drivers designed specifically for
this purpose. None of the above is desirable, however, because
doing that directly in the namespace scanning code makes that code
overly complicated and difficult to follow and doing that in
"special" device drivers leads to a great deal of confusion about
their role and to confusing interactions with the driver core (for
example, sysfs directories are created for those drivers, but they
are completely unnecessary and only increase the kernel's memory
footprint in vain).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Make acpi_bus_scan_fixed() use device_attach() directly to attach
drivers, if any, to the fixed devices in analogy with how
acpi_bus_scan() works, which allows the last argument of
acpi_add_single_object() to be dropped and the manipulation of the
flags.match_driver bit to be moved to acpi_init_device_object()
and acpi_device_add_finalize().
After these changes all of the functions for the initialization
and registration of struct acpi_device objects work in the same
way for all of them.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
There is no guarantee that acpi_bus_scan() and acpi_bus_trim() will
not be run in parallel for the same scope of the ACPI namespace,
which may lead to a great deal of confusion, so introduce a new mutex
to prevent that from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
The second argument of ACPI driver .remove() operation is only used
by the ACPI processor driver and the value passed to that driver
through it is always available from the given struct acpi_device
object's removal_type field. For this reason, the second ACPI driver
.remove() argument is in fact useless, so drop it.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Since acpi_bus_trim() cannot fail, change its definition to a void
function, so that its callers don't check the return value in vain
and update the callers.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Since ACPI power resources are going to be used more extensively on
new hardware platforms, it becomes necessary for user space (powertop
in particular) to observe some properties of those resources for
diagnostics purposes.
For this reason, expose the current status of each ACPI power
resource to user space via sysfs by adding a new resource_in_use
attribute to the sysfs directory representing the given power
resource.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Make it possible to retrieve the current power state of a device with
ACPI power management from user space via sysfs by adding two new
attributes, power_state and real_power_state, to the sysfs directory
associated with the struct acpi_device object representing the
device's ACPI node.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
ACPI core adds sysfs device files after the given devices have been
registered with device_register(), which is not appropriate, because
it may lead to race conditions with user space tools using those
files.
Fix the problem by delaying the KOBJ_ADD uevent for ACPI devices
until after all of the devices' sysfs files have been created.
This also fixes a use-after-free in acpi_device_unregister().
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Intel Lynxpoint LPSS peripheral drivers depend on LPSS clock tree being
created in order to function properly. The clock tree is exposed as a
platform driver that binds to a device named 'clk-lpt'.
To support this we modify the acpi_create_platform_device() to take one
additional parameter called flags. This is passed from
acpi_platform_device_ids[] array when acpi_create_platform_device() is
called.
We then introduce a new flag ACPI_PLATFORM_CLK which is used to tell
acpi_create_platform_device() to create the platform clocks as well.
Finally we set the ACPI_PLATFORM_CLK flags for all the Lynxpoint LPSS
devices and make sure that when this flag is set we create the
corresponding clock tree platform device.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Core System Resources Table (CSRT) is a proprietary ACPI table that
contains resources for certain devices that are not found in the DSDT
table. Typically a shared DMA controller might be found here.
This patch adds support for this table. We go through all entries in the
table and make platform devices of them. The resources from the table are
passed with the platform device.
There is one special resource in the table and it is the DMA request line
base and number of request lines. This information might be needed by the
DMA controller driver as it needs to map the ACPI DMA request line number
to the actual request line understood by the hardware. This range is passed
as IORESOURCE_DMA resource.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The only difference between acpi_bus_scan() and acpi_bus_add() is the
invocation of acpi_update_all_gpes() in the latter which in fact is
unnecessary, because acpi_update_all_gpes() has already been called
by acpi_scan_init() and the way it is implemented guarantees the next
invocations of it to do nothing.
For this reason, drop acpi_bus_add() and make all its callers use
acpi_bus_scan() directly instead of it. Additionally, rearrange the
code in acpi_scan_init() slightly to improve the visibility of the
acpi_update_all_gpes() call in there.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
The system level attribute of ACPI power resources is the lowest
system sleep level (S0, S2 etc.) in which the given resource can be
"on" (ACPI 5.0, Section 7.1). On the other hand, wakeup power
resources have to be "on" for devices depending on them to be able to
signal wakeup. Therefore devices cannot wake up the system from
sleep states higher than the minimum of the system level attributes
of their wakeup power resources.
Use the wakeup power resources' system level values to get the
deepest system sleep state (highest system sleep level) the given
device can wake up the system from.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Some ACPI power resource initialization errors, like memory
allocation errors, are not taken into account appropriately in some
cases, which may lead to a device having an incomplete list of power
resources that one of its power states depends on, for one example.
Rework the power resource initialization and namespace scanning code
so that power resource initialization errors are treated more
seriously.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The lists of ACPI power resources are currently extracted in two
different ways, one for wakeup power resources and one for power
resources that device power states depend on. There is no reason
why it should be done differently in those two cases, so introduce
a common routine for extracting power resources lists from data
returned by AML, acpi_extract_power_resources(), and make the
namespace scanning code use it for both wakeup and device power
states power resources.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The local variables in acpi_bus_get_power_flags() need not be
initialized upfront, so change the code accordingly.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
To reduce indentation level and improve code readability, move the
initialization code related to device power states from
acpi_bus_get_power_flags() to a new routine,
acpi_bus_init_power_state().
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
ACPI power resources have an order attribute that should be taken
into account when turning them on and off, but it is not used now.
Modify the power resources management code to preserve the
spec-compliant ordering of wakeup power resources.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
ACPI power resources have an order attribute that should be taken
into account when turning them on and off, but it is not used now.
Modify the power resources management code to preserve the
spec-compliant ordering of power resources that power states of
devices depend on (analogous changes will be done separately for
power resources used for wakeup).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI power resources driver is not very useful, because the only
thing it really does is to restore the state of the power resources
that were "on" before system suspend or hibernation, but that may be
achieved in a different way.
Drop the ACPI power resources driver entirely and add
acpi_resume_power_resources() that will walk the list of all
registered power resources during system resume and turn on the ones
that were "on" before the preceding system suspend or hibernation.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
ACPI power resources need to be treated in a special way by the
namespace scanning code, because they need to be ready to use as
soon as they have been discovered (even before registering ACPI
device nodes using them for power management).
For this reason, it doesn't make sense to separate the preparation
of struct acpi_device objects representing them in the device
hierarchy from the creation of struct acpi_power_resource objects
actually used for power resource manipulation. Accordingly, it
doesn't make sense to define non-empty .add() and .remove() callbacks
in the power resources "driver" (in fact, it is questionable whether
or not it is useful to register such a "driver" at all).
Rearrange the code in scan.c and power.c so that power resources are
initialized entirely by one routine, acpi_add_power_resource(), that
also prepares their struct acpi_device objects and registers them
with the driver core, telling it to use a special release routine,
acpi_release_power_resource(), for removing objects that represent
power resources from memory. Make the ACPI namespace scanning code
in scan.c always use acpi_add_power_resource() for preparing and
registering objects that represent power resources.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Simplify the code preparing struct acpi_device objects for
registration by removing useless code, moving different pieces of
code into the functions they belong to and making a couple of int
functions always returning 0 void.
This also fixes a possible memory leak in ACPI device registration
error code path by making acpi_device_register() detach data from
device->handle if device_register() fails and prepares the scanning
code for special-casing ACPI power resources (next patch).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Commit 0090def6 (ACPI: Add interface to register/unregister device
to/from power resources) made it possible to indicate to the ACPI
core that if the given device depends on any power resources, then
it should be resumed as soon as all of the power resources required
by it to transition to the D0 power state have been turned on.
Unfortunately, however, this was a mistake, because all devices
depending on power resources should be treated this way (i.e. they
should be resumed when all power resources required by their D0
state have been turned on) and for the majority of those devices
the ACPI core can figure out by itself which (physical) devices
depend on what power resources.
For this reason, replace the code added by commit 0090def6 with a
new, much more straightforward, mechanism that will be used
internally by the ACPI core and remove all references to that code
from kernel subsystems using ACPI.
For the cases when there are (physical) devices that should be
resumed whenever a not directly related ACPI device node goes into
D0 as a result of power resources configuration changes, like in
the SATA case, add two new routines, acpi_dev_pm_add_dependent()
and acpi_dev_pm_remove_dependent(), allowing subsystems to manage
such dependencies. Convert the SATA subsystem to use the new
functions accordingly.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Should use acpi_device pointer directly instead of use handle and
get the device pointer again later.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Make acpi_bus_trim() work in analogy with acpi_bus_scan() and carry
out two passes such that ACPI drivers will be detached from device
nodes being removed in the first pass and the device nodes themselves
will be removed in the second pass.
For this purpose split the driver unregistration out of
acpi_bus_remove() into a new routine, acpi_bus_device_detach(), that
will be executed by acpi_bus_trim() in the additional first pass as
a post-order callback.
This is necessary, because some ACPI drivers' .remove() routines
unregister struct device objects associated with the ACPI device
nodes being removed and that needs to happen while the ACPI
device nodes are still around (for example, in case they need to be
used for power management or similar things at that time).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
The current acpi_bus_trim() implementation is not really
straightforward and may be simplified significantly by using
acpi_walk_namespace() with acpi_bus_remove() as a post-order
callback.
Observe that acpi_bus_remove(), as called by acpi_bus_trim(), cannot
actually fail, because its first argument is guaranteed not to be
NULL thanks to the acpi_bus_get_device() check in acpi_bus_trim(),
so simply move the acpi_bus_get_device() check to acpi_bus_remove()
and use acpi_walk_namespace() to execute it for every device under
start->handle as a post-order callback. The, run it directly for
start->handle itself.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
All callers of acpi_bus_trim() pass 1 (true) as the second argument
of it, so remove that argument entirely and change acpi_bus_trim()
to always behave as though it were 1.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Drop the second argument of acpi_device_unregister(), type, which is
not used by that function.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Since device_attach() returns 1 on success (a driver has been bound
to the device), the check against its return value in
acpi_bus_device_attach() should modified to take that into accout.
Make it so.
[rjw: Subject and changelog.]
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Commit 805d410 (ACPI: Separate adding ACPI device objects from
probing ACPI drivers) introduced an ACPI power resources management
regression, because it didn't ensure that the power resources
driver bind to the struct acpi_device objects corresponding
to power resources as soon as they were created. As a result,
ACPI power management routines may attempt to access power resource
objects before they are ready to use.
To fix this problem, tell the acpi_add_single_object() in
acpi_bus_check_add() to probe the driver for objects of type
ACPI_BUS_TYPE_POWER. This fix has been verified to work on
HP nx6325 where the problem was first observed.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
At one point acpi_device_set_id() checks if acpi_device_hid(device)
returns NULL, but that never happens, so system bus devices with an
empty list of PNP IDs are given the dummy HID ("device") instead of
the "system bus HID" ("LNXSYBUS"). Fix the code to use the right
check.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: <stable@vger.kernel.org>
Drop the .bind() and .unbind() that have no more users from
struct acpi_device_ops and remove all of the code referring to
them from drivers/acpi/scan.c.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
The callers of acpi_bus_add() usually assume that if it has
succeeded, then a struct acpi_device object has been attached to
the handle passed as the first argument. Unfortunately, however,
this assumption is wrong, because acpi_bus_scan(), and acpi_bus_add()
too as a result, may return a pointer to a different struct
acpi_device object on success (it may be an object corresponding to
one of the descendant ACPI nodes in the namespace scope below that
handle).
For this reason, the callers of acpi_bus_add() who care about
whether or not a struct acpi_device object has been created for
its first argument need to check that using acpi_bus_get_device()
anyway, so the second argument of acpi_bus_add() is not really
useful for them. The same observation applies to acpi_bus_scan()
executed directly from acpi_scan_init().
Therefore modify the relevant callers of acpi_bus_add() to check the
existence of the struct acpi_device in question with the help of
acpi_bus_get_device() and drop the no longer necessary second
argument of acpi_bus_add(). Accordingly, modify acpi_scan_init() to
use acpi_bus_get_device() to get acpi_root and drop the no longer
needed second argument of acpi_bus_scan().
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
After the removal of the second argument of acpi_bus_scan() there is
no difference between the ACPI_BUS_ADD_MATCH and ACPI_BUS_ADD_START
add types, so the add_type field in struct acpi_device may be
replaced with a single flag. Do that calling the flag match_driver.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
After the removal of acpi_start_single_object() and acpi_bus_start()
the second argument of acpi_bus_scan() is not necessary any more,
so drop it and update acpi_bus_check_add() accordingly.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Notice that acpi_bus_add() uses only 2 of its 4 arguments and
redefine its header to match the body. Update all of its callers as
necessary and observe that this leads to quite a number of removed
lines of code (Linus will like that).
Add a kerneldoc comment documenting acpi_bus_add() and wonder how
its callers make wrong assumptions about the second argument (make
note to self to take care of that later).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
The ACPI PCI root bridge driver was the only ACPI driver implementing
the .start() callback, which isn't used by any ACPI drivers any more
now.
For this reason, acpi_start_single_object() has no purpose any more,
so remove it and all references to it. Also remove
acpi_bus_start_device(), whose only purpose was to call
acpi_start_single_object().
Moreover, since after the removal of acpi_bus_start_device() the
only purpose of acpi_bus_start() remains to call
acpi_update_all_gpes(), move that into acpi_bus_add() and drop
acpi_bus_start() too, remove its header from acpi_bus.h and
update all of its former users accordingly.
This change was previously proposed in a different from by
Yinghai Lu.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
If acpi_bus_check_add() is called for a handle already having an
existing struct acpi_device object attached, it is not necessary to
check the type and status of the device correspondig to it, so
change the ordering of acpi_bus_check_add() to avoid that.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Notice that one member of struct acpi_bus_ops, acpi_op_add, is not
used anywhere any more and the relationship between its remaining
members, acpi_op_match and acpi_op_start, is such that it doesn't
make sense to set the latter without setting the former at the same
time. Therefore, replace struct acpi_bus_ops with new a enum type,
enum acpi_bus_add_type, with three values, ACPI_BUS_ADD_BASIC,
ACPI_BUS_ADD_MATCH, ACPI_BUS_ADD_START, corresponding to
both acpi_op_match and acpi_op_start unset, acpi_op_match set and
acpi_op_start unset, and both acpi_op_match and acpi_op_start set,
respectively.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Toshi Kani <toshi.kani@hp.com>