@@ -377,7 +377,7 @@ struct ahci_host_priv {
extern int ahci_ignore_sss;
extern struct attribute *ahci_shost_attrs[];
-extern struct device_attribute *ahci_sdev_attrs[];
+extern struct attribute *ahci_sdev_attrs[];
/*
* This must be instantiated by the edge drivers. Read the comments
@@ -122,11 +122,11 @@ struct attribute *ahci_shost_attrs[] = {
};
EXPORT_SYMBOL_GPL(ahci_shost_attrs);
-struct device_attribute *ahci_sdev_attrs[] = {
- &dev_attr_sw_activity,
- &dev_attr_unload_heads,
- &dev_attr_ncq_prio_supported,
- &dev_attr_ncq_prio_enable,
+struct attribute *ahci_sdev_attrs[] = {
+ &dev_attr_sw_activity.attr,
+ &dev_attr_unload_heads.attr,
+ &dev_attr_ncq_prio_supported.attr,
+ &dev_attr_ncq_prio_enable.attr,
NULL
};
EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
@@ -922,10 +922,10 @@ DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR,
ata_ncq_prio_enable_show, ata_ncq_prio_enable_store);
EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
-struct device_attribute *ata_ncq_sdev_attrs[] = {
- &dev_attr_unload_heads,
- &dev_attr_ncq_prio_enable,
- &dev_attr_ncq_prio_supported,
+struct attribute *ata_ncq_sdev_attrs[] = {
+ &dev_attr_unload_heads.attr,
+ &dev_attr_ncq_prio_enable.attr,
+ &dev_attr_ncq_prio_supported.attr,
NULL
};
EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs);
@@ -234,8 +234,8 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev,
field, 0xff, 0);
}
-struct device_attribute *ata_common_sdev_attrs[] = {
- &dev_attr_unload_heads,
+struct attribute *ata_common_sdev_attrs[] = {
+ &dev_attr_unload_heads.attr,
NULL
};
EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
@@ -1578,8 +1578,8 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
-static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
- &dev_attr_ieee1394_id,
+static struct attribute *sbp2_scsi_sysfs_attrs[] = {
+ &dev_attr_ieee1394_id.attr,
NULL
};
@@ -184,7 +184,7 @@ extern const struct attribute_group *zfcp_sysfs_adapter_attr_groups[];
extern const struct attribute_group *zfcp_unit_attr_groups[];
extern const struct attribute_group *zfcp_port_attr_groups[];
extern struct mutex zfcp_sysfs_port_units_mutex;
-extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
+extern struct attribute *zfcp_sysfs_sdev_attrs[];
extern struct attribute *zfcp_sysfs_shost_attrs[];
bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port);
@@ -672,17 +672,17 @@ ZFCP_DEFINE_SCSI_ATTR(zfcp_in_recovery, "%d\n",
ZFCP_DEFINE_SCSI_ATTR(zfcp_status, "0x%08x\n",
atomic_read(&zfcp_sdev->status));
-struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
- &dev_attr_fcp_lun,
- &dev_attr_wwpn,
- &dev_attr_hba_id,
- &dev_attr_read_latency,
- &dev_attr_write_latency,
- &dev_attr_cmd_latency,
- &dev_attr_zfcp_access_denied,
- &dev_attr_zfcp_failed,
- &dev_attr_zfcp_in_recovery,
- &dev_attr_zfcp_status,
+struct attribute *zfcp_sysfs_sdev_attrs[] = {
+ &dev_attr_fcp_lun.attr,
+ &dev_attr_wwpn.attr,
+ &dev_attr_hba_id.attr,
+ &dev_attr_read_latency.attr,
+ &dev_attr_write_latency.attr,
+ &dev_attr_cmd_latency.attr,
+ &dev_attr_zfcp_access_denied.attr,
+ &dev_attr_zfcp_failed.attr,
+ &dev_attr_zfcp_in_recovery.attr,
+ &dev_attr_zfcp_status.attr,
NULL
};
@@ -605,9 +605,9 @@ static struct device_attribute aac_unique_id_attr = {
-static struct device_attribute *aac_dev_attrs[] = {
- &aac_raid_level_attr,
- &aac_unique_id_attr,
+static struct attribute *aac_dev_attrs[] = {
+ &aac_raid_level_attr.attr,
+ &aac_unique_id_attr.attr,
NULL,
};
@@ -936,13 +936,13 @@ static DEVICE_ATTR(ctlr_num, S_IRUGO,
static DEVICE_ATTR(legacy_board, S_IRUGO,
host_show_legacy_board, NULL);
-static struct device_attribute *hpsa_sdev_attrs[] = {
- &dev_attr_raid_level,
- &dev_attr_lunid,
- &dev_attr_unique_id,
- &dev_attr_hp_ssd_smart_path_enabled,
- &dev_attr_path_info,
- &dev_attr_sas_address,
+static struct attribute *hpsa_sdev_attrs[] = {
+ &dev_attr_raid_level.attr,
+ &dev_attr_lunid.attr,
+ &dev_attr_unique_id.attr,
+ &dev_attr_hp_ssd_smart_path_enabled.attr,
+ &dev_attr_path_info.attr,
+ &dev_attr_sas_address.attr,
NULL,
};
@@ -4732,12 +4732,12 @@ static struct device_attribute ipr_raw_mode_attr = {
.store = ipr_store_raw_mode
};
-static struct device_attribute *ipr_dev_attrs[] = {
- &ipr_adapter_handle_attr,
- &ipr_resource_path_attr,
- &ipr_device_id_attr,
- &ipr_resource_type_attr,
- &ipr_raw_mode_attr,
+static struct attribute *ipr_dev_attrs[] = {
+ &ipr_adapter_handle_attr.attr,
+ &ipr_resource_path_attr.attr,
+ &ipr_device_id_attr.attr,
+ &ipr_resource_type_attr.attr,
+ &ipr_raw_mode_attr.attr,
NULL,
};
@@ -314,8 +314,8 @@ static struct attribute *megaraid_shost_attrs[] = {
static DEVICE_ATTR_ADMIN_RO(megaraid_mbox_ld);
// Host template initializer for megaraid mbox sysfs device attributes
-static struct device_attribute *megaraid_sdev_attrs[] = {
- &dev_attr_megaraid_mbox_ld,
+static struct attribute *megaraid_sdev_attrs[] = {
+ &dev_attr_megaraid_mbox_ld.attr,
NULL,
};
@@ -1940,7 +1940,7 @@ mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
/* ctl shared API */
extern struct attribute *mpt3sas_host_attrs[];
-extern struct device_attribute *mpt3sas_dev_attrs[];
+extern struct attribute *mpt3sas_dev_attrs[];
void mpt3sas_ctl_init(ushort hbas_to_enumerate);
void mpt3sas_ctl_exit(ushort hbas_to_enumerate);
u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
@@ -3976,11 +3976,11 @@ sas_ncq_prio_enable_store(struct device *dev,
}
static DEVICE_ATTR_RW(sas_ncq_prio_enable);
-struct device_attribute *mpt3sas_dev_attrs[] = {
- &dev_attr_sas_address,
- &dev_attr_sas_device_handle,
- &dev_attr_sas_ncq_prio_supported,
- &dev_attr_sas_ncq_prio_enable,
+struct attribute *mpt3sas_dev_attrs[] = {
+ &dev_attr_sas_address.attr,
+ &dev_attr_sas_device_handle.attr,
+ &dev_attr_sas_ncq_prio_supported.attr,
+ &dev_attr_sas_ncq_prio_enable.attr,
NULL,
};
@@ -2182,11 +2182,11 @@ static ssize_t flush_cache_store(struct device *dev,
}
static DEVICE_ATTR_WO(flush_cache);
-static struct device_attribute *myrb_sdev_attrs[] = {
- &dev_attr_rebuild,
- &dev_attr_consistency_check,
- &dev_attr_raid_state,
- &dev_attr_raid_level,
+static struct attribute *myrb_sdev_attrs[] = {
+ &dev_attr_rebuild.attr,
+ &dev_attr_consistency_check.attr,
+ &dev_attr_raid_state.attr,
+ &dev_attr_raid_level.attr,
NULL,
};
@@ -1286,11 +1286,11 @@ static ssize_t consistency_check_store(struct device *dev,
}
static DEVICE_ATTR_RW(consistency_check);
-static struct device_attribute *myrs_sdev_attrs[] = {
- &dev_attr_consistency_check,
- &dev_attr_rebuild,
- &dev_attr_raid_state,
- &dev_attr_raid_level,
+static struct attribute *myrs_sdev_attrs[] = {
+ &dev_attr_consistency_check.attr,
+ &dev_attr_rebuild.attr,
+ &dev_attr_raid_state.attr,
+ &dev_attr_raid_level.attr,
NULL,
};
@@ -1328,7 +1328,7 @@ static int scsi_target_add(struct scsi_target *starget)
**/
int scsi_sysfs_add_sdev(struct scsi_device *sdev)
{
- int error, i;
+ int error;
struct scsi_target *starget = sdev->sdev_target;
error = scsi_target_add(starget);
@@ -1381,23 +1381,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
}
}
- /* add additional host specific attributes */
- if (sdev->host->hostt->sdev_attrs) {
- for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
- error = device_create_file(&sdev->sdev_gendev,
- sdev->host->hostt->sdev_attrs[i]);
- if (error)
- return error;
- }
- }
-
- if (sdev->host->hostt->sdev_groups) {
- error = sysfs_create_groups(&sdev->sdev_gendev.kobj,
- sdev->host->hostt->sdev_groups);
- if (error)
- return error;
- }
-
scsi_autopm_put_device(sdev);
return error;
}
@@ -1437,10 +1420,6 @@ void __scsi_remove_device(struct scsi_device *sdev)
if (res != 0)
return;
- if (sdev->host->hostt->sdev_groups)
- sysfs_remove_groups(&sdev->sdev_gendev.kobj,
- sdev->host->hostt->sdev_groups);
-
if (IS_ENABLED(CONFIG_BLK_DEV_BSG) && sdev->bsg_dev)
bsg_unregister_queue(sdev->bsg_dev);
device_unregister(&sdev->sdev_dev);
@@ -1592,8 +1571,10 @@ static struct device_type scsi_dev_type = {
void scsi_sysfs_device_initialize(struct scsi_device *sdev)
{
+ int i, j = 0;
unsigned long flags;
struct Scsi_Host *shost = sdev->host;
+ struct scsi_host_template *hostt = shost->hostt;
struct scsi_target *starget = sdev->sdev_target;
device_initialize(&sdev->sdev_gendev);
@@ -1601,6 +1582,20 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
sdev->sdev_gendev.type = &scsi_dev_type;
dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
+ sdev->sdev_gendev.groups = sdev->gendev_attr_groups;
+ if (hostt->sdev_attrs) {
+ sdev->gendev_first_attr_group = (struct attribute_group){
+ .attrs = hostt->sdev_attrs,
+ };
+ sdev->gendev_attr_groups[j++] = &sdev->gendev_first_attr_group;
+ }
+ if (hostt->sdev_groups) {
+ for (i = 0; j + 1 < ARRAY_SIZE(sdev->gendev_attr_groups) &&
+ hostt->sdev_groups[i]; i++) {
+ sdev->gendev_attr_groups[j++] = hostt->sdev_groups[i];
+ }
+ }
+ WARN_ON_ONCE(j + 1 >= ARRAY_SIZE(sdev->gendev_attr_groups));
device_initialize(&sdev->sdev_dev);
sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
@@ -6915,14 +6915,14 @@ static DEVICE_ATTR(ssd_smart_path_enabled, 0444, pqi_ssd_smart_path_enabled_show
static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL);
static DEVICE_ATTR(raid_bypass_cnt, 0444, pqi_raid_bypass_cnt_show, NULL);
-static struct device_attribute *pqi_sdev_attrs[] = {
- &dev_attr_lunid,
- &dev_attr_unique_id,
- &dev_attr_path_info,
- &dev_attr_sas_address,
- &dev_attr_ssd_smart_path_enabled,
- &dev_attr_raid_level,
- &dev_attr_raid_bypass_cnt,
+static struct attribute *pqi_sdev_attrs[] = {
+ &dev_attr_lunid.attr,
+ &dev_attr_unique_id.attr,
+ &dev_attr_path_info.attr,
+ &dev_attr_sas_address.attr,
+ &dev_attr_ssd_smart_path_enabled.attr,
+ &dev_attr_raid_level.attr,
+ &dev_attr_raid_bypass_cnt.attr,
NULL
};
@@ -588,8 +588,8 @@ static ssize_t max_sectors_store(struct device *dev, struct device_attribute *at
}
static DEVICE_ATTR_RW(max_sectors);
-static struct device_attribute *sysfs_device_attr_list[] = {
- &dev_attr_max_sectors,
+static struct attribute *sysfs_device_attr_list[] = {
+ &dev_attr_max_sectors.attr,
NULL,
};
@@ -1388,7 +1388,7 @@ extern int ata_link_nr_enabled(struct ata_link *link);
*/
extern const struct ata_port_operations ata_base_port_ops;
extern const struct ata_port_operations sata_port_ops;
-extern struct device_attribute *ata_common_sdev_attrs[];
+extern struct attribute *ata_common_sdev_attrs[];
/*
* All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated
@@ -1421,7 +1421,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
.sdev_attrs = ata_common_sdev_attrs
#ifdef CONFIG_SATA_HOST
-extern struct device_attribute *ata_ncq_sdev_attrs[];
+extern struct attribute *ata_ncq_sdev_attrs[];
#define ATA_NCQ_SHT(drv_name) \
ATA_SUBBASE_SHT(drv_name), \
@@ -226,6 +226,8 @@ struct scsi_device {
struct device sdev_gendev,
sdev_dev;
+ struct attribute_group gendev_first_attr_group;
+ const struct attribute_group *gendev_attr_groups[6];
struct execute_work ew; /* used to get process context on put */
struct work_struct requeue_work;
@@ -481,7 +481,7 @@ struct scsi_host_template {
/*
* Pointer to the SCSI device properties for this host, NULL terminated.
*/
- struct device_attribute **sdev_attrs;
+ struct attribute **sdev_attrs;
/*
* Pointer to the SCSI device attribute groups for this host,
A quote from Documentation/driver-api/driver-model/device.rst: "Word of warning: While the kernel allows device_create_file() and device_remove_file() to be called on a device at any time, userspace has strict expectations on when attributes get created. When a new device is registered in the kernel, a uevent is generated to notify userspace (like udev) that a new device is available. If attributes are added after the device is registered, then userspace won't get notified and userspace will not know about the new attributes." Hence register SCSI device sysfs attributes before the SCSI host shost_dev uevent is emitted instead of after that event has been emitted. Fixes: 86b87cde0b55 ("scsi: core: host template attribute groups") Signed-off-by: Bart Van Assche <bvanassche@acm.org> --- drivers/ata/ahci.h | 2 +- drivers/ata/libahci.c | 10 +++---- drivers/ata/libata-sata.c | 8 +++--- drivers/ata/libata-scsi.c | 4 +-- drivers/firewire/sbp2.c | 4 +-- drivers/s390/scsi/zfcp_ext.h | 2 +- drivers/s390/scsi/zfcp_sysfs.c | 22 +++++++-------- drivers/scsi/aacraid/linit.c | 6 ++--- drivers/scsi/hpsa.c | 14 +++++----- drivers/scsi/ipr.c | 12 ++++----- drivers/scsi/megaraid/megaraid_mbox.c | 4 +-- drivers/scsi/mpt3sas/mpt3sas_base.h | 2 +- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 10 +++---- drivers/scsi/myrb.c | 10 +++---- drivers/scsi/myrs.c | 10 +++---- drivers/scsi/scsi_sysfs.c | 39 ++++++++++++--------------- drivers/scsi/smartpqi/smartpqi_init.c | 16 +++++------ drivers/usb/storage/scsiglue.c | 4 +-- include/linux/libata.h | 4 +-- include/scsi/scsi_device.h | 2 ++ include/scsi/scsi_host.h | 2 +- 21 files changed, 92 insertions(+), 95 deletions(-)