^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2008 ioogle, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Libata transport class.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The ATA transport class contains common code to deal with ATA HBAs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * an approximated representation of ATA topologies in the driver model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * and various sysfs attributes to expose these topologies and management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * interfaces to user-space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * There are 3 objects defined in in this class:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - ata_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * - ata_link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * - ata_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Each port has a link object. Each link can have up to two devices for PATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * and generally one for SATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * If there is SATA port multiplier [PMP], 15 additional ata_link object are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * These objects are created when the ata host is initialized and when a PMP is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * found. They are removed only when the HBA is removed, cleaned before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * error handler runs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <scsi/scsi_transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/libata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/hdreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "libata.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "libata-transport.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ATA_PORT_ATTRS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ATA_LINK_ATTRS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ATA_DEV_ATTRS 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct scsi_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct scsi_transport_template *ata_scsi_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct ata_internal {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct scsi_transport_template t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct device_attribute private_port_attrs[ATA_PORT_ATTRS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct device_attribute private_link_attrs[ATA_LINK_ATTRS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct device_attribute private_dev_attrs[ATA_DEV_ATTRS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct transport_container link_attr_cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct transport_container dev_attr_cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * The array of null terminated pointers to attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * needed by scsi_sysfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct device_attribute *link_attrs[ATA_LINK_ATTRS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct device_attribute *port_attrs[ATA_PORT_ATTRS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct device_attribute *dev_attrs[ATA_DEV_ATTRS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define to_ata_internal(tmpl) container_of(tmpl, struct ata_internal, t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define tdev_to_device(d) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) container_of((d), struct ata_device, tdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define transport_class_to_dev(dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tdev_to_device((dev)->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define tdev_to_link(d) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) container_of((d), struct ata_link, tdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define transport_class_to_link(dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) tdev_to_link((dev)->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define tdev_to_port(d) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) container_of((d), struct ata_port, tdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define transport_class_to_port(dev) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) tdev_to_port((dev)->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Device objects are always created whit link objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int ata_tdev_add(struct ata_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void ata_tdev_delete(struct ata_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Hack to allow attributes of the same name in different objects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define ATA_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct device_attribute device_attr_##_prefix##_##_name = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) __ATTR(_name,_mode,_show,_store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ata_bitfield_name_match(title, table) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) get_ata_##title##_names(u32 table_key, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) char *prefix = ""; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ssize_t len = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) for (i = 0; i < ARRAY_SIZE(table); i++) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (table[i].value & table_key) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) len += sprintf(buf + len, "%s%s", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) prefix, table[i].name); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) prefix = ", "; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) len += sprintf(buf + len, "\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return len; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define ata_bitfield_name_search(title, table) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) get_ata_##title##_names(u32 table_key, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ssize_t len = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i = 0; i < ARRAY_SIZE(table); i++) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (table[i].value == table_key) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) len += sprintf(buf + len, "%s", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) table[i].name); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) len += sprintf(buf + len, "\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return len; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) } ata_class_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { ATA_DEV_UNKNOWN, "unknown" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { ATA_DEV_ATA, "ata" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { ATA_DEV_ATA_UNSUP, "ata" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { ATA_DEV_ATAPI, "atapi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { ATA_DEV_ATAPI_UNSUP, "atapi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { ATA_DEV_PMP, "pmp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { ATA_DEV_PMP_UNSUP, "pmp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { ATA_DEV_SEMB, "semb" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { ATA_DEV_SEMB_UNSUP, "semb" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { ATA_DEV_ZAC, "zac" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { ATA_DEV_NONE, "none" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ata_bitfield_name_search(class, ata_class_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) } ata_err_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { AC_ERR_DEV, "DeviceError" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { AC_ERR_HSM, "HostStateMachineError" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { AC_ERR_TIMEOUT, "Timeout" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { AC_ERR_MEDIA, "MediaError" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { AC_ERR_ATA_BUS, "BusError" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { AC_ERR_HOST_BUS, "HostBusError" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { AC_ERR_SYSTEM, "SystemError" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { AC_ERR_INVALID, "InvalidArg" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) { AC_ERR_OTHER, "Unknown" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) { AC_ERR_NODEV_HINT, "NoDeviceHint" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { AC_ERR_NCQ, "NCQError" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ata_bitfield_name_match(err, ata_err_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } ata_xfer_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { XFER_UDMA_7, "XFER_UDMA_7" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) { XFER_UDMA_6, "XFER_UDMA_6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { XFER_UDMA_5, "XFER_UDMA_5" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { XFER_UDMA_4, "XFER_UDMA_4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { XFER_UDMA_3, "XFER_UDMA_3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { XFER_UDMA_2, "XFER_UDMA_2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { XFER_UDMA_1, "XFER_UDMA_1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { XFER_UDMA_0, "XFER_UDMA_0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { XFER_MW_DMA_4, "XFER_MW_DMA_4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { XFER_MW_DMA_3, "XFER_MW_DMA_3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { XFER_MW_DMA_2, "XFER_MW_DMA_2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { XFER_MW_DMA_1, "XFER_MW_DMA_1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { XFER_MW_DMA_0, "XFER_MW_DMA_0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) { XFER_SW_DMA_2, "XFER_SW_DMA_2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { XFER_SW_DMA_1, "XFER_SW_DMA_1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { XFER_SW_DMA_0, "XFER_SW_DMA_0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) { XFER_PIO_6, "XFER_PIO_6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) { XFER_PIO_5, "XFER_PIO_5" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { XFER_PIO_4, "XFER_PIO_4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) { XFER_PIO_3, "XFER_PIO_3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) { XFER_PIO_2, "XFER_PIO_2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) { XFER_PIO_1, "XFER_PIO_1" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) { XFER_PIO_0, "XFER_PIO_0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { XFER_PIO_SLOW, "XFER_PIO_SLOW" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ata_bitfield_name_match(xfer,ata_xfer_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * ATA Port attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define ata_port_show_simple(field, name, format_string, cast) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) show_ata_port_##name(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct ata_port *ap = transport_class_to_port(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return scnprintf(buf, 20, format_string, cast ap->field); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define ata_port_simple_attr(field, name, format_string, type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ata_port_show_simple(field, name, format_string, (type)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ata_port_simple_attr(local_port_no, port_no, "%u\n", unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static DECLARE_TRANSPORT_CLASS(ata_port_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "ata_port", NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void ata_tport_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct ata_port *ap = tdev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ata_host_put(ap->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * ata_is_port -- check if a struct device represents a ATA port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @dev: device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * %1 if the device represents a ATA Port, %0 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int ata_is_port(const struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return dev->release == ata_tport_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int ata_tport_match(struct attribute_container *cont,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!ata_is_port(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return &ata_scsi_transport_template->host_attrs.ac == cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * ata_tport_delete -- remove ATA PORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * @port: ATA PORT to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Removes the specified ATA PORT. Remove the associated link as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) void ata_tport_delete(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct device *dev = &ap->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ata_tlink_delete(&ap->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) transport_remove_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) device_del(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) transport_destroy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /** ata_tport_add - initialize a transport ATA port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @parent: parent device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * @ap: existing ata_port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Initialize a ATA port structure for sysfs. It will be added to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * tree below the device specified by @parent which could be a PCI device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Returns %0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int ata_tport_add(struct device *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct device *dev = &ap->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) device_initialize(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dev->type = &ata_port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dev->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ata_host_get(ap->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) dev->release = ata_tport_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dev_set_name(dev, "ata%d", ap->print_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) transport_setup_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ata_acpi_bind_port(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) error = device_add(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) goto tport_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) device_enable_async_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pm_runtime_forbid(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) transport_add_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) transport_configure_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) error = ata_tlink_add(&ap->link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto tport_link_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) tport_link_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) transport_remove_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) device_del(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) tport_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) transport_destroy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ata_host_put(ap->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * ATA link attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int noop(int x) { return x; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define ata_link_show_linkspeed(field, format) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) show_ata_link_##field(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct ata_link *link = transport_class_to_link(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return sprintf(buf, "%s\n", sata_spd_string(format(link->field))); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define ata_link_linkspeed_attr(field, format) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ata_link_show_linkspeed(field, format) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ata_link_linkspeed_attr(hw_sata_spd_limit, fls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ata_link_linkspeed_attr(sata_spd_limit, fls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ata_link_linkspeed_attr(sata_spd, noop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static DECLARE_TRANSPORT_CLASS(ata_link_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) "ata_link", NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static void ata_tlink_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * ata_is_link -- check if a struct device represents a ATA link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @dev: device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * %1 if the device represents a ATA link, %0 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int ata_is_link(const struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return dev->release == ata_tlink_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int ata_tlink_match(struct attribute_container *cont,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!ata_is_link(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return &i->link_attr_cont.ac == cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * ata_tlink_delete -- remove ATA LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * @port: ATA LINK to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Removes the specified ATA LINK. remove associated ATA device(s) as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) void ata_tlink_delete(struct ata_link *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct device *dev = &link->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct ata_device *ata_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ata_for_each_dev(ata_dev, link, ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ata_tdev_delete(ata_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) transport_remove_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) device_del(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) transport_destroy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * ata_tlink_add -- initialize a transport ATA link structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * @link: allocated ata_link structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * Initialize an ATA LINK structure for sysfs. It will be added in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * device tree below the ATA PORT it belongs to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Returns %0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int ata_tlink_add(struct ata_link *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct device *dev = &link->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct ata_port *ap = link->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct ata_device *ata_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) device_initialize(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) dev->parent = &ap->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dev->release = ata_tlink_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (ata_is_host_link(link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dev_set_name(dev, "link%d", ap->print_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) transport_setup_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) error = device_add(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto tlink_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) transport_add_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) transport_configure_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ata_for_each_dev(ata_dev, link, ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) error = ata_tdev_add(ata_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) goto tlink_dev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) tlink_dev_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) while (--ata_dev >= link->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ata_tdev_delete(ata_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) transport_remove_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) device_del(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) tlink_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) transport_destroy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * ATA device attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) #define ata_dev_show_class(title, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) show_ata_dev_##field(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct ata_device *ata_dev = transport_class_to_dev(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return get_ata_##title##_names(ata_dev->field, buf); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define ata_dev_attr(title, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ata_dev_show_class(title, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ata_dev_attr(class, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ata_dev_attr(xfer, pio_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ata_dev_attr(xfer, dma_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ata_dev_attr(xfer, xfer_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #define ata_dev_show_simple(field, format_string, cast) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) show_ata_dev_##field(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct ata_device *ata_dev = transport_class_to_dev(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return scnprintf(buf, 20, format_string, cast ata_dev->field); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #define ata_dev_simple_attr(field, format_string, type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ata_dev_show_simple(field, format_string, (type)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static DEVICE_ATTR(field, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) show_ata_dev_##field, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ata_dev_simple_attr(spdn_cnt, "%d\n", int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct ata_show_ering_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) char* buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct ata_show_ering_arg* arg = void_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) u64 seconds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u32 rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) seconds = div_u64_rem(ent->timestamp, HZ, &rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) arg->written += sprintf(arg->buf + arg->written,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) "[%5llu.%09lu]", seconds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) rem * NSEC_PER_SEC / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) arg->written += get_ata_err_names(ent->err_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) arg->buf + arg->written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) show_ata_dev_ering(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct ata_device *ata_dev = transport_class_to_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct ata_show_ering_arg arg = { buf, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ata_ering_map(&ata_dev->ering, ata_show_ering, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return arg.written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) show_ata_dev_id(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct ata_device *ata_dev = transport_class_to_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int written = 0, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (ata_dev->class == ATA_DEV_PMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) for(i=0;i<ATA_ID_WORDS;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) written += scnprintf(buf+written, 20, "%04x%c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ata_dev->id[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ((i+1) & 7) ? ' ' : '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) show_ata_dev_gscr(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct ata_device *ata_dev = transport_class_to_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int written = 0, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ata_dev->class != ATA_DEV_PMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) written += scnprintf(buf+written, 20, "%08x%c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ata_dev->gscr[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ((i+1) & 3) ? ' ' : '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (SATA_PMP_GSCR_DWORDS & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) buf[written-1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) show_ata_dev_trim(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct ata_device *ata_dev = transport_class_to_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned char *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (!ata_id_has_trim(ata_dev->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) mode = "unsupported";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) else if (ata_dev->horkage & ATA_HORKAGE_NOTRIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) mode = "forced_unsupported";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) else if (ata_dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mode = "forced_unqueued";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else if (ata_fpdma_dsm_supported(ata_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) mode = "queued";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mode = "unqueued";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return scnprintf(buf, 20, "%s\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static DECLARE_TRANSPORT_CLASS(ata_dev_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) "ata_device", NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void ata_tdev_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * ata_is_ata_dev -- check if a struct device represents a ATA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * @dev: device to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * %1 if the device represents a ATA device, %0 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static int ata_is_ata_dev(const struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return dev->release == ata_tdev_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int ata_tdev_match(struct attribute_container *cont,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (!ata_is_ata_dev(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return &i->dev_attr_cont.ac == cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * ata_tdev_free -- free a ATA LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * @dev: ATA PHY to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * Frees the specified ATA PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * Note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * This function must only be called on a PHY that has not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * successfully been added using ata_tdev_add().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static void ata_tdev_free(struct ata_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) transport_destroy_device(&dev->tdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) put_device(&dev->tdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * ata_tdev_delete -- remove ATA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * @port: ATA PORT to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * Removes the specified ATA device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static void ata_tdev_delete(struct ata_device *ata_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct device *dev = &ata_dev->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) transport_remove_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) device_del(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ata_tdev_free(ata_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * ata_tdev_add -- initialize a transport ATA device structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * @ata_dev: ata_dev structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * Initialize an ATA device structure for sysfs. It will be added in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * device tree below the ATA LINK device it belongs to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Returns %0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static int ata_tdev_add(struct ata_device *ata_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct device *dev = &ata_dev->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct ata_link *link = ata_dev->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct ata_port *ap = link->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) device_initialize(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) dev->parent = &link->tdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) dev->release = ata_tdev_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (ata_is_host_link(link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) transport_setup_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ata_acpi_bind_dev(ata_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) error = device_add(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ata_tdev_free(ata_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) transport_add_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) transport_configure_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * Setup / Teardown code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) #define SETUP_TEMPLATE(attrb, field, perm, test) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) i->private_##attrb[count] = dev_attr_##field; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) i->private_##attrb[count].attr.mode = perm; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) i->attrb[count] = &i->private_##attrb[count]; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (test) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) count++
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) #define SETUP_LINK_ATTRIBUTE(field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) SETUP_TEMPLATE(link_attrs, field, S_IRUGO, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #define SETUP_PORT_ATTRIBUTE(field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) #define SETUP_DEV_ATTRIBUTE(field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) SETUP_TEMPLATE(dev_attrs, field, S_IRUGO, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * ata_attach_transport -- instantiate ATA transport template
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct scsi_transport_template *ata_attach_transport(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct ata_internal *i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) i->t.eh_strategy_handler = ata_scsi_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) i->t.user_scan = ata_scsi_user_scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) i->t.host_attrs.ac.attrs = &i->port_attrs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) i->t.host_attrs.ac.class = &ata_port_class.class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) i->t.host_attrs.ac.match = ata_tport_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) transport_container_register(&i->t.host_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) i->link_attr_cont.ac.class = &ata_link_class.class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) i->link_attr_cont.ac.attrs = &i->link_attrs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) i->link_attr_cont.ac.match = ata_tlink_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) transport_container_register(&i->link_attr_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) i->dev_attr_cont.ac.class = &ata_dev_class.class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) i->dev_attr_cont.ac.attrs = &i->dev_attrs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) i->dev_attr_cont.ac.match = ata_tdev_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) transport_container_register(&i->dev_attr_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) SETUP_PORT_ATTRIBUTE(nr_pmp_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) SETUP_PORT_ATTRIBUTE(idle_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) SETUP_PORT_ATTRIBUTE(port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) BUG_ON(count > ATA_PORT_ATTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) i->port_attrs[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) SETUP_LINK_ATTRIBUTE(hw_sata_spd_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) SETUP_LINK_ATTRIBUTE(sata_spd_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) SETUP_LINK_ATTRIBUTE(sata_spd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) BUG_ON(count > ATA_LINK_ATTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) i->link_attrs[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) SETUP_DEV_ATTRIBUTE(class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) SETUP_DEV_ATTRIBUTE(pio_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) SETUP_DEV_ATTRIBUTE(dma_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) SETUP_DEV_ATTRIBUTE(xfer_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) SETUP_DEV_ATTRIBUTE(spdn_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) SETUP_DEV_ATTRIBUTE(ering);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) SETUP_DEV_ATTRIBUTE(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) SETUP_DEV_ATTRIBUTE(gscr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) SETUP_DEV_ATTRIBUTE(trim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) BUG_ON(count > ATA_DEV_ATTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) i->dev_attrs[count] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return &i->t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * ata_release_transport -- release ATA transport template instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * @t: transport template instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) void ata_release_transport(struct scsi_transport_template *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct ata_internal *i = to_ata_internal(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) transport_container_unregister(&i->t.host_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) transport_container_unregister(&i->link_attr_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) transport_container_unregister(&i->dev_attr_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) kfree(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) __init int libata_transport_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) error = transport_class_register(&ata_link_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) goto out_unregister_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) error = transport_class_register(&ata_port_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) goto out_unregister_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) error = transport_class_register(&ata_dev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto out_unregister_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) out_unregister_port:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) transport_class_unregister(&ata_port_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) out_unregister_link:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) transport_class_unregister(&ata_link_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) out_unregister_transport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) void __exit libata_transport_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) transport_class_unregister(&ata_link_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) transport_class_unregister(&ata_port_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) transport_class_unregister(&ata_dev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }