// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2008 ioogle, Inc. All rights reserved. * * Libata transport class. * * The ATA transport class contains common code to deal with ATA HBAs, * an approximated representation of ATA topologies in the driver model, * and various sysfs attributes to expose these topologies and management * interfaces to user-space. * * There are 3 objects defined in this class: * - ata_port * - ata_link * - ata_device * Each port has a link object. Each link can have up to two devices for PATA * and generally one for SATA. * If there is SATA port multiplier [PMP], 15 additional ata_link object are * created. * * These objects are created when the ata host is initialized and when a PMP is * found. They are removed only when the HBA is removed, cleaned before the * error handler runs.
*/
/* * Hack to allow attributes of the same name in different objects.
*/ #define ATA_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \ struct device_attribute device_attr_##_prefix##_##_name = \
__ATTR(_name,_mode,_show,_store)
#define ata_bitfield_name_match(title, table) \ static ssize_t \
get_ata_##title##_names(u32 table_key, char *buf) \
{ \ char *prefix = ""; \
ssize_t len = 0; \ int i; \
\ for (i = 0; i < ARRAY_SIZE(table); i++) { \ if (table[i].value & table_key) { \
len += sprintf(buf + len, "%s%s", \
prefix, table[i].name); \
prefix = ", "; \
} \
} \
len += sprintf(buf + len, "\n"); \ return len; \
}
#define ata_bitfield_name_search(title, table) \ static ssize_t \
get_ata_##title##_names(u32 table_key, char *buf) \
{ \
ssize_t len = 0; \ int i; \
\ for (i = 0; i < ARRAY_SIZE(table); i++) { \ if (table[i].value == table_key) { \
len += sprintf(buf + len, "%s", \
table[i].name); \ break; \
} \
} \
len += sprintf(buf + len, "\n"); \ return len; \
}
/** * ata_is_port -- check if a struct device represents a ATA port * @dev: device to check * * Returns: * %1 if the device represents a ATA Port, %0 else
*/ staticint ata_is_port(conststruct device *dev)
{ return dev->release == ata_tport_release;
}
/** * ata_tport_delete -- remove ATA PORT * @ap: ATA PORT to remove * * Removes the specified ATA PORT. Remove the associated link as well.
*/ void ata_tport_delete(struct ata_port *ap)
{ struct device *dev = &ap->tdev;
/** ata_tport_add - initialize a transport ATA port structure * * @parent: parent device * @ap: existing ata_port structure * * Initialize a ATA port structure for sysfs. It will be added to the device * tree below the device specified by @parent which could be a PCI device. * * Returns %0 on success
*/ int ata_tport_add(struct device *parent, struct ata_port *ap)
{ int error; struct device *dev = &ap->tdev;
/** * ata_port_classify - determine device type based on ATA-spec signature * @ap: ATA port device on which the classification should be run * @tf: ATA taskfile register set for device to be identified * * A wrapper around ata_dev_classify() to provide additional logging * * RETURNS: * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP, * %ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure.
*/ unsignedint ata_port_classify(struct ata_port *ap, conststruct ata_taskfile *tf)
{ int i; unsignedintclass = ata_dev_classify(tf);
/* Start with index '1' to skip the 'unknown' entry */ for (i = 1; i < ARRAY_SIZE(ata_class_names); i++) { if (ata_class_names[i].value == class) {
ata_port_dbg(ap, "found %s device by sig\n",
ata_class_names[i].name); returnclass;
}
}
/** * ata_is_ata_dev -- check if a struct device represents a ATA device * @dev: device to check * * Returns: * true if the device represents a ATA device, false otherwise
*/ staticbool ata_is_ata_dev(conststruct device *dev)
{ return dev->release == ata_tdev_release;
}
if (!ata_is_ata_dev(dev)) return 0; return &i->dev_attr_cont.ac == cont;
}
/** * ata_tdev_free -- free an ATA transport device * @dev: struct ata_device owning the transport device to free * * Free the ATA transport device for the specified ATA device. * * Note: * This function must only be called for a ATA transport device that has not * yet successfully been added using ata_tdev_add().
*/ staticvoid ata_tdev_free(struct ata_device *dev)
{
transport_destroy_device(&dev->tdev);
put_device(&dev->tdev);
}
/** * ata_tdev_delete -- remove an ATA transport device * @ata_dev: struct ata_device owning the transport device to delete * * Removes the ATA transport device for the specified ATA device.
*/ staticvoid ata_tdev_delete(struct ata_device *ata_dev)
{ struct device *dev = &ata_dev->tdev;
/** * ata_tdev_add -- initialize an ATA transport device * @ata_dev: struct ata_device owning the transport device to add * * Initialize an ATA transport device for sysfs. It will be added in the * device tree below the ATA link device it belongs to. * * Returns %0 on success and a negative error code on error.
*/ staticint ata_tdev_add(struct ata_device *ata_dev)
{ struct device *dev = &ata_dev->tdev; struct ata_link *link = ata_dev->link; struct ata_port *ap = link->ap; int error;
/** * ata_is_link -- check if a struct device represents a ATA link * @dev: device to check * * Returns: * true if the device represents a ATA link, false otherwise
*/ staticbool ata_is_link(conststruct device *dev)
{ return dev->release == ata_tlink_release;
}
if (!ata_is_link(dev)) return 0; return &i->link_attr_cont.ac == cont;
}
/** * ata_tlink_delete -- remove an ATA link transport device * @link: struct ata_link owning the link transport device to remove * * Removes the link transport device of the specified ATA link. This also * removes the ATA device(s) associated with the link as well.
*/ void ata_tlink_delete(struct ata_link *link)
{ struct device *dev = &link->tdev; struct ata_device *ata_dev;
/** * ata_tlink_add -- initialize an ATA link transport device * @link: struct ata_link owning the link transport device to initialize * * Initialize an ATA link transport device for sysfs. It will be added in the * device tree below the ATA port it belongs to. * * Returns %0 on success and a negative error code on error.
*/ int ata_tlink_add(struct ata_link *link)
{ struct device *dev = &link->tdev; struct ata_port *ap = link->ap; struct ata_device *ata_dev; int error;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.