18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/kernel.h> 38c2ecf20Sopenharmony_ci#include <linux/ide.h> 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_cichar *ide_media_string(ide_drive_t *drive) 68c2ecf20Sopenharmony_ci{ 78c2ecf20Sopenharmony_ci switch (drive->media) { 88c2ecf20Sopenharmony_ci case ide_disk: 98c2ecf20Sopenharmony_ci return "disk"; 108c2ecf20Sopenharmony_ci case ide_cdrom: 118c2ecf20Sopenharmony_ci return "cdrom"; 128c2ecf20Sopenharmony_ci case ide_tape: 138c2ecf20Sopenharmony_ci return "tape"; 148c2ecf20Sopenharmony_ci case ide_floppy: 158c2ecf20Sopenharmony_ci return "floppy"; 168c2ecf20Sopenharmony_ci case ide_optical: 178c2ecf20Sopenharmony_ci return "optical"; 188c2ecf20Sopenharmony_ci default: 198c2ecf20Sopenharmony_ci return "UNKNOWN"; 208c2ecf20Sopenharmony_ci } 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic ssize_t media_show(struct device *dev, struct device_attribute *attr, 248c2ecf20Sopenharmony_ci char *buf) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci ide_drive_t *drive = to_ide_device(dev); 278c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", ide_media_string(drive)); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(media); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic ssize_t drivename_show(struct device *dev, struct device_attribute *attr, 328c2ecf20Sopenharmony_ci char *buf) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci ide_drive_t *drive = to_ide_device(dev); 358c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", drive->name); 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(drivename); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic ssize_t modalias_show(struct device *dev, struct device_attribute *attr, 408c2ecf20Sopenharmony_ci char *buf) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci ide_drive_t *drive = to_ide_device(dev); 438c2ecf20Sopenharmony_ci return sprintf(buf, "ide:m-%s\n", ide_media_string(drive)); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(modalias); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic ssize_t model_show(struct device *dev, struct device_attribute *attr, 488c2ecf20Sopenharmony_ci char *buf) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci ide_drive_t *drive = to_ide_device(dev); 518c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(model); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic ssize_t firmware_show(struct device *dev, struct device_attribute *attr, 568c2ecf20Sopenharmony_ci char *buf) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci ide_drive_t *drive = to_ide_device(dev); 598c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]); 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(firmware); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic ssize_t serial_show(struct device *dev, struct device_attribute *attr, 648c2ecf20Sopenharmony_ci char *buf) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci ide_drive_t *drive = to_ide_device(dev); 678c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_cistatic DEVICE_ATTR(serial, 0400, serial_show, NULL); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic DEVICE_ATTR(unload_heads, 0644, ide_park_show, ide_park_store); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic struct attribute *ide_attrs[] = { 748c2ecf20Sopenharmony_ci &dev_attr_media.attr, 758c2ecf20Sopenharmony_ci &dev_attr_drivename.attr, 768c2ecf20Sopenharmony_ci &dev_attr_modalias.attr, 778c2ecf20Sopenharmony_ci &dev_attr_model.attr, 788c2ecf20Sopenharmony_ci &dev_attr_firmware.attr, 798c2ecf20Sopenharmony_ci &dev_attr_serial.attr, 808c2ecf20Sopenharmony_ci &dev_attr_unload_heads.attr, 818c2ecf20Sopenharmony_ci NULL, 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic const struct attribute_group ide_attr_group = { 858c2ecf20Sopenharmony_ci .attrs = ide_attrs, 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ciconst struct attribute_group *ide_dev_groups[] = { 898c2ecf20Sopenharmony_ci &ide_attr_group, 908c2ecf20Sopenharmony_ci NULL, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic ssize_t store_delete_devices(struct device *portdev, 948c2ecf20Sopenharmony_ci struct device_attribute *attr, 958c2ecf20Sopenharmony_ci const char *buf, size_t n) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci ide_hwif_t *hwif = dev_get_drvdata(portdev); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if (strncmp(buf, "1", n)) 1008c2ecf20Sopenharmony_ci return -EINVAL; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci ide_port_unregister_devices(hwif); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci return n; 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic ssize_t store_scan(struct device *portdev, 1108c2ecf20Sopenharmony_ci struct device_attribute *attr, 1118c2ecf20Sopenharmony_ci const char *buf, size_t n) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci ide_hwif_t *hwif = dev_get_drvdata(portdev); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci if (strncmp(buf, "1", n)) 1168c2ecf20Sopenharmony_ci return -EINVAL; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci ide_port_unregister_devices(hwif); 1198c2ecf20Sopenharmony_ci ide_port_scan(hwif); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci return n; 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic struct device_attribute *ide_port_attrs[] = { 1278c2ecf20Sopenharmony_ci &dev_attr_delete_devices, 1288c2ecf20Sopenharmony_ci &dev_attr_scan, 1298c2ecf20Sopenharmony_ci NULL 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ciint ide_sysfs_register_port(ide_hwif_t *hwif) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci int i, rc; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci for (i = 0; ide_port_attrs[i]; i++) { 1378c2ecf20Sopenharmony_ci rc = device_create_file(hwif->portdev, ide_port_attrs[i]); 1388c2ecf20Sopenharmony_ci if (rc) 1398c2ecf20Sopenharmony_ci break; 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci return rc; 1438c2ecf20Sopenharmony_ci} 144