| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * scsi.c Copyright (C) 1992 Drew Eckhardt |
|---|
| 3 | 4 | * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale |
|---|
| .. | .. |
|---|
| 85 | 86 | EXPORT_SYMBOL(scsi_logging_level); |
|---|
| 86 | 87 | #endif |
|---|
| 87 | 88 | |
|---|
| 88 | | -/* sd, scsi core and power management need to coordinate flushing async actions */ |
|---|
| 89 | | -ASYNC_DOMAIN(scsi_sd_probe_domain); |
|---|
| 90 | | -EXPORT_SYMBOL(scsi_sd_probe_domain); |
|---|
| 91 | | - |
|---|
| 92 | 89 | /* |
|---|
| 93 | | - * Separate domain (from scsi_sd_probe_domain) to maximize the benefit of |
|---|
| 94 | | - * asynchronous system resume operations. It is marked 'exclusive' to avoid |
|---|
| 95 | | - * being included in the async_synchronize_full() that is invoked by |
|---|
| 96 | | - * dpm_resume() |
|---|
| 90 | + * Domain for asynchronous system resume operations. It is marked 'exclusive' |
|---|
| 91 | + * to avoid being included in the async_synchronize_full() that is invoked by |
|---|
| 92 | + * dpm_resume(). |
|---|
| 97 | 93 | */ |
|---|
| 98 | 94 | ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain); |
|---|
| 99 | 95 | EXPORT_SYMBOL(scsi_sd_pm_domain); |
|---|
| 100 | | - |
|---|
| 101 | | -/** |
|---|
| 102 | | - * scsi_put_command - Free a scsi command block |
|---|
| 103 | | - * @cmd: command block to free |
|---|
| 104 | | - * |
|---|
| 105 | | - * Returns: Nothing. |
|---|
| 106 | | - * |
|---|
| 107 | | - * Notes: The command must not belong to any lists. |
|---|
| 108 | | - */ |
|---|
| 109 | | -void scsi_put_command(struct scsi_cmnd *cmd) |
|---|
| 110 | | -{ |
|---|
| 111 | | - scsi_del_cmd_from_list(cmd); |
|---|
| 112 | | - BUG_ON(delayed_work_pending(&cmd->abort_work)); |
|---|
| 113 | | -} |
|---|
| 114 | 96 | |
|---|
| 115 | 97 | #ifdef CONFIG_SCSI_LOGGING |
|---|
| 116 | 98 | void scsi_log_send(struct scsi_cmnd *cmd) |
|---|
| .. | .. |
|---|
| 175 | 157 | #endif |
|---|
| 176 | 158 | |
|---|
| 177 | 159 | /** |
|---|
| 178 | | - * scsi_cmd_get_serial - Assign a serial number to a command |
|---|
| 179 | | - * @host: the scsi host |
|---|
| 180 | | - * @cmd: command to assign serial number to |
|---|
| 181 | | - * |
|---|
| 182 | | - * Description: a serial number identifies a request for error recovery |
|---|
| 183 | | - * and debugging purposes. Protected by the Host_Lock of host. |
|---|
| 184 | | - */ |
|---|
| 185 | | -void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
|---|
| 186 | | -{ |
|---|
| 187 | | - cmd->serial_number = host->cmd_serial_number++; |
|---|
| 188 | | - if (cmd->serial_number == 0) |
|---|
| 189 | | - cmd->serial_number = host->cmd_serial_number++; |
|---|
| 190 | | -} |
|---|
| 191 | | -EXPORT_SYMBOL(scsi_cmd_get_serial); |
|---|
| 192 | | - |
|---|
| 193 | | -/** |
|---|
| 194 | 160 | * scsi_finish_command - cleanup and pass command back to upper layer |
|---|
| 195 | 161 | * @cmd: the command |
|---|
| 196 | 162 | * |
|---|
| .. | .. |
|---|
| 206 | 172 | struct scsi_driver *drv; |
|---|
| 207 | 173 | unsigned int good_bytes; |
|---|
| 208 | 174 | |
|---|
| 209 | | - scsi_device_unbusy(sdev); |
|---|
| 175 | + scsi_device_unbusy(sdev, cmd); |
|---|
| 210 | 176 | |
|---|
| 211 | 177 | /* |
|---|
| 212 | 178 | * Clear the flags that say that the device/target/host is no longer |
|---|
| .. | .. |
|---|
| 454 | 420 | return; |
|---|
| 455 | 421 | |
|---|
| 456 | 422 | mutex_lock(&sdev->inquiry_mutex); |
|---|
| 457 | | - rcu_swap_protected(*sdev_vpd_buf, vpd_buf, |
|---|
| 458 | | - lockdep_is_held(&sdev->inquiry_mutex)); |
|---|
| 423 | + vpd_buf = rcu_replace_pointer(*sdev_vpd_buf, vpd_buf, |
|---|
| 424 | + lockdep_is_held(&sdev->inquiry_mutex)); |
|---|
| 459 | 425 | mutex_unlock(&sdev->inquiry_mutex); |
|---|
| 460 | 426 | |
|---|
| 461 | 427 | if (vpd_buf) |
|---|
| .. | .. |
|---|
| 485 | 451 | return; |
|---|
| 486 | 452 | |
|---|
| 487 | 453 | for (i = 4; i < vpd_buf->len; i++) { |
|---|
| 454 | + if (vpd_buf->data[i] == 0x0) |
|---|
| 455 | + scsi_update_vpd_page(sdev, 0x0, &sdev->vpd_pg0); |
|---|
| 488 | 456 | if (vpd_buf->data[i] == 0x80) |
|---|
| 489 | 457 | scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80); |
|---|
| 490 | 458 | if (vpd_buf->data[i] == 0x83) |
|---|
| 491 | 459 | scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83); |
|---|
| 460 | + if (vpd_buf->data[i] == 0x89) |
|---|
| 461 | + scsi_update_vpd_page(sdev, 0x89, &sdev->vpd_pg89); |
|---|
| 492 | 462 | } |
|---|
| 493 | 463 | kfree(vpd_buf); |
|---|
| 494 | 464 | } |
|---|
| .. | .. |
|---|
| 782 | 752 | module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR); |
|---|
| 783 | 753 | MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels"); |
|---|
| 784 | 754 | |
|---|
| 785 | | -#ifdef CONFIG_SCSI_MQ_DEFAULT |
|---|
| 786 | | -bool scsi_use_blk_mq = true; |
|---|
| 787 | | -#else |
|---|
| 788 | | -bool scsi_use_blk_mq = false; |
|---|
| 789 | | -#endif |
|---|
| 790 | | -module_param_named(use_blk_mq, scsi_use_blk_mq, bool, S_IWUSR | S_IRUGO); |
|---|
| 791 | | - |
|---|
| 792 | 755 | static int __init init_scsi(void) |
|---|
| 793 | 756 | { |
|---|
| 794 | 757 | int error; |
|---|
| 795 | 758 | |
|---|
| 796 | | - error = scsi_init_queue(); |
|---|
| 797 | | - if (error) |
|---|
| 798 | | - return error; |
|---|
| 799 | 759 | error = scsi_init_procfs(); |
|---|
| 800 | 760 | if (error) |
|---|
| 801 | 761 | goto cleanup_queue; |
|---|
| .. | .. |
|---|
| 841 | 801 | scsi_exit_devinfo(); |
|---|
| 842 | 802 | scsi_exit_procfs(); |
|---|
| 843 | 803 | scsi_exit_queue(); |
|---|
| 844 | | - async_unregister_domain(&scsi_sd_probe_domain); |
|---|
| 845 | 804 | } |
|---|
| 846 | 805 | |
|---|
| 847 | 806 | subsys_initcall(init_scsi); |
|---|