diff options
34 files changed, 283 insertions, 236 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 106687f4f6b7..0c7efaf62de0 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -994,7 +994,7 @@ Description: This file shows the amount of physical memory needed What: /sys/bus/platform/drivers/ufshcd/*/rpm_lvl What: /sys/bus/platform/devices/*.ufs/rpm_lvl Date: September 2014 -Contact: Subhash Jadavani <subhashj@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This entry could be used to set or show the UFS device runtime power management level. The current driver implementation supports 7 levels with next target states: @@ -1021,7 +1021,7 @@ Description: This entry could be used to set or show the UFS device What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state What: /sys/bus/platform/devices/*.ufs/rpm_target_dev_state Date: February 2018 -Contact: Subhash Jadavani <subhashj@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This entry shows the target power mode of an UFS device for the chosen runtime power management level. @@ -1030,7 +1030,7 @@ Description: This entry shows the target power mode of an UFS device What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_link_state What: /sys/bus/platform/devices/*.ufs/rpm_target_link_state Date: February 2018 -Contact: Subhash Jadavani <subhashj@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This entry shows the target state of an UFS UIC link for the chosen runtime power management level. @@ -1039,7 +1039,7 @@ Description: This entry shows the target state of an UFS UIC link What: /sys/bus/platform/drivers/ufshcd/*/spm_lvl What: /sys/bus/platform/devices/*.ufs/spm_lvl Date: September 2014 -Contact: Subhash Jadavani <subhashj@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This entry could be used to set or show the UFS device system power management level. The current driver implementation supports 7 levels with next target states: @@ -1066,7 +1066,7 @@ Description: This entry could be used to set or show the UFS device What: /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state What: /sys/bus/platform/devices/*.ufs/spm_target_dev_state Date: February 2018 -Contact: Subhash Jadavani <subhashj@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This entry shows the target power mode of an UFS device for the chosen system power management level. @@ -1075,7 +1075,7 @@ Description: This entry shows the target power mode of an UFS device What: /sys/bus/platform/drivers/ufshcd/*/spm_target_link_state What: /sys/bus/platform/devices/*.ufs/spm_target_link_state Date: February 2018 -Contact: Subhash Jadavani <subhashj@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This entry shows the target state of an UFS UIC link for the chosen system power management level. @@ -1084,7 +1084,7 @@ Description: This entry shows the target state of an UFS UIC link What: /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_enable What: /sys/bus/platform/devices/*.ufs/monitor/monitor_enable Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the status of performance monitor enablement and it can be used to start/stop the monitor. When the monitor is stopped, the performance data collected is also cleared. @@ -1092,7 +1092,7 @@ Description: This file shows the status of performance monitor enablement What: /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_chunk_size What: /sys/bus/platform/devices/*.ufs/monitor/monitor_chunk_size Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file tells the monitor to focus on requests transferring data of specific chunk size (in Bytes). 0 means any chunk size. It can only be changed when monitor is disabled. @@ -1100,7 +1100,7 @@ Description: This file tells the monitor to focus on requests transferring What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_sectors What: /sys/bus/platform/devices/*.ufs/monitor/read_total_sectors Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows how many sectors (in 512 Bytes) have been sent from device to host after monitor gets started. @@ -1109,7 +1109,7 @@ Description: This file shows how many sectors (in 512 Bytes) have been What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_busy What: /sys/bus/platform/devices/*.ufs/monitor/read_total_busy Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows how long (in micro seconds) has been spent sending data from device to host after monitor gets started. @@ -1118,7 +1118,7 @@ Description: This file shows how long (in micro seconds) has been spent What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_nr_requests What: /sys/bus/platform/devices/*.ufs/monitor/read_nr_requests Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows how many read requests have been sent after monitor gets started. @@ -1127,7 +1127,7 @@ Description: This file shows how many read requests have been sent after What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_max What: /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_max Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the maximum latency (in micro seconds) of read requests after monitor gets started. @@ -1136,7 +1136,7 @@ Description: This file shows the maximum latency (in micro seconds) of What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_min What: /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_min Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the minimum latency (in micro seconds) of read requests after monitor gets started. @@ -1145,7 +1145,7 @@ Description: This file shows the minimum latency (in micro seconds) of What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_avg What: /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_avg Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the average latency (in micro seconds) of read requests after monitor gets started. @@ -1154,7 +1154,7 @@ Description: This file shows the average latency (in micro seconds) of What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_sum What: /sys/bus/platform/devices/*.ufs/monitor/read_req_latency_sum Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the total latency (in micro seconds) of read requests sent after monitor gets started. @@ -1163,7 +1163,7 @@ Description: This file shows the total latency (in micro seconds) of What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_sectors What: /sys/bus/platform/devices/*.ufs/monitor/write_total_sectors Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows how many sectors (in 512 Bytes) have been sent from host to device after monitor gets started. @@ -1172,7 +1172,7 @@ Description: This file shows how many sectors (in 512 Bytes) have been sent What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_busy What: /sys/bus/platform/devices/*.ufs/monitor/write_total_busy Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows how long (in micro seconds) has been spent sending data from host to device after monitor gets started. @@ -1181,7 +1181,7 @@ Description: This file shows how long (in micro seconds) has been spent What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_nr_requests What: /sys/bus/platform/devices/*.ufs/monitor/write_nr_requests Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows how many write requests have been sent after monitor gets started. @@ -1190,7 +1190,7 @@ Description: This file shows how many write requests have been sent after What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_max What: /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_max Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the maximum latency (in micro seconds) of write requests after monitor gets started. @@ -1199,7 +1199,7 @@ Description: This file shows the maximum latency (in micro seconds) of write What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_min What: /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_min Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the minimum latency (in micro seconds) of write requests after monitor gets started. @@ -1208,7 +1208,7 @@ Description: This file shows the minimum latency (in micro seconds) of write What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_avg What: /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_avg Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the average latency (in micro seconds) of write requests after monitor gets started. @@ -1217,7 +1217,7 @@ Description: This file shows the average latency (in micro seconds) of write What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_sum What: /sys/bus/platform/devices/*.ufs/monitor/write_req_latency_sum Date: January 2021 -Contact: Can Guo <cang@codeaurora.org> +Contact: Can Guo <quic_cang@quicinc.com> Description: This file shows the total latency (in micro seconds) of write requests after monitor gets started. @@ -1226,7 +1226,7 @@ Description: This file shows the total latency (in micro seconds) of write What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_presv_us_en What: /sys/bus/platform/devices/*.ufs/device_descriptor/wb_presv_us_en Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows if preserve user-space was configured The file is read only. @@ -1234,7 +1234,7 @@ Description: This entry shows if preserve user-space was configured What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_shared_alloc_units What: /sys/bus/platform/devices/*.ufs/device_descriptor/wb_shared_alloc_units Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the shared allocated units of WB buffer The file is read only. @@ -1242,7 +1242,7 @@ Description: This entry shows the shared allocated units of WB buffer What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_type What: /sys/bus/platform/devices/*.ufs/device_descriptor/wb_type Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the configured WB type. 0x1 for shared buffer mode. 0x0 for dedicated buffer mode. @@ -1251,7 +1251,7 @@ Description: This entry shows the configured WB type. What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_buff_cap_adj What: /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_buff_cap_adj Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the total user-space decrease in shared buffer mode. The value of this parameter is 3 for TLC NAND when SLC mode @@ -1262,7 +1262,7 @@ Description: This entry shows the total user-space decrease in shared What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_max_alloc_units What: /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_max_alloc_units Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the Maximum total WriteBooster Buffer size which is supported by the entire device. @@ -1271,7 +1271,7 @@ Description: This entry shows the Maximum total WriteBooster Buffer size What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_max_wb_luns What: /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_max_wb_luns Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the maximum number of luns that can support WriteBooster. @@ -1280,7 +1280,7 @@ Description: This entry shows the maximum number of luns that can support What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_sup_red_type What: /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_sup_red_type Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: The supportability of user space reduction mode and preserve user space mode. 00h: WriteBooster Buffer can be configured only in @@ -1295,7 +1295,7 @@ Description: The supportability of user space reduction mode What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_sup_wb_type What: /sys/bus/platform/devices/*.ufs/geometry_descriptor/wb_sup_wb_type Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: The supportability of WriteBooster Buffer type. === ========================================================== @@ -1310,7 +1310,7 @@ Description: The supportability of WriteBooster Buffer type. What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable What: /sys/bus/platform/devices/*.ufs/flags/wb_enable Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the status of WriteBooster. == ============================ @@ -1323,7 +1323,7 @@ Description: This entry shows the status of WriteBooster. What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_flush_en What: /sys/bus/platform/devices/*.ufs/flags/wb_flush_en Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows if flush is enabled. == ================================= @@ -1336,7 +1336,7 @@ Description: This entry shows if flush is enabled. What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_flush_during_h8 What: /sys/bus/platform/devices/*.ufs/flags/wb_flush_during_h8 Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: Flush WriteBooster Buffer during hibernate state. == ================================================= @@ -1351,7 +1351,7 @@ Description: Flush WriteBooster Buffer during hibernate state. What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_avail_buf What: /sys/bus/platform/devices/*.ufs/attributes/wb_avail_buf Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the amount of unused WriteBooster buffer available. @@ -1360,7 +1360,7 @@ Description: This entry shows the amount of unused WriteBooster buffer What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_cur_buf What: /sys/bus/platform/devices/*.ufs/attributes/wb_cur_buf Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the amount of unused current buffer. The file is read only. @@ -1368,7 +1368,7 @@ Description: This entry shows the amount of unused current buffer. What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_flush_status What: /sys/bus/platform/devices/*.ufs/attributes/wb_flush_status Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the flush operation status. @@ -1385,7 +1385,7 @@ Description: This entry shows the flush operation status. What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_life_time_est What: /sys/bus/platform/devices/*.ufs/attributes/wb_life_time_est Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows an indication of the WriteBooster Buffer lifetime based on the amount of performed program/erase cycles @@ -1399,7 +1399,7 @@ Description: This entry shows an indication of the WriteBooster Buffer What: /sys/class/scsi_device/*/device/unit_descriptor/wb_buf_alloc_units Date: June 2020 -Contact: Asutosh Das <asutoshd@codeaurora.org> +Contact: Asutosh Das <quic_asutoshd@quicinc.com> Description: This entry shows the configured size of WriteBooster buffer. 0400h corresponds to 4GB. diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 0f9f97cdddd9..619ee41a51cc 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -442,7 +442,6 @@ struct blk_revalidate_zone_args { unsigned long *conv_zones_bitmap; unsigned long *seq_zones_wlock; unsigned int nr_zones; - sector_t zone_sectors; sector_t sector; }; @@ -456,38 +455,34 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, struct gendisk *disk = args->disk; struct request_queue *q = disk->queue; sector_t capacity = get_capacity(disk); + sector_t zone_sectors = q->limits.chunk_sectors; + + /* Check for bad zones and holes in the zone report */ + if (zone->start != args->sector) { + pr_warn("%s: Zone gap at sectors %llu..%llu\n", + disk->disk_name, args->sector, zone->start); + return -ENODEV; + } + + if (zone->start >= capacity || !zone->len) { + pr_warn("%s: Invalid zone start %llu, length %llu\n", + disk->disk_name, zone->start, zone->len); + return -ENODEV; + } /* * All zones must have the same size, with the exception on an eventual * smaller last zone. */ - if (zone->start == 0) { - if (zone->len == 0 || !is_power_of_2(zone->len)) { - pr_warn("%s: Invalid zoned device with non power of two zone size (%llu)\n", - disk->disk_name, zone->len); - return -ENODEV; - } - - args->zone_sectors = zone->len; - args->nr_zones = (capacity + zone->len - 1) >> ilog2(zone->len); - } else if (zone->start + args->zone_sectors < capacity) { - if (zone->len != args->zone_sectors) { + if (zone->start + zone->len < capacity) { + if (zone->len != zone_sectors) { pr_warn("%s: Invalid zoned device with non constant zone size\n", disk->disk_name); return -ENODEV; } - } else { - if (zone->len > args->zone_sectors) { - pr_warn("%s: Invalid zoned device with larger last zone size\n", - disk->disk_name); - return -ENODEV; - } - } - - /* Check for holes in the zone report */ - if (zone->start != args->sector) { - pr_warn("%s: Zone gap at sectors %llu..%llu\n", - disk->disk_name, args->sector, zone->start); + } else if (zone->len > zone_sectors) { + pr_warn("%s: Invalid zoned device with larger last zone size\n", + disk->disk_name); return -ENODEV; } @@ -526,11 +521,13 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, * @disk: Target disk * @update_driver_data: Callback to update driver data on the frozen disk * - * Helper function for low-level device drivers to (re) allocate and initialize - * a disk request queue zone bitmaps. This functions should normally be called - * within the disk ->revalidate method for blk-mq based drivers. For BIO based - * drivers only q->nr_zones needs to be updated so that the sysfs exposed value - * is correct. + * Helper function for low-level device drivers to check and (re) allocate and + * initialize a disk request queue zone bitmaps. This functions should normally + * be called within the disk ->revalidate method for blk-mq based drivers. + * Before calling this function, the device driver must already have set the + * device zone size (chunk_sector limit) and the max zone append limit. + * For BIO based drivers, this function cannot be used. BIO based device drivers + * only need to set disk->nr_zones so that the sysfs exposed value is correct. * If the @update_driver_data callback function is not NULL, the callback is * executed with the device request queue frozen after all zones have been * checked. @@ -539,9 +536,9 @@ int blk_revalidate_disk_zones(struct gendisk *disk, void (*update_driver_data)(struct gendisk *disk)) { struct request_queue *q = disk->queue; - struct blk_revalidate_zone_args args = { - .disk = disk, - }; + sector_t zone_sectors = q->limits.chunk_sectors; + sector_t capacity = get_capacity(disk); + struct blk_revalidate_zone_args args = { }; unsigned int noio_flag; int ret; @@ -550,13 +547,31 @@ int blk_revalidate_disk_zones(struct gendisk *disk, if (WARN_ON_ONCE(!queue_is_mq(q))) return -EIO; - if (!get_capacity(disk)) - return -EIO; + if (!capacity) + return -ENODEV; + + /* + * Checks that the device driver indicated a valid zone size and that + * the max zone append limit is set. + */ + if (!zone_sectors || !is_power_of_2(zone_sectors)) { + pr_warn("%s: Invalid non power of two zone size (%llu)\n", + disk->disk_name, zone_sectors); + return -ENODEV; + } + + if (!q->limits.max_zone_append_sectors) { + pr_warn("%s: Invalid 0 maximum zone append limit\n", + disk->disk_name); + return -ENODEV; + } /* * Ensure that all memory allocations in this context are done as if * GFP_NOIO was specified. */ + args.disk = disk; + args.nr_zones = (capacity + zone_sectors - 1) >> ilog2(zone_sectors); noio_flag = memalloc_noio_save(); ret = disk->fops->report_zones(disk, 0, UINT_MAX, blk_revalidate_zone_cb, &args); @@ -570,7 +585,7 @@ int blk_revalidate_disk_zones(struct gendisk *disk, * If zones where reported, make sure that the entire disk capacity * has been checked. */ - if (ret > 0 && args.sector != get_capacity(disk)) { + if (ret > 0 && args.sector != capacity) { pr_warn("%s: Missing zones from sector %llu\n", disk->disk_name, args.sector); ret = -ENODEV; @@ -583,7 +598,6 @@ int blk_revalidate_disk_zones(struct gendisk *disk, */ blk_mq_freeze_queue(q); if (ret > 0) { - blk_queue_chunk_sectors(q, args.zone_sectors); disk->nr_zones = args.nr_zones; swap(disk->seq_zones_wlock, args.seq_zones_wlock); swap(disk->conv_zones_bitmap, args.conv_zones_bitmap); diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index 635ce0648133..55c5b48bc276 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -162,21 +162,15 @@ int null_register_zoned_dev(struct nullb *nullb) disk_set_zoned(nullb->disk, BLK_ZONED_HM); blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); blk_queue_required_elevator_features(q, ELEVATOR_F_ZBD_SEQ_WRITE); - - if (queue_is_mq(q)) { - int ret = blk_revalidate_disk_zones(nullb->disk, NULL); - - if (ret) - return ret; - } else { - blk_queue_chunk_sectors(q, dev->zone_size_sects); - nullb->disk->nr_zones = bdev_nr_zones(nullb->disk->part0); - } - + blk_queue_chunk_sectors(q, dev->zone_size_sects); + nullb->disk->nr_zones = bdev_nr_zones(nullb->disk->part0); blk_queue_max_zone_append_sectors(q, dev->zone_size_sects); disk_set_max_open_zones(nullb->disk, dev->zone_max_open); disk_set_max_active_zones(nullb->disk, dev->zone_max_active); + if (queue_is_mq(q)) + return blk_revalidate_disk_zones(nullb->disk, NULL); + return 0; } diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index b47358da92a2..1fe011676d07 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -751,7 +751,6 @@ static int virtblk_probe_zoned_device(struct virtio_device *vdev, { u32 v, wg; u8 model; - int ret; virtio_cread(vdev, struct virtio_blk_config, zoned.model, &model); @@ -806,6 +805,7 @@ static int virtblk_probe_zoned_device(struct virtio_device *vdev, vblk->zone_sectors); return -ENODEV; } + blk_queue_chunk_sectors(q, vblk->zone_sectors); dev_dbg(&vdev->dev, "zone sectors = %u\n", vblk->zone_sectors); if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD)) { @@ -814,26 +814,22 @@ static int virtblk_probe_zoned_device(struct virtio_device *vdev, blk_queue_max_discard_sectors(q, 0); } - ret = blk_revalidate_disk_zones(vblk->disk, NULL); - if (!ret) { - virtio_cread(vdev, struct virtio_blk_config, - zoned.max_append_sectors, &v); - if (!v) { - dev_warn(&vdev->dev, "zero max_append_sectors reported\n"); - return -ENODEV; - } - if ((v << SECTOR_SHIFT) < wg) { - dev_err(&vdev->dev, - "write granularity %u exceeds max_append_sectors %u limit\n", - wg, v); - return -ENODEV; - } - - blk_queue_max_zone_append_sectors(q, v); - dev_dbg(&vdev->dev, "max append sectors = %u\n", v); + virtio_cread(vdev, struct virtio_blk_config, + zoned.max_append_sectors, &v); + if (!v) { + dev_warn(&vdev->dev, "zero max_append_sectors reported\n"); + return -ENODEV; + } + if ((v << SECTOR_SHIFT) < wg) { + dev_err(&vdev->dev, + "write granularity %u exceeds max_append_sectors %u limit\n", + wg, v); + return -ENODEV; } + blk_queue_max_zone_append_sectors(q, v); + dev_dbg(&vdev->dev, "max append sectors = %u\n", v); - return ret; + return blk_revalidate_disk_zones(vblk->disk, NULL); } #else diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c index 12316ab51bda..ec8557810c21 100644 --- a/drivers/nvme/host/zns.c +++ b/drivers/nvme/host/zns.c @@ -10,12 +10,11 @@ int nvme_revalidate_zones(struct nvme_ns *ns) { struct request_queue *q = ns->queue; - int ret; - ret = blk_revalidate_disk_zones(ns->disk, NULL); - if (!ret) - blk_queue_max_zone_append_sectors(q, ns->ctrl->max_zone_append); - return ret; + blk_queue_chunk_sectors(q, ns->zsze); + blk_queue_max_zone_append_sectors(q, ns->ctrl->max_zone_append); + + return blk_revalidate_disk_zones(ns->disk, NULL); } static int nvme_set_max_append(struct nvme_ctrl *ctrl) diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index f21307537829..4f0d0e55f0d4 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -534,8 +534,7 @@ static void zfcp_fc_adisc_handler(void *data) /* re-init to undo drop from zfcp_fc_adisc() */ port->d_id = ntoh24(adisc_resp->adisc_port_id); - /* port is good, unblock rport without going through erp */ - zfcp_scsi_schedule_rport_register(port); + /* port is still good, nothing to do */ out: atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status); put_device(&port->dev); @@ -595,9 +594,6 @@ void zfcp_fc_link_test_work(struct work_struct *work) int retval; set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */ - get_device(&port->dev); - port->rport_task = RPORT_DEL; - zfcp_scsi_rport_work(&port->rport_work); /* only issue one test command at one time per port */ if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index e1e4f9d10887..857be0f3ae5b 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -1598,7 +1598,7 @@ NCR_700_intr(int irq, void *dev_id) printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG))); #endif resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch; - } else if(dsp >= to32bit(&slot->pSG[0].ins) && + } else if (slot && dsp >= to32bit(&slot->pSG[0].ins) && dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) { int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff; int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List); diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 7c6efde75da6..73b6ac0c01f5 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2618,7 +2618,7 @@ struct aac_hba_info { struct aac_aifcmd { __le32 command; /* Tell host what type of notify this is */ __le32 seqnum; /* To allow ordering of reports (if necessary) */ - u8 data[1]; /* Undefined length (from kernel viewpoint) */ + u8 data[]; /* Undefined length (from kernel viewpoint) */ }; /** diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index d82de34f6fd7..e51e92f932fa 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -27,7 +27,7 @@ #define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.6.0.54" +#define DRV_VERSION "1.6.0.55" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: " diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 26dbd347156e..be89ce96df46 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2139,7 +2139,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, bool new_sc) { - int ret = SUCCESS; + int ret = 0; struct fnic_pending_aborts_iter_data iter_data = { .fnic = fnic, .lun_dev = lr_sc->device, @@ -2159,9 +2159,11 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, /* walk again to check, if IOs are still pending in fw */ if (fnic_is_abts_pending(fnic, lr_sc)) - ret = FAILED; + ret = 1; clean_pending_aborts_end: + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, + "%s: exit status: %d\n", __func__, ret); return ret; } diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c index f3c3a26a1384..be0d7c57b242 100644 --- a/drivers/scsi/fnic/fnic_trace.c +++ b/drivers/scsi/fnic/fnic_trace.c @@ -465,7 +465,7 @@ int fnic_trace_buf_init(void) fnic_max_trace_entries = (trace_max_pages * PAGE_SIZE)/ FNIC_ENTRY_SIZE_BYTES; - fnic_trace_buf_p = (unsigned long)vzalloc(trace_max_pages * PAGE_SIZE); + fnic_trace_buf_p = (unsigned long)vcalloc(trace_max_pages, PAGE_SIZE); if (!fnic_trace_buf_p) { printk(KERN_ERR PFX "Failed to allocate memory " "for fnic_trace_buf_p\n"); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 467c255bbe4c..51afb60859eb 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -6971,7 +6971,9 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) if (rc) return; /* Reset HBA FCF states after successful unregister FCF */ + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag = 0; + spin_unlock_irq(&phba->hbalock); phba->fcf.current_rec.flag = 0; /* diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index a62e091894f6..d26941b131fd 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -109,8 +109,6 @@ lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba, } } -#define LPFC_INVALID_REFTAG ((u32)-1) - /** * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread * @phba: The Hba for which this call is being executed. @@ -978,8 +976,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, sgpe = scsi_prot_sglist(sc); lba = scsi_prot_ref_tag(sc); - if (lba == LPFC_INVALID_REFTAG) - return 0; /* First check if we need to match the LBA */ if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { @@ -1560,8 +1556,6 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command for pde*/ reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -1723,8 +1717,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = scsi_prot_interval(sc); reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -1953,8 +1945,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command for pde*/ reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -2154,8 +2144,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = scsi_prot_interval(sc); reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -2746,8 +2734,6 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) src = (struct scsi_dif_tuple *)sg_virt(sgpe); start_ref_tag = scsi_prot_ref_tag(cmd); - if (start_ref_tag == LPFC_INVALID_REFTAG) - goto out; start_app_tag = src->app_tag; len = sgpe->length; while (src && protsegcnt) { @@ -3493,11 +3479,11 @@ err: scsi_cmnd->sc_data_direction); lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, - "9084 Cannot setup S/G List for HBA" - "IO segs %d/%d SGL %d SCSI %d: %d %d\n", + "9084 Cannot setup S/G List for HBA " + "IO segs %d/%d SGL %d SCSI %d: %d %d %d\n", lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, - prot_group_type, num_sge); + prot_group_type, num_sge, ret); lpfc_cmd->seg_cnt = 0; lpfc_cmd->prot_seg_cnt = 0; diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 8ed3bb1f698a..5e5ce1e74c3b 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -1178,7 +1178,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev, pm80xx_set_thermal_config(pm8001_ha); } - if (pm8001_init_sas_add(pm8001_ha)) + rc = pm8001_init_sas_add(pm8001_ha); + if (rc) goto err_out_shost; /* phy setting support for motherboard controller */ rc = pm8001_configure_phy_settings(pm8001_ha); diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 2a31ddc99dde..7825765c936c 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -31,6 +31,7 @@ static void qedf_remove(struct pci_dev *pdev); static void qedf_shutdown(struct pci_dev *pdev); static void qedf_schedule_recovery_handler(void *dev); static void qedf_recovery_handler(struct work_struct *work); +static int qedf_suspend(struct pci_dev *pdev, pm_message_t state); /* * Driver module parameters. @@ -3271,6 +3272,7 @@ static struct pci_driver qedf_pci_driver = { .probe = qedf_probe, .remove = qedf_remove, .shutdown = qedf_shutdown, + .suspend = qedf_suspend, }; static int __qedf_probe(struct pci_dev *pdev, int mode) @@ -4000,6 +4002,22 @@ static void qedf_shutdown(struct pci_dev *pdev) __qedf_remove(pdev, QEDF_MODE_NORMAL); } +static int qedf_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct qedf_ctx *qedf; + + if (!pdev) { + QEDF_ERR(NULL, "pdev is NULL.\n"); + return -ENODEV; + } + + qedf = pci_get_drvdata(pdev); + + QEDF_ERR(&qedf->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); + + return -EPERM; +} + /* * Recovery handler code */ diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 450522b204d6..cd0180b1f5b9 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -69,6 +69,7 @@ static struct nvm_iscsi_block *qedi_get_nvram_block(struct qedi_ctx *qedi); static void qedi_recovery_handler(struct work_struct *work); static void qedi_schedule_hw_err_handler(void *dev, enum qed_hw_err_type err_type); +static int qedi_suspend(struct pci_dev *pdev, pm_message_t state); static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle) { @@ -1976,8 +1977,9 @@ static int qedi_cpu_offline(unsigned int cpu) struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu); struct qedi_work *work, *tmp; struct task_struct *thread; + unsigned long flags; - spin_lock_bh(&p->p_work_lock); + spin_lock_irqsave(&p->p_work_lock, flags); thread = p->iothread; p->iothread = NULL; @@ -1988,7 +1990,7 @@ static int qedi_cpu_offline(unsigned int cpu) kfree(work); } - spin_unlock_bh(&p->p_work_lock); + spin_unlock_irqrestore(&p->p_work_lock, flags); if (thread) kthread_stop(thread); return 0; @@ -2510,6 +2512,22 @@ static void qedi_shutdown(struct pci_dev *pdev) __qedi_remove(pdev, QEDI_MODE_SHUTDOWN); } +static int qedi_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct qedi_ctx *qedi; + + if (!pdev) { + QEDI_ERR(NULL, "pdev is NULL.\n"); + return -ENODEV; + } + + qedi = pci_get_drvdata(pdev); + + QEDI_ERR(&qedi->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); + + return -EPERM; +} + static int __qedi_probe(struct pci_dev *pdev, int mode) { struct qedi_ctx *qedi; @@ -2868,6 +2886,7 @@ static struct pci_driver qedi_pci_driver = { .remove = qedi_remove, .shutdown = qedi_shutdown, .err_handler = &qedi_err_handler, + .suspend = qedi_suspend, }; static int __init qedi_init(void) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b3b1df34afd3..336b8c665cb4 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4459,7 +4459,6 @@ struct qla_hw_data { /* n2n */ struct fc_els_flogi plogi_els_payld; -#define LOGIN_TEMPLATE_SIZE (sizeof(struct fc_els_flogi) - 4) void *swl; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 059175f2c8f5..df623de89255 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -8487,7 +8487,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, ql_dbg(ql_dbg_init, vha, 0x0163, "-> fwdt%u template allocate template %#x words...\n", j, risc_size); - fwdt->template = vmalloc(risc_size * sizeof(*dcode)); + fwdt->template = vmalloc_array(risc_size, sizeof(*dcode)); if (!fwdt->template) { ql_log(ql_log_warn, vha, 0x0164, "-> fwdt%u failed allocate template.\n", j); @@ -8742,7 +8742,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) ql_dbg(ql_dbg_init, vha, 0x0173, "-> fwdt%u template allocate template %#x words...\n", j, risc_size); - fwdt->template = vmalloc(risc_size * sizeof(*dcode)); + fwdt->template = vmalloc_array(risc_size, sizeof(*dcode)); if (!fwdt->template) { ql_log(ql_log_warn, vha, 0x0174, "-> fwdt%u failed allocate template.\n", j); diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 1c6e300ed3ab..1ee9b7d5fc15 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -3073,7 +3073,8 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, memset(ptr, 0, sizeof(struct els_plogi_payload)); memset(resp_ptr, 0, sizeof(struct els_plogi_payload)); memcpy(elsio->u.els_plogi.els_plogi_pyld->data, - &ha->plogi_els_payld.fl_csp, LOGIN_TEMPLATE_SIZE); + (void *)&ha->plogi_els_payld + offsetof(struct fc_els_flogi, fl_csp), + sizeof(ha->plogi_els_payld) - offsetof(struct fc_els_flogi, fl_csp)); elsio->u.els_plogi.els_cmd = els_opcode; elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode; @@ -3912,7 +3913,7 @@ qla2x00_start_sp(srb_t *sp) pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); if (!pkt) { - rval = EAGAIN; + rval = -EAGAIN; ql_log(ql_log_warn, vha, 0x700c, "qla2x00_alloc_iocbs failed.\n"); goto done; diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index 898a0bdf8df6..95a86e0dfd77 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c @@ -209,53 +209,6 @@ raid_attr_ro_state(level); raid_attr_ro_fn(resync); raid_attr_ro_state_fn(state); -static void raid_component_release(struct device *dev) -{ - struct raid_component *rc = - container_of(dev, struct raid_component, dev); - dev_printk(KERN_ERR, rc->dev.parent, "COMPONENT RELEASE\n"); - put_device(rc->dev.parent); - kfree(rc); -} - -int raid_component_add(struct raid_template *r,struct device *raid_dev, - struct device *component_dev) -{ - struct device *cdev = - attribute_container_find_class_device(&r->raid_attrs.ac, - raid_dev); - struct raid_component *rc; - struct raid_data *rd = dev_get_drvdata(cdev); - int err; - - rc = kzalloc(sizeof(*rc), GFP_KERNEL); - if (!rc) - return -ENOMEM; - - INIT_LIST_HEAD(&rc->node); - device_initialize(&rc->dev); - rc->dev.release = raid_component_release; - rc->dev.parent = get_device(component_dev); - rc->num = rd->component_count++; - - dev_set_name(&rc->dev, "component-%d", rc->num); - list_add_tail(&rc->node, &rd->component_list); - rc->dev.class = &raid_class.class; - err = device_add(&rc->dev); - if (err) - goto err_out; - - return 0; - -err_out: - list_del(&rc->node); - rd->component_count--; - put_device(component_dev); - kfree(rc); - return err; -} -EXPORT_SYMBOL(raid_component_add); - struct raid_template * raid_class_attach(struct raid_function_template *ft) { diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 8c58128ad32a..9c0af50501f9 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -841,11 +841,6 @@ static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES; static int submit_queues = DEF_SUBMIT_QUEUES; /* > 1 for multi-queue (mq) */ static int poll_queues; /* iouring iopoll interface.*/ -static DEFINE_RWLOCK(atomic_rw); -static DEFINE_RWLOCK(atomic_rw2); - -static rwlock_t *ramdisk_lck_a[2]; - static char sdebug_proc_name[] = MY_NAME; static const char *my_name = MY_NAME; @@ -6818,9 +6813,6 @@ static int __init scsi_debug_init(void) int k, ret, hosts_to_add; int idx = -1; - ramdisk_lck_a[0] = &atomic_rw; - ramdisk_lck_a[1] = &atomic_rw2; - if (sdebug_ndelay >= 1000 * 1000 * 1000) { pr_warn("ndelay must be less than 1 second, ignored\n"); sdebug_ndelay = 0; diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 4a6eb1741be0..41f23cd0bfb4 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -406,7 +406,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, size_t length, loff_t *ppos) { int host, channel, id, lun; - char *buffer, *p; + char *buffer, *end, *p; int err; if (!buf || length > PAGE_SIZE) @@ -421,10 +421,14 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, goto out; err = -EINVAL; - if (length < PAGE_SIZE) - buffer[length] = '\0'; - else if (buffer[PAGE_SIZE-1]) - goto out; + if (length < PAGE_SIZE) { + end = buffer + length; + *end = '\0'; + } else { + end = buffer + PAGE_SIZE - 1; + if (*end) + goto out; + } /* * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi @@ -433,10 +437,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, if (!strncmp("scsi add-single-device", buffer, 22)) { p = buffer + 23; - host = simple_strtoul(p, &p, 0); - channel = simple_strtoul(p + 1, &p, 0); - id = simple_strtoul(p + 1, &p, 0); - lun = simple_strtoul(p + 1, &p, 0); + host = (p < end) ? simple_strtoul(p, &p, 0) : 0; + channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; err = scsi_add_single_device(host, channel, id, lun); @@ -447,10 +451,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, } else if (!strncmp("scsi remove-single-device", buffer, 25)) { p = buffer + 26; - host = simple_strtoul(p, &p, 0); - channel = simple_strtoul(p + 1, &p, 0); - id = simple_strtoul(p + 1, &p, 0); - lun = simple_strtoul(p + 1, &p, 0); + host = (p < end) ? simple_strtoul(p, &p, 0) : 0; + channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; err = scsi_remove_single_device(host, channel, id, lun); } diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index abbd08933ac7..a25215507668 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -831,7 +831,6 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) struct request_queue *q = disk->queue; u32 zone_blocks = sdkp->early_zone_info.zone_blocks; unsigned int nr_zones = sdkp->early_zone_info.nr_zones; - u32 max_append; int ret = 0; unsigned int flags; @@ -876,6 +875,11 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) goto unlock; } + blk_queue_chunk_sectors(q, + logical_to_sectors(sdkp->device, zone_blocks)); + blk_queue_max_zone_append_sectors(q, + q->limits.max_segments << PAGE_SECTORS_SHIFT); + ret = blk_revalidate_disk_zones(disk, sd_zbc_revalidate_zones_cb); memalloc_noio_restore(flags); @@ -888,12 +892,6 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) goto unlock; } - max_append = min_t(u32, logical_to_sectors(sdkp->device, zone_blocks), - q->limits.max_segments << PAGE_SECTORS_SHIFT); - max_append = min_t(u32, max_append, queue_max_hw_sectors(q)); - - blk_queue_max_zone_append_sectors(q, max_append); - sd_zbc_print_zones(sdkp); unlock: diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 89fa046c7158..0d8afffd1683 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1497,9 +1497,10 @@ sg_add_device(struct device *cl_dev) int error; unsigned long iflags; - error = blk_get_queue(scsidp->request_queue); - if (error) - return error; + if (!blk_get_queue(scsidp->request_queue)) { + pr_warn("%s: get scsi_device queue failed\n", __func__); + return -ENODEV; + } error = -ENOMEM; cdev = cdev_alloc(); diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c index 3e2e5783924d..4db3ba62fcd3 100644 --- a/drivers/scsi/snic/snic_disc.c +++ b/drivers/scsi/snic/snic_disc.c @@ -307,7 +307,7 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) spin_lock_irqsave(snic->shost->host_lock, flags); list_del(&tgt->list); spin_unlock_irqrestore(snic->shost->host_lock, flags); - kfree(tgt); + put_device(&tgt->dev); tgt = NULL; return tgt; diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 659196a2f63a..068625556dda 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -316,8 +316,12 @@ enum storvsc_request_type { #define SRB_STATUS_ABORTED 0x02 #define SRB_STATUS_ERROR 0x04 #define SRB_STATUS_INVALID_REQUEST 0x06 +#define SRB_STATUS_TIMEOUT 0x09 +#define SRB_STATUS_SELECTION_TIMEOUT 0x0A +#define SRB_STATUS_BUS_RESET 0x0E #define SRB_STATUS_DATA_OVERRUN 0x12 #define SRB_STATUS_INVALID_LUN 0x20 +#define SRB_STATUS_INTERNAL_ERROR 0x30 #define SRB_STATUS(status) \ (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN)) @@ -365,6 +369,7 @@ static void storvsc_on_channel_callback(void *context); #define STORVSC_FC_MAX_LUNS_PER_TARGET 255 #define STORVSC_FC_MAX_TARGETS 128 #define STORVSC_FC_MAX_CHANNELS 8 +#define STORVSC_FC_MAX_XFER_SIZE ((u32)(512 * 1024)) #define STORVSC_IDE_MAX_LUNS_PER_TARGET 64 #define STORVSC_IDE_MAX_TARGETS 1 @@ -978,6 +983,11 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, case SRB_STATUS_ERROR: case SRB_STATUS_ABORTED: case SRB_STATUS_INVALID_REQUEST: + case SRB_STATUS_INTERNAL_ERROR: + case SRB_STATUS_TIMEOUT: + case SRB_STATUS_SELECTION_TIMEOUT: + case SRB_STATUS_BUS_RESET: + case SRB_STATUS_DATA_OVERRUN: if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) { /* Check for capacity change */ if ((asc == 0x2a) && (ascq == 0x9)) { @@ -1671,10 +1681,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) */ static enum scsi_timeout_action storvsc_eh_timed_out(struct scsi_cmnd *scmnd) { -#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (scmnd->device->host->transportt == fc_transport_template) - return fc_eh_timed_out(scmnd); -#endif return SCSI_EH_RESET_TIMER; } @@ -2004,6 +2010,9 @@ static int storvsc_probe(struct hv_device *device, * protecting it from any weird value. */ max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE); + if (is_fc) + max_xfer_bytes = min(max_xfer_bytes, STORVSC_FC_MAX_XFER_SIZE); + /* max_hw_sectors_kb */ host->max_sectors = max_xfer_bytes >> 9; /* diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 66a4e24484a3..2ba8ec254dce 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -578,7 +578,6 @@ static bool ufshcd_mcq_sqe_search(struct ufs_hba *hba, { struct ufshcd_lrb *lrbp = &hba->lrb[task_tag]; struct utp_transfer_req_desc *utrd; - u32 mask = hwq->max_entries - 1; __le64 cmd_desc_base_addr; bool ret = false; u64 addr, match; @@ -606,7 +605,10 @@ static bool ufshcd_mcq_sqe_search(struct ufs_hba *hba, ret = true; goto out; } - sq_head_slot = (sq_head_slot + 1) & mask; + + sq_head_slot++; + if (sq_head_slot == hwq->max_entries) + sq_head_slot = 0; } out: diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index b00ec996d04d..e4318171381b 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -8452,6 +8452,41 @@ out: return ret; } +static void ufshcd_set_timestamp_attr(struct ufs_hba *hba) +{ + int err; + struct ufs_query_req *request = NULL; + struct ufs_query_res *response = NULL; + struct ufs_dev_info *dev_info = &hba->dev_info; + struct utp_upiu_query_v4_0 *upiu_data; + + if (dev_info->wspecversion < 0x400) + return; + + ufshcd_hold(hba); + + mutex_lock(&hba->dev_cmd.lock); + + ufshcd_init_query(hba, &request, &response, + UPIU_QUERY_OPCODE_WRITE_ATTR, + QUERY_ATTR_IDN_TIMESTAMP, 0, 0); + + request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST; + + upiu_data = (struct utp_upiu_query_v4_0 *)&request->upiu_req; + + put_unaligned_be64(ktime_get_real_ns(), &upiu_data->osf3); + + err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT); + + if (err) + dev_err(hba->dev, "%s: failed to set timestamp %d\n", + __func__, err); + + mutex_unlock(&hba->dev_cmd.lock); + ufshcd_release(hba); +} + /** * ufshcd_add_lus - probe and add UFS logical units * @hba: per-adapter instance @@ -8641,6 +8676,8 @@ static int ufshcd_device_init(struct ufs_hba *hba, bool init_dev_params) ufshcd_set_ufs_dev_active(hba); ufshcd_force_reset_auto_bkops(hba); + ufshcd_set_timestamp_attr(hba); + /* Gear up to HS gear if supported */ if (hba->max_pwr_info.is_valid) { /* @@ -9677,6 +9714,7 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ret = ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE); if (ret) goto set_old_link_state; + ufshcd_set_timestamp_attr(hba); } if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) diff --git a/drivers/ufs/host/Kconfig b/drivers/ufs/host/Kconfig index 16624ba08050..580c8d0bd8bb 100644 --- a/drivers/ufs/host/Kconfig +++ b/drivers/ufs/host/Kconfig @@ -72,6 +72,7 @@ config SCSI_UFS_QCOM config SCSI_UFS_MEDIATEK tristate "Mediatek specific hooks to UFS controller platform driver" depends on SCSI_UFSHCD_PLATFORM && ARCH_MEDIATEK + depends on RESET_CONTROLLER select PHY_MTK_UFS select RESET_TI_SYSCON help diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index f88febb23123..d1149b1c3ed5 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -365,7 +365,7 @@ static void ufs_qcom_select_unipro_mode(struct ufs_qcom_host *host) ufs_qcom_cap_qunipro(host) ? QUNIPRO_SEL : 0, REG_UFS_CFG1); - if (host->hw_ver.major == 0x05) + if (host->hw_ver.major >= 0x05) ufshcd_rmwl(host->hba, QUNIPRO_G4_SEL, 0, REG_UFS_CFG0); /* make sure above configuration is applied before we return */ diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c index 49f7bafc7d55..cc94970b86c9 100644 --- a/drivers/ufs/host/ufs-renesas.c +++ b/drivers/ufs/host/ufs-renesas.c @@ -359,7 +359,7 @@ static int ufs_renesas_init(struct ufs_hba *hba) { struct ufs_renesas_priv *priv; - priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(hba->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; ufshcd_set_variant(hba, priv); diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h index 6a9b177d5c41..e50416ba9cd9 100644 --- a/include/linux/raid_class.h +++ b/include/linux/raid_class.h @@ -77,7 +77,3 @@ DEFINE_RAID_ATTRIBUTE(enum raid_state, state) struct raid_template *raid_class_attach(struct raid_function_template *); void raid_class_release(struct raid_template *); - -int __must_check raid_component_add(struct raid_template *, struct device *, - struct device *); - diff --git a/include/uapi/scsi/scsi_bsg_ufs.h b/include/uapi/scsi/scsi_bsg_ufs.h index bf1832dc35db..7c7975f9905e 100644 --- a/include/uapi/scsi/scsi_bsg_ufs.h +++ b/include/uapi/scsi/scsi_bsg_ufs.h @@ -117,6 +117,31 @@ struct utp_upiu_query { }; /** + * struct utp_upiu_query_v4_0 - upiu request buffer structure for + * query request >= UFS 4.0 spec. + * @opcode: command to perform B-0 + * @idn: a value that indicates the particular type of data B-1 + * @index: Index to further identify data B-2 + * @selector: Index to further identify data B-3 + * @osf4: spec field B-5 + * @osf5: spec field B 6,7 + * @osf6: spec field DW 8,9 + * @osf7: spec field DW 10,11 + */ +struct utp_upiu_query_v4_0 { + __u8 opcode; + __u8 idn; + __u8 index; + __u8 selector; + __u8 osf3; + __u8 osf4; + __be16 osf5; + __be32 osf6; + __be32 osf7; + __be32 reserved; +}; + +/** * struct utp_upiu_cmd - Command UPIU structure * @data_transfer_len: Data Transfer Length DW-3 * @cdb: Command Descriptor Block CDB DW-4 to DW-7 diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 3ebb677d993a..0cced88f4531 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -179,6 +179,7 @@ enum attr_idn { QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F, QUERY_ATTR_IDN_EXT_IID_EN = 0x2A, + QUERY_ATTR_IDN_TIMESTAMP = 0x30 }; /* Descriptor idn for Query requests */ |