.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * scsi_sysfs.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
367 | 368 | |
---|
368 | 369 | static DEVICE_ATTR(eh_deadline, S_IRUGO | S_IWUSR, show_shost_eh_deadline, store_shost_eh_deadline); |
---|
369 | 370 | |
---|
370 | | -shost_rd_attr(use_blk_mq, "%d\n"); |
---|
371 | 371 | shost_rd_attr(unique_id, "%u\n"); |
---|
372 | 372 | shost_rd_attr(cmd_per_lun, "%hd\n"); |
---|
373 | 373 | shost_rd_attr(can_queue, "%hd\n"); |
---|
.. | .. |
---|
385 | 385 | return snprintf(buf, 20, "%d\n", scsi_host_busy(shost)); |
---|
386 | 386 | } |
---|
387 | 387 | static DEVICE_ATTR(host_busy, S_IRUGO, show_host_busy, NULL); |
---|
| 388 | + |
---|
| 389 | +static ssize_t |
---|
| 390 | +show_use_blk_mq(struct device *dev, struct device_attribute *attr, char *buf) |
---|
| 391 | +{ |
---|
| 392 | + return sprintf(buf, "1\n"); |
---|
| 393 | +} |
---|
| 394 | +static DEVICE_ATTR(use_blk_mq, S_IRUGO, show_use_blk_mq, NULL); |
---|
| 395 | + |
---|
| 396 | +static ssize_t |
---|
| 397 | +show_nr_hw_queues(struct device *dev, struct device_attribute *attr, char *buf) |
---|
| 398 | +{ |
---|
| 399 | + struct Scsi_Host *shost = class_to_shost(dev); |
---|
| 400 | + struct blk_mq_tag_set *tag_set = &shost->tag_set; |
---|
| 401 | + |
---|
| 402 | + return snprintf(buf, 20, "%d\n", tag_set->nr_hw_queues); |
---|
| 403 | +} |
---|
| 404 | +static DEVICE_ATTR(nr_hw_queues, S_IRUGO, show_nr_hw_queues, NULL); |
---|
388 | 405 | |
---|
389 | 406 | static struct attribute *scsi_sysfs_shost_attrs[] = { |
---|
390 | 407 | &dev_attr_use_blk_mq.attr, |
---|
.. | .. |
---|
404 | 421 | &dev_attr_prot_guard_type.attr, |
---|
405 | 422 | &dev_attr_host_reset.attr, |
---|
406 | 423 | &dev_attr_eh_deadline.attr, |
---|
| 424 | + &dev_attr_nr_hw_queues.attr, |
---|
407 | 425 | NULL |
---|
408 | 426 | }; |
---|
409 | 427 | |
---|
.. | .. |
---|
430 | 448 | struct device *parent; |
---|
431 | 449 | struct list_head *this, *tmp; |
---|
432 | 450 | struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; |
---|
| 451 | + struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL; |
---|
433 | 452 | unsigned long flags; |
---|
434 | 453 | struct module *mod; |
---|
435 | 454 | |
---|
.. | .. |
---|
462 | 481 | sdev->request_queue = NULL; |
---|
463 | 482 | |
---|
464 | 483 | mutex_lock(&sdev->inquiry_mutex); |
---|
465 | | - rcu_swap_protected(sdev->vpd_pg80, vpd_pg80, |
---|
466 | | - lockdep_is_held(&sdev->inquiry_mutex)); |
---|
467 | | - rcu_swap_protected(sdev->vpd_pg83, vpd_pg83, |
---|
468 | | - lockdep_is_held(&sdev->inquiry_mutex)); |
---|
| 484 | + vpd_pg0 = rcu_replace_pointer(sdev->vpd_pg0, vpd_pg0, |
---|
| 485 | + lockdep_is_held(&sdev->inquiry_mutex)); |
---|
| 486 | + vpd_pg80 = rcu_replace_pointer(sdev->vpd_pg80, vpd_pg80, |
---|
| 487 | + lockdep_is_held(&sdev->inquiry_mutex)); |
---|
| 488 | + vpd_pg83 = rcu_replace_pointer(sdev->vpd_pg83, vpd_pg83, |
---|
| 489 | + lockdep_is_held(&sdev->inquiry_mutex)); |
---|
| 490 | + vpd_pg89 = rcu_replace_pointer(sdev->vpd_pg89, vpd_pg89, |
---|
| 491 | + lockdep_is_held(&sdev->inquiry_mutex)); |
---|
469 | 492 | mutex_unlock(&sdev->inquiry_mutex); |
---|
470 | 493 | |
---|
| 494 | + if (vpd_pg0) |
---|
| 495 | + kfree_rcu(vpd_pg0, rcu); |
---|
471 | 496 | if (vpd_pg83) |
---|
472 | 497 | kfree_rcu(vpd_pg83, rcu); |
---|
473 | 498 | if (vpd_pg80) |
---|
474 | 499 | kfree_rcu(vpd_pg80, rcu); |
---|
| 500 | + if (vpd_pg89) |
---|
| 501 | + kfree_rcu(vpd_pg89, rcu); |
---|
475 | 502 | kfree(sdev->inquiry); |
---|
476 | 503 | kfree(sdev); |
---|
477 | 504 | |
---|
.. | .. |
---|
769 | 796 | int i, ret; |
---|
770 | 797 | struct scsi_device *sdev = to_scsi_device(dev); |
---|
771 | 798 | enum scsi_device_state state = 0; |
---|
| 799 | + bool rescan_dev = false; |
---|
772 | 800 | |
---|
773 | 801 | for (i = 0; i < ARRAY_SIZE(sdev_states); i++) { |
---|
774 | 802 | const int len = strlen(sdev_states[i].name); |
---|
.. | .. |
---|
778 | 806 | break; |
---|
779 | 807 | } |
---|
780 | 808 | } |
---|
781 | | - if (!state) |
---|
| 809 | + switch (state) { |
---|
| 810 | + case SDEV_RUNNING: |
---|
| 811 | + case SDEV_OFFLINE: |
---|
| 812 | + break; |
---|
| 813 | + default: |
---|
782 | 814 | return -EINVAL; |
---|
| 815 | + } |
---|
783 | 816 | |
---|
784 | 817 | mutex_lock(&sdev->state_mutex); |
---|
785 | | - ret = scsi_device_set_state(sdev, state); |
---|
| 818 | + switch (sdev->sdev_state) { |
---|
| 819 | + case SDEV_RUNNING: |
---|
| 820 | + case SDEV_OFFLINE: |
---|
| 821 | + break; |
---|
| 822 | + default: |
---|
| 823 | + mutex_unlock(&sdev->state_mutex); |
---|
| 824 | + return -EINVAL; |
---|
| 825 | + } |
---|
| 826 | + if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) { |
---|
| 827 | + ret = 0; |
---|
| 828 | + } else { |
---|
| 829 | + ret = scsi_device_set_state(sdev, state); |
---|
| 830 | + if (ret == 0 && state == SDEV_RUNNING) |
---|
| 831 | + rescan_dev = true; |
---|
| 832 | + } |
---|
786 | 833 | mutex_unlock(&sdev->state_mutex); |
---|
| 834 | + |
---|
| 835 | + if (rescan_dev) { |
---|
| 836 | + /* |
---|
| 837 | + * If the device state changes to SDEV_RUNNING, we need to |
---|
| 838 | + * run the queue to avoid I/O hang, and rescan the device |
---|
| 839 | + * to revalidate it. Running the queue first is necessary |
---|
| 840 | + * because another thread may be waiting inside |
---|
| 841 | + * blk_mq_freeze_queue_wait() and because that call may be |
---|
| 842 | + * waiting for pending I/O to finish. |
---|
| 843 | + */ |
---|
| 844 | + blk_mq_run_hw_queues(sdev->request_queue, true); |
---|
| 845 | + scsi_rescan_device(dev); |
---|
| 846 | + } |
---|
787 | 847 | |
---|
788 | 848 | return ret == 0 ? count : -EINVAL; |
---|
789 | 849 | } |
---|
.. | .. |
---|
838 | 898 | struct bin_attribute *bin_attr, \ |
---|
839 | 899 | char *buf, loff_t off, size_t count) \ |
---|
840 | 900 | { \ |
---|
841 | | - struct device *dev = container_of(kobj, struct device, kobj); \ |
---|
| 901 | + struct device *dev = kobj_to_dev(kobj); \ |
---|
842 | 902 | struct scsi_device *sdev = to_scsi_device(dev); \ |
---|
843 | 903 | struct scsi_vpd *vpd_page; \ |
---|
844 | 904 | int ret = -EINVAL; \ |
---|
.. | .. |
---|
859 | 919 | |
---|
860 | 920 | sdev_vpd_pg_attr(pg83); |
---|
861 | 921 | sdev_vpd_pg_attr(pg80); |
---|
| 922 | +sdev_vpd_pg_attr(pg89); |
---|
| 923 | +sdev_vpd_pg_attr(pg0); |
---|
862 | 924 | |
---|
863 | 925 | static ssize_t show_inquiry(struct file *filep, struct kobject *kobj, |
---|
864 | 926 | struct bin_attribute *bin_attr, |
---|
865 | 927 | char *buf, loff_t off, size_t count) |
---|
866 | 928 | { |
---|
867 | | - struct device *dev = container_of(kobj, struct device, kobj); |
---|
| 929 | + struct device *dev = kobj_to_dev(kobj); |
---|
868 | 930 | struct scsi_device *sdev = to_scsi_device(dev); |
---|
869 | 931 | |
---|
870 | 932 | if (!sdev->inquiry) |
---|
.. | .. |
---|
1025 | 1087 | name = sdev_bflags_name[i]; |
---|
1026 | 1088 | |
---|
1027 | 1089 | if (name) |
---|
1028 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
1029 | | - "%s%s", len ? " " : "", name); |
---|
| 1090 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
| 1091 | + "%s%s", len ? " " : "", name); |
---|
1030 | 1092 | else |
---|
1031 | | - len += snprintf(buf + len, PAGE_SIZE - len, |
---|
1032 | | - "%sINVALID_BIT(%d)", len ? " " : "", i); |
---|
| 1093 | + len += scnprintf(buf + len, PAGE_SIZE - len, |
---|
| 1094 | + "%sINVALID_BIT(%d)", len ? " " : "", i); |
---|
1033 | 1095 | } |
---|
1034 | 1096 | if (len) |
---|
1035 | | - len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
---|
| 1097 | + len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); |
---|
1036 | 1098 | return len; |
---|
1037 | 1099 | } |
---|
1038 | 1100 | static DEVICE_ATTR(blacklist, S_IRUGO, sdev_show_blacklist, NULL); |
---|
.. | .. |
---|
1161 | 1223 | static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj, |
---|
1162 | 1224 | struct attribute *attr, int i) |
---|
1163 | 1225 | { |
---|
1164 | | - struct device *dev = container_of(kobj, struct device, kobj); |
---|
| 1226 | + struct device *dev = kobj_to_dev(kobj); |
---|
1165 | 1227 | struct scsi_device *sdev = to_scsi_device(dev); |
---|
1166 | 1228 | |
---|
1167 | 1229 | |
---|
.. | .. |
---|
1187 | 1249 | static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj, |
---|
1188 | 1250 | struct bin_attribute *attr, int i) |
---|
1189 | 1251 | { |
---|
1190 | | - struct device *dev = container_of(kobj, struct device, kobj); |
---|
| 1252 | + struct device *dev = kobj_to_dev(kobj); |
---|
1191 | 1253 | struct scsi_device *sdev = to_scsi_device(dev); |
---|
1192 | 1254 | |
---|
| 1255 | + |
---|
| 1256 | + if (attr == &dev_attr_vpd_pg0 && !sdev->vpd_pg0) |
---|
| 1257 | + return 0; |
---|
1193 | 1258 | |
---|
1194 | 1259 | if (attr == &dev_attr_vpd_pg80 && !sdev->vpd_pg80) |
---|
1195 | 1260 | return 0; |
---|
1196 | 1261 | |
---|
1197 | 1262 | if (attr == &dev_attr_vpd_pg83 && !sdev->vpd_pg83) |
---|
| 1263 | + return 0; |
---|
| 1264 | + |
---|
| 1265 | + if (attr == &dev_attr_vpd_pg89 && !sdev->vpd_pg89) |
---|
1198 | 1266 | return 0; |
---|
1199 | 1267 | |
---|
1200 | 1268 | return S_IRUGO; |
---|
.. | .. |
---|
1239 | 1307 | }; |
---|
1240 | 1308 | |
---|
1241 | 1309 | static struct bin_attribute *scsi_sdev_bin_attrs[] = { |
---|
| 1310 | + &dev_attr_vpd_pg0, |
---|
1242 | 1311 | &dev_attr_vpd_pg83, |
---|
1243 | 1312 | &dev_attr_vpd_pg80, |
---|
| 1313 | + &dev_attr_vpd_pg89, |
---|
1244 | 1314 | &dev_attr_inquiry, |
---|
1245 | 1315 | NULL |
---|
1246 | 1316 | }; |
---|