^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/ide.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) char *ide_media_string(ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) switch (drive->media) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) case ide_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) return "disk";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) case ide_cdrom:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) return "cdrom";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) case ide_tape:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) return "tape";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) case ide_floppy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) return "floppy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) case ide_optical:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) return "optical";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) return "UNKNOWN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static ssize_t media_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ide_drive_t *drive = to_ide_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return sprintf(buf, "%s\n", ide_media_string(drive));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static DEVICE_ATTR_RO(media);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ide_drive_t *drive = to_ide_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return sprintf(buf, "%s\n", drive->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static DEVICE_ATTR_RO(drivename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ide_drive_t *drive = to_ide_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return sprintf(buf, "ide:m-%s\n", ide_media_string(drive));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static DEVICE_ATTR_RO(modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static ssize_t model_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ide_drive_t *drive = to_ide_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static DEVICE_ATTR_RO(model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ide_drive_t *drive = to_ide_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static DEVICE_ATTR_RO(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ide_drive_t *drive = to_ide_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static DEVICE_ATTR(serial, 0400, serial_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static DEVICE_ATTR(unload_heads, 0644, ide_park_show, ide_park_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct attribute *ide_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) &dev_attr_media.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) &dev_attr_drivename.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) &dev_attr_modalias.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) &dev_attr_model.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) &dev_attr_firmware.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) &dev_attr_serial.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) &dev_attr_unload_heads.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) NULL,
^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) static const struct attribute_group ide_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .attrs = ide_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) const struct attribute_group *ide_dev_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) &ide_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static ssize_t store_delete_devices(struct device *portdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) const char *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ide_hwif_t *hwif = dev_get_drvdata(portdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (strncmp(buf, "1", n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ide_port_unregister_devices(hwif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static ssize_t store_scan(struct device *portdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) const char *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ide_hwif_t *hwif = dev_get_drvdata(portdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (strncmp(buf, "1", n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ide_port_unregister_devices(hwif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ide_port_scan(hwif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static struct device_attribute *ide_port_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) &dev_attr_delete_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) &dev_attr_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int ide_sysfs_register_port(ide_hwif_t *hwif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) for (i = 0; ide_port_attrs[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) rc = device_create_file(hwif->portdev, ide_port_attrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }