From 45bced87e79316ecd868aee8f187284025792c5f Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:02 +0200 Subject: scsi: ufs: sysfs: device descriptor This patch introduces a sysfs group entry for the UFS device descriptor parameters. The group adds "device_descriptor" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown as hexadecimal numbers. The full information about the parameters could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 223 +++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-ufs (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs new file mode 100644 index 000000000000..8da7b8448f13 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -0,0 +1,223 @@ +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the device type. This is one of the UFS + device descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the device class. This is one of the UFS + device descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_class +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the UFS storage subclass. This is one of + the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the protocol supported by an UFS device. + This is one of the UFS device descriptor parameters. + The full information about the descriptor could be found + at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_luns +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows number of logical units. This is one of + the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_wluns +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows number of well known logical units. + This is one of the UFS device descriptor parameters. + The full information about the descriptor could be found + at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows value that indicates whether the device is + enabled for boot. This is one of the UFS device descriptor + parameters. The full information about the descriptor could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_access_enable +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows value that indicates whether the device + descriptor could be read after partial initialization phase + of the boot sequence. This is one of the UFS device descriptor + parameters. The full information about the descriptor could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_power_mode +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows value that defines the power mode after + device initialization or hardware reset. This is one of + the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority_lun +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the high priority lun. This is one of + the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_removal_type +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the secure removal type. This is one of + the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_security_lun +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether the security lun is supported. + This is one of the UFS device descriptor parameters. + The full information about the descriptor could be found + at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termination_latency +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the background operations termination + latency. This is one of the UFS device descriptor parameters. + The full information about the descriptor could be found + at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active_icc_level +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the initial active ICC level. This is one + of the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification_version +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the specification version. This is one + of the UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturing_date +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the manufacturing date in BCD format. + This is one of the UFS device descriptor parameters. + The full information about the descriptor could be found + at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturer_id +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the manufacturee ID. This is one of the + UFS device descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capability +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum number of outstanding RTTs + supported by the device. This is one of the UFS device + descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the frequency and method of the realtime + clock update. This is one of the UFS device descriptor + parameters. The full information about the descriptor + could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows which features are supported by the device. + This is one of the UFS device descriptor parameters. + The full information about the descriptor could be + found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the FFU timeout. This is one of the + UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_depth +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the device queue depth. This is one of the + UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_version +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the device version. This is one of the + UFS device descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_secure_wpa +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows number of secure write protect areas + supported by the device. This is one of the UFS device + descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_data_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum amount of data that may be + written during the pre-soldering phase of the PSA flow. + This is one of the UFS device descriptor parameters. + The full information about the descriptor could be found + at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_timeout +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the command maximum timeout for a change + in PSA state. This is one of the UFS device descriptor + parameters. The full information about the descriptor could + be found at UFS specifications 2.1. + The file is read only. -- cgit v1.2.3 From 8c2582bfbd9abe84b9cf435996aa720a84f908c4 Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:03 +0200 Subject: scsi: ufs: sysfs: interconnect descriptor This patch introduces a sysfs group entry for the UFS interconnect descriptor parameters. The group adds "interconnect_descriptor" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown as hexadecimal numbers. The full information about the parameters could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 19 +++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 18 ++++++++++++++++++ drivers/scsi/ufs/ufs.h | 8 ++++++++ 3 files changed, 45 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 8da7b8448f13..099e6fa0e301 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -221,3 +221,22 @@ Description: This file shows the command maximum timeout for a change parameters. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/unipro_version +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the MIPI UniPro version number in BCD format. + This is one of the UFS interconnect descriptor parameters. + The full information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/mphy_version +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the MIPI M-PHY version number in BCD format. + This is one of the UFS interconnect descriptor parameters. + The full information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 440b94e453bf..ba229d9f326b 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -249,9 +249,27 @@ static const struct attribute_group ufs_sysfs_device_descriptor_group = { .attrs = ufs_sysfs_device_descriptor, }; +#define UFS_INTERCONNECT_DESC_PARAM(_name, _uname, _size) \ + UFS_DESC_PARAM(_name, _uname, INTERCONNECT, _size) + +UFS_INTERCONNECT_DESC_PARAM(unipro_version, _UNIPRO_VER, 2); +UFS_INTERCONNECT_DESC_PARAM(mphy_version, _MPHY_VER, 2); + +static struct attribute *ufs_sysfs_interconnect_descriptor[] = { + &dev_attr_unipro_version.attr, + &dev_attr_mphy_version.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_interconnect_descriptor_group = { + .name = "interconnect_descriptor", + .attrs = ufs_sysfs_interconnect_descriptor, +}; + static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, &ufs_sysfs_device_descriptor_group, + &ufs_sysfs_interconnect_descriptor_group, NULL, }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 6ae1e08329cc..773c0495c542 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -230,6 +230,14 @@ enum device_desc_param { DEVICE_DESC_PARAM_PRDCT_REV = 0x2A, }; +/* Interconnect descriptor parameters offsets in bytes*/ +enum interconnect_desc_param { + INTERCONNECT_DESC_PARAM_LEN = 0x0, + INTERCONNECT_DESC_PARAM_TYPE = 0x1, + INTERCONNECT_DESC_PARAM_UNIPRO_VER = 0x2, + INTERCONNECT_DESC_PARAM_MPHY_VER = 0x4, +}; + /* * Logical Unit Write Protect * 00h: LU not write protected -- cgit v1.2.3 From c720c091222e26d46c0fd9c70144a0f916bf3993 Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:04 +0200 Subject: scsi: ufs: sysfs: geometry descriptor This patch introduces a sysfs group entry for the UFS geometry descriptor parameters. The group adds "geometry_descriptor" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown as hexadecimal numbers. The full information about the parameters could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 173 +++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 84 ++++++++++++++ drivers/scsi/ufs/ufs.h | 36 ++++++ 3 files changed, 293 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 099e6fa0e301..6ea7613a3f3e 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -240,3 +240,176 @@ Description: This file shows the MIPI M-PHY version number in BCD format. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/raw_device_capacity +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the total memory quantity available to + the user to configure the device logical units. This is one + of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_luns +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum number of logical units + supported by the UFS device. This is one of the UFS + geometry descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/segment_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the segment size. This is one of the UFS + geometry descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/allocation_unit_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the allocation unit size. This is one of + the UFS geometry descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/min_addressable_block_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the minimum addressable block size. This + is one of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at UFS + specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_read_block_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the optimal read block size. This is one + of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at UFS + specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_write_block_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the optimal write block size. This is one + of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at UFS + specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_in_buffer_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum data-in buffer size. This + is one of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at UFS + specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_out_buffer_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum data-out buffer size. This + is one of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at UFS + specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/rpmb_rw_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum number of RPMB frames allowed + in Security Protocol In/Out. This is one of the UFS geometry + descriptor parameters. The full information about the + descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/dyn_capacity_resource_policy +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the dynamic capacity resource policy. This + is one of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/data_ordering +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows support for out-of-order data transfer. + This is one of the UFS geometry descriptor parameters. + The full information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_contexts +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows maximum available number of contexts which + are supported by the device. This is one of the UFS geometry + descriptor parameters. The full information about the + descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_unit_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows system data tag unit size. This is one of + the UFS geometry descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_resource_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows maximum storage area size allocated by + the device to handle system data by the tagging mechanism. + This is one of the UFS geometry descriptor parameters. + The full information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/secure_removal_types +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows supported secure removal types. This is + one of the UFS geometry descriptor parameters. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/memory_types +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows supported memory types. This is one of + the UFS geometry descriptor parameters. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_max_alloc_units +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum number of allocation units for + different memory types (system code, non persistent, + enhanced type 1-4). This is one of the UFS geometry + descriptor parameters. The full information about the + descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_capacity_adjustment_factor +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the memory capacity adjustment factor for + different memory types (system code, non persistent, + enhanced type 1-4). This is one of the UFS geometry + descriptor parameters. The full information about the + descriptor could be found at UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index ba229d9f326b..ecd3dcb05f67 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -266,10 +266,94 @@ static const struct attribute_group ufs_sysfs_interconnect_descriptor_group = { .attrs = ufs_sysfs_interconnect_descriptor, }; +#define UFS_GEOMETRY_DESC_PARAM(_name, _uname, _size) \ + UFS_DESC_PARAM(_name, _uname, GEOMETRY, _size) + +UFS_GEOMETRY_DESC_PARAM(raw_device_capacity, _DEV_CAP, 8); +UFS_GEOMETRY_DESC_PARAM(max_number_of_luns, _MAX_NUM_LUN, 1); +UFS_GEOMETRY_DESC_PARAM(segment_size, _SEG_SIZE, 4); +UFS_GEOMETRY_DESC_PARAM(allocation_unit_size, _ALLOC_UNIT_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(min_addressable_block_size, _MIN_BLK_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(optimal_read_block_size, _OPT_RD_BLK_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(optimal_write_block_size, _OPT_WR_BLK_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(max_in_buffer_size, _MAX_IN_BUF_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(max_out_buffer_size, _MAX_OUT_BUF_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(rpmb_rw_size, _RPMB_RW_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(dyn_capacity_resource_policy, _DYN_CAP_RSRC_PLC, 1); +UFS_GEOMETRY_DESC_PARAM(data_ordering, _DATA_ORDER, 1); +UFS_GEOMETRY_DESC_PARAM(max_number_of_contexts, _MAX_NUM_CTX, 1); +UFS_GEOMETRY_DESC_PARAM(sys_data_tag_unit_size, _TAG_UNIT_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(sys_data_tag_resource_size, _TAG_RSRC_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(secure_removal_types, _SEC_RM_TYPES, 1); +UFS_GEOMETRY_DESC_PARAM(memory_types, _MEM_TYPES, 2); +UFS_GEOMETRY_DESC_PARAM(sys_code_memory_max_alloc_units, + _SCM_MAX_NUM_UNITS, 4); +UFS_GEOMETRY_DESC_PARAM(sys_code_memory_capacity_adjustment_factor, + _SCM_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(non_persist_memory_max_alloc_units, + _NPM_MAX_NUM_UNITS, 4); +UFS_GEOMETRY_DESC_PARAM(non_persist_memory_capacity_adjustment_factor, + _NPM_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(enh1_memory_max_alloc_units, + _ENM1_MAX_NUM_UNITS, 4); +UFS_GEOMETRY_DESC_PARAM(enh1_memory_capacity_adjustment_factor, + _ENM1_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(enh2_memory_max_alloc_units, + _ENM2_MAX_NUM_UNITS, 4); +UFS_GEOMETRY_DESC_PARAM(enh2_memory_capacity_adjustment_factor, + _ENM2_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(enh3_memory_max_alloc_units, + _ENM3_MAX_NUM_UNITS, 4); +UFS_GEOMETRY_DESC_PARAM(enh3_memory_capacity_adjustment_factor, + _ENM3_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(enh4_memory_max_alloc_units, + _ENM4_MAX_NUM_UNITS, 4); +UFS_GEOMETRY_DESC_PARAM(enh4_memory_capacity_adjustment_factor, + _ENM4_CAP_ADJ_FCTR, 2); + +static struct attribute *ufs_sysfs_geometry_descriptor[] = { + &dev_attr_raw_device_capacity.attr, + &dev_attr_max_number_of_luns.attr, + &dev_attr_segment_size.attr, + &dev_attr_allocation_unit_size.attr, + &dev_attr_min_addressable_block_size.attr, + &dev_attr_optimal_read_block_size.attr, + &dev_attr_optimal_write_block_size.attr, + &dev_attr_max_in_buffer_size.attr, + &dev_attr_max_out_buffer_size.attr, + &dev_attr_rpmb_rw_size.attr, + &dev_attr_dyn_capacity_resource_policy.attr, + &dev_attr_data_ordering.attr, + &dev_attr_max_number_of_contexts.attr, + &dev_attr_sys_data_tag_unit_size.attr, + &dev_attr_sys_data_tag_resource_size.attr, + &dev_attr_secure_removal_types.attr, + &dev_attr_memory_types.attr, + &dev_attr_sys_code_memory_max_alloc_units.attr, + &dev_attr_sys_code_memory_capacity_adjustment_factor.attr, + &dev_attr_non_persist_memory_max_alloc_units.attr, + &dev_attr_non_persist_memory_capacity_adjustment_factor.attr, + &dev_attr_enh1_memory_max_alloc_units.attr, + &dev_attr_enh1_memory_capacity_adjustment_factor.attr, + &dev_attr_enh2_memory_max_alloc_units.attr, + &dev_attr_enh2_memory_capacity_adjustment_factor.attr, + &dev_attr_enh3_memory_max_alloc_units.attr, + &dev_attr_enh3_memory_capacity_adjustment_factor.attr, + &dev_attr_enh4_memory_max_alloc_units.attr, + &dev_attr_enh4_memory_capacity_adjustment_factor.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_geometry_descriptor_group = { + .name = "geometry_descriptor", + .attrs = ufs_sysfs_geometry_descriptor, +}; + static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, &ufs_sysfs_device_descriptor_group, &ufs_sysfs_interconnect_descriptor_group, + &ufs_sysfs_geometry_descriptor_group, NULL, }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 773c0495c542..04d41c8d3dc1 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -238,6 +238,42 @@ enum interconnect_desc_param { INTERCONNECT_DESC_PARAM_MPHY_VER = 0x4, }; +/* Geometry descriptor parameters offsets in bytes*/ +enum geometry_desc_param { + GEOMETRY_DESC_PARAM_LEN = 0x0, + GEOMETRY_DESC_PARAM_TYPE = 0x1, + GEOMETRY_DESC_PARAM_DEV_CAP = 0x4, + GEOMETRY_DESC_PARAM_MAX_NUM_LUN = 0xC, + GEOMETRY_DESC_PARAM_SEG_SIZE = 0xD, + GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE = 0x11, + GEOMETRY_DESC_PARAM_MIN_BLK_SIZE = 0x12, + GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE = 0x13, + GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE = 0x14, + GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE = 0x15, + GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE = 0x16, + GEOMETRY_DESC_PARAM_RPMB_RW_SIZE = 0x17, + GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC = 0x18, + GEOMETRY_DESC_PARAM_DATA_ORDER = 0x19, + GEOMETRY_DESC_PARAM_MAX_NUM_CTX = 0x1A, + GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE = 0x1B, + GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE = 0x1C, + GEOMETRY_DESC_PARAM_SEC_RM_TYPES = 0x1D, + GEOMETRY_DESC_PARAM_MEM_TYPES = 0x1E, + GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS = 0x20, + GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR = 0x24, + GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS = 0x26, + GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR = 0x2A, + GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS = 0x2C, + GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR = 0x30, + GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS = 0x32, + GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR = 0x36, + GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS = 0x38, + GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR = 0x3C, + GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E, + GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42, + GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44, +}; + /* * Logical Unit Write Protect * 00h: LU not write protected -- cgit v1.2.3 From c648c2d27f168ae4faeb43f8c3074226aae3862c Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:05 +0200 Subject: scsi: ufs: sysfs: health descriptor This patch introduces a sysfs group entry for the UFS health descriptor parameters. The group adds "health_descriptor" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown as hexadecimal numbers. The full information about the parameters could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 28 ++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 20 ++++++++++++++++++++ drivers/scsi/ufs/ufs.h | 11 +++++++++++ drivers/scsi/ufs/ufshcd.c | 8 ++++++++ drivers/scsi/ufs/ufshcd.h | 1 + 5 files changed, 68 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 6ea7613a3f3e..ddb012b05f0d 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -413,3 +413,31 @@ Description: This file shows the memory capacity adjustment factor for descriptor parameters. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/health_descriptor/eol_info +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows preend of life information. This is one + of the UFS health descriptor parameters. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_a +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows indication of the device life time + (method a). This is one of the UFS health descriptor + parameters. The full information about the descriptor + could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_b +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows indication of the device life time + (method b). This is one of the UFS health descriptor + parameters. The full information about the descriptor + could be found at UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index ecd3dcb05f67..c4f18b0970db 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -349,11 +349,31 @@ static const struct attribute_group ufs_sysfs_geometry_descriptor_group = { .attrs = ufs_sysfs_geometry_descriptor, }; +#define UFS_HEALTH_DESC_PARAM(_name, _uname, _size) \ + UFS_DESC_PARAM(_name, _uname, HEALTH, _size) + +UFS_HEALTH_DESC_PARAM(eol_info, _EOL_INFO, 1); +UFS_HEALTH_DESC_PARAM(life_time_estimation_a, _LIFE_TIME_EST_A, 1); +UFS_HEALTH_DESC_PARAM(life_time_estimation_b, _LIFE_TIME_EST_B, 1); + +static struct attribute *ufs_sysfs_health_descriptor[] = { + &dev_attr_eol_info.attr, + &dev_attr_life_time_estimation_a.attr, + &dev_attr_life_time_estimation_b.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_health_descriptor_group = { + .name = "health_descriptor", + .attrs = ufs_sysfs_health_descriptor, +}; + static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, &ufs_sysfs_device_descriptor_group, &ufs_sysfs_interconnect_descriptor_group, &ufs_sysfs_geometry_descriptor_group, + &ufs_sysfs_health_descriptor_group, NULL, }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 04d41c8d3dc1..6bfeedb934f1 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -154,6 +154,7 @@ enum desc_idn { QUERY_DESC_IDN_RFU_1 = 0x6, QUERY_DESC_IDN_GEOMETRY = 0x7, QUERY_DESC_IDN_POWER = 0x8, + QUERY_DESC_IDN_HEALTH = 0x9, QUERY_DESC_IDN_MAX, }; @@ -169,6 +170,7 @@ enum ufs_desc_def_size { QUERY_DESC_INTERCONNECT_DEF_SIZE = 0x06, QUERY_DESC_GEOMETRY_DEF_SIZE = 0x44, QUERY_DESC_POWER_DEF_SIZE = 0x62, + QUERY_DESC_HEALTH_DEF_SIZE = 0x25, }; /* Unit descriptor parameters offsets in bytes*/ @@ -274,6 +276,15 @@ enum geometry_desc_param { GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44, }; +/* Health descriptor parameters offsets in bytes*/ +enum health_desc_param { + HEALTH_DESC_PARAM_LEN = 0x0, + HEALTH_DESC_PARAM_TYPE = 0x1, + HEALTH_DESC_PARAM_EOL_INFO = 0x2, + HEALTH_DESC_PARAM_LIFE_TIME_EST_A = 0x3, + HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4, +}; + /* * Logical Unit Write Protect * 00h: LU not write protected diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 540a431e38ce..b88fcf7be47b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2966,6 +2966,9 @@ int ufshcd_map_desc_id_to_length(struct ufs_hba *hba, case QUERY_DESC_IDN_STRING: *desc_len = QUERY_DESC_MAX_SIZE; break; + case QUERY_DESC_IDN_HEALTH: + *desc_len = hba->desc_size.hlth_desc; + break; case QUERY_DESC_IDN_RFU_0: case QUERY_DESC_IDN_RFU_1: *desc_len = 0; @@ -6277,6 +6280,10 @@ static void ufshcd_init_desc_sizes(struct ufs_hba *hba) &hba->desc_size.geom_desc); if (err) hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; + err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_HEALTH, 0, + &hba->desc_size.hlth_desc); + if (err) + hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE; } static void ufshcd_def_desc_sizes(struct ufs_hba *hba) @@ -6287,6 +6294,7 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba) hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE; hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE; hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; + hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE; } /** diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 38c307d053c7..515c6e6244be 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -229,6 +229,7 @@ struct ufs_desc_size { int interc_desc; int unit_desc; int conf_desc; + int hlth_desc; }; /** -- cgit v1.2.3 From c2e6e283c52f3a2c4a99774b36bcc88e7cbd5eb7 Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:06 +0200 Subject: scsi: ufs: sysfs: power descriptor This patch introduces a sysfs group entry for the UFS power descriptor parameters. The group adds "power_descriptor" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The parameters are shown as hexadecimal numbers. The full information about the parameters could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 10 +++ drivers/scsi/ufs/ufs-sysfs.c | 117 +++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index ddb012b05f0d..7460566f557d 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -441,3 +441,13 @@ Description: This file shows indication of the device life time parameters. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/power_descriptor/active_icc_levels_vcc* +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows maximum VCC, VCCQ and VCCQ2 value for + active ICC levels from 0 to 15. This is one of the UFS + power descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index c4f18b0970db..16e357a95b6b 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -368,12 +368,129 @@ static const struct attribute_group ufs_sysfs_health_descriptor_group = { .attrs = ufs_sysfs_health_descriptor, }; +#define UFS_POWER_DESC_PARAM(_name, _uname, _index) \ +static ssize_t _name##_index##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct ufs_hba *hba = dev_get_drvdata(dev); \ + return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_POWER, 0, \ + PWR_DESC##_uname##_0 + _index * 2, buf, 2); \ +} \ +static DEVICE_ATTR_RO(_name##_index) + +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 0); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 1); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 2); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 3); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 4); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 5); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 6); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 7); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 8); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 9); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 10); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 11); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 12); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 13); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 14); +UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 15); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 0); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 1); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 2); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 3); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 4); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 5); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 6); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 7); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 8); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 9); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 10); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 11); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 12); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 13); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 14); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 15); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 0); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 1); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 2); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 3); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 4); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 5); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 6); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 7); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 8); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 9); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 10); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 11); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 12); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 13); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 14); +UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 15); + +static struct attribute *ufs_sysfs_power_descriptor[] = { + &dev_attr_active_icc_levels_vcc0.attr, + &dev_attr_active_icc_levels_vcc1.attr, + &dev_attr_active_icc_levels_vcc2.attr, + &dev_attr_active_icc_levels_vcc3.attr, + &dev_attr_active_icc_levels_vcc4.attr, + &dev_attr_active_icc_levels_vcc5.attr, + &dev_attr_active_icc_levels_vcc6.attr, + &dev_attr_active_icc_levels_vcc7.attr, + &dev_attr_active_icc_levels_vcc8.attr, + &dev_attr_active_icc_levels_vcc9.attr, + &dev_attr_active_icc_levels_vcc10.attr, + &dev_attr_active_icc_levels_vcc11.attr, + &dev_attr_active_icc_levels_vcc12.attr, + &dev_attr_active_icc_levels_vcc13.attr, + &dev_attr_active_icc_levels_vcc14.attr, + &dev_attr_active_icc_levels_vcc15.attr, + &dev_attr_active_icc_levels_vccq0.attr, + &dev_attr_active_icc_levels_vccq1.attr, + &dev_attr_active_icc_levels_vccq2.attr, + &dev_attr_active_icc_levels_vccq3.attr, + &dev_attr_active_icc_levels_vccq4.attr, + &dev_attr_active_icc_levels_vccq5.attr, + &dev_attr_active_icc_levels_vccq6.attr, + &dev_attr_active_icc_levels_vccq7.attr, + &dev_attr_active_icc_levels_vccq8.attr, + &dev_attr_active_icc_levels_vccq9.attr, + &dev_attr_active_icc_levels_vccq10.attr, + &dev_attr_active_icc_levels_vccq11.attr, + &dev_attr_active_icc_levels_vccq12.attr, + &dev_attr_active_icc_levels_vccq13.attr, + &dev_attr_active_icc_levels_vccq14.attr, + &dev_attr_active_icc_levels_vccq15.attr, + &dev_attr_active_icc_levels_vccq20.attr, + &dev_attr_active_icc_levels_vccq21.attr, + &dev_attr_active_icc_levels_vccq22.attr, + &dev_attr_active_icc_levels_vccq23.attr, + &dev_attr_active_icc_levels_vccq24.attr, + &dev_attr_active_icc_levels_vccq25.attr, + &dev_attr_active_icc_levels_vccq26.attr, + &dev_attr_active_icc_levels_vccq27.attr, + &dev_attr_active_icc_levels_vccq28.attr, + &dev_attr_active_icc_levels_vccq29.attr, + &dev_attr_active_icc_levels_vccq210.attr, + &dev_attr_active_icc_levels_vccq211.attr, + &dev_attr_active_icc_levels_vccq212.attr, + &dev_attr_active_icc_levels_vccq213.attr, + &dev_attr_active_icc_levels_vccq214.attr, + &dev_attr_active_icc_levels_vccq215.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_power_descriptor_group = { + .name = "power_descriptor", + .attrs = ufs_sysfs_power_descriptor, +}; + static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, &ufs_sysfs_device_descriptor_group, &ufs_sysfs_interconnect_descriptor_group, &ufs_sysfs_geometry_descriptor_group, &ufs_sysfs_health_descriptor_group, + &ufs_sysfs_power_descriptor_group, NULL, }; -- cgit v1.2.3 From 2238d31cdeabc585de5869efd11856815aa4dd13 Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:07 +0200 Subject: scsi: ufs: sysfs: string descriptors This patch introduces a sysfs group entry for the UFS string descriptors. The group adds "string_descriptors" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The folder will contain 5 files that will show string values defined by the UFS spec: a manufacturer name, a product name, an OEM id, a serial number and a product revision. The full information about the string descriptors could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 39 +++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 56 ++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd.c | 14 ++++---- drivers/scsi/ufs/ufshcd.h | 9 +++++ 4 files changed, 111 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 7460566f557d..c17a9685048b 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -451,3 +451,42 @@ Description: This file shows maximum VCC, VCCQ and VCCQ2 value for power descriptor parameters. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/manufacturer_name +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file contains a device manufactureer name string. + The full information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_name +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file contains a product name string. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/oem_id +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file contains a OEM ID string. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/serial_number +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file contains a device serial number string. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_revision +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file contains a product revision string. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 16e357a95b6b..c1aeb8aa3160 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -484,6 +484,61 @@ static const struct attribute_group ufs_sysfs_power_descriptor_group = { .attrs = ufs_sysfs_power_descriptor, }; +#define UFS_STRING_DESCRIPTOR(_name, _pname) \ +static ssize_t _name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + u8 index; \ + struct ufs_hba *hba = dev_get_drvdata(dev); \ + int ret; \ + int desc_len = QUERY_DESC_MAX_SIZE; \ + u8 *desc_buf; \ + desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_ATOMIC); \ + if (!desc_buf) \ + return -ENOMEM; \ + ret = ufshcd_query_descriptor_retry(hba, \ + UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE, \ + 0, 0, desc_buf, &desc_len); \ + if (ret) { \ + ret = -EINVAL; \ + goto out; \ + } \ + index = desc_buf[DEVICE_DESC_PARAM##_pname]; \ + memset(desc_buf, 0, QUERY_DESC_MAX_SIZE); \ + if (ufshcd_read_string_desc(hba, index, desc_buf, \ + QUERY_DESC_MAX_SIZE, true)) { \ + ret = -EINVAL; \ + goto out; \ + } \ + ret = snprintf(buf, PAGE_SIZE, "%s\n", \ + desc_buf + QUERY_DESC_HDR_SIZE); \ +out: \ + kfree(desc_buf); \ + return ret; \ +} \ +static DEVICE_ATTR_RO(_name) + +UFS_STRING_DESCRIPTOR(manufacturer_name, _MANF_NAME); +UFS_STRING_DESCRIPTOR(product_name, _PRDCT_NAME); +UFS_STRING_DESCRIPTOR(oem_id, _OEM_ID); +UFS_STRING_DESCRIPTOR(serial_number, _SN); +UFS_STRING_DESCRIPTOR(product_revision, _PRDCT_REV); + +static struct attribute *ufs_sysfs_string_descriptors[] = { + &dev_attr_manufacturer_name.attr, + &dev_attr_product_name.attr, + &dev_attr_oem_id.attr, + &dev_attr_serial_number.attr, + &dev_attr_product_revision.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_string_descriptors_group = { + .name = "string_descriptors", + .attrs = ufs_sysfs_string_descriptors, +}; + + static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, &ufs_sysfs_device_descriptor_group, @@ -491,6 +546,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_geometry_descriptor_group, &ufs_sysfs_health_descriptor_group, &ufs_sysfs_power_descriptor_group, + &ufs_sysfs_string_descriptors_group, NULL, }; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b88fcf7be47b..9cfdd8ed198a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2873,11 +2873,11 @@ out: * The buf_len parameter will contain, on return, the length parameter * received on the response. */ -static int ufshcd_query_descriptor_retry(struct ufs_hba *hba, - enum query_opcode opcode, - enum desc_idn idn, u8 index, - u8 selector, - u8 *desc_buf, int *buf_len) +int ufshcd_query_descriptor_retry(struct ufs_hba *hba, + enum query_opcode opcode, + enum desc_idn idn, u8 index, + u8 selector, + u8 *desc_buf, int *buf_len) { int err; int retries; @@ -3093,8 +3093,8 @@ static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size) * Return 0 in case of success, non-zero otherwise */ #define ASCII_STD true -static int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, - u8 *buf, u32 size, bool ascii) +int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, + u8 *buf, u32 size, bool ascii) { int err = 0; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 515c6e6244be..2dad9dada86a 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -842,6 +842,12 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info) } /* Expose Query-Request API */ +int ufshcd_query_descriptor_retry(struct ufs_hba *hba, + enum query_opcode opcode, + enum desc_idn idn, u8 index, + u8 selector, + u8 *desc_buf, int *buf_len); + int ufshcd_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, int desc_index, @@ -850,6 +856,9 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, u8 param_size); int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, enum flag_idn idn, bool *flag_res); +int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, + u8 *buf, u32 size, bool ascii); + int ufshcd_hold(struct ufs_hba *hba, bool async); void ufshcd_release(struct ufs_hba *hba); -- cgit v1.2.3 From d829fc8a1058851f1058b4a29ea02da125c1684a Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:09 +0200 Subject: scsi: ufs: sysfs: unit descriptor This patch introduces a sysfs group entry for the UFS unit descriptor parameters. The group adds "unit_descriptor" folder under the corresponding SCSI device sysfs entry (/sys/class/scsi_device/*/device/). The parameters are shown as hexadecimal numbers. The full information about the parameters could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 108 +++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 53 ++++++++++++++ drivers/scsi/ufs/ufs-sysfs.h | 2 + drivers/scsi/ufs/ufs.h | 11 +++ drivers/scsi/ufs/ufshcd.c | 23 ++---- drivers/scsi/ufs/ufshcd.h | 15 ++++ 6 files changed, 196 insertions(+), 16 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index c17a9685048b..57c6a9028108 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -490,3 +490,111 @@ Description: This file contains a product revision string. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/class/scsi_device/*/device/unit_descriptor/boot_lun_id +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows boot LUN information. This is one of + the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/lun_write_protect +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows LUN write protection status. This is one of + the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/lun_queue_depth +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows LUN queue depth. This is one of the UFS + unit descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/psa_sensitive +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows PSA sensitivity. This is one of the UFS + unit descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/lun_memory_type +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows LUN memory type. This is one of the UFS + unit descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/data_reliability +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file defines the device behavior when a power failure + occurs during a write operation. This is one of the UFS + unit descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/logical_block_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the size of addressable logical blocks + (calculated as an exponent with base 2). This is one of + the UFS unit descriptor parameters. The full information about + the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/logical_block_count +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows total number of addressable logical blocks. + This is one of the UFS unit descriptor parameters. The full + information about the descriptor could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/erase_block_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the erase block size. This is one of + the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/provisioning_type +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the thin provisioning type. This is one of + the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resourse_count +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the total physical memory resources. This is + one of the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/context_capabilities +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the context capabilities. This is one of + the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/large_unit_granularity +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the granularity of the LUN. This is one of + the UFS unit descriptor parameters. The full information + about the descriptor could be found at UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index c1aeb8aa3160..cd4d9d039ee9 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -550,6 +550,59 @@ static const struct attribute_group *ufs_sysfs_groups[] = { NULL, }; +#define UFS_LUN_DESC_PARAM(_pname, _puname, _duname, _size) \ +static ssize_t _pname##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct ufs_hba *hba = shost_priv(sdev->host); \ + u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); \ + if (!ufs_is_valid_unit_desc_lun(lun)) \ + return -EINVAL; \ + return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname, \ + lun, _duname##_DESC_PARAM##_puname, buf, _size); \ +} \ +static DEVICE_ATTR_RO(_pname) + +#define UFS_UNIT_DESC_PARAM(_name, _uname, _size) \ + UFS_LUN_DESC_PARAM(_name, _uname, UNIT, _size) + +UFS_UNIT_DESC_PARAM(boot_lun_id, _BOOT_LUN_ID, 1); +UFS_UNIT_DESC_PARAM(lun_write_protect, _LU_WR_PROTECT, 1); +UFS_UNIT_DESC_PARAM(lun_queue_depth, _LU_Q_DEPTH, 1); +UFS_UNIT_DESC_PARAM(psa_sensitive, _PSA_SENSITIVE, 1); +UFS_UNIT_DESC_PARAM(lun_memory_type, _MEM_TYPE, 1); +UFS_UNIT_DESC_PARAM(data_reliability, _DATA_RELIABILITY, 1); +UFS_UNIT_DESC_PARAM(logical_block_size, _LOGICAL_BLK_SIZE, 1); +UFS_UNIT_DESC_PARAM(logical_block_count, _LOGICAL_BLK_COUNT, 8); +UFS_UNIT_DESC_PARAM(erase_block_size, _ERASE_BLK_SIZE, 4); +UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1); +UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8); +UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2); +UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1); + +static struct attribute *ufs_sysfs_unit_descriptor[] = { + &dev_attr_boot_lun_id.attr, + &dev_attr_lun_write_protect.attr, + &dev_attr_lun_queue_depth.attr, + &dev_attr_psa_sensitive.attr, + &dev_attr_lun_memory_type.attr, + &dev_attr_data_reliability.attr, + &dev_attr_logical_block_size.attr, + &dev_attr_logical_block_count.attr, + &dev_attr_erase_block_size.attr, + &dev_attr_provisioning_type.attr, + &dev_attr_physical_memory_resourse_count.attr, + &dev_attr_context_capabilities.attr, + &dev_attr_large_unit_granularity.attr, + NULL, +}; + +const struct attribute_group ufs_sysfs_unit_descriptor_group = { + .name = "unit_descriptor", + .attrs = ufs_sysfs_unit_descriptor, +}; + void ufs_sysfs_add_nodes(struct device *dev) { int ret; diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h index ce58861f548a..2afce169a9f0 100644 --- a/drivers/scsi/ufs/ufs-sysfs.h +++ b/drivers/scsi/ufs/ufs-sysfs.h @@ -11,4 +11,6 @@ void ufs_sysfs_add_nodes(struct device *dev); void ufs_sysfs_remove_nodes(struct device *dev); + +extern const struct attribute_group ufs_sysfs_unit_descriptor_group; #endif diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 6bfeedb934f1..73870597e34c 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -182,6 +182,7 @@ enum unit_desc_param { UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4, UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5, UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6, + UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7, UNIT_DESC_PARAM_MEM_TYPE = 0x8, UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9, UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA, @@ -592,4 +593,14 @@ struct ufs_dev_desc { char model[MAX_MODEL_LEN + 1]; }; +/** + * ufs_is_valid_unit_desc_lun - checks if the given LUN has a unit descriptor + * @lun: LU number to check + * @return: true if the lun has a matching unit descriptor, false otherwise + */ +static inline bool ufs_is_valid_unit_desc_lun(u8 lun) +{ + return lun == UFS_UPIU_RPMB_WLUN || (lun < UFS_UPIU_MAX_GENERAL_LUN); +} + #endif /* End of Header */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9cfdd8ed198a..ace3acdc9a5b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2222,21 +2222,6 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) return ret; } -/* - * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN - * @scsi_lun: scsi LUN id - * - * Returns UPIU LUN id - */ -static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) -{ - if (scsi_is_wlun(scsi_lun)) - return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID) - | UFS_UPIU_WLUN_ID; - else - return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID; -} - /** * ufshcd_upiu_wlun_to_scsi_wlun - maps UPIU W-LUN id to SCSI W-LUN ID * @scsi_lun: UPIU W-LUN id @@ -3171,7 +3156,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba, * Unit descriptors are only available for general purpose LUs (LUN id * from 0 to 7) and RPMB Well known LU. */ - if (lun != UFS_UPIU_RPMB_WLUN && (lun >= UFS_UPIU_MAX_GENERAL_LUN)) + if (!ufs_is_valid_unit_desc_lun(lun)) return -EOPNOTSUPP; return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun, @@ -6481,6 +6466,11 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd) return found ? BLK_EH_NOT_HANDLED : BLK_EH_RESET_TIMER; } +static const struct attribute_group *ufshcd_driver_groups[] = { + &ufs_sysfs_unit_descriptor_group, + NULL, +}; + static struct scsi_host_template ufshcd_driver_template = { .module = THIS_MODULE, .name = UFSHCD, @@ -6500,6 +6490,7 @@ static struct scsi_host_template ufshcd_driver_template = { .can_queue = UFSHCD_CAN_QUEUE, .max_host_blocked = 1, .track_queue_depth = 1, + .sdev_groups = ufshcd_driver_groups, }; static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 2dad9dada86a..f4cb31b23728 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1003,4 +1003,19 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba) extern struct ufs_pm_lvl_states ufs_pm_lvl_states[]; +/* + * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN + * @scsi_lun: scsi LUN id + * + * Returns UPIU LUN id + */ +static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) +{ + if (scsi_is_wlun(scsi_lun)) + return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID) + | UFS_UPIU_WLUN_ID; + else + return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID; +} + #endif /* End of Header */ -- cgit v1.2.3 From d10b2a8ea8fd0d6c8a667dc1950c8c061bfbbcdd Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:10 +0200 Subject: scsi: ufs: sysfs: flags This patch introduces a sysfs group entry for the UFS flags. The group adds "flags" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The flags are shown as boolean value ("true" or "false"). The full information about the UFS flags could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 65 ++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 39 ++++++++++++++++++ drivers/scsi/ufs/ufs.h | 14 +++++-- 3 files changed, 115 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 57c6a9028108..f4f49e29e225 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -598,3 +598,68 @@ Description: This file shows the granularity of the LUN. This is one of the UFS unit descriptor parameters. The full information about the descriptor could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/flags/device_init +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the device init status. The full information + about the flag could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/permanent_wpe +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether permanent write protection is enabled. + The full information about the flag could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/power_on_wpe +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether write protection is enabled on all + logical units configured as power on write protected. The + full information about the flag could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/bkops_enable +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether the device background operations are + enabled. The full information about the flag could be + found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/life_span_mode_enable +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether the device life span mode is enabled. + The full information about the flag could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/phy_resource_removal +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether physical resource removal is enable. + The full information about the flag could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/busy_rtc +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether the device is executing internal + operation related to real time clock. The full information + about the flag could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/disable_fw_update +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether the device FW update is permanently + disabled. The full information about the flag could be found + at UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index cd4d9d039ee9..a09a8a2ed46c 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -538,6 +538,44 @@ static const struct attribute_group ufs_sysfs_string_descriptors_group = { .attrs = ufs_sysfs_string_descriptors, }; +#define UFS_FLAG(_name, _uname) \ +static ssize_t _name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + bool flag; \ + struct ufs_hba *hba = dev_get_drvdata(dev); \ + if (ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG, \ + QUERY_FLAG_IDN##_uname, &flag)) \ + return -EINVAL; \ + return sprintf(buf, "%s\n", flag ? "true" : "false"); \ +} \ +static DEVICE_ATTR_RO(_name) + +UFS_FLAG(device_init, _FDEVICEINIT); +UFS_FLAG(permanent_wpe, _PERMANENT_WPE); +UFS_FLAG(power_on_wpe, _PWR_ON_WPE); +UFS_FLAG(bkops_enable, _BKOPS_EN); +UFS_FLAG(life_span_mode_enable, _LIFE_SPAN_MODE_ENABLE); +UFS_FLAG(phy_resource_removal, _FPHYRESOURCEREMOVAL); +UFS_FLAG(busy_rtc, _BUSY_RTC); +UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE); + +static struct attribute *ufs_sysfs_device_flags[] = { + &dev_attr_device_init.attr, + &dev_attr_permanent_wpe.attr, + &dev_attr_power_on_wpe.attr, + &dev_attr_bkops_enable.attr, + &dev_attr_life_span_mode_enable.attr, + &dev_attr_phy_resource_removal.attr, + &dev_attr_busy_rtc.attr, + &dev_attr_disable_fw_update.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_flags_group = { + .name = "flags", + .attrs = ufs_sysfs_device_flags, +}; static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, @@ -547,6 +585,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_health_descriptor_group, &ufs_sysfs_power_descriptor_group, &ufs_sysfs_string_descriptors_group, + &ufs_sysfs_flags_group, NULL, }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 73870597e34c..df5e73e7de3e 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -130,9 +130,17 @@ enum { /* Flag idn for Query Requests*/ enum flag_idn { - QUERY_FLAG_IDN_FDEVICEINIT = 0x01, - QUERY_FLAG_IDN_PWR_ON_WPE = 0x03, - QUERY_FLAG_IDN_BKOPS_EN = 0x04, + QUERY_FLAG_IDN_FDEVICEINIT = 0x01, + QUERY_FLAG_IDN_PERMANENT_WPE = 0x02, + QUERY_FLAG_IDN_PWR_ON_WPE = 0x03, + QUERY_FLAG_IDN_BKOPS_EN = 0x04, + QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE = 0x05, + QUERY_FLAG_IDN_PURGE_ENABLE = 0x06, + QUERY_FLAG_IDN_RESERVED2 = 0x07, + QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL = 0x08, + QUERY_FLAG_IDN_BUSY_RTC = 0x09, + QUERY_FLAG_IDN_RESERVED3 = 0x0A, + QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE = 0x0B, }; /* Attribute idn for Query requests */ -- cgit v1.2.3 From ec92b59cc03c3d5757449c1c9344524e088df2bd Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 15 Feb 2018 14:14:11 +0200 Subject: scsi: ufs: sysfs: attributes This patch introduces a sysfs group entry for the UFS attributes. The group adds "attributes" folder under the UFS driver sysfs entry (/sys/bus/platform/drivers/ufshcd/*). The attributes are shown as hexadecimal numbers. The full information about the attributes could be found at UFS specifications 2.1. Signed-off-by: Stanislav Nijnikov Reviewed-by: Greg Kroah-Hartman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 139 +++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 80 +++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.h | 1 + drivers/scsi/ufs/ufs.h | 27 +++++- drivers/scsi/ufs/ufshcd.c | 5 +- drivers/scsi/ufs/ufshcd.h | 3 +- 6 files changed, 248 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index f4f49e29e225..07f1c2f8dbfc 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -663,3 +663,142 @@ Description: This file shows whether the device FW update is permanently disabled. The full information about the flag could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/boot_lun_enabled +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the boot lun enabled UFS device attribute. + The full information about the attribute could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/current_power_mode +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the current power mode UFS device attribute. + The full information about the attribute could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/active_icc_level +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the active icc level UFS device attribute. + The full information about the attribute could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/ooo_data_enabled +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the out of order data transfer enabled UFS + device attribute. The full information about the attribute + could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/bkops_status +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the background operations status UFS device + attribute. The full information about the attribute could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/purge_status +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the purge operation status UFS device + attribute. The full information about the attribute could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_in_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum data size in a DATA IN + UPIU. The full information about the attribute could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_out_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the maximum number of bytes that can be + requested with a READY TO TRANSFER UPIU. The full information + about the attribute could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/reference_clock_frequency +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the reference clock frequency UFS device + attribute. The full information about the attribute could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/configuration_descriptor_lock +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows whether the configuration descriptor is locked. + The full information about the attribute could be found at + UFS specifications 2.1. The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_number_of_rtt +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the maximum current number of + outstanding RTTs in device that is allowed. The full + information about the attribute could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_control +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the exception event control UFS device + attribute. The full information about the attribute could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_status +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the exception event status UFS device + attribute. The full information about the attribute could + be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/ffu_status +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file provides the ffu status UFS device attribute. + The full information about the attribute could be found at + UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/psa_state +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file show the PSA feature status. The full information + about the attribute could be found at UFS specifications 2.1. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/psa_data_size +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the amount of data that the host plans to + load to all logical units in pre-soldering state. + The full information about the attribute could be found at + UFS specifications 2.1. + The file is read only. + + +What: /sys/class/scsi_device/*/device/dyn_cap_needed +Date: February 2018 +Contact: Stanislav Nijnikov +Description: This file shows the The amount of physical memory needed + to be removed from the physical memory resources pool of + the particular logical unit. The full information about + the attribute could be found at UFS specifications 2.1. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index a09a8a2ed46c..cd7174d2d225 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -577,6 +577,61 @@ static const struct attribute_group ufs_sysfs_flags_group = { .attrs = ufs_sysfs_device_flags, }; +#define UFS_ATTRIBUTE(_name, _uname) \ +static ssize_t _name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct ufs_hba *hba = dev_get_drvdata(dev); \ + u32 value; \ + if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, \ + QUERY_ATTR_IDN##_uname, 0, 0, &value)) \ + return -EINVAL; \ + return sprintf(buf, "0x%08X\n", value); \ +} \ +static DEVICE_ATTR_RO(_name) + +UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN); +UFS_ATTRIBUTE(current_power_mode, _POWER_MODE); +UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL); +UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN); +UFS_ATTRIBUTE(bkops_status, _BKOPS_STATUS); +UFS_ATTRIBUTE(purge_status, _PURGE_STATUS); +UFS_ATTRIBUTE(max_data_in_size, _MAX_DATA_IN); +UFS_ATTRIBUTE(max_data_out_size, _MAX_DATA_OUT); +UFS_ATTRIBUTE(reference_clock_frequency, _REF_CLK_FREQ); +UFS_ATTRIBUTE(configuration_descriptor_lock, _CONF_DESC_LOCK); +UFS_ATTRIBUTE(max_number_of_rtt, _MAX_NUM_OF_RTT); +UFS_ATTRIBUTE(exception_event_control, _EE_CONTROL); +UFS_ATTRIBUTE(exception_event_status, _EE_STATUS); +UFS_ATTRIBUTE(ffu_status, _FFU_STATUS); +UFS_ATTRIBUTE(psa_state, _PSA_STATE); +UFS_ATTRIBUTE(psa_data_size, _PSA_DATA_SIZE); + +static struct attribute *ufs_sysfs_attributes[] = { + &dev_attr_boot_lun_enabled.attr, + &dev_attr_current_power_mode.attr, + &dev_attr_active_icc_level.attr, + &dev_attr_ooo_data_enabled.attr, + &dev_attr_bkops_status.attr, + &dev_attr_purge_status.attr, + &dev_attr_max_data_in_size.attr, + &dev_attr_max_data_out_size.attr, + &dev_attr_reference_clock_frequency.attr, + &dev_attr_configuration_descriptor_lock.attr, + &dev_attr_max_number_of_rtt.attr, + &dev_attr_exception_event_control.attr, + &dev_attr_exception_event_status.attr, + &dev_attr_ffu_status.attr, + &dev_attr_psa_state.attr, + &dev_attr_psa_data_size.attr, + NULL, +}; + +static const struct attribute_group ufs_sysfs_attributes_group = { + .name = "attributes", + .attrs = ufs_sysfs_attributes, +}; + static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, &ufs_sysfs_device_descriptor_group, @@ -586,6 +641,7 @@ static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_power_descriptor_group, &ufs_sysfs_string_descriptors_group, &ufs_sysfs_flags_group, + &ufs_sysfs_attributes_group, NULL, }; @@ -642,6 +698,30 @@ const struct attribute_group ufs_sysfs_unit_descriptor_group = { .attrs = ufs_sysfs_unit_descriptor, }; +static ssize_t dyn_cap_needed_attribute_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 value; + struct scsi_device *sdev = to_scsi_device(dev); + struct ufs_hba *hba = shost_priv(sdev->host); + u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); + + if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, + QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value)) + return -EINVAL; + return sprintf(buf, "0x%08X\n", value); +} +static DEVICE_ATTR_RO(dyn_cap_needed_attribute); + +static struct attribute *ufs_sysfs_lun_attributes[] = { + &dev_attr_dyn_cap_needed_attribute.attr, + NULL, +}; + +const struct attribute_group ufs_sysfs_lun_attributes_group = { + .attrs = ufs_sysfs_lun_attributes, +}; + void ufs_sysfs_add_nodes(struct device *dev) { int ret; diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h index 2afce169a9f0..e5621e59a432 100644 --- a/drivers/scsi/ufs/ufs-sysfs.h +++ b/drivers/scsi/ufs/ufs-sysfs.h @@ -13,4 +13,5 @@ void ufs_sysfs_add_nodes(struct device *dev); void ufs_sysfs_remove_nodes(struct device *dev); extern const struct attribute_group ufs_sysfs_unit_descriptor_group; +extern const struct attribute_group ufs_sysfs_lun_attributes_group; #endif diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index df5e73e7de3e..14e5bf7af0bb 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -145,10 +145,29 @@ enum flag_idn { /* Attribute idn for Query requests */ enum attr_idn { - QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, - QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, - QUERY_ATTR_IDN_EE_CONTROL = 0x0D, - QUERY_ATTR_IDN_EE_STATUS = 0x0E, + QUERY_ATTR_IDN_BOOT_LU_EN = 0x00, + QUERY_ATTR_IDN_RESERVED = 0x01, + QUERY_ATTR_IDN_POWER_MODE = 0x02, + QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, + QUERY_ATTR_IDN_OOO_DATA_EN = 0x04, + QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, + QUERY_ATTR_IDN_PURGE_STATUS = 0x06, + QUERY_ATTR_IDN_MAX_DATA_IN = 0x07, + QUERY_ATTR_IDN_MAX_DATA_OUT = 0x08, + QUERY_ATTR_IDN_DYN_CAP_NEEDED = 0x09, + QUERY_ATTR_IDN_REF_CLK_FREQ = 0x0A, + QUERY_ATTR_IDN_CONF_DESC_LOCK = 0x0B, + QUERY_ATTR_IDN_MAX_NUM_OF_RTT = 0x0C, + QUERY_ATTR_IDN_EE_CONTROL = 0x0D, + QUERY_ATTR_IDN_EE_STATUS = 0x0E, + QUERY_ATTR_IDN_SECONDS_PASSED = 0x0F, + QUERY_ATTR_IDN_CNTX_CONF = 0x10, + QUERY_ATTR_IDN_CORR_PRG_BLK_NUM = 0x11, + QUERY_ATTR_IDN_RESERVED2 = 0x12, + QUERY_ATTR_IDN_RESERVED3 = 0x13, + QUERY_ATTR_IDN_FFU_STATUS = 0x14, + QUERY_ATTR_IDN_PSA_STATE = 0x15, + QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16, }; /* Descriptor idn for Query requests */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ace3acdc9a5b..1fbb17bb175b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2689,8 +2689,8 @@ out_unlock: * * Returns 0 for success, non-zero in case of failure */ -static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, - enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) +int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, + enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) { struct ufs_query_req *request = NULL; struct ufs_query_res *response = NULL; @@ -6468,6 +6468,7 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd) static const struct attribute_group *ufshcd_driver_groups[] = { &ufs_sysfs_unit_descriptor_group, + &ufs_sysfs_lun_attributes_group, NULL, }; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index f4cb31b23728..deb3c5d382e9 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -847,13 +847,14 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba, enum desc_idn idn, u8 index, u8 selector, u8 *desc_buf, int *buf_len); - int ufshcd_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, int desc_index, u8 param_offset, u8 *param_read_buf, u8 param_size); +int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, + enum attr_idn idn, u8 index, u8 selector, u32 *attr_val); int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, enum flag_idn idn, bool *flag_res); int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, -- cgit v1.2.3 From 18d595bf9de99a0f092d8522da42df8b09ef5c2f Mon Sep 17 00:00:00 2001 From: Weiping Zhang Date: Mon, 26 Feb 2018 22:08:28 +0800 Subject: scsi: sd: Documentation: add sd-parameters.txt Add a file for documenting SCSI sd module parameters and describe the cache_type setting. [mkp: tweaked text a bit] Signed-off-by: Weiping Zhang Signed-off-by: Martin K. Petersen --- Documentation/scsi/sd-parameters.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/scsi/sd-parameters.txt (limited to 'Documentation') diff --git a/Documentation/scsi/sd-parameters.txt b/Documentation/scsi/sd-parameters.txt new file mode 100644 index 000000000000..8e5af00d88e7 --- /dev/null +++ b/Documentation/scsi/sd-parameters.txt @@ -0,0 +1,22 @@ +Linux SCSI Disk Driver (sd) Parameters +====================================== + +cache_type (RW) +--------------- +Enable/disable drive write & read cache. + + cache_type string | WCE RCD | Write cache | Read cache +----------------------------+---------+-------------+------------ + write through | 0 0 | off | on + none | 0 1 | off | off + write back | 1 0 | on | on + write back, no read (daft) | 1 1 | on | off + +To set cache type to "write back" and save this setting to the drive: + + # echo "write back" > cache_type + +To modify the caching mode without making the change persistent, prepend +"temporary " to the cache type string. E.g.: + + # echo "temporary write back" > cache_type -- cgit v1.2.3 From 4c40db995eb54c3ee8cb5a8340640f49395d5f9e Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Wed, 7 Mar 2018 20:25:05 +0800 Subject: scsi: hisi_sas: dt-bindings: add an property of signal attenuation For some new boards with hip07 chipset we are required to set PHY config registers differently. The hw property which determines how to set these registers is in the PHY signal attenuation readings. This patch add an devicetree property, "hisilicon,signal-attenuation", which is used to describe the signal attenuation of an board. Cc: Rob Herring Cc: Mark Rutland Signed-off-by: Xiaofei Tan Signed-off-by: John Garry Reviewed-by: Rob Herring Signed-off-by: Martin K. Petersen --- Documentation/devicetree/bindings/scsi/hisilicon-sas.txt | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt index df3bef7998fa..8c6659ed2cfc 100644 --- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt @@ -53,6 +53,13 @@ Main node required properties: Optional main node properties: - hip06-sas-v2-quirk-amt : when set, indicates that the v2 controller has the "am-max-transmissions" limitation. + - hisilicon,signal-attenuation : array of 3 32-bit values, containing de-emphasis, + preshoot, and boost attenuation readings for the board. They + are used to describe the signal attenuation of the board. These + values' range is 7600 to 12400, and used to represent -24dB to + 24dB. + The formula is "y = (x-10000)/10000". For example, 10478 + means 4.78dB. Example: sas0: sas@c1000000 { -- cgit v1.2.3 From 6b1745caa14ae0afccf1c6ee4c814fd8d5df3dcd Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 13 Mar 2018 15:06:22 -0400 Subject: scsi: eata: eata-pio: Deprecate legacy EATA drivers These two drivers do not appear to be in active use. Deprecate them. Suggested-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- Documentation/scsi/scsi-parameters.txt | 2 - MAINTAINERS | 6 - drivers/scsi/Kconfig | 62 - drivers/scsi/Makefile | 2 - drivers/scsi/eata.c | 2571 -------------------------------- drivers/scsi/eata_generic.h | 401 ----- drivers/scsi/eata_pio.c | 966 ------------ drivers/scsi/eata_pio.h | 54 - 8 files changed, 4064 deletions(-) delete mode 100644 drivers/scsi/eata.c delete mode 100644 drivers/scsi/eata_generic.h delete mode 100644 drivers/scsi/eata_pio.c delete mode 100644 drivers/scsi/eata_pio.h (limited to 'Documentation') diff --git a/Documentation/scsi/scsi-parameters.txt b/Documentation/scsi/scsi-parameters.txt index 453d4b79c78d..8f7be8a05642 100644 --- a/Documentation/scsi/scsi-parameters.txt +++ b/Documentation/scsi/scsi-parameters.txt @@ -34,8 +34,6 @@ parameters may be changed at runtime by the command See drivers/scsi/BusLogic.c, comment before function BusLogic_ParseDriverOptions(). - eata= [HW,SCSI] - fdomain= [HW,SCSI] See header of drivers/scsi/fdomain.c. diff --git a/MAINTAINERS b/MAINTAINERS index 3bdc260e36b7..36eb73238cf5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5003,12 +5003,6 @@ T: git git://linuxtv.org/anttip/media_tree.git S: Maintained F: drivers/media/tuners/e4000* -EATA ISA/EISA/PCI SCSI DRIVER -M: Dario Ballabio -L: linux-scsi@vger.kernel.org -S: Maintained -F: drivers/scsi/eata.c - EC100 MEDIA DRIVER M: Antti Palosaari L: linux-media@vger.kernel.org diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 8647ca9199b3..b18dfa1c14a1 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -640,68 +640,6 @@ config SCSI_DMX3191D To compile this driver as a module, choose M here: the module will be called dmx3191d. -config SCSI_EATA - tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support" - depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API - ---help--- - This driver supports all EATA/DMA-compliant SCSI host adapters. DPT - ISA and all EISA I/O addresses are probed looking for the "EATA" - signature. The addresses of all the PCI SCSI controllers reported - by the PCI subsystem are probed as well. - - You want to read the start of and the - SCSI-HOWTO, available from - . - - To compile this driver as a module, choose M here: the - module will be called eata. - -config SCSI_EATA_TAGGED_QUEUE - bool "enable tagged command queueing" - depends on SCSI_EATA - help - This is a feature of SCSI-2 which improves performance: the host - adapter can send several SCSI commands to a device's queue even if - previous commands haven't finished yet. - This is equivalent to the "eata=tc:y" boot option. - -config SCSI_EATA_LINKED_COMMANDS - bool "enable elevator sorting" - depends on SCSI_EATA - help - This option enables elevator sorting for all probed SCSI disks and - CD-ROMs. It definitely reduces the average seek distance when doing - random seeks, but this does not necessarily result in a noticeable - performance improvement: your mileage may vary... - This is equivalent to the "eata=lc:y" boot option. - -config SCSI_EATA_MAX_TAGS - int "maximum number of queued commands" - depends on SCSI_EATA - default "16" - help - This specifies how many SCSI commands can be maximally queued for - each probed SCSI device. You should reduce the default value of 16 - only if you have disks with buggy or limited tagged command support. - Minimum is 2 and maximum is 62. This value is also the window size - used by the elevator sorting option above. The effective value used - by the driver for each probed SCSI device is reported at boot time. - This is equivalent to the "eata=mq:8" boot option. - -config SCSI_EATA_PIO - tristate "EATA-PIO (old DPT PM2001, PM2012A) support" - depends on (ISA || EISA || PCI) && SCSI && BROKEN - ---help--- - This driver supports all EATA-PIO protocol compliant SCSI Host - Adapters like the DPT PM2001 and the PM2012A. EATA-DMA compliant - host adapters could also use this driver but are discouraged from - doing so, since this driver only supports hard disks and lacks - numerous features. You might want to have a look at the SCSI-HOWTO, - available from . - - To compile this driver as a module, choose M here: the - module will be called eata_pio. - config SCSI_FUTURE_DOMAIN tristate "Future Domain 16xx SCSI/AHA-2920A support" depends on (ISA || PCI) && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index fcfd28d2884c..46f1c1033f0e 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -93,8 +93,6 @@ obj-$(CONFIG_SCSI_HPSA) += hpsa.o obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi/ obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o -obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o -obj-$(CONFIG_SCSI_EATA) += eata.o obj-$(CONFIG_SCSI_DC395x) += dc395x.o obj-$(CONFIG_SCSI_AM53C974) += esp_scsi.o am53c974.o obj-$(CONFIG_CXLFLASH) += cxlflash/ diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c deleted file mode 100644 index 6501c330d8c8..000000000000 --- a/drivers/scsi/eata.c +++ /dev/null @@ -1,2571 +0,0 @@ -/* - * eata.c - Low-level driver for EATA/DMA SCSI host adapters. - * - * 03 Jun 2003 Rev. 8.10 for linux-2.5.70 - * + Update for new IRQ API. - * + Use "goto" when appropriate. - * + Drop eata.h. - * + Update for new module_param API. - * + Module parameters can now be specified only in the - * same format as the kernel boot options. - * - * boot option old module param - * ----------- ------------------ - * addr,... io_port=addr,... - * lc:[y|n] linked_comm=[1|0] - * mq:xx max_queue_depth=xx - * tm:[0|1|2] tag_mode=[0|1|2] - * et:[y|n] ext_tran=[1|0] - * rs:[y|n] rev_scan=[1|0] - * ip:[y|n] isa_probe=[1|0] - * ep:[y|n] eisa_probe=[1|0] - * pp:[y|n] pci_probe=[1|0] - * - * A valid example using the new parameter format is: - * modprobe eata "eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n" - * - * which is equivalent to the old format: - * modprobe eata io_port=0x7410,0x230 linked_comm=1 tag_mode=0 \ - * max_queue_depth=4 eisa_probe=0 - * - * 12 Feb 2003 Rev. 8.04 for linux 2.5.60 - * + Release irq before calling scsi_register. - * - * 12 Nov 2002 Rev. 8.02 for linux 2.5.47 - * + Release driver_lock before calling scsi_register. - * - * 11 Nov 2002 Rev. 8.01 for linux 2.5.47 - * + Fixed bios_param and scsicam_bios_param calling parameters. - * - * 28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4 - * + Use new tcq and adjust_queue_depth api. - * + New command line option (tm:[0-2]) to choose the type of tags: - * 0 -> disable tagging ; 1 -> simple tags ; 2 -> ordered tags. - * Default is tm:0 (tagged commands disabled). - * For compatibility the "tc:" option is an alias of the "tm:" - * option; tc:n is equivalent to tm:0 and tc:y is equivalent to - * tm:1. - * + The tagged_comm module parameter has been removed, use tag_mode - * instead, equivalent to the "tm:" boot option. - * - * 10 Oct 2002 Rev. 7.70 for linux 2.5.42 - * + Foreport from revision 6.70. - * - * 25 Jun 2002 Rev. 6.70 for linux 2.4.19 - * + This release is the first one tested on a Big Endian platform: - * fixed endian-ness problem due to bitfields; - * fixed endian-ness problem in read_pio. - * + Added new options for selectively probing ISA, EISA and PCI bus: - * - * Boot option Parameter name Default according to - * - * ip:[y|n] isa_probe=[1|0] CONFIG_ISA defined - * ep:[y|n] eisa_probe=[1|0] CONFIG_EISA defined - * pp:[y|n] pci_probe=[1|0] CONFIG_PCI defined - * - * The default action is to perform probing if the corresponding - * bus is configured and to skip probing otherwise. - * - * + If pci_probe is in effect and a list of I/O ports is specified - * as parameter or boot option, pci_enable_device() is performed - * on all pci devices matching PCI_CLASS_STORAGE_SCSI. - * - * 21 Feb 2002 Rev. 6.52 for linux 2.4.18 - * + Backport from rev. 7.22 (use io_request_lock). - * - * 20 Feb 2002 Rev. 7.22 for linux 2.5.5 - * + Remove any reference to virt_to_bus(). - * + Fix pio hang while detecting multiple HBAs. - * + Fixed a board detection bug: in a system with - * multiple ISA/EISA boards, all but the first one - * were erroneously detected as PCI. - * - * 01 Jan 2002 Rev. 7.20 for linux 2.5.1 - * + Use the dynamic DMA mapping API. - * - * 19 Dec 2001 Rev. 7.02 for linux 2.5.1 - * + Use SCpnt->sc_data_direction if set. - * + Use sglist.page instead of sglist.address. - * - * 11 Dec 2001 Rev. 7.00 for linux 2.5.1 - * + Use host->host_lock instead of io_request_lock. - * - * 1 May 2001 Rev. 6.05 for linux 2.4.4 - * + Clean up all pci related routines. - * + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d) - * - * 30 Jan 2001 Rev. 6.04 for linux 2.4.1 - * + Call pci_resource_start after pci_enable_device. - * - * 25 Jan 2001 Rev. 6.03 for linux 2.4.0 - * + "check_region" call replaced by "request_region". - * - * 22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11 - * + Return code checked when calling pci_enable_device. - * + Removed old scsi error handling support. - * + The obsolete boot option flag eh:n is silently ignored. - * + Removed error messages while a disk drive is powered up at - * boot time. - * + Improved boot messages: all tagged capable device are - * indicated as "tagged" or "soft-tagged" : - * - "soft-tagged" means that the driver is trying to do its - * own tagging (i.e. the tc:y option is in effect); - * - "tagged" means that the device supports tagged commands, - * but the driver lets the HBA be responsible for tagging - * support. - * - * 16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18 - * + Updated to the new __setup interface for boot command line options. - * + When loaded as a module, accepts the new parameter boot_options - * which value is a string with the same format of the kernel boot - * command line options. A valid example is: - * modprobe eata 'boot_options="0x7410,0x230,lc:y,tc:n,mq:4"' - * - * 9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17 - * + 64bit cleanup for Linux/Alpha platform support - * (contribution from H.J. Lu). - * - * 22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11 - * + Removed pre-2.2 source code compatibility. - * + Added call to pci_set_master. - * - * 26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111 - * + Added command line option (rs:[y|n]) to reverse the scan order - * of PCI boards. The default is rs:y, which reverses the BIOS order - * while registering PCI boards. The default value rs:y generates - * the same order of all previous revisions of this driver. - * Pls. note that "BIOS order" might have been reversed itself - * after the 2.1.9x PCI modifications in the linux kernel. - * The rs value is ignored when the explicit list of addresses - * is used by the "eata=port0,port1,..." command line option. - * + Added command line option (et:[y|n]) to force use of extended - * translation (255 heads, 63 sectors) as disk geometry. - * The default is et:n, which uses the disk geometry returned - * by scsicam_bios_param. The default value et:n is compatible with - * all previous revisions of this driver. - * - * 28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104 - * Increased busy timeout from 10 msec. to 200 msec. while - * processing interrupts. - * - * 16 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102 - * Improved abort handling during the eh recovery process. - * - * 13 May 1998 Rev. 4.30 for linux 2.0.33 and 2.1.101 - * The driver is now fully SMP safe, including the - * abort and reset routines. - * Added command line options (eh:[y|n]) to choose between - * new_eh_code and the old scsi code. - * If linux version >= 2.1.101 the default is eh:y, while the eh - * option is ignored for previous releases and the old scsi code - * is used. - * - * 18 Apr 1998 Rev. 4.20 for linux 2.0.33 and 2.1.97 - * Reworked interrupt handler. - * - * 11 Apr 1998 rev. 4.05 for linux 2.0.33 and 2.1.95 - * Major reliability improvement: when a batch with overlapping - * requests is detected, requests are queued one at a time - * eliminating any possible board or drive reordering. - * - * 10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95 - * Improved SMP support (if linux version >= 2.1.95). - * - * 9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94 - * Added support for new PCI code and IO-APIC remapping of irqs. - * Performance improvement: when sequential i/o is detected, - * always use direct sort instead of reverse sort. - * - * 4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92 - * io_port is now unsigned long. - * - * 17 Mar 1998 rev. 4.01 for linux 2.0.33 and 2.1.88 - * Use new scsi error handling code (if linux version >= 2.1.88). - * Use new interrupt code. - * - * 12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 - * Use of udelay inside the wait loops to avoid timeout - * problems with fast cpus. - * Removed check about useless calls to the interrupt service - * routine (reported on SMP systems only). - * At initialization time "sorted/unsorted" is displayed instead - * of "linked/unlinked" to reinforce the fact that "linking" is - * nothing but "elevator sorting" in the actual implementation. - * - * 17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 - * Use of serial_number_at_timeout in abort and reset processing. - * Use of the __initfunc and __initdata macro in setup code. - * Minor cleanups in the list_statistics code. - * Increased controller busy timeout in order to better support - * slow SCSI devices. - * - * 24 Feb 1997 rev. 3.00 for linux 2.0.29 and 2.1.26 - * When loading as a module, parameter passing is now supported - * both in 2.0 and in 2.1 style. - * Fixed data transfer direction for some SCSI opcodes. - * Immediate acknowledge to request sense commands. - * Linked commands to each disk device are now reordered by elevator - * sorting. Rare cases in which reordering of write requests could - * cause wrong results are managed. - * Fixed spurious timeouts caused by long simple queue tag sequences. - * New command line option (tm:[0-3]) to choose the type of tags: - * 0 -> mixed (default); 1 -> simple; 2 -> head; 3 -> ordered. - * - * 18 Jan 1997 rev. 2.60 for linux 2.1.21 and 2.0.28 - * Added command line options to enable/disable linked commands - * (lc:[y|n]), tagged commands (tc:[y|n]) and to set the max queue - * depth (mq:xx). Default is "eata=lc:n,tc:n,mq:16". - * Improved command linking. - * Documented how to setup RAID-0 with DPT SmartRAID boards. - * - * 8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 - * Added linked command support. - * Improved detection of PCI boards using ISA base addresses. - * - * 3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 - * Added support for tagged commands and queue depth adjustment. - * - * 22 Nov 1996 rev. 2.30 for linux 2.1.12 and 2.0.26 - * When CONFIG_PCI is defined, BIOS32 is used to include in the - * list of i/o ports to be probed all the PCI SCSI controllers. - * The list of i/o ports to be probed can be overwritten by the - * "eata=port0,port1,...." boot command line option. - * Scatter/gather lists are now allocated by a number of kmalloc - * calls, in order to avoid the previous size limit of 64Kb. - * - * 16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25 - * Added support for EATA 2.0C, PCI, multichannel and wide SCSI. - * - * 27 Sep 1996 rev. 2.12 for linux 2.1.0 - * Portability cleanups (virtual/bus addressing, little/big endian - * support). - * - * 09 Jul 1996 rev. 2.11 for linux 2.0.4 - * Number of internal retries is now limited. - * - * 16 Apr 1996 rev. 2.10 for linux 1.3.90 - * New argument "reset_flags" to the reset routine. - * - * 6 Jul 1995 rev. 2.01 for linux 1.3.7 - * Update required by the new /proc/scsi support. - * - * 11 Mar 1995 rev. 2.00 for linux 1.2.0 - * Fixed a bug which prevented media change detection for removable - * disk drives. - * - * 23 Feb 1995 rev. 1.18 for linux 1.1.94 - * Added a check for scsi_register returning NULL. - * - * 11 Feb 1995 rev. 1.17 for linux 1.1.91 - * Now DEBUG_RESET is disabled by default. - * Register a board even if it does not assert DMA protocol support - * (DPT SK2011B does not report correctly the dmasup bit). - * - * 9 Feb 1995 rev. 1.16 for linux 1.1.90 - * Use host->wish_block instead of host->block. - * New list of Data Out SCSI commands. - * - * 8 Feb 1995 rev. 1.15 for linux 1.1.89 - * Cleared target_time_out counter while performing a reset. - * All external symbols renamed to avoid possible name conflicts. - * - * 28 Jan 1995 rev. 1.14 for linux 1.1.86 - * Added module support. - * Log and do a retry when a disk drive returns a target status - * different from zero on a recovered error. - * - * 24 Jan 1995 rev. 1.13 for linux 1.1.85 - * Use optimized board configuration, with a measured performance - * increase in the range 10%-20% on i/o throughput. - * - * 16 Jan 1995 rev. 1.12 for linux 1.1.81 - * Fix mscp structure comments (no functional change). - * Display a message if check_region detects a port address - * already in use. - * - * 17 Dec 1994 rev. 1.11 for linux 1.1.74 - * Use the scsicam_bios_param routine. This allows an easy - * migration path from disk partition tables created using - * different SCSI drivers and non optimal disk geometry. - * - * 15 Dec 1994 rev. 1.10 for linux 1.1.74 - * Added support for ISA EATA boards (DPT PM2011, DPT PM2021). - * The host->block flag is set for all the detected ISA boards. - * The detect routine no longer enforces LEVEL triggering - * for EISA boards, it just prints a warning message. - * - * 30 Nov 1994 rev. 1.09 for linux 1.1.68 - * Redo i/o on target status CHECK_CONDITION for TYPE_DISK only. - * Added optional support for using a single board at a time. - * - * 18 Nov 1994 rev. 1.08 for linux 1.1.64 - * Forces sg_tablesize = 64 and can_queue = 64 if these - * values are not correctly detected (DPT PM2012). - * - * 14 Nov 1994 rev. 1.07 for linux 1.1.63 Final BETA release. - * 04 Aug 1994 rev. 1.00 for linux 1.1.39 First BETA release. - * - * - * This driver is based on the CAM (Common Access Method Committee) - * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. - * - * Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com) - * - * Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that redistributions of source - * code retain the above copyright notice and this comment without - * modification. - * - */ - -/* - * - * Here is a brief description of the DPT SCSI host adapters. - * All these boards provide an EATA/DMA compatible programming interface - * and are fully supported by this driver in any configuration, including - * multiple SCSI channels: - * - * PM2011B/9X - Entry Level ISA - * PM2021A/9X - High Performance ISA - * PM2012A Old EISA - * PM2012B Old EISA - * PM2022A/9X - Entry Level EISA - * PM2122A/9X - High Performance EISA - * PM2322A/9X - Extra High Performance EISA - * PM3021 - SmartRAID Adapter for ISA - * PM3222 - SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI) - * PM3224 - SmartRAID Adapter for PCI (PM3224W is 16-bit wide SCSI) - * PM33340UW - SmartRAID Adapter for PCI ultra wide multichannel - * - * The above list is just an indication: as a matter of fact all DPT - * boards using the EATA/DMA protocol are supported by this driver, - * since they use exactely the same programming interface. - * - * The DPT PM2001 provides only the EATA/PIO interface and hence is not - * supported by this driver. - * - * This code has been tested with up to 3 Distributed Processing Technology - * PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) EISA controllers, - * in any combination of private and shared IRQ. - * PCI support has been tested using up to 2 DPT PM3224W (DPT SCSI BIOS - * v003.D0, firmware v07G.0). - * - * DPT SmartRAID boards support "Hardware Array" - a group of disk drives - * which are all members of the same RAID-0, RAID-1 or RAID-5 array implemented - * in host adapter hardware. Hardware Arrays are fully compatible with this - * driver, since they look to it as a single disk drive. - * - * WARNING: to create a RAID-0 "Hardware Array" you must select "Other Unix" - * as the current OS in the DPTMGR "Initial System Installation" menu. - * Otherwise RAID-0 is generated as an "Array Group" (i.e. software RAID-0), - * which is not supported by the actual SCSI subsystem. - * To get the "Array Group" functionality, the Linux MD driver must be used - * instead of the DPT "Array Group" feature. - * - * Multiple ISA, EISA and PCI boards can be configured in the same system. - * It is suggested to put all the EISA boards on the same IRQ level, all - * the PCI boards on another IRQ level, while ISA boards cannot share - * interrupts. - * - * If you configure multiple boards on the same IRQ, the interrupt must - * be _level_ triggered (not _edge_ triggered). - * - * This driver detects EATA boards by probes at fixed port addresses, - * so no BIOS32 or PCI BIOS support is required. - * The suggested way to detect a generic EATA PCI board is to force on it - * any unused EISA address, even if there are other controllers on the EISA - * bus, or even if you system has no EISA bus at all. - * Do not force any ISA address on EATA PCI boards. - * - * If PCI bios support is configured into the kernel, BIOS32 is used to - * include in the list of i/o ports to be probed all the PCI SCSI controllers. - * - * Due to a DPT BIOS "feature", it might not be possible to force an EISA - * address on more than a single DPT PCI board, so in this case you have to - * let the PCI BIOS assign the addresses. - * - * The sequence of detection probes is: - * - * - ISA 0x1F0; - * - PCI SCSI controllers (only if BIOS32 is available); - * - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15); - * - ISA 0x170, 0x230, 0x330. - * - * The above list of detection probes can be totally replaced by the - * boot command line option: "eata=port0,port1,port2,...", where the - * port0, port1... arguments are ISA/EISA/PCI addresses to be probed. - * For example using "eata=0x7410,0x7450,0x230", the driver probes - * only the two PCI addresses 0x7410 and 0x7450 and the ISA address 0x230, - * in this order; "eata=0" totally disables this driver. - * - * After the optional list of detection probes, other possible command line - * options are: - * - * et:y force use of extended translation (255 heads, 63 sectors); - * et:n use disk geometry detected by scsicam_bios_param; - * rs:y reverse scan order while detecting PCI boards; - * rs:n use BIOS order while detecting PCI boards; - * lc:y enables linked commands; - * lc:n disables linked commands; - * tm:0 disables tagged commands (same as tc:n); - * tm:1 use simple queue tags (same as tc:y); - * tm:2 use ordered queue tags (same as tc:2); - * mq:xx set the max queue depth to the value xx (2 <= xx <= 32). - * - * The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n". - * An example using the list of detection probes could be: - * "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n". - * - * When loading as a module, parameters can be specified as well. - * The above example would be (use 1 in place of y and 0 in place of n): - * - * modprobe eata io_port=0x7410,0x230 linked_comm=1 \ - * max_queue_depth=4 ext_tran=0 tag_mode=2 \ - * rev_scan=1 - * - * ---------------------------------------------------------------------------- - * In this implementation, linked commands are designed to work with any DISK - * or CD-ROM, since this linking has only the intent of clustering (time-wise) - * and reordering by elevator sorting commands directed to each device, - * without any relation with the actual SCSI protocol between the controller - * and the device. - * If Q is the queue depth reported at boot time for each device (also named - * cmds/lun) and Q > 2, whenever there is already an active command to the - * device all other commands to the same device (up to Q-1) are kept waiting - * in the elevator sorting queue. When the active command completes, the - * commands in this queue are sorted by sector address. The sort is chosen - * between increasing or decreasing by minimizing the seek distance between - * the sector of the commands just completed and the sector of the first - * command in the list to be sorted. - * Trivial math assures that the unsorted average seek distance when doing - * random seeks over S sectors is S/3. - * When (Q-1) requests are uniformly distributed over S sectors, the average - * distance between two adjacent requests is S/((Q-1) + 1), so the sorted - * average seek distance for (Q-1) random requests over S sectors is S/Q. - * The elevator sorting hence divides the seek distance by a factor Q/3. - * The above pure geometric remarks are valid in all cases and the - * driver effectively reduces the seek distance by the predicted factor - * when there are Q concurrent read i/o operations on the device, but this - * does not necessarily results in a noticeable performance improvement: - * your mileage may vary.... - * - * Note: command reordering inside a batch of queued commands could cause - * wrong results only if there is at least one write request and the - * intersection (sector-wise) of all requests is not empty. - * When the driver detects a batch including overlapping requests - * (a really rare event) strict serial (pid) order is enforced. - * ---------------------------------------------------------------------------- - * The extended translation option (et:y) is useful when using large physical - * disks/arrays. It could also be useful when switching between Adaptec boards - * and DPT boards without reformatting the disk. - * When a boot disk is partitioned with extended translation, in order to - * be able to boot it with a DPT board is could be necessary to add to - * lilo.conf additional commands as in the following example: - * - * fix-table - * disk=/dev/sda bios=0x80 sectors=63 heads=128 cylindres=546 - * - * where the above geometry should be replaced with the one reported at - * power up by the DPT controller. - * ---------------------------------------------------------------------------- - * - * The boards are named EATA0, EATA1,... according to the detection order. - * - * In order to support multiple ISA boards in a reliable way, - * the driver sets host->wish_block = 1 for all ISA boards. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static int eata2x_detect(struct scsi_host_template *); -static int eata2x_release(struct Scsi_Host *); -static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); -static int eata2x_eh_abort(struct scsi_cmnd *); -static int eata2x_eh_host_reset(struct scsi_cmnd *); -static int eata2x_bios_param(struct scsi_device *, struct block_device *, - sector_t, int *); -static int eata2x_slave_configure(struct scsi_device *); - -static struct scsi_host_template driver_template = { - .name = "EATA/DMA 2.0x rev. 8.10.00 ", - .detect = eata2x_detect, - .release = eata2x_release, - .queuecommand = eata2x_queuecommand, - .eh_abort_handler = eata2x_eh_abort, - .eh_host_reset_handler = eata2x_eh_host_reset, - .bios_param = eata2x_bios_param, - .slave_configure = eata2x_slave_configure, - .this_id = 7, - .unchecked_isa_dma = 1, - .use_clustering = ENABLE_CLUSTERING, -}; - -#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) -#error "Adjust your defines" -#endif - -/* Subversion values */ -#define ISA 0 -#define ESA 1 - -#undef FORCE_CONFIG - -#undef DEBUG_LINKED_COMMANDS -#undef DEBUG_DETECT -#undef DEBUG_PCI_DETECT -#undef DEBUG_INTERRUPT -#undef DEBUG_RESET -#undef DEBUG_GENERATE_ERRORS -#undef DEBUG_GENERATE_ABORTS -#undef DEBUG_GEOMETRY - -#define MAX_ISA 4 -#define MAX_VESA 0 -#define MAX_EISA 15 -#define MAX_PCI 16 -#define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI) -#define MAX_CHANNEL 4 -#define MAX_LUN 32 -#define MAX_TARGET 32 -#define MAX_MAILBOXES 64 -#define MAX_SGLIST 64 -#define MAX_LARGE_SGLIST 122 -#define MAX_INTERNAL_RETRIES 64 -#define MAX_CMD_PER_LUN 2 -#define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN) - -#define SKIP ULONG_MAX -#define FREE 0 -#define IN_USE 1 -#define LOCKED 2 -#define IN_RESET 3 -#define IGNORE 4 -#define READY 5 -#define ABORTING 6 -#define NO_DMA 0xff -#define MAXLOOP 10000 -#define TAG_DISABLED 0 -#define TAG_SIMPLE 1 -#define TAG_ORDERED 2 - -#define REG_CMD 7 -#define REG_STATUS 7 -#define REG_AUX_STATUS 8 -#define REG_DATA 0 -#define REG_DATA2 1 -#define REG_SEE 6 -#define REG_LOW 2 -#define REG_LM 3 -#define REG_MID 4 -#define REG_MSB 5 -#define REGION_SIZE 9UL -#define MAX_ISA_ADDR 0x03ff -#define MIN_EISA_ADDR 0x1c88 -#define MAX_EISA_ADDR 0xfc88 -#define BSY_ASSERTED 0x80 -#define DRQ_ASSERTED 0x08 -#define ABSY_ASSERTED 0x01 -#define IRQ_ASSERTED 0x02 -#define READ_CONFIG_PIO 0xf0 -#define SET_CONFIG_PIO 0xf1 -#define SEND_CP_PIO 0xf2 -#define RECEIVE_SP_PIO 0xf3 -#define TRUNCATE_XFR_PIO 0xf4 -#define RESET_PIO 0xf9 -#define READ_CONFIG_DMA 0xfd -#define SET_CONFIG_DMA 0xfe -#define SEND_CP_DMA 0xff -#define ASOK 0x00 -#define ASST 0x01 - -#define YESNO(a) ((a) ? 'y' : 'n') -#define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) - -/* "EATA", in Big Endian format */ -#define EATA_SIG_BE 0x45415441 - -/* Number of valid bytes in the board config structure for EATA 2.0x */ -#define EATA_2_0A_SIZE 28 -#define EATA_2_0B_SIZE 30 -#define EATA_2_0C_SIZE 34 - -/* Board info structure */ -struct eata_info { - u_int32_t data_len; /* Number of valid bytes after this field */ - u_int32_t sign; /* ASCII "EATA" signature */ - -#if defined(__BIG_ENDIAN_BITFIELD) - unchar version : 4, - : 4; - unchar haaval : 1, - ata : 1, - drqvld : 1, - dmasup : 1, - morsup : 1, - trnxfr : 1, - tarsup : 1, - ocsena : 1; -#else - unchar : 4, /* unused low nibble */ - version : 4; /* EATA version, should be 0x1 */ - unchar ocsena : 1, /* Overlap Command Support Enabled */ - tarsup : 1, /* Target Mode Supported */ - trnxfr : 1, /* Truncate Transfer Cmd NOT Necessary */ - morsup : 1, /* More Supported */ - dmasup : 1, /* DMA Supported */ - drqvld : 1, /* DRQ Index (DRQX) is valid */ - ata : 1, /* This is an ATA device */ - haaval : 1; /* Host Adapter Address Valid */ -#endif - - ushort cp_pad_len; /* Number of pad bytes after cp_len */ - unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */ - u_int32_t cp_len; /* Number of valid bytes in cp */ - u_int32_t sp_len; /* Number of valid bytes in sp */ - ushort queue_size; /* Max number of cp that can be queued */ - ushort unused; - ushort scatt_size; /* Max number of entries in scatter/gather table */ - -#if defined(__BIG_ENDIAN_BITFIELD) - unchar drqx : 2, - second : 1, - irq_tr : 1, - irq : 4; - unchar sync; - unchar : 4, - res1 : 1, - large_sg : 1, - forcaddr : 1, - isaena : 1; - unchar max_chan : 3, - max_id : 5; - unchar max_lun; - unchar eisa : 1, - pci : 1, - idquest : 1, - m1 : 1, - : 4; -#else - unchar irq : 4, /* Interrupt Request assigned to this controller */ - irq_tr : 1, /* 0 for edge triggered, 1 for level triggered */ - second : 1, /* 1 if this is a secondary (not primary) controller */ - drqx : 2; /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */ - unchar sync; /* 1 if scsi target id 7...0 is running sync scsi */ - - /* Structure extension defined in EATA 2.0B */ - unchar isaena : 1, /* ISA i/o addressing is disabled/enabled */ - forcaddr : 1, /* Port address has been forced */ - large_sg : 1, /* 1 if large SG lists are supported */ - res1 : 1, - : 4; - unchar max_id : 5, /* Max SCSI target ID number */ - max_chan : 3; /* Max SCSI channel number on this board */ - - /* Structure extension defined in EATA 2.0C */ - unchar max_lun; /* Max SCSI LUN number */ - unchar - : 4, - m1 : 1, /* This is a PCI with an M1 chip installed */ - idquest : 1, /* RAIDNUM returned is questionable */ - pci : 1, /* This board is PCI */ - eisa : 1; /* This board is EISA */ -#endif - - unchar raidnum; /* Uniquely identifies this HBA in a system */ - unchar notused; - - ushort ipad[247]; -}; - -/* Board config structure */ -struct eata_config { - ushort len; /* Number of bytes following this field */ - -#if defined(__BIG_ENDIAN_BITFIELD) - unchar : 4, - tarena : 1, - mdpena : 1, - ocena : 1, - edis : 1; -#else - unchar edis : 1, /* Disable EATA interface after config command */ - ocena : 1, /* Overlapped Commands Enabled */ - mdpena : 1, /* Transfer all Modified Data Pointer Messages */ - tarena : 1, /* Target Mode Enabled for this controller */ - : 4; -#endif - unchar cpad[511]; -}; - -/* Returned status packet structure */ -struct mssp { -#if defined(__BIG_ENDIAN_BITFIELD) - unchar eoc : 1, - adapter_status : 7; -#else - unchar adapter_status : 7, /* State related to current command */ - eoc : 1; /* End Of Command (1 = command completed) */ -#endif - unchar target_status; /* SCSI status received after data transfer */ - unchar unused[2]; - u_int32_t inv_res_len; /* Number of bytes not transferred */ - u_int32_t cpp_index; /* Index of address set in cp */ - char mess[12]; -}; - -struct sg_list { - unsigned int address; /* Segment Address */ - unsigned int num_bytes; /* Segment Length */ -}; - -/* MailBox SCSI Command Packet */ -struct mscp { -#if defined(__BIG_ENDIAN_BITFIELD) - unchar din : 1, - dout : 1, - interp : 1, - : 1, - sg : 1, - reqsen :1, - init : 1, - sreset : 1; - unchar sense_len; - unchar unused[3]; - unchar : 7, - fwnest : 1; - unchar : 5, - hbaci : 1, - iat : 1, - phsunit : 1; - unchar channel : 3, - target : 5; - unchar one : 1, - dispri : 1, - luntar : 1, - lun : 5; -#else - unchar sreset :1, /* SCSI Bus Reset Signal should be asserted */ - init :1, /* Re-initialize controller and self test */ - reqsen :1, /* Transfer Request Sense Data to addr using DMA */ - sg :1, /* Use Scatter/Gather */ - :1, - interp :1, /* The controller interprets cp, not the target */ - dout :1, /* Direction of Transfer is Out (Host to Target) */ - din :1; /* Direction of Transfer is In (Target to Host) */ - unchar sense_len; /* Request Sense Length */ - unchar unused[3]; - unchar fwnest : 1, /* Send command to a component of an Array Group */ - : 7; - unchar phsunit : 1, /* Send to Target Physical Unit (bypass RAID) */ - iat : 1, /* Inhibit Address Translation */ - hbaci : 1, /* Inhibit HBA Caching for this command */ - : 5; - unchar target : 5, /* SCSI target ID */ - channel : 3; /* SCSI channel number */ - unchar lun : 5, /* SCSI logical unit number */ - luntar : 1, /* This cp is for Target (not LUN) */ - dispri : 1, /* Disconnect Privilege granted */ - one : 1; /* 1 */ -#endif - - unchar mess[3]; /* Massage to/from Target */ - unchar cdb[12]; /* Command Descriptor Block */ - u_int32_t data_len; /* If sg=0 Data Length, if sg=1 sglist length */ - u_int32_t cpp_index; /* Index of address to be returned in sp */ - u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */ - u_int32_t sp_dma_addr; /* Address where sp is DMA'ed when cp completes */ - u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */ - - /* Additional fields begin here. */ - struct scsi_cmnd *SCpnt; - - /* All the cp structure is zero filled by queuecommand except the - following CP_TAIL_SIZE bytes, initialized by detect */ - dma_addr_t cp_dma_addr; /* dma handle for this cp structure */ - struct sg_list *sglist; /* pointer to the allocated SG list */ -}; - -#define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t)) - -struct hostdata { - struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */ - unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */ - unsigned int last_cp_used; /* Index of last mailbox used */ - unsigned int iocount; /* Total i/o done for this board */ - int board_number; /* Number of this board */ - char board_name[16]; /* Name of this board */ - int in_reset; /* True if board is doing a reset */ - int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */ - int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If 1 redo i/o on target */ - unsigned int retries; /* Number of internal retries */ - unsigned long last_retried_pid; /* Pid of last retried command */ - unsigned char subversion; /* Bus type, either ISA or EISA/PCI */ - unsigned char protocol_rev; /* EATA 2.0 rev., 'A' or 'B' or 'C' */ - unsigned char is_pci; /* 1 is bus type is PCI */ - struct pci_dev *pdev; /* pdev for PCI bus, NULL otherwise */ - struct mssp *sp_cpu_addr; /* cpu addr for DMA buffer sp */ - dma_addr_t sp_dma_addr; /* dma handle for DMA buffer sp */ - struct mssp sp; /* Local copy of sp buffer */ -}; - -static struct Scsi_Host *sh[MAX_BOARDS]; -static const char *driver_name = "EATA"; -static char sha[MAX_BOARDS]; - -/* Initialize num_boards so that ihdlr can work while detect is in progress */ -static unsigned int num_boards = MAX_BOARDS; - -static unsigned long io_port[] = { - - /* Space for MAX_INT_PARAM ports usable while loading as a module */ - SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, - SKIP, SKIP, - - /* First ISA */ - 0x1f0, - - /* Space for MAX_PCI ports possibly reported by PCI_BIOS */ - SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, - SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, - - /* MAX_EISA ports */ - 0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88, - 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, - - /* Other (MAX_ISA - 1) ports */ - 0x170, 0x230, 0x330, - - /* End of list */ - 0x0 -}; - -/* Device is Big Endian */ -#define H2DEV(x) cpu_to_be32(x) -#define DEV2H(x) be32_to_cpu(x) -#define H2DEV16(x) cpu_to_be16(x) -#define DEV2H16(x) be16_to_cpu(x) - -/* But transfer orientation from the 16 bit data register is Little Endian */ -#define REG2H(x) le16_to_cpu(x) - -static irqreturn_t do_interrupt_handler(int, void *); -static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *, - unsigned int); -static int do_trace = 0; -static int setup_done = 0; -static int link_statistics; -static int ext_tran = 0; -static int rev_scan = 1; - -#if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE) -static int tag_mode = TAG_SIMPLE; -#else -static int tag_mode = TAG_DISABLED; -#endif - -#if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS) -static int linked_comm = 1; -#else -static int linked_comm = 0; -#endif - -#if defined(CONFIG_SCSI_EATA_MAX_TAGS) -static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS; -#else -static int max_queue_depth = MAX_CMD_PER_LUN; -#endif - -#if defined(CONFIG_ISA) -static int isa_probe = 1; -#else -static int isa_probe = 0; -#endif - -#if defined(CONFIG_EISA) -static int eisa_probe = 1; -#else -static int eisa_probe = 0; -#endif - -#if defined(CONFIG_PCI) -static int pci_probe = 1; -#else -static int pci_probe = 0; -#endif - -#define MAX_INT_PARAM 10 -#define MAX_BOOT_OPTIONS_SIZE 256 -static char boot_options[MAX_BOOT_OPTIONS_SIZE]; - -#if defined(MODULE) -#include -#include - -module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0); -MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." - " Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\""); -MODULE_AUTHOR("Dario Ballabio"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("EATA/DMA SCSI Driver"); - -#endif - -static int eata2x_slave_configure(struct scsi_device *dev) -{ - int tqd, utqd; - char *tag_suffix, *link_suffix; - - utqd = MAX_CMD_PER_LUN; - tqd = max_queue_depth; - - if (TLDEV(dev->type) && dev->tagged_supported) { - if (tag_mode == TAG_SIMPLE) { - tag_suffix = ", simple tags"; - } else if (tag_mode == TAG_ORDERED) { - tag_suffix = ", ordered tags"; - } else { - tag_suffix = ", no tags"; - } - scsi_change_queue_depth(dev, tqd); - } else if (TLDEV(dev->type) && linked_comm) { - scsi_change_queue_depth(dev, tqd); - tag_suffix = ", untagged"; - } else { - scsi_change_queue_depth(dev, utqd); - tag_suffix = ""; - } - - if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2) - link_suffix = ", sorted"; - else if (TLDEV(dev->type)) - link_suffix = ", unsorted"; - else - link_suffix = ""; - - sdev_printk(KERN_INFO, dev, - "cmds/lun %d%s%s.\n", - dev->queue_depth, link_suffix, tag_suffix); - - return 0; -} - -static int wait_on_busy(unsigned long iobase, unsigned int loop) -{ - while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) { - udelay(1L); - if (--loop == 0) - return 1; - } - return 0; -} - -static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) -{ - unsigned char *byaddr; - unsigned long devaddr; - - if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) - return 1; - - if (addr) { - devaddr = H2DEV(addr); - byaddr = (unsigned char *)&devaddr; - outb(byaddr[3], iobase + REG_LOW); - outb(byaddr[2], iobase + REG_LM); - outb(byaddr[1], iobase + REG_MID); - outb(byaddr[0], iobase + REG_MSB); - } - - outb(cmd, iobase + REG_CMD); - return 0; -} - -static int read_pio(unsigned long iobase, ushort * start, ushort * end) -{ - unsigned int loop = MAXLOOP; - ushort *p; - - for (p = start; p <= end; p++) { - while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) { - udelay(1L); - if (--loop == 0) - return 1; - } - loop = MAXLOOP; - *p = REG2H(inw(iobase)); - } - - return 0; -} - -static struct pci_dev *get_pci_dev(unsigned long port_base) -{ -#if defined(CONFIG_PCI) - unsigned int addr; - struct pci_dev *dev = NULL; - - while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { - addr = pci_resource_start(dev, 0); - -#if defined(DEBUG_PCI_DETECT) - printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n", - driver_name, dev->bus->number, dev->devfn, addr); -#endif - - /* we are in so much trouble for a pci hotplug system with this driver - * anyway, so doing this at least lets people unload the driver and not - * cause memory problems, but in general this is a bad thing to do (this - * driver needs to be converted to the proper PCI api someday... */ - pci_dev_put(dev); - if (addr + PCI_BASE_ADDRESS_0 == port_base) - return dev; - } -#endif /* end CONFIG_PCI */ - return NULL; -} - -static void enable_pci_ports(void) -{ -#if defined(CONFIG_PCI) - struct pci_dev *dev = NULL; - - while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { -#if defined(DEBUG_PCI_DETECT) - printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n", - driver_name, dev->bus->number, dev->devfn); -#endif - - if (pci_enable_device(dev)) - printk - ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n", - driver_name, dev->bus->number, dev->devfn); - } - -#endif /* end CONFIG_PCI */ -} - -static int port_detect(unsigned long port_base, unsigned int j, - struct scsi_host_template *tpnt) -{ - unsigned char irq, dma_channel, subversion, i, is_pci = 0; - unsigned char protocol_rev; - struct eata_info info; - char *bus_type, dma_name[16]; - struct pci_dev *pdev; - /* Allowed DMA channels for ISA (0 indicates reserved) */ - unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; - struct Scsi_Host *shost; - struct hostdata *ha; - char name[16]; - - sprintf(name, "%s%d", driver_name, j); - - if (!request_region(port_base, REGION_SIZE, driver_name)) { -#if defined(DEBUG_DETECT) - printk("%s: address 0x%03lx in use, skipping probe.\n", name, - port_base); -#endif - goto fail; - } - - if (do_dma(port_base, 0, READ_CONFIG_PIO)) { -#if defined(DEBUG_DETECT) - printk("%s: detect, do_dma failed at 0x%03lx.\n", name, - port_base); -#endif - goto freelock; - } - - /* Read the info structure */ - if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) { -#if defined(DEBUG_DETECT) - printk("%s: detect, read_pio failed at 0x%03lx.\n", name, - port_base); -#endif - goto freelock; - } - - info.data_len = DEV2H(info.data_len); - info.sign = DEV2H(info.sign); - info.cp_pad_len = DEV2H16(info.cp_pad_len); - info.cp_len = DEV2H(info.cp_len); - info.sp_len = DEV2H(info.sp_len); - info.scatt_size = DEV2H16(info.scatt_size); - info.queue_size = DEV2H16(info.queue_size); - - /* Check the controller "EATA" signature */ - if (info.sign != EATA_SIG_BE) { -#if defined(DEBUG_DETECT) - printk("%s: signature 0x%04x discarded.\n", name, info.sign); -#endif - goto freelock; - } - - if (info.data_len < EATA_2_0A_SIZE) { - printk - ("%s: config structure size (%d bytes) too short, detaching.\n", - name, info.data_len); - goto freelock; - } else if (info.data_len == EATA_2_0A_SIZE) - protocol_rev = 'A'; - else if (info.data_len == EATA_2_0B_SIZE) - protocol_rev = 'B'; - else - protocol_rev = 'C'; - - if (protocol_rev != 'A' && info.forcaddr) { - printk("%s: warning, port address has been forced.\n", name); - bus_type = "PCI"; - is_pci = 1; - subversion = ESA; - } else if (port_base > MAX_EISA_ADDR - || (protocol_rev == 'C' && info.pci)) { - bus_type = "PCI"; - is_pci = 1; - subversion = ESA; - } else if (port_base >= MIN_EISA_ADDR - || (protocol_rev == 'C' && info.eisa)) { - bus_type = "EISA"; - subversion = ESA; - } else if (protocol_rev == 'C' && !info.eisa && !info.pci) { - bus_type = "ISA"; - subversion = ISA; - } else if (port_base > MAX_ISA_ADDR) { - bus_type = "PCI"; - is_pci = 1; - subversion = ESA; - } else { - bus_type = "ISA"; - subversion = ISA; - } - - if (!info.haaval || info.ata) { - printk - ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n", - name, port_base, bus_type, info.haaval, info.ata); - goto freelock; - } - - if (info.drqvld) { - if (subversion == ESA) - printk("%s: warning, weird %s board using DMA.\n", name, - bus_type); - - subversion = ISA; - dma_channel = dma_channel_table[3 - info.drqx]; - } else { - if (subversion == ISA) - printk("%s: warning, weird %s board not using DMA.\n", - name, bus_type); - - subversion = ESA; - dma_channel = NO_DMA; - } - - if (!info.dmasup) - printk("%s: warning, DMA protocol support not asserted.\n", - name); - - irq = info.irq; - - if (subversion == ESA && !info.irq_tr) - printk - ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n", - name, irq); - - if (is_pci) { - pdev = get_pci_dev(port_base); - if (!pdev) - printk - ("%s: warning, failed to get pci_dev structure.\n", - name); - } else - pdev = NULL; - - if (pdev && (irq != pdev->irq)) { - printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, - pdev->irq); - irq = pdev->irq; - } - - /* Board detected, allocate its IRQ */ - if (request_irq(irq, do_interrupt_handler, - (subversion == ESA) ? IRQF_SHARED : 0, - driver_name, (void *)&sha[j])) { - printk("%s: unable to allocate IRQ %u, detaching.\n", name, - irq); - goto freelock; - } - - if (subversion == ISA && request_dma(dma_channel, driver_name)) { - printk("%s: unable to allocate DMA channel %u, detaching.\n", - name, dma_channel); - goto freeirq; - } -#if defined(FORCE_CONFIG) - { - struct eata_config *cf; - dma_addr_t cf_dma_addr; - - cf = pci_zalloc_consistent(pdev, sizeof(struct eata_config), - &cf_dma_addr); - - if (!cf) { - printk - ("%s: config, pci_alloc_consistent failed, detaching.\n", - name); - goto freedma; - } - - /* Set board configuration */ - cf->len = (ushort) H2DEV16((ushort) 510); - cf->ocena = 1; - - if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) { - printk - ("%s: busy timeout sending configuration, detaching.\n", - name); - pci_free_consistent(pdev, sizeof(struct eata_config), - cf, cf_dma_addr); - goto freedma; - } - - } -#endif - - sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata)); - if (shost == NULL) { - printk("%s: unable to register host, detaching.\n", name); - goto freedma; - } - - shost->io_port = port_base; - shost->unique_id = port_base; - shost->n_io_port = REGION_SIZE; - shost->dma_channel = dma_channel; - shost->irq = irq; - shost->sg_tablesize = (ushort) info.scatt_size; - shost->this_id = (ushort) info.host_addr[3]; - shost->can_queue = (ushort) info.queue_size; - shost->cmd_per_lun = MAX_CMD_PER_LUN; - - ha = (struct hostdata *)shost->hostdata; - - memset(ha, 0, sizeof(struct hostdata)); - ha->subversion = subversion; - ha->protocol_rev = protocol_rev; - ha->is_pci = is_pci; - ha->pdev = pdev; - ha->board_number = j; - - if (ha->subversion == ESA) - shost->unchecked_isa_dma = 0; - else { - unsigned long flags; - shost->unchecked_isa_dma = 1; - - flags = claim_dma_lock(); - disable_dma(dma_channel); - clear_dma_ff(dma_channel); - set_dma_mode(dma_channel, DMA_MODE_CASCADE); - enable_dma(dma_channel); - release_dma_lock(flags); - - } - - strcpy(ha->board_name, name); - - /* DPT PM2012 does not allow to detect sg_tablesize correctly */ - if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) { - printk("%s: detect, wrong n. of SG lists %d, fixed.\n", - ha->board_name, shost->sg_tablesize); - shost->sg_tablesize = MAX_SGLIST; - } - - /* DPT PM2012 does not allow to detect can_queue correctly */ - if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) { - printk("%s: detect, wrong n. of mbox %d, fixed.\n", - ha->board_name, shost->can_queue); - shost->can_queue = MAX_MAILBOXES; - } - - if (protocol_rev != 'A') { - if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL) - shost->max_channel = info.max_chan; - - if (info.max_id > 7 && info.max_id < MAX_TARGET) - shost->max_id = info.max_id + 1; - - if (info.large_sg && shost->sg_tablesize == MAX_SGLIST) - shost->sg_tablesize = MAX_LARGE_SGLIST; - } - - if (protocol_rev == 'C') { - if (info.max_lun > 7 && info.max_lun < MAX_LUN) - shost->max_lun = info.max_lun + 1; - } - - if (dma_channel == NO_DMA) - sprintf(dma_name, "%s", "BMST"); - else - sprintf(dma_name, "DMA %u", dma_channel); - - for (i = 0; i < shost->can_queue; i++) - ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev, - &ha->cp[i], - sizeof(struct mscp), - PCI_DMA_BIDIRECTIONAL); - - for (i = 0; i < shost->can_queue; i++) { - size_t sz = shost->sg_tablesize *sizeof(struct sg_list); - gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC; - ha->cp[i].sglist = kmalloc(sz, gfp_mask); - if (!ha->cp[i].sglist) { - printk - ("%s: kmalloc SGlist failed, mbox %d, detaching.\n", - ha->board_name, i); - goto release; - } - } - - if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev, - sizeof(struct mssp), - &ha->sp_dma_addr))) { - printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name); - goto release; - } - - if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) - max_queue_depth = MAX_TAGGED_CMD_PER_LUN; - - if (max_queue_depth < MAX_CMD_PER_LUN) - max_queue_depth = MAX_CMD_PER_LUN; - - if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE) - tag_mode = TAG_ORDERED; - - if (j == 0) { - printk - ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n"); - printk - ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, " - "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode, - YESNO(linked_comm), max_queue_depth, YESNO(rev_scan), - YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe), - YESNO(pci_probe)); - } - - printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n", - ha->board_name, ha->protocol_rev, bus_type, - (unsigned long)shost->io_port, shost->irq, dma_name, - shost->sg_tablesize, shost->can_queue); - - if (shost->max_id > 8 || shost->max_lun > 8) - printk - ("%s: wide SCSI support enabled, max_id %u, max_lun %llu.\n", - ha->board_name, shost->max_id, shost->max_lun); - - for (i = 0; i <= shost->max_channel; i++) - printk("%s: SCSI channel %u enabled, host target ID %d.\n", - ha->board_name, i, info.host_addr[3 - i]); - -#if defined(DEBUG_DETECT) - printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, " - "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version, - info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync, - info.second, info.data_len, info.cp_len, info.sp_len); - - if (protocol_rev == 'B' || protocol_rev == 'C') - printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, " - "large_sg %u, res1 %u.\n", name, info.isaena, - info.forcaddr, info.max_id, info.max_chan, info.large_sg, - info.res1); - - if (protocol_rev == 'C') - printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, " - "raidnum %u.\n", name, info.max_lun, info.m1, - info.idquest, info.pci, info.eisa, info.raidnum); -#endif - - if (ha->pdev) { - pci_set_master(ha->pdev); - if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32))) - printk("%s: warning, pci_set_dma_mask failed.\n", - ha->board_name); - } - - return 1; - - freedma: - if (subversion == ISA) - free_dma(dma_channel); - freeirq: - free_irq(irq, &sha[j]); - freelock: - release_region(port_base, REGION_SIZE); - fail: - return 0; - - release: - eata2x_release(shost); - return 0; -} - -static void internal_setup(char *str, int *ints) -{ - int i, argc = ints[0]; - char *cur = str, *pc; - - if (argc > 0) { - if (argc > MAX_INT_PARAM) - argc = MAX_INT_PARAM; - - for (i = 0; i < argc; i++) - io_port[i] = ints[i + 1]; - - io_port[i] = 0; - setup_done = 1; - } - - while (cur && (pc = strchr(cur, ':'))) { - int val = 0, c = *++pc; - - if (c == 'n' || c == 'N') - val = 0; - else if (c == 'y' || c == 'Y') - val = 1; - else - val = (int)simple_strtoul(pc, NULL, 0); - - if (!strncmp(cur, "lc:", 3)) - linked_comm = val; - else if (!strncmp(cur, "tm:", 3)) - tag_mode = val; - else if (!strncmp(cur, "tc:", 3)) - tag_mode = val; - else if (!strncmp(cur, "mq:", 3)) - max_queue_depth = val; - else if (!strncmp(cur, "ls:", 3)) - link_statistics = val; - else if (!strncmp(cur, "et:", 3)) - ext_tran = val; - else if (!strncmp(cur, "rs:", 3)) - rev_scan = val; - else if (!strncmp(cur, "ip:", 3)) - isa_probe = val; - else if (!strncmp(cur, "ep:", 3)) - eisa_probe = val; - else if (!strncmp(cur, "pp:", 3)) - pci_probe = val; - - if ((cur = strchr(cur, ','))) - ++cur; - } - - return; -} - -static int option_setup(char *str) -{ - int ints[MAX_INT_PARAM]; - char *cur = str; - int i = 1; - - while (cur && isdigit(*cur) && i < MAX_INT_PARAM) { - ints[i++] = simple_strtoul(cur, NULL, 0); - - if ((cur = strchr(cur, ',')) != NULL) - cur++; - } - - ints[0] = i - 1; - internal_setup(cur, ints); - return 1; -} - -static void add_pci_ports(void) -{ -#if defined(CONFIG_PCI) - unsigned int addr, k; - struct pci_dev *dev = NULL; - - for (k = 0; k < MAX_PCI; k++) { - - if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) - break; - - if (pci_enable_device(dev)) { -#if defined(DEBUG_PCI_DETECT) - printk - ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n", - driver_name, dev->bus->number, dev->devfn); -#endif - - continue; - } - - addr = pci_resource_start(dev, 0); - -#if defined(DEBUG_PCI_DETECT) - printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n", - driver_name, k, dev->bus->number, dev->devfn, addr); -#endif - - /* Order addresses according to rev_scan value */ - io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] = - addr + PCI_BASE_ADDRESS_0; - } - - pci_dev_put(dev); -#endif /* end CONFIG_PCI */ -} - -static int eata2x_detect(struct scsi_host_template *tpnt) -{ - unsigned int j = 0, k; - - tpnt->proc_name = "eata2x"; - - if (strlen(boot_options)) - option_setup(boot_options); - -#if defined(MODULE) - /* io_port could have been modified when loading as a module */ - if (io_port[0] != SKIP) { - setup_done = 1; - io_port[MAX_INT_PARAM] = 0; - } -#endif - - for (k = MAX_INT_PARAM; io_port[k]; k++) - if (io_port[k] == SKIP) - continue; - else if (io_port[k] <= MAX_ISA_ADDR) { - if (!isa_probe) - io_port[k] = SKIP; - } else if (io_port[k] >= MIN_EISA_ADDR - && io_port[k] <= MAX_EISA_ADDR) { - if (!eisa_probe) - io_port[k] = SKIP; - } - - if (pci_probe) { - if (!setup_done) - add_pci_ports(); - else - enable_pci_ports(); - } - - for (k = 0; io_port[k]; k++) { - - if (io_port[k] == SKIP) - continue; - - if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) - j++; - } - - num_boards = j; - return j; -} - -static void map_dma(unsigned int i, struct hostdata *ha) -{ - unsigned int k, pci_dir; - int count; - struct scatterlist *sg; - struct mscp *cpp; - struct scsi_cmnd *SCpnt; - - cpp = &ha->cp[i]; - SCpnt = cpp->SCpnt; - pci_dir = SCpnt->sc_data_direction; - - if (SCpnt->sense_buffer) - cpp->sense_addr = - H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer, - SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE)); - - cpp->sense_len = SCSI_SENSE_BUFFERSIZE; - - if (!scsi_sg_count(SCpnt)) { - cpp->data_len = 0; - return; - } - - count = pci_map_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), - pci_dir); - BUG_ON(!count); - - scsi_for_each_sg(SCpnt, sg, count, k) { - cpp->sglist[k].address = H2DEV(sg_dma_address(sg)); - cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg)); - } - - cpp->sg = 1; - cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist, - scsi_sg_count(SCpnt) * - sizeof(struct sg_list), - pci_dir)); - cpp->data_len = H2DEV((scsi_sg_count(SCpnt) * sizeof(struct sg_list))); -} - -static void unmap_dma(unsigned int i, struct hostdata *ha) -{ - unsigned int pci_dir; - struct mscp *cpp; - struct scsi_cmnd *SCpnt; - - cpp = &ha->cp[i]; - SCpnt = cpp->SCpnt; - pci_dir = SCpnt->sc_data_direction; - - if (DEV2H(cpp->sense_addr)) - pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr), - DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); - - if (scsi_sg_count(SCpnt)) - pci_unmap_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), - pci_dir); - - if (!DEV2H(cpp->data_len)) - pci_dir = PCI_DMA_BIDIRECTIONAL; - - if (DEV2H(cpp->data_address)) - pci_unmap_single(ha->pdev, DEV2H(cpp->data_address), - DEV2H(cpp->data_len), pci_dir); -} - -static void sync_dma(unsigned int i, struct hostdata *ha) -{ - unsigned int pci_dir; - struct mscp *cpp; - struct scsi_cmnd *SCpnt; - - cpp = &ha->cp[i]; - SCpnt = cpp->SCpnt; - pci_dir = SCpnt->sc_data_direction; - - if (DEV2H(cpp->sense_addr)) - pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr), - DEV2H(cpp->sense_len), - PCI_DMA_FROMDEVICE); - - if (scsi_sg_count(SCpnt)) - pci_dma_sync_sg_for_cpu(ha->pdev, scsi_sglist(SCpnt), - scsi_sg_count(SCpnt), pci_dir); - - if (!DEV2H(cpp->data_len)) - pci_dir = PCI_DMA_BIDIRECTIONAL; - - if (DEV2H(cpp->data_address)) - pci_dma_sync_single_for_cpu(ha->pdev, - DEV2H(cpp->data_address), - DEV2H(cpp->data_len), pci_dir); -} - -static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha) -{ - unsigned int k; - - static const unsigned char data_out_cmds[] = { - 0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e, - 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40, - 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d - }; - - static const unsigned char data_none_cmds[] = { - 0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e, - 0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47, - 0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00 - }; - - struct mscp *cpp; - struct scsi_cmnd *SCpnt; - - cpp = &ha->cp[i]; - SCpnt = cpp->SCpnt; - - if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) { - cpp->din = 1; - cpp->dout = 0; - return; - } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) { - cpp->din = 0; - cpp->dout = 1; - return; - } else if (SCpnt->sc_data_direction == DMA_NONE) { - cpp->din = 0; - cpp->dout = 0; - return; - } - - if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL) - panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", - ha->board_name); - - for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++) - if (SCpnt->cmnd[0] == data_out_cmds[k]) { - cpp->dout = 1; - break; - } - - if ((cpp->din = !cpp->dout)) - for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++) - if (SCpnt->cmnd[0] == data_none_cmds[k]) { - cpp->din = 0; - break; - } - -} - -static int eata2x_queuecommand_lck(struct scsi_cmnd *SCpnt, - void (*done) (struct scsi_cmnd *)) -{ - struct Scsi_Host *shost = SCpnt->device->host; - struct hostdata *ha = (struct hostdata *)shost->hostdata; - unsigned int i, k; - struct mscp *cpp; - - if (SCpnt->host_scribble) - panic("%s: qcomm, SCpnt %p already active.\n", - ha->board_name, SCpnt); - - /* i is the mailbox number, look for the first free mailbox - starting from last_cp_used */ - i = ha->last_cp_used + 1; - - for (k = 0; k < shost->can_queue; k++, i++) { - if (i >= shost->can_queue) - i = 0; - if (ha->cp_stat[i] == FREE) { - ha->last_cp_used = i; - break; - } - } - - if (k == shost->can_queue) { - printk("%s: qcomm, no free mailbox.\n", ha->board_name); - return 1; - } - - /* Set pointer to control packet structure */ - cpp = &ha->cp[i]; - - memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE); - - /* Set pointer to status packet structure, Big Endian format */ - cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr); - - SCpnt->scsi_done = done; - cpp->cpp_index = i; - SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index; - - if (do_trace) - scmd_printk(KERN_INFO, SCpnt, - "qcomm, mbox %d.\n", i); - - cpp->reqsen = 1; - cpp->dispri = 1; -#if 0 - if (SCpnt->device->type == TYPE_TAPE) - cpp->hbaci = 1; -#endif - cpp->one = 1; - cpp->channel = SCpnt->device->channel; - cpp->target = SCpnt->device->id; - cpp->lun = SCpnt->device->lun; - cpp->SCpnt = SCpnt; - memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); - - /* Use data transfer direction SCpnt->sc_data_direction */ - scsi_to_dev_dir(i, ha); - - /* Map DMA buffers and SG list */ - map_dma(i, ha); - - if (linked_comm && SCpnt->device->queue_depth > 2 - && TLDEV(SCpnt->device->type)) { - ha->cp_stat[i] = READY; - flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 0); - return 0; - } - - /* Send control packet to the board */ - if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { - unmap_dma(i, ha); - SCpnt->host_scribble = NULL; - scmd_printk(KERN_INFO, SCpnt, "qcomm, adapter busy.\n"); - return 1; - } - - ha->cp_stat[i] = IN_USE; - return 0; -} - -static DEF_SCSI_QCMD(eata2x_queuecommand) - -static int eata2x_eh_abort(struct scsi_cmnd *SCarg) -{ - struct Scsi_Host *shost = SCarg->device->host; - struct hostdata *ha = (struct hostdata *)shost->hostdata; - unsigned int i; - - if (SCarg->host_scribble == NULL) { - scmd_printk(KERN_INFO, SCarg, "abort, cmd inactive.\n"); - return SUCCESS; - } - - i = *(unsigned int *)SCarg->host_scribble; - scmd_printk(KERN_WARNING, SCarg, "abort, mbox %d.\n", i); - - if (i >= shost->can_queue) - panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); - - if (wait_on_busy(shost->io_port, MAXLOOP)) { - printk("%s: abort, timeout error.\n", ha->board_name); - return FAILED; - } - - if (ha->cp_stat[i] == FREE) { - printk("%s: abort, mbox %d is free.\n", ha->board_name, i); - return SUCCESS; - } - - if (ha->cp_stat[i] == IN_USE) { - printk("%s: abort, mbox %d is in use.\n", ha->board_name, i); - - if (SCarg != ha->cp[i].SCpnt) - panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", - ha->board_name, i, SCarg, ha->cp[i].SCpnt); - - if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) - printk("%s: abort, mbox %d, interrupt pending.\n", - ha->board_name, i); - - return FAILED; - } - - if (ha->cp_stat[i] == IN_RESET) { - printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i); - return FAILED; - } - - if (ha->cp_stat[i] == LOCKED) { - printk("%s: abort, mbox %d is locked.\n", ha->board_name, i); - return SUCCESS; - } - - if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { - unmap_dma(i, ha); - SCarg->result = DID_ABORT << 16; - SCarg->host_scribble = NULL; - ha->cp_stat[i] = FREE; - printk("%s, abort, mbox %d ready, DID_ABORT, done.\n", - ha->board_name, i); - SCarg->scsi_done(SCarg); - return SUCCESS; - } - - panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i); -} - -static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) -{ - unsigned int i, time, k, c, limit = 0; - struct scsi_cmnd *SCpnt; - struct Scsi_Host *shost = SCarg->device->host; - struct hostdata *ha = (struct hostdata *)shost->hostdata; - - scmd_printk(KERN_INFO, SCarg, "reset, enter.\n"); - - spin_lock_irq(shost->host_lock); - - if (SCarg->host_scribble == NULL) - printk("%s: reset, inactive.\n", ha->board_name); - - if (ha->in_reset) { - printk("%s: reset, exit, already in reset.\n", ha->board_name); - spin_unlock_irq(shost->host_lock); - return FAILED; - } - - if (wait_on_busy(shost->io_port, MAXLOOP)) { - printk("%s: reset, exit, timeout error.\n", ha->board_name); - spin_unlock_irq(shost->host_lock); - return FAILED; - } - - ha->retries = 0; - - for (c = 0; c <= shost->max_channel; c++) - for (k = 0; k < shost->max_id; k++) { - ha->target_redo[k][c] = 1; - ha->target_to[k][c] = 0; - } - - for (i = 0; i < shost->can_queue; i++) { - - if (ha->cp_stat[i] == FREE) - continue; - - if (ha->cp_stat[i] == LOCKED) { - ha->cp_stat[i] = FREE; - printk("%s: reset, locked mbox %d forced free.\n", - ha->board_name, i); - continue; - } - - if (!(SCpnt = ha->cp[i].SCpnt)) - panic("%s: reset, mbox %d, SCpnt == NULL.\n", ha->board_name, i); - - if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { - ha->cp_stat[i] = ABORTING; - printk("%s: reset, mbox %d aborting.\n", - ha->board_name, i); - } - - else { - ha->cp_stat[i] = IN_RESET; - printk("%s: reset, mbox %d in reset.\n", - ha->board_name, i); - } - - if (SCpnt->host_scribble == NULL) - panic("%s: reset, mbox %d, garbled SCpnt.\n", ha->board_name, i); - - if (*(unsigned int *)SCpnt->host_scribble != i) - panic("%s: reset, mbox %d, index mismatch.\n", ha->board_name, i); - - if (SCpnt->scsi_done == NULL) - panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", - ha->board_name, i); - } - - if (do_dma(shost->io_port, 0, RESET_PIO)) { - printk("%s: reset, cannot reset, timeout error.\n", ha->board_name); - spin_unlock_irq(shost->host_lock); - return FAILED; - } - - printk("%s: reset, board reset done, enabling interrupts.\n", ha->board_name); - -#if defined(DEBUG_RESET) - do_trace = 1; -#endif - - ha->in_reset = 1; - - spin_unlock_irq(shost->host_lock); - - /* FIXME: use a sleep instead */ - time = jiffies; - while ((jiffies - time) < (10 * HZ) && limit++ < 200000) - udelay(100L); - - spin_lock_irq(shost->host_lock); - - printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit); - - for (i = 0; i < shost->can_queue; i++) { - - if (ha->cp_stat[i] == IN_RESET) { - SCpnt = ha->cp[i].SCpnt; - unmap_dma(i, ha); - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - /* This mailbox is still waiting for its interrupt */ - ha->cp_stat[i] = LOCKED; - - printk - ("%s, reset, mbox %d locked, DID_RESET, done.\n", - ha->board_name, i); - } - - else if (ha->cp_stat[i] == ABORTING) { - SCpnt = ha->cp[i].SCpnt; - unmap_dma(i, ha); - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - /* This mailbox was never queued to the adapter */ - ha->cp_stat[i] = FREE; - - printk - ("%s, reset, mbox %d aborting, DID_RESET, done.\n", - ha->board_name, i); - } - - else - /* Any other mailbox has already been set free by interrupt */ - continue; - - SCpnt->scsi_done(SCpnt); - } - - ha->in_reset = 0; - do_trace = 0; - - printk("%s: reset, exit.\n", ha->board_name); - - spin_unlock_irq(shost->host_lock); - return SUCCESS; -} - -int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int *dkinfo) -{ - unsigned int size = capacity; - - if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) { - dkinfo[0] = 255; - dkinfo[1] = 63; - dkinfo[2] = size / (dkinfo[0] * dkinfo[1]); - } -#if defined (DEBUG_GEOMETRY) - printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name, - dkinfo[0], dkinfo[1], dkinfo[2]); -#endif - - return 0; -} - -static void sort(unsigned long sk[], unsigned int da[], unsigned int n, - unsigned int rev) -{ - unsigned int i, j, k, y; - unsigned long x; - - for (i = 0; i < n - 1; i++) { - k = i; - - for (j = k + 1; j < n; j++) - if (rev) { - if (sk[j] > sk[k]) - k = j; - } else { - if (sk[j] < sk[k]) - k = j; - } - - if (k != i) { - x = sk[k]; - sk[k] = sk[i]; - sk[i] = x; - y = da[k]; - da[k] = da[i]; - da[i] = y; - } - } - - return; -} - -static int reorder(struct hostdata *ha, unsigned long cursec, - unsigned int ihdlr, unsigned int il[], unsigned int n_ready) -{ - struct scsi_cmnd *SCpnt; - struct mscp *cpp; - unsigned int k, n; - unsigned int rev = 0, s = 1, r = 1; - unsigned int input_only = 1, overlap = 0; - unsigned long sl[n_ready], pl[n_ready], ll[n_ready]; - unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0; - unsigned long ioseek = 0; - - static unsigned int flushcount = 0, batchcount = 0, sortcount = 0; - static unsigned int readycount = 0, ovlcount = 0, inputcount = 0; - static unsigned int readysorted = 0, revcount = 0; - static unsigned long seeksorted = 0, seeknosort = 0; - - if (link_statistics && !(++flushcount % link_statistics)) - printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d" - " av %ldK as %ldK.\n", flushcount, batchcount, - inputcount, ovlcount, readycount, readysorted, sortcount, - revcount, seeknosort / (readycount + 1), - seeksorted / (readycount + 1)); - - if (n_ready <= 1) - return 0; - - for (n = 0; n < n_ready; n++) { - k = il[n]; - cpp = &ha->cp[k]; - SCpnt = cpp->SCpnt; - - if (!cpp->din) - input_only = 0; - - if (blk_rq_pos(SCpnt->request) < minsec) - minsec = blk_rq_pos(SCpnt->request); - if (blk_rq_pos(SCpnt->request) > maxsec) - maxsec = blk_rq_pos(SCpnt->request); - - sl[n] = blk_rq_pos(SCpnt->request); - ioseek += blk_rq_sectors(SCpnt->request); - - if (!n) - continue; - - if (sl[n] < sl[n - 1]) - s = 0; - if (sl[n] > sl[n - 1]) - r = 0; - - if (link_statistics) { - if (sl[n] > sl[n - 1]) - seek += sl[n] - sl[n - 1]; - else - seek += sl[n - 1] - sl[n]; - } - - } - - if (link_statistics) { - if (cursec > sl[0]) - seek += cursec - sl[0]; - else - seek += sl[0] - cursec; - } - - if (cursec > ((maxsec + minsec) / 2)) - rev = 1; - - if (ioseek > ((maxsec - minsec) / 2)) - rev = 0; - - if (!((rev && r) || (!rev && s))) - sort(sl, il, n_ready, rev); - - if (!input_only) - for (n = 0; n < n_ready; n++) { - k = il[n]; - cpp = &ha->cp[k]; - SCpnt = cpp->SCpnt; - ll[n] = blk_rq_sectors(SCpnt->request); - pl[n] = SCpnt->serial_number; - - if (!n) - continue; - - if ((sl[n] == sl[n - 1]) - || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n])) - || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) - overlap = 1; - } - - if (overlap) - sort(pl, il, n_ready, 0); - - if (link_statistics) { - if (cursec > sl[0]) - iseek = cursec - sl[0]; - else - iseek = sl[0] - cursec; - batchcount++; - readycount += n_ready; - seeknosort += seek / 1024; - if (input_only) - inputcount++; - if (overlap) { - ovlcount++; - seeksorted += iseek / 1024; - } else - seeksorted += (iseek + maxsec - minsec) / 1024; - if (rev && !r) { - revcount++; - readysorted += n_ready; - } - if (!rev && !s) { - sortcount++; - readysorted += n_ready; - } - } -#if defined(DEBUG_LINKED_COMMANDS) - if (link_statistics && (overlap || !(flushcount % link_statistics))) - for (n = 0; n < n_ready; n++) { - k = il[n]; - cpp = &ha->cp[k]; - SCpnt = cpp->SCpnt; - scmd_printk(KERN_INFO, SCpnt, - "%s mb %d fc %d nr %d sec %ld ns %u" - " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", - (ihdlr ? "ihdlr" : "qcomm"), - k, flushcount, - n_ready, blk_rq_pos(SCpnt->request), - blk_rq_sectors(SCpnt->request), cursec, YESNO(s), - YESNO(r), YESNO(rev), YESNO(input_only), - YESNO(overlap), cpp->din); - } -#endif - return overlap; -} - -static void flush_dev(struct scsi_device *dev, unsigned long cursec, - struct hostdata *ha, unsigned int ihdlr) -{ - struct scsi_cmnd *SCpnt; - struct mscp *cpp; - unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES]; - - for (k = 0; k < dev->host->can_queue; k++) { - - if (ha->cp_stat[k] != READY && ha->cp_stat[k] != IN_USE) - continue; - - cpp = &ha->cp[k]; - SCpnt = cpp->SCpnt; - - if (SCpnt->device != dev) - continue; - - if (ha->cp_stat[k] == IN_USE) - return; - - il[n_ready++] = k; - } - - if (reorder(ha, cursec, ihdlr, il, n_ready)) - n_ready = 1; - - for (n = 0; n < n_ready; n++) { - k = il[n]; - cpp = &ha->cp[k]; - SCpnt = cpp->SCpnt; - - if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { - scmd_printk(KERN_INFO, SCpnt, - "%s, mbox %d, adapter" - " busy, will abort.\n", - (ihdlr ? "ihdlr" : "qcomm"), - k); - ha->cp_stat[k] = ABORTING; - continue; - } - - ha->cp_stat[k] = IN_USE; - } -} - -static irqreturn_t ihdlr(struct Scsi_Host *shost) -{ - struct scsi_cmnd *SCpnt; - unsigned int i, k, c, status, tstatus, reg; - struct mssp *spp; - struct mscp *cpp; - struct hostdata *ha = (struct hostdata *)shost->hostdata; - int irq = shost->irq; - - /* Check if this board need to be serviced */ - if (!(inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) - goto none; - - ha->iocount++; - - if (do_trace) - printk("%s: ihdlr, enter, irq %d, count %d.\n", ha->board_name, irq, - ha->iocount); - - /* Check if this board is still busy */ - if (wait_on_busy(shost->io_port, 20 * MAXLOOP)) { - reg = inb(shost->io_port + REG_STATUS); - printk - ("%s: ihdlr, busy timeout error, irq %d, reg 0x%x, count %d.\n", - ha->board_name, irq, reg, ha->iocount); - goto none; - } - - spp = &ha->sp; - - /* Make a local copy just before clearing the interrupt indication */ - memcpy(spp, ha->sp_cpu_addr, sizeof(struct mssp)); - - /* Clear the completion flag and cp pointer on the dynamic copy of sp */ - memset(ha->sp_cpu_addr, 0, sizeof(struct mssp)); - - /* Read the status register to clear the interrupt indication */ - reg = inb(shost->io_port + REG_STATUS); - -#if defined (DEBUG_INTERRUPT) - { - unsigned char *bytesp; - int cnt; - bytesp = (unsigned char *)spp; - if (ha->iocount < 200) { - printk("sp[] ="); - for (cnt = 0; cnt < 15; cnt++) - printk(" 0x%x", bytesp[cnt]); - printk("\n"); - } - } -#endif - - /* Reject any sp with supspect data */ - if (spp->eoc == 0 && ha->iocount > 1) - printk - ("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n", - ha->board_name, irq, reg, ha->iocount); - if (spp->cpp_index < 0 || spp->cpp_index >= shost->can_queue) - printk - ("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n", - ha->board_name, spp->cpp_index, irq, reg, ha->iocount); - if (spp->eoc == 0 || spp->cpp_index < 0 - || spp->cpp_index >= shost->can_queue) - goto handled; - - /* Find the mailbox to be serviced on this board */ - i = spp->cpp_index; - - cpp = &(ha->cp[i]); - -#if defined(DEBUG_GENERATE_ABORTS) - if ((ha->iocount > 500) && ((ha->iocount % 500) < 3)) - goto handled; -#endif - - if (ha->cp_stat[i] == IGNORE) { - ha->cp_stat[i] = FREE; - goto handled; - } else if (ha->cp_stat[i] == LOCKED) { - ha->cp_stat[i] = FREE; - printk("%s: ihdlr, mbox %d unlocked, count %d.\n", ha->board_name, i, - ha->iocount); - goto handled; - } else if (ha->cp_stat[i] == FREE) { - printk("%s: ihdlr, mbox %d is free, count %d.\n", ha->board_name, i, - ha->iocount); - goto handled; - } else if (ha->cp_stat[i] == IN_RESET) - printk("%s: ihdlr, mbox %d is in reset.\n", ha->board_name, i); - else if (ha->cp_stat[i] != IN_USE) - panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", - ha->board_name, i, ha->cp_stat[i]); - - ha->cp_stat[i] = FREE; - SCpnt = cpp->SCpnt; - - if (SCpnt == NULL) - panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i); - - if (SCpnt->host_scribble == NULL) - panic("%s: ihdlr, mbox %d, SCpnt %p garbled.\n", ha->board_name, - i, SCpnt); - - if (*(unsigned int *)SCpnt->host_scribble != i) - panic("%s: ihdlr, mbox %d, index mismatch %d.\n", - ha->board_name, i, - *(unsigned int *)SCpnt->host_scribble); - - sync_dma(i, ha); - - if (linked_comm && SCpnt->device->queue_depth > 2 - && TLDEV(SCpnt->device->type)) - flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 1); - - tstatus = status_byte(spp->target_status); - -#if defined(DEBUG_GENERATE_ERRORS) - if ((ha->iocount > 500) && ((ha->iocount % 200) < 2)) - spp->adapter_status = 0x01; -#endif - - switch (spp->adapter_status) { - case ASOK: /* status OK */ - - /* Forces a reset if a disk drive keeps returning BUSY */ - if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) - status = DID_ERROR << 16; - - /* If there was a bus reset, redo operation on each target */ - else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK - && ha->target_redo[SCpnt->device->id][SCpnt-> - device-> - channel]) - status = DID_BUS_BUSY << 16; - - /* Works around a flaw in scsi.c */ - else if (tstatus == CHECK_CONDITION - && SCpnt->device->type == TYPE_DISK - && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR) - status = DID_BUS_BUSY << 16; - - else - status = DID_OK << 16; - - if (tstatus == GOOD) - ha->target_redo[SCpnt->device->id][SCpnt->device-> - channel] = 0; - - if (spp->target_status && SCpnt->device->type == TYPE_DISK && - (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 && - (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) - printk("%s: ihdlr, target %d.%d:%d, " - "target_status 0x%x, sense key 0x%x.\n", - ha->board_name, - SCpnt->device->channel, SCpnt->device->id, - (u8)SCpnt->device->lun, - spp->target_status, SCpnt->sense_buffer[2]); - - ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; - - if (ha->last_retried_pid == SCpnt->serial_number) - ha->retries = 0; - - break; - case ASST: /* Selection Time Out */ - case 0x02: /* Command Time Out */ - - if (ha->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) - status = DID_ERROR << 16; - else { - status = DID_TIME_OUT << 16; - ha->target_to[SCpnt->device->id][SCpnt->device-> - channel]++; - } - - break; - - /* Perform a limited number of internal retries */ - case 0x03: /* SCSI Bus Reset Received */ - case 0x04: /* Initial Controller Power-up */ - - for (c = 0; c <= shost->max_channel; c++) - for (k = 0; k < shost->max_id; k++) - ha->target_redo[k][c] = 1; - - if (SCpnt->device->type != TYPE_TAPE - && ha->retries < MAX_INTERNAL_RETRIES) { - -#if defined(DID_SOFT_ERROR) - status = DID_SOFT_ERROR << 16; -#else - status = DID_BUS_BUSY << 16; -#endif - - ha->retries++; - ha->last_retried_pid = SCpnt->serial_number; - } else - status = DID_ERROR << 16; - - break; - case 0x05: /* Unexpected Bus Phase */ - case 0x06: /* Unexpected Bus Free */ - case 0x07: /* Bus Parity Error */ - case 0x08: /* SCSI Hung */ - case 0x09: /* Unexpected Message Reject */ - case 0x0a: /* SCSI Bus Reset Stuck */ - case 0x0b: /* Auto Request-Sense Failed */ - case 0x0c: /* Controller Ram Parity Error */ - default: - status = DID_ERROR << 16; - break; - } - - SCpnt->result = status | spp->target_status; - -#if defined(DEBUG_INTERRUPT) - if (SCpnt->result || do_trace) -#else - if ((spp->adapter_status != ASOK && ha->iocount > 1000) || - (spp->adapter_status != ASOK && - spp->adapter_status != ASST && ha->iocount <= 1000) || - do_trace || msg_byte(spp->target_status)) -#endif - scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," - " reg 0x%x, count %d.\n", - i, spp->adapter_status, spp->target_status, - reg, ha->iocount); - - unmap_dma(i, ha); - - /* Set the command state to inactive */ - SCpnt->host_scribble = NULL; - - SCpnt->scsi_done(SCpnt); - - if (do_trace) - printk("%s: ihdlr, exit, irq %d, count %d.\n", ha->board_name, - irq, ha->iocount); - - handled: - return IRQ_HANDLED; - none: - return IRQ_NONE; -} - -static irqreturn_t do_interrupt_handler(int dummy, void *shap) -{ - struct Scsi_Host *shost; - unsigned int j; - unsigned long spin_flags; - irqreturn_t ret; - - /* Check if the interrupt must be processed by this handler */ - if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) - return IRQ_NONE; - shost = sh[j]; - - spin_lock_irqsave(shost->host_lock, spin_flags); - ret = ihdlr(shost); - spin_unlock_irqrestore(shost->host_lock, spin_flags); - return ret; -} - -static int eata2x_release(struct Scsi_Host *shost) -{ - struct hostdata *ha = (struct hostdata *)shost->hostdata; - unsigned int i; - - for (i = 0; i < shost->can_queue; i++) - kfree((&ha->cp[i])->sglist); - - for (i = 0; i < shost->can_queue; i++) - pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr, - sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL); - - if (ha->sp_cpu_addr) - pci_free_consistent(ha->pdev, sizeof(struct mssp), - ha->sp_cpu_addr, ha->sp_dma_addr); - - free_irq(shost->irq, &sha[ha->board_number]); - - if (shost->dma_channel != NO_DMA) - free_dma(shost->dma_channel); - - release_region(shost->io_port, shost->n_io_port); - scsi_unregister(shost); - return 0; -} - -#include "scsi_module.c" - -#ifndef MODULE -__setup("eata=", option_setup); -#endif /* end MODULE */ diff --git a/drivers/scsi/eata_generic.h b/drivers/scsi/eata_generic.h deleted file mode 100644 index 1a396c5e7f73..000000000000 --- a/drivers/scsi/eata_generic.h +++ /dev/null @@ -1,401 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/******************************************************** -* Header file for eata_dma.c and eata_pio.c * -* Linux EATA SCSI drivers * -* (c) 1993-96 Michael Neuffer * -* mike@i-Connect.Net * -* neuffer@mail.uni-mainz.de * -********************************************************* -* last change: 96/08/14 * -********************************************************/ - - -#ifndef _EATA_GENERIC_H -#define _EATA_GENERIC_H - - - -/********************************************* - * Misc. definitions * - *********************************************/ - -#define R_LIMIT 0x20000 - -#define MAXISA 4 -#define MAXEISA 16 -#define MAXPCI 16 -#define MAXIRQ 16 -#define MAXTARGET 16 -#define MAXCHANNEL 3 - -#define IS_ISA 'I' -#define IS_EISA 'E' -#define IS_PCI 'P' - -#define BROKEN_INQUIRY 1 - -#define BUSMASTER 0xff -#define PIO 0xfe - -#define EATA_SIGNATURE 0x45415441 /* BIG ENDIAN coded "EATA" sig. */ - -#define DPT_ID1 0x12 -#define DPT_ID2 0x14 - -#define ATT_ID1 0x06 -#define ATT_ID2 0x94 -#define ATT_ID3 0x0 - -#define NEC_ID1 0x38 -#define NEC_ID2 0xa3 -#define NEC_ID3 0x82 - - -#define EATA_CP_SIZE 44 - -#define MAX_PCI_DEVICES 32 /* Maximum # Of Devices Per Bus */ -#define MAX_METHOD_2 16 /* Max Devices For Method 2 */ -#define MAX_PCI_BUS 16 /* Maximum # Of Busses Allowed */ - -#define SG_SIZE 64 -#define SG_SIZE_BIG 252 /* max. 8096 elements, 64k */ - -#define UPPER_DEVICE_QUEUE_LIMIT 64 /* The limit we have to set for the - * device queue to keep the broken - * midlevel SCSI code from producing - * bogus timeouts - */ - -#define TYPE_DISK_QUEUE 16 -#define TYPE_TAPE_QUEUE 4 -#define TYPE_ROM_QUEUE 4 -#define TYPE_OTHER_QUEUE 2 - -#define FREE 0 -#define OK 0 -#define NO_TIMEOUT 0 -#define USED 1 -#define TIMEOUT 2 -#define RESET 4 -#define LOCKED 8 -#define ABORTED 16 - -#define READ 0 -#define WRITE 1 -#define OTHER 2 - -#define HD(cmd) ((hostdata *)&(cmd->device->host->hostdata)) -#define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble)) -#define SD(host) ((hostdata *)&(host->hostdata)) - -/*********************************************** - * EATA Command & Register definitions * - ***********************************************/ -#define PCI_REG_DPTconfig 0x40 -#define PCI_REG_PumpModeAddress 0x44 -#define PCI_REG_PumpModeData 0x48 -#define PCI_REG_ConfigParam1 0x50 -#define PCI_REG_ConfigParam2 0x54 - - -#define EATA_CMD_PIO_SETUPTEST 0xc6 -#define EATA_CMD_PIO_READ_CONFIG 0xf0 -#define EATA_CMD_PIO_SET_CONFIG 0xf1 -#define EATA_CMD_PIO_SEND_CP 0xf2 -#define EATA_CMD_PIO_RECEIVE_SP 0xf3 -#define EATA_CMD_PIO_TRUNC 0xf4 - -#define EATA_CMD_RESET 0xf9 -#define EATA_CMD_IMMEDIATE 0xfa - -#define EATA_CMD_DMA_READ_CONFIG 0xfd -#define EATA_CMD_DMA_SET_CONFIG 0xfe -#define EATA_CMD_DMA_SEND_CP 0xff - -#define ECS_EMULATE_SENSE 0xd4 - -#define EATA_GENERIC_ABORT 0x00 -#define EATA_SPECIFIC_RESET 0x01 -#define EATA_BUS_RESET 0x02 -#define EATA_SPECIFIC_ABORT 0x03 -#define EATA_QUIET_INTR 0x04 -#define EATA_COLD_BOOT_HBA 0x06 /* Only as a last resort */ -#define EATA_FORCE_IO 0x07 - -#define HA_CTRLREG 0x206 /* control register for HBA */ -#define HA_CTRL_DISINT 0x02 /* CTRLREG: disable interrupts */ -#define HA_CTRL_RESCPU 0x04 /* CTRLREG: reset processor */ -#define HA_CTRL_8HEADS 0x08 /* CTRLREG: set for drives with* - * >=8 heads (WD1003 rudimentary :-) */ - -#define HA_WCOMMAND 0x07 /* command register offset */ -#define HA_WIFC 0x06 /* immediate command offset */ -#define HA_WCODE 0x05 -#define HA_WCODE2 0x04 -#define HA_WDMAADDR 0x02 /* DMA address LSB offset */ -#define HA_RAUXSTAT 0x08 /* aux status register offset*/ -#define HA_RSTATUS 0x07 /* status register offset */ -#define HA_RDATA 0x00 /* data register (16bit) */ -#define HA_WDATA 0x00 /* data register (16bit) */ - -#define HA_ABUSY 0x01 /* aux busy bit */ -#define HA_AIRQ 0x02 /* aux IRQ pending bit */ -#define HA_SERROR 0x01 /* pr. command ended in error*/ -#define HA_SMORE 0x02 /* more data soon to come */ -#define HA_SCORR 0x04 /* data corrected */ -#define HA_SDRQ 0x08 /* data request active */ -#define HA_SSC 0x10 /* seek complete */ -#define HA_SFAULT 0x20 /* write fault */ -#define HA_SREADY 0x40 /* drive ready */ -#define HA_SBUSY 0x80 /* drive busy */ -#define HA_SDRDY HA_SSC+HA_SREADY+HA_SDRQ - -/********************************************** - * Message definitions * - **********************************************/ - -#define HA_NO_ERROR 0x00 /* No Error */ -#define HA_ERR_SEL_TO 0x01 /* Selection Timeout */ -#define HA_ERR_CMD_TO 0x02 /* Command Timeout */ -#define HA_BUS_RESET 0x03 /* SCSI Bus Reset Received */ -#define HA_INIT_POWERUP 0x04 /* Initial Controller Power-up */ -#define HA_UNX_BUSPHASE 0x05 /* Unexpected Bus Phase */ -#define HA_UNX_BUS_FREE 0x06 /* Unexpected Bus Free */ -#define HA_BUS_PARITY 0x07 /* Bus Parity Error */ -#define HA_SCSI_HUNG 0x08 /* SCSI Hung */ -#define HA_UNX_MSGRJCT 0x09 /* Unexpected Message Rejected */ -#define HA_RESET_STUCK 0x0a /* SCSI Bus Reset Stuck */ -#define HA_RSENSE_FAIL 0x0b /* Auto Request-Sense Failed */ -#define HA_PARITY_ERR 0x0c /* Controller Ram Parity Error */ -#define HA_CP_ABORT_NA 0x0d /* Abort Message sent to non-active cmd */ -#define HA_CP_ABORTED 0x0e /* Abort Message sent to active cmd */ -#define HA_CP_RESET_NA 0x0f /* Reset Message sent to non-active cmd */ -#define HA_CP_RESET 0x10 /* Reset Message sent to active cmd */ -#define HA_ECC_ERR 0x11 /* Controller Ram ECC Error */ -#define HA_PCI_PARITY 0x12 /* PCI Parity Error */ -#define HA_PCI_MABORT 0x13 /* PCI Master Abort */ -#define HA_PCI_TABORT 0x14 /* PCI Target Abort */ -#define HA_PCI_STABORT 0x15 /* PCI Signaled Target Abort */ - -/********************************************** - * Other definitions * - **********************************************/ - -struct reg_bit { /* reading this one will clear the interrupt */ - __u8 error:1; /* previous command ended in an error */ - __u8 more:1; /* more DATA coming soon, poll BSY & DRQ (PIO) */ - __u8 corr:1; /* data read was successfully corrected with ECC*/ - __u8 drq:1; /* data request active */ - __u8 sc:1; /* seek complete */ - __u8 fault:1; /* write fault */ - __u8 ready:1; /* drive ready */ - __u8 busy:1; /* controller busy */ -}; - -struct reg_abit { /* reading this won't clear the interrupt */ - __u8 abusy:1; /* auxiliary busy */ - __u8 irq:1; /* set when drive interrupt is asserted */ - __u8 dummy:6; -}; - -struct eata_register { /* EATA register set */ - __u8 data_reg[2]; /* R, couldn't figure this one out */ - __u8 cp_addr[4]; /* W, CP address register */ - union { - __u8 command; /* W, command code: [read|set] conf, send CP*/ - struct reg_bit status; /* R, see register_bit1 */ - __u8 statusbyte; - } ovr; - struct reg_abit aux_stat; /* R, see register_bit2 */ -}; - -struct get_conf { /* Read Configuration Array */ - __u32 len; /* Should return 0x22, 0x24, etc */ - __u32 signature; /* Signature MUST be "EATA" */ - __u8 version2:4, - version:4; /* EATA Version level */ - __u8 OCS_enabled:1, /* Overlap Command Support enabled */ - TAR_support:1, /* SCSI Target Mode supported */ - TRNXFR:1, /* Truncate Transfer Cmd not necessary * - * Only used in PIO Mode */ - MORE_support:1, /* MORE supported (only PIO Mode) */ - DMA_support:1, /* DMA supported Driver uses only * - * this mode */ - DMA_valid:1, /* DRQ value in Byte 30 is valid */ - ATA:1, /* ATA device connected (not supported) */ - HAA_valid:1; /* Hostadapter Address is valid */ - - __u16 cppadlen; /* Number of pad bytes send after CD data * - * set to zero for DMA commands */ - __u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. * - * if not, zero is returned */ - __u32 cplen; /* CP length: number of valid cp bytes */ - __u32 splen; /* Number of bytes returned after * - * Receive SP command */ - __u16 queuesiz; /* max number of queueable CPs */ - __u16 dummy; - __u16 SGsiz; /* max number of SG table entries */ - __u8 IRQ:4, /* IRQ used this HA */ - IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */ - SECOND:1, /* This is a secondary controller */ - DMA_channel:2; /* DRQ index, DRQ is 2comp of DRQX */ - __u8 sync; /* device at ID 7 tru 0 is running in * - * synchronous mode, this will disappear */ - __u8 DSBLE:1, /* ISA i/o addressing is disabled */ - FORCADR:1, /* i/o address has been forced */ - SG_64K:1, - SG_UAE:1, - :4; - __u8 MAX_ID:5, /* Max number of SCSI target IDs */ - MAX_CHAN:3; /* Number of SCSI busses on HBA */ - __u8 MAX_LUN; /* Max number of LUNs */ - __u8 :3, - AUTOTRM:1, - M1_inst:1, - ID_qest:1, /* Raidnum ID is questionable */ - is_PCI:1, /* HBA is PCI */ - is_EISA:1; /* HBA is EISA */ - __u8 RAIDNUM; /* unique HBA identifier */ - __u8 unused[474]; -}; - -struct eata_sg_list -{ - __u32 data; - __u32 len; -}; - -struct eata_ccb { /* Send Command Packet structure */ - - __u8 SCSI_Reset:1, /* Cause a SCSI Bus reset on the cmd */ - HBA_Init:1, /* Cause Controller to reinitialize */ - Auto_Req_Sen:1, /* Do Auto Request Sense on errors */ - scatter:1, /* Data Ptr points to a SG Packet */ - Resrvd:1, /* RFU */ - Interpret:1, /* Interpret the SCSI cdb of own use */ - DataOut:1, /* Data Out phase with command */ - DataIn:1; /* Data In phase with command */ - __u8 reqlen; /* Request Sense Length * - * Valid if Auto_Req_Sen=1 */ - __u8 unused[3]; - __u8 FWNEST:1, /* send cmd to phys RAID component */ - unused2:7; - __u8 Phsunit:1, /* physical unit on mirrored pair */ - I_AT:1, /* inhibit address translation */ - I_HBA_C:1, /* HBA inhibit caching */ - unused3:5; - - __u8 cp_id:5, /* SCSI Device ID of target */ - cp_channel:3; /* SCSI Channel # of HBA */ - __u8 cp_lun:3, - :2, - cp_luntar:1, /* CP is for target ROUTINE */ - cp_dispri:1, /* Grant disconnect privilege */ - cp_identify:1; /* Always TRUE */ - __u8 cp_msg1; /* Message bytes 0-3 */ - __u8 cp_msg2; - __u8 cp_msg3; - __u8 cp_cdb[12]; /* Command Descriptor Block */ - __u32 cp_datalen; /* Data Transfer Length * - * If scatter=1 len of sg package */ - void *cp_viraddr; /* address of this ccb */ - __u32 cp_dataDMA; /* Data Address, if scatter=1 * - * address of scatter packet */ - __u32 cp_statDMA; /* address for Status Packet */ - __u32 cp_reqDMA; /* Request Sense Address, used if * - * CP command ends with error */ - /* Additional CP info begins here */ - __u32 timestamp; /* Needed to measure command latency */ - __u32 timeout; - __u8 sizeindex; - __u8 rw_latency; - __u8 retries; - __u8 status; /* status of this queueslot */ - struct scsi_cmnd *cmd; /* address of cmd */ - struct eata_sg_list *sg_list; -}; - - -struct eata_sp { - __u8 hba_stat:7, /* HBA status */ - EOC:1; /* True if command finished */ - __u8 scsi_stat; /* Target SCSI status */ - __u8 reserved[2]; - __u32 residue_len; /* Number of bytes not transferred */ - struct eata_ccb *ccb; /* Address set in COMMAND PACKET */ - __u8 msg[12]; -}; - -typedef struct hstd { - __u8 vendor[9]; - __u8 name[18]; - __u8 revision[6]; - __u8 EATA_revision; - __u32 firmware_revision; - __u8 HBA_number; - __u8 bustype; /* bustype of HBA */ - __u8 channel; /* # of avail. scsi channels */ - __u8 state; /* state of HBA */ - __u8 primary; /* true if primary */ - __u8 more_support:1, /* HBA supports MORE flag */ - immediate_support:1, /* HBA supports IMMEDIATE CMDs*/ - broken_INQUIRY:1; /* This is an EISA HBA with * - * broken INQUIRY */ - __u8 do_latency; /* Latency measurement flag */ - __u32 reads[13]; - __u32 writes[13]; - __u32 reads_lat[12][4]; - __u32 writes_lat[12][4]; - __u32 all_lat[4]; - __u8 resetlevel[MAXCHANNEL]; - __u32 last_ccb; /* Last used ccb */ - __u32 cplen; /* size of CP in words */ - __u16 cppadlen; /* pad length of cp in words */ - __u16 queuesize; - __u16 sgsize; /* # of entries in the SG list*/ - __u16 devflags; /* bits set for detected devices */ - __u8 hostid; /* SCSI ID of HBA */ - __u8 moresupport; /* HBA supports MORE flag */ - struct Scsi_Host *next; - struct Scsi_Host *prev; - struct pci_dev *pdev; /* PCI device or NULL for non PCI */ - struct eata_sp sp; /* status packet */ - struct eata_ccb ccb[0]; /* ccb array begins here */ -}hostdata; - -/* structure for max. 2 emulated drives */ -struct drive_geom_emul { - __u8 trans; /* translation flag 1=transl */ - __u8 channel; /* SCSI channel number */ - __u8 HBA; /* HBA number (prim/sec) */ - __u8 id; /* drive id */ - __u8 lun; /* drive lun */ - __u32 heads; /* number of heads */ - __u32 sectors; /* number of sectors */ - __u32 cylinder; /* number of cylinders */ -}; - -struct geom_emul { - __u8 bios_drives; /* number of emulated drives */ - struct drive_geom_emul drv[2]; /* drive structures */ -}; - -#endif /* _EATA_GENERIC_H */ - -/* - * Overrides for Emacs so that we almost follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * tab-width: 8 - * End: - */ diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c deleted file mode 100644 index 4299fa485622..000000000000 --- a/drivers/scsi/eata_pio.c +++ /dev/null @@ -1,966 +0,0 @@ -/************************************************************ - * * - * Linux EATA SCSI PIO driver * - * * - * based on the CAM document CAM/89-004 rev. 2.0c, * - * DPT's driver kit, some internal documents and source, * - * and several other Linux scsi drivers and kernel docs. * - * * - * The driver currently: * - * -supports all EATA-PIO boards * - * -only supports DASD devices * - * * - * (c)1993-96 Michael Neuffer, Alfred Arnold * - * neuffer@goofy.zdv.uni-mainz.de * - * a.arnold@kfa-juelich.de * - * * - * Updated 2002 by Alan Cox for * - * Linux 2.5.x and the newer locking and error handling * - * * - * This program is free software; you can redistribute it * - * and/or modify it under the terms of the GNU General * - * Public License as published by the Free Software * - * Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the * - * implied warranty of MERCHANTABILITY or FITNESS FOR A * - * PARTICULAR PURPOSE. See the GNU General Public License * - * for more details. * - * * - * You should have received a copy of the GNU General * - * Public License along with this kernel; if not, write to * - * the Free Software Foundation, Inc., 675 Mass Ave, * - * Cambridge, MA 02139, USA. * - * * - * For the avoidance of doubt the "preferred form" of this * - * code is one which is in an open non patent encumbered * - * format. Where cryptographic key signing forms part of * - * the process of creating an executable the information * - * including keys needed to generate an equivalently * - * functional executable are deemed to be part of the * - * source code are deemed to be part of the source code. * - * * - ************************************************************ - * last change: 2002/11/02 OS: Linux 2.5.45 * - ************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "eata_generic.h" -#include "eata_pio.h" - - -static unsigned int ISAbases[MAXISA] = { - 0x1F0, 0x170, 0x330, 0x230 -}; - -static unsigned int ISAirqs[MAXISA] = { - 14, 12, 15, 11 -}; - -static unsigned char EISAbases[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 -}; - -static unsigned int registered_HBAs; -static struct Scsi_Host *last_HBA; -static struct Scsi_Host *first_HBA; -static unsigned char reg_IRQ[16]; -static unsigned char reg_IRQL[16]; -static unsigned long int_counter; -static unsigned long queue_counter; - -static struct scsi_host_template driver_template; - -static int eata_pio_show_info(struct seq_file *m, struct Scsi_Host *shost) -{ - seq_printf(m, "EATA (Extended Attachment) PIO driver version: " - "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); - seq_printf(m, "queued commands: %10ld\n" - "processed interrupts:%10ld\n", queue_counter, int_counter); - seq_printf(m, "\nscsi%-2d: HBA %.10s\n", - shost->host_no, SD(shost)->name); - seq_printf(m, "Firmware revision: v%s\n", - SD(shost)->revision); - seq_puts(m, "IO: PIO\n"); - seq_printf(m, "Base IO : %#.4x\n", (u32) shost->base); - seq_printf(m, "Host Bus: %s\n", - (SD(shost)->bustype == 'P')?"PCI ": - (SD(shost)->bustype == 'E')?"EISA":"ISA "); - return 0; -} - -static int eata_pio_release(struct Scsi_Host *sh) -{ - hostdata *hd = SD(sh); - if (sh->irq && reg_IRQ[sh->irq] == 1) - free_irq(sh->irq, NULL); - else - reg_IRQ[sh->irq]--; - if (SD(sh)->channel == 0) { - if (sh->io_port && sh->n_io_port) - release_region(sh->io_port, sh->n_io_port); - } - /* At this point the PCI reference can go */ - if (hd->pdev) - pci_dev_put(hd->pdev); - return 1; -} - -static void IncStat(struct scsi_pointer *SCp, unsigned int Increment) -{ - SCp->ptr += Increment; - if ((SCp->this_residual -= Increment) == 0) { - if ((--SCp->buffers_residual) == 0) - SCp->Status = 0; - else { - SCp->buffer++; - SCp->ptr = sg_virt(SCp->buffer); - SCp->this_residual = SCp->buffer->length; - } - } -} - -static irqreturn_t eata_pio_int_handler(int irq, void *dev_id); - -static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - irqreturn_t ret; - - spin_lock_irqsave(dev->host_lock, flags); - ret = eata_pio_int_handler(irq, dev_id); - spin_unlock_irqrestore(dev->host_lock, flags); - return ret; -} - -static irqreturn_t eata_pio_int_handler(int irq, void *dev_id) -{ - unsigned int eata_stat = 0xfffff; - struct scsi_cmnd *cmd; - hostdata *hd; - struct eata_ccb *cp; - unsigned long base; - unsigned int x, z; - struct Scsi_Host *sh; - unsigned short zwickel = 0; - unsigned char stat, odd; - irqreturn_t ret = IRQ_NONE; - - for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) - { - if (sh->irq != irq) - continue; - if (inb(sh->base + HA_RSTATUS) & HA_SBUSY) - continue; - - int_counter++; - ret = IRQ_HANDLED; - - hd = SD(sh); - - cp = &hd->ccb[0]; - cmd = cp->cmd; - base = cmd->device->host->base; - - do { - stat = inb(base + HA_RSTATUS); - if (stat & HA_SDRQ) { - if (cp->DataIn) { - z = 256; - odd = 0; - while ((cmd->SCp.Status) && ((z > 0) || (odd))) { - if (odd) { - *(cmd->SCp.ptr) = zwickel >> 8; - IncStat(&cmd->SCp, 1); - odd = 0; - } - x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); - insw(base + HA_RDATA, cmd->SCp.ptr, x); - z -= x; - IncStat(&cmd->SCp, 2 * x); - if ((z > 0) && (cmd->SCp.this_residual == 1)) { - zwickel = inw(base + HA_RDATA); - *(cmd->SCp.ptr) = zwickel & 0xff; - IncStat(&cmd->SCp, 1); - z--; - odd = 1; - } - } - while (z > 0) { - zwickel = inw(base + HA_RDATA); - z--; - } - } else { /* cp->DataOut */ - - odd = 0; - z = 256; - while ((cmd->SCp.Status) && ((z > 0) || (odd))) { - if (odd) { - zwickel += *(cmd->SCp.ptr) << 8; - IncStat(&cmd->SCp, 1); - outw(zwickel, base + HA_RDATA); - z--; - odd = 0; - } - x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); - outsw(base + HA_RDATA, cmd->SCp.ptr, x); - z -= x; - IncStat(&cmd->SCp, 2 * x); - if ((z > 0) && (cmd->SCp.this_residual == 1)) { - zwickel = *(cmd->SCp.ptr); - zwickel &= 0xff; - IncStat(&cmd->SCp, 1); - odd = 1; - } - } - while (z > 0 || odd) { - outw(zwickel, base + HA_RDATA); - z--; - odd = 0; - } - } - } - } - while ((stat & HA_SDRQ) || ((stat & HA_SMORE) && hd->moresupport)); - - /* terminate handler if HBA goes busy again, i.e. transfers - * more data */ - - if (stat & HA_SBUSY) - break; - - /* OK, this is quite stupid, but I haven't found any correct - * way to get HBA&SCSI status so far */ - - if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { - cmd->result = (DID_OK << 16); - hd->devflags |= (1 << cp->cp_id); - } else if (hd->devflags & (1 << cp->cp_id)) - cmd->result = (DID_OK << 16) + 0x02; - else - cmd->result = (DID_NO_CONNECT << 16); - - if (cp->status == LOCKED) { - cp->status = FREE; - eata_stat = inb(base + HA_RSTATUS); - printk(KERN_CRIT "eata_pio: int_handler, freeing locked " "queueslot\n"); - return ret; - } -#if DBG_INTR2 - if (stat != 0x50) - printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat, cmd->result); -#endif - - cp->status = FREE; /* now we can release the slot */ - - cmd->scsi_done(cmd); - } - - return ret; -} - -static inline unsigned int eata_pio_send_command(unsigned long base, unsigned char command) -{ - unsigned int loop = 50; - - while (inb(base + HA_RSTATUS) & HA_SBUSY) - if (--loop == 0) - return 1; - - /* Enable interrupts for HBA. It is not the best way to do it at this - * place, but I hope that it doesn't interfere with the IDE driver - * initialization this way */ - - outb(HA_CTRL_8HEADS, base + HA_CTRLREG); - - outb(command, base + HA_WCOMMAND); - return 0; -} - -static int eata_pio_queue_lck(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) -{ - unsigned int x, y; - unsigned long base; - - hostdata *hd; - struct Scsi_Host *sh; - struct eata_ccb *cp; - - queue_counter++; - - hd = HD(cmd); - sh = cmd->device->host; - base = sh->base; - - /* use only slot 0, as 2001 can handle only one cmd at a time */ - - y = x = 0; - - if (hd->ccb[y].status != FREE) { - - DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n", sh->can_queue, x, y)); -#if DEBUG_EATA - panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld " "intrno: %ld\n", queue_counter, int_counter); -#else - panic(KERN_EMERG "eata_pio: run out of queue slots....\n"); -#endif - } - - cp = &hd->ccb[y]; - - memset(cp, 0, sizeof(struct eata_ccb)); - - cp->status = USED; /* claim free slot */ - - DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, - "eata_pio_queue 0x%p, y %d\n", cmd, y)); - - cmd->scsi_done = (void *) done; - - if (cmd->sc_data_direction == DMA_TO_DEVICE) - cp->DataOut = 1; /* Output mode */ - else - cp->DataIn = 0; /* Input mode */ - - cp->Interpret = (cmd->device->id == hd->hostid); - cp->cp_datalen = cpu_to_be32(scsi_bufflen(cmd)); - cp->Auto_Req_Sen = 0; - cp->cp_reqDMA = 0; - cp->reqlen = 0; - - cp->cp_id = cmd->device->id; - cp->cp_lun = cmd->device->lun; - cp->cp_dispri = 0; - cp->cp_identify = 1; - memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); - - cp->cp_statDMA = 0; - - cp->cp_viraddr = cp; - cp->cmd = cmd; - cmd->host_scribble = (char *) &hd->ccb[y]; - - if (!scsi_bufflen(cmd)) { - cmd->SCp.buffers_residual = 1; - cmd->SCp.ptr = NULL; - cmd->SCp.this_residual = 0; - cmd->SCp.buffer = NULL; - } else { - cmd->SCp.buffer = scsi_sglist(cmd); - cmd->SCp.buffers_residual = scsi_sg_count(cmd); - cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); - cmd->SCp.this_residual = cmd->SCp.buffer->length; - } - cmd->SCp.Status = (cmd->SCp.this_residual != 0); /* TRUE as long as bytes - * are to transfer */ - - if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) { - cmd->result = DID_BUS_BUSY << 16; - scmd_printk(KERN_NOTICE, cmd, - "eata_pio_queue pid 0x%p, HBA busy, " - "returning DID_BUS_BUSY, done.\n", cmd); - done(cmd); - cp->status = FREE; - return 0; - } - /* FIXME: timeout */ - while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) - cpu_relax(); - outsw(base + HA_RDATA, cp, hd->cplen); - outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); - for (x = 0; x < hd->cppadlen; x++) - outw(0, base + HA_RDATA); - - DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, - "Queued base %#.4lx cmd: 0x%p " - "slot %d irq %d\n", sh->base, cmd, y, sh->irq)); - - return 0; -} - -static DEF_SCSI_QCMD(eata_pio_queue) - -static int eata_pio_abort(struct scsi_cmnd *cmd) -{ - unsigned int loop = 100; - - DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, - "eata_pio_abort called pid: 0x%p\n", cmd)); - - while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) - if (--loop == 0) { - printk(KERN_WARNING "eata_pio: abort, timeout error.\n"); - return FAILED; - } - if (CD(cmd)->status == FREE) { - DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_NOT_RUNNING\n")); - return FAILED; - } - if (CD(cmd)->status == USED) { - DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_BUSY\n")); - /* We want to sleep a bit more here */ - return FAILED; /* SNOOZE */ - } - if (CD(cmd)->status == RESET) { - printk(KERN_WARNING "eata_pio: abort, command reset error.\n"); - return FAILED; - } - if (CD(cmd)->status == LOCKED) { - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot " "locked.\n")); - return FAILED; - } - panic("eata_pio: abort: invalid slot status\n"); -} - -static int eata_pio_host_reset(struct scsi_cmnd *cmd) -{ - unsigned int x, limit = 0; - unsigned char success = 0; - struct scsi_cmnd *sp; - struct Scsi_Host *host = cmd->device->host; - - DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, - "eata_pio_reset called\n")); - - spin_lock_irq(host->host_lock); - - if (HD(cmd)->state == RESET) { - printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n"); - spin_unlock_irq(host->host_lock); - return FAILED; - } - - /* force all slots to be free */ - - for (x = 0; x < cmd->device->host->can_queue; x++) { - - if (HD(cmd)->ccb[x].status == FREE) - continue; - - sp = HD(cmd)->ccb[x].cmd; - HD(cmd)->ccb[x].status = RESET; - printk(KERN_WARNING "eata_pio_reset: slot %d in reset.\n", x); - - if (sp == NULL) - panic("eata_pio_reset: slot %d, sp==NULL.\n", x); - } - - /* hard reset the HBA */ - outb(EATA_CMD_RESET, cmd->device->host->base + HA_WCOMMAND); - - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n")); - HD(cmd)->state = RESET; - - spin_unlock_irq(host->host_lock); - msleep(3000); - spin_lock_irq(host->host_lock); - - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit)); - - for (x = 0; x < cmd->device->host->can_queue; x++) { - - /* Skip slots already set free by interrupt */ - if (HD(cmd)->ccb[x].status != RESET) - continue; - - sp = HD(cmd)->ccb[x].cmd; - sp->result = DID_RESET << 16; - - /* This mailbox is terminated */ - printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n", x); - HD(cmd)->ccb[x].status = FREE; - - sp->scsi_done(sp); - } - - HD(cmd)->state = 0; - - spin_unlock_irq(host->host_lock); - - if (success) { /* hmmm... */ - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n")); - return SUCCESS; - } else { - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, wakeup.\n")); - return FAILED; - } -} - -static char *get_pio_board_data(unsigned long base, unsigned int irq, unsigned int id, unsigned long cplen, unsigned short cppadlen) -{ - struct eata_ccb cp; - static char buff[256]; - int z; - - memset(&cp, 0, sizeof(struct eata_ccb)); - memset(buff, 0, sizeof(buff)); - - cp.DataIn = 1; - cp.Interpret = 1; /* Interpret command */ - - cp.cp_datalen = cpu_to_be32(254); - cp.cp_dataDMA = cpu_to_be32(0); - - cp.cp_id = id; - cp.cp_lun = 0; - - cp.cp_cdb[0] = INQUIRY; - cp.cp_cdb[1] = 0; - cp.cp_cdb[2] = 0; - cp.cp_cdb[3] = 0; - cp.cp_cdb[4] = 254; - cp.cp_cdb[5] = 0; - - if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) - return NULL; - - while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) - cpu_relax(); - - outsw(base + HA_RDATA, &cp, cplen); - outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); - for (z = 0; z < cppadlen; z++) - outw(0, base + HA_RDATA); - - while (inb(base + HA_RSTATUS) & HA_SBUSY) - cpu_relax(); - - if (inb(base + HA_RSTATUS) & HA_SERROR) - return NULL; - else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) - return NULL; - else { - insw(base + HA_RDATA, &buff, 127); - while (inb(base + HA_RSTATUS) & HA_SDRQ) - inw(base + HA_RDATA); - return buff; - } -} - -static int get_pio_conf_PIO(unsigned long base, struct get_conf *buf) -{ - unsigned long loop = HZ / 2; - int z; - unsigned short *p; - - if (!request_region(base, 9, "eata_pio")) - return 0; - - memset(buf, 0, sizeof(struct get_conf)); - - while (inb(base + HA_RSTATUS) & HA_SBUSY) - if (--loop == 0) - goto fail; - - DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#lx\n", base)); - eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG); - - loop = 50; - for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) { - while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) - if (--loop == 0) - goto fail; - - loop = 50; - *p = inw(base + HA_RDATA); - } - if (inb(base + HA_RSTATUS) & HA_SERROR) { - DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during " - "transfer for HBA at %lx\n", base)); - goto fail; - } - - if (cpu_to_be32(EATA_SIGNATURE) != buf->signature) - goto fail; - - DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " - "at %#4lx EATA Level: %x\n", - base, (unsigned int) (buf->version))); - - while (inb(base + HA_RSTATUS) & HA_SDRQ) - inw(base + HA_RDATA); - - if (!ALLOW_DMA_BOARDS) { - for (z = 0; z < MAXISA; z++) - if (base == ISAbases[z]) { - buf->IRQ = ISAirqs[z]; - break; - } - } - - return 1; - - fail: - release_region(base, 9); - return 0; -} - -static void print_pio_config(struct get_conf *gc) -{ - printk("Please check values: (read config data)\n"); - printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n", be32_to_cpu(gc->len), gc->version, gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support); - printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], gc->scsi_id[1], be16_to_cpu(gc->queuesiz), be16_to_cpu(gc->SGsiz), gc->SECOND); - printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", gc->IRQ, gc->IRQ_TR, gc->FORCADR, gc->MAX_CHAN, gc->ID_qest); -} - -static unsigned int print_selftest(unsigned int base) -{ - unsigned char buffer[512]; -#ifdef VERBOSE_SETUP - int z; -#endif - - printk("eata_pio: executing controller self test & setup...\n"); - while (inb(base + HA_RSTATUS) & HA_SBUSY); - outb(EATA_CMD_PIO_SETUPTEST, base + HA_WCOMMAND); - do { - while (inb(base + HA_RSTATUS) & HA_SBUSY) - /* nothing */ ; - if (inb(base + HA_RSTATUS) & HA_SDRQ) { - insw(base + HA_RDATA, &buffer, 256); -#ifdef VERBOSE_SETUP - /* no beeps please... */ - for (z = 0; z < 511 && buffer[z]; z++) - if (buffer[z] != 7) - printk("%c", buffer[z]); -#endif - } - } while (inb(base + HA_RSTATUS) & (HA_SBUSY | HA_SDRQ)); - - return (!(inb(base + HA_RSTATUS) & HA_SERROR)); -} - -static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev) -{ - unsigned long size = 0; - char *buff; - unsigned long cplen; - unsigned short cppadlen; - struct Scsi_Host *sh; - hostdata *hd; - - DBG(DBG_REGISTER, print_pio_config(gc)); - - if (gc->DMA_support) { - printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base); - if (!ALLOW_DMA_BOARDS) - return 0; - } - - if ((buff = get_pio_board_data(base, gc->IRQ, gc->scsi_id[3], cplen = (cpu_to_be32(gc->cplen) + 1) / 2, cppadlen = (cpu_to_be16(gc->cppadlen) + 1) / 2)) == NULL) { - printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", base); - return 0; - } - - if (!print_selftest(base) && !ALLOW_DMA_BOARDS) { - printk("HBA at %#lx failed while performing self test & setup.\n", base); - return 0; - } - - size = sizeof(hostdata) + (sizeof(struct eata_ccb) * be16_to_cpu(gc->queuesiz)); - - sh = scsi_register(&driver_template, size); - if (sh == NULL) - return 0; - - if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */ - if (!request_irq(gc->IRQ, do_eata_pio_int_handler, 0, "EATA-PIO", sh)) { - reg_IRQ[gc->IRQ]++; - if (!gc->IRQ_TR) - reg_IRQL[gc->IRQ] = 1; /* IRQ is edge triggered */ - } else { - printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ); - return 0; - } - } else { /* More than one HBA on this IRQ */ - if (reg_IRQL[gc->IRQ]) { - printk("Can't support more than one HBA on this IRQ,\n" " if the IRQ is edge triggered. Sorry.\n"); - return 0; - } else - reg_IRQ[gc->IRQ]++; - } - - hd = SD(sh); - - memset(hd->ccb, 0, (sizeof(struct eata_ccb) * be16_to_cpu(gc->queuesiz))); - memset(hd->reads, 0, sizeof(hd->reads)); - - strlcpy(SD(sh)->vendor, &buff[8], sizeof(SD(sh)->vendor)); - strlcpy(SD(sh)->name, &buff[16], sizeof(SD(sh)->name)); - SD(sh)->revision[0] = buff[32]; - SD(sh)->revision[1] = buff[33]; - SD(sh)->revision[2] = buff[34]; - SD(sh)->revision[3] = '.'; - SD(sh)->revision[4] = buff[35]; - SD(sh)->revision[5] = 0; - - switch (be32_to_cpu(gc->len)) { - case 0x1c: - SD(sh)->EATA_revision = 'a'; - break; - case 0x1e: - SD(sh)->EATA_revision = 'b'; - break; - case 0x22: - SD(sh)->EATA_revision = 'c'; - break; - case 0x24: - SD(sh)->EATA_revision = 'z'; - break; - default: - SD(sh)->EATA_revision = '?'; - } - - if (be32_to_cpu(gc->len) >= 0x22) { - if (gc->is_PCI) - hd->bustype = IS_PCI; - else if (gc->is_EISA) - hd->bustype = IS_EISA; - else - hd->bustype = IS_ISA; - } else { - if (buff[21] == '4') - hd->bustype = IS_PCI; - else if (buff[21] == '2') - hd->bustype = IS_EISA; - else - hd->bustype = IS_ISA; - } - - SD(sh)->cplen = cplen; - SD(sh)->cppadlen = cppadlen; - SD(sh)->hostid = gc->scsi_id[3]; - SD(sh)->devflags = 1 << gc->scsi_id[3]; - SD(sh)->moresupport = gc->MORE_support; - sh->unique_id = base; - sh->base = base; - sh->io_port = base; - sh->n_io_port = 9; - sh->irq = gc->IRQ; - sh->dma_channel = PIO; - sh->this_id = gc->scsi_id[3]; - sh->can_queue = 1; - sh->cmd_per_lun = 1; - sh->sg_tablesize = SG_ALL; - - hd->channel = 0; - - hd->pdev = pci_dev_get(pdev); /* Keep a PCI reference */ - - sh->max_id = 8; - sh->max_lun = 8; - - if (gc->SECOND) - hd->primary = 0; - else - hd->primary = 1; - - hd->next = NULL; /* build a linked list of all HBAs */ - hd->prev = last_HBA; - if (hd->prev != NULL) - SD(hd->prev)->next = sh; - last_HBA = sh; - if (first_HBA == NULL) - first_HBA = sh; - registered_HBAs++; - return (1); -} - -static void find_pio_ISA(struct get_conf *buf) -{ - int i; - - for (i = 0; i < MAXISA; i++) { - if (!ISAbases[i]) - continue; - if (!get_pio_conf_PIO(ISAbases[i], buf)) - continue; - if (!register_pio_HBA(ISAbases[i], buf, NULL)) - release_region(ISAbases[i], 9); - else - ISAbases[i] = 0; - } - return; -} - -static void find_pio_EISA(struct get_conf *buf) -{ - u32 base; - int i; - -#ifdef CHECKPAL - u8 pal1, pal2, pal3; -#endif - - for (i = 0; i < MAXEISA; i++) { - if (EISAbases[i]) { /* Still a possibility ? */ - - base = 0x1c88 + (i * 0x1000); -#ifdef CHECKPAL - pal1 = inb((u16) base - 8); - pal2 = inb((u16) base - 7); - pal3 = inb((u16) base - 6); - - if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) { - DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3)); -#endif - if (get_pio_conf_PIO(base, buf)) { - DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf)); - if (buf->IRQ) { - if (!register_pio_HBA(base, buf, NULL)) - release_region(base, 9); - } else { - printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n"); - release_region(base, 9); - } - } - /* Nothing found here so we take it from the list */ - EISAbases[i] = 0; -#ifdef CHECKPAL - } -#endif - } - } - return; -} - -static void find_pio_PCI(struct get_conf *buf) -{ -#ifndef CONFIG_PCI - printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); -#else - struct pci_dev *dev = NULL; - unsigned long base, x; - - while ((dev = pci_get_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) { - DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", pci_name(dev))); - if (pci_enable_device(dev)) - continue; - pci_set_master(dev); - base = pci_resource_flags(dev, 0); - if (base & IORESOURCE_MEM) { - printk("eata_pio: invalid base address of device %s\n", pci_name(dev)); - continue; - } - base = pci_resource_start(dev, 0); - /* EISA tag there ? */ - if ((inb(base) == 0x12) && (inb(base + 1) == 0x14)) - continue; /* Jep, it's forced, so move on */ - base += 0x10; /* Now, THIS is the real address */ - if (base != 0x1f8) { - /* We didn't find it in the primary search */ - if (get_pio_conf_PIO(base, buf)) { - if (buf->FORCADR) { /* If the address is forced */ - release_region(base, 9); - continue; /* we'll find it later */ - } - - /* OK. We made it till here, so we can go now - * and register it. We only have to check and - * eventually remove it from the EISA and ISA list - */ - - if (!register_pio_HBA(base, buf, dev)) { - release_region(base, 9); - continue; - } - - if (base < 0x1000) { - for (x = 0; x < MAXISA; ++x) { - if (ISAbases[x] == base) { - ISAbases[x] = 0; - break; - } - } - } else if ((base & 0x0fff) == 0x0c88) { - x = (base >> 12) & 0x0f; - EISAbases[x] = 0; - } - } -#ifdef CHECK_BLINK - else if (check_blink_state(base)) { - printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n"); - } -#endif - } - } -#endif /* #ifndef CONFIG_PCI */ -} - -static int eata_pio_detect(struct scsi_host_template *tpnt) -{ - struct Scsi_Host *HBA_ptr; - struct get_conf gc; - int i; - - find_pio_PCI(&gc); - find_pio_EISA(&gc); - find_pio_ISA(&gc); - - for (i = 0; i < MAXIRQ; i++) - if (reg_IRQ[i]) - request_irq(i, do_eata_pio_int_handler, 0, "EATA-PIO", NULL); - - HBA_ptr = first_HBA; - - if (registered_HBAs != 0) { - printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n" - "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n" " Alfred Arnold, a.arnold@kfa-juelich.de\n" "This release only supports DASD devices (harddisks)\n", VER_MAJOR, VER_MINOR, VER_SUB); - - printk("Registered HBAs:\n"); - printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:" " QS: SG: CPL:\n"); - for (i = 1; i <= registered_HBAs; i++) { - printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4lx %2d %d %d %c" - " %2d %2d %2d\n", - HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, - SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ? - "PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ", - HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, - SD(HBA_ptr)->primary ? 'Y' : 'N', HBA_ptr->can_queue, - HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); - HBA_ptr = SD(HBA_ptr)->next; - } - } - return (registered_HBAs); -} - -static struct scsi_host_template driver_template = { - .proc_name = "eata_pio", - .name = "EATA (Extended Attachment) PIO driver", - .show_info = eata_pio_show_info, - .detect = eata_pio_detect, - .release = eata_pio_release, - .queuecommand = eata_pio_queue, - .eh_abort_handler = eata_pio_abort, - .eh_host_reset_handler = eata_pio_host_reset, - .use_clustering = ENABLE_CLUSTERING, -}; - -MODULE_AUTHOR("Michael Neuffer, Alfred Arnold"); -MODULE_DESCRIPTION("EATA SCSI PIO driver"); -MODULE_LICENSE("GPL"); - -#include "scsi_module.c" diff --git a/drivers/scsi/eata_pio.h b/drivers/scsi/eata_pio.h deleted file mode 100644 index 5b5e3d13670b..000000000000 --- a/drivers/scsi/eata_pio.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/******************************************************** -* Header file for eata_pio.c Linux EATA-PIO SCSI driver * -* (c) 1993-96 Michael Neuffer * -********************************************************* -* last change: 2002/11/02 * -********************************************************/ - - -#ifndef _EATA_PIO_H -#define _EATA_PIO_H - -#define VER_MAJOR 0 -#define VER_MINOR 0 -#define VER_SUB "1b" - -/************************************************************************ - * Here you can switch parts of the code on and of * - ************************************************************************/ - -#define VERBOSE_SETUP /* show startup screen of 2001 */ -#define ALLOW_DMA_BOARDS 1 - -/************************************************************************ - * Debug options. * - * Enable DEBUG and whichever options you require. * - ************************************************************************/ -#define DEBUG_EATA 1 /* Enable debug code. */ -#define DPT_DEBUG 0 /* Bobs special */ -#define DBG_DELAY 0 /* Build in delays so debug messages can be - * be read before they vanish of the top of - * the screen! - */ -#define DBG_PROBE 0 /* Debug probe routines. */ -#define DBG_ISA 0 /* Trace ISA routines */ -#define DBG_EISA 0 /* Trace EISA routines */ -#define DBG_PCI 0 /* Trace PCI routines */ -#define DBG_PIO 0 /* Trace get_config_PIO */ -#define DBG_COM 0 /* Trace command call */ -#define DBG_QUEUE 0 /* Trace command queueing. */ -#define DBG_INTR 0 /* Trace interrupt service routine. */ -#define DBG_INTR2 0 /* Trace interrupt service routine. */ -#define DBG_PROC 0 /* Debug proc-fs related statistics */ -#define DBG_PROC_WRITE 0 -#define DBG_REGISTER 0 /* */ -#define DBG_ABNORM 1 /* Debug abnormal actions (reset, abort) */ - -#if DEBUG_EATA -#define DBG(x, y) if ((x)) {y;} -#else -#define DBG(x, y) -#endif - -#endif /* _EATA_PIO_H */ -- cgit v1.2.3 From 50041071b5716eb1585c68a482989ab9fc885968 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 14 Mar 2018 12:48:34 +0100 Subject: scsi: documentation: remove ChangeLog.1992-1997 This 20+ year old changelog has no useful information for kernel development or users, so remove it. Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- Documentation/scsi/ChangeLog.1992-1997 | 2023 -------------------------------- 1 file changed, 2023 deletions(-) delete mode 100644 Documentation/scsi/ChangeLog.1992-1997 (limited to 'Documentation') diff --git a/Documentation/scsi/ChangeLog.1992-1997 b/Documentation/scsi/ChangeLog.1992-1997 deleted file mode 100644 index 6faad7e6417c..000000000000 --- a/Documentation/scsi/ChangeLog.1992-1997 +++ /dev/null @@ -1,2023 +0,0 @@ -Sat Jan 18 15:51:45 1997 Richard Henderson - - * Don't play with usage_count directly, instead hand around - the module header and use the module macros. - -Fri May 17 00:00:00 1996 Leonard N. Zubkoff - - * BusLogic Driver Version 2.0.3 Released. - -Tue Apr 16 21:00:00 1996 Leonard N. Zubkoff - - * BusLogic Driver Version 1.3.2 Released. - -Sun Dec 31 23:26:00 1995 Leonard N. Zubkoff - - * BusLogic Driver Version 1.3.1 Released. - -Fri Nov 10 15:29:49 1995 Leonard N. Zubkoff - - * Released new BusLogic driver. - -Wed Aug 9 22:37:04 1995 Andries Brouwer - - As a preparation for new device code, separated the various - functions the request->dev field had into the device proper, - request->rq_dev and a status field request->rq_status. - - The 2nd argument of bios_param is now a kdev_t. - -Wed Jul 19 10:43:15 1995 Michael Neuffer - - * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all - attached devices. - - * scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and - eata_dma_proc.c to produce some device info for /proc/scsi. - - * eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done): - Changed handling of internal SCSI commands send to the HBA. - - -Wed Jul 19 10:09:17 1995 Michael Neuffer - - * Linux 1.3.11 released. - - * eata_dma.c (eata_queue)(eata_int_handler): Added code to do - command latency measurements if requested by root through - /proc/scsi interface. - Throughout Use HZ constant for time references. - - * eata_pio.c: Use HZ constant for time references. - - * aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD - to GNU style. - - * scsi.h: Added READ_12 command opcode constant - -Wed Jul 19 09:25:30 1995 Michael Neuffer - - * Linux 1.3.10 released. - - * scsi_proc.c (dispatch_scsi_info): Removed unused variable. - -Wed Jul 19 09:25:30 1995 Michael Neuffer - - * Linux 1.3.9 released. - - * scsi.c Blacklist concept expanded to 'support' more device - deficiencies. blacklist[] renamed to device_list[] - (scan_scsis): Code cleanup. - - * scsi_debug.c (scsi_debug_proc_info): Added support to control - device lockup simulation via /proc/scsi interface. - - -Wed Jul 19 09:22:34 1995 Michael Neuffer - - * Linux 1.3.7 released. - - * scsi_proc.c: Fixed a number of bugs in directory handling - -Wed Jul 19 09:18:28 1995 Michael Neuffer - - * Linux 1.3.5 released. - - * Native wide, multichannel and /proc/scsi support now in official - kernel distribution. - - * scsi.c/h, hosts.c/h et al reindented to increase readability - (especially on 80 column wide terminals). - - * scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added - /proc/scsi/scsi which allows root to scan for hotplugged devices. - - * scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi. - (scan_scsis): Added some 'spaghetti' code to allow scanning for - single devices. - - -Thu Jun 20 15:20:27 1995 Michael Neuffer - - * proc.c: Renamed to scsi_proc.c - -Mon Jun 12 20:32:45 1995 Michael Neuffer - - * Linux 1.3.0 released. - -Mon May 15 19:33:14 1995 Michael Neuffer - - * scsi.c: Added native multichannel and wide scsi support. - - * proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries): - Updated /proc/scsi interface. - -Thu May 4 17:58:48 1995 Michael Neuffer - - * sd.c (requeue_sd_request): Zero out the scatterlist only if - scsi_malloc returned memory for it. - - * eata_dma.c (register_HBA) (eata_queue): Add support for - large scatter/gather tables and set use_clustering accordingly - - * hosts.c: Make use_clustering changeable in the Scsi_Host structure. - -Wed Apr 12 15:25:52 1995 Eric Youngdale (eric@andante) - - * Linux 1.2.5 released. - - * buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff). - Fixed interrupt routine to avoid races when handling multiple - complete commands per interrupt. Seems to come up with faster - cards. - - * eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling - throughout and fixed bug interrupt routine which resulted in shifted - status bytes. Added blink LED state checks for ISA and EISA HBAs. - Memory management bug seems to have disappeared ==> increasing - C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for - performance reasons. - - * scsi.c: If we get a FMK, EOM, or ILI when attempting to scan - the bus, assume that it was just noise on the bus, and ignore - the device. - - * scsi.h: Update and add a bunch of missing commands which we - were never using. - - * sd.c: Use restore_flags in do_sd_request - this may result in - latency conditions, but it gets rid of races and crashes. - Do not save flags again when searching for a second command to - queue. - - * st.c: Use bytes, not STP->buffer->buffer_size when reading - from tape. - - -Tue Apr 4 09:42:08 1995 Eric Youngdale (eric@andante) - - * Linux 1.2.4 released. - - * st.c: Fix typo - restoring wrong flags. - -Wed Mar 29 06:55:12 1995 Eric Youngdale (eric@andante) - - * Linux 1.2.3 released. - - * st.c: Perform some waiting operations with interrupts off. - Is this correct??? - -Wed Mar 22 10:34:26 1995 Eric Youngdale (eric@andante) - - * Linux 1.2.2 released. - - * aha152x.c: Modularize. Add support for PCMCIA. - - * eata.c: Update to version 2.0. Fixed bug preventing media - detection. If scsi_register_host returns NULL, fail gracefully. - - * scsi.c: Detect as NEC (for photo-cd purposes) for the 84 - and 25 models as "NEC_OLDCDR". - - * scsi.h: Add define for NEC_OLDCDR - - * sr.c: Add handling for NEC_OLDCDR. Treat as unknown. - - * u14-34f.c: Update to version 2.0. Fixed same bug as in - eata.c. - - -Mon Mar 6 11:11:20 1995 Eric Youngdale (eric@andante) - - * Linux 1.2.0 released. Yeah!!! - - * Minor spelling/punctuation changes throughout. Nothing - substantive. - -Mon Feb 20 21:33:03 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.95 released. - - * qlogic.c: Update to version 0.41. - - * seagate.c: Change some message to be more descriptive about what - we detected. - - * sr.c: spelling/whitespace changes. - -Mon Feb 20 21:33:03 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.94 released. - -Mon Feb 20 08:57:17 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.93 released. - - * hosts.h: Change io_port to long int from short. - - * 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP, - NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output - fixed, should initialize correctly if left running, now loadable, - new memory allocation, extraneous diagnostic output suppressed, - splx() replaced with save/restore flags. [ Drew ] - - * hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c, - sr_ioctl.c: Add special junk at end that Emacs will use for - formatting the file. - - * qlogic.c: Update to v0.40a. Improve parity handling. - - * scsi.c: Add Hitachi DK312C to blacklist. Change "};" to "}" in - many places. Use scsi_init_malloc to get command block - may - need this to be dma compatible for some host adapters. - Restore interrupts after unregistering a host. - - * sd.c: Use sti instead of restore flags - causes latency problems. - - * seagate.c: Use controller_type to determine string used when - registering irq. - - * sr.c: More photo-cd hacks to make sure we get the xa stuff right. - * sr.h, sr.c: Change is_xa to xa_flags field. - - * st.c: Disable retries for write operations. - -Wed Feb 15 10:52:56 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.92 released. - - * eata.c: Update to 1.17. - - * eata_dma.c: Update to 2.31a. Add more support for /proc/scsi. - Continuing modularization. Less crashes because of the bug in the - memory management ==> increase C_P_L_CURRENT_MAX to 10 - and decrease C_P_L_DIV to 4. - - * hosts.c: If we remove last host registered, reuse host number. - When freeing memory from host being deregistered, free extra_bytes - too. - - * scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt. - Change memory allocation to work around bugs in __get_dma_pages. - Do not free host if usage count is not zero (for modules). - - * sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000. - - * st.c: Allow for ST_EXTRA_DEVS in st data structures. - - * u14-34f.c: Update to 1.17. - -Thu Feb 9 10:11:16 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.91 released. - - * eata.c: Update to 1.16. Use wish_block instead of host->block. - - * hosts.c: Initialize wish_block to 0. - - * hosts.h: Add wish_block. - - * scsi.c: Use wish_block as indicator that the host should be added - to block list. - - * sg.c: Add SG_EXTRA_DEVS to number of slots. - - * u14-34f.c: Use wish_block. - -Tue Feb 7 11:46:04 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.90 released. - - * eata.c: Change naming from eata_* to eata2x_*. Now at vers 1.15. - Update interrupt handler to take pt_regs as arg. Allow blocking - even if loaded as module. Initialize target_time_out array. - Do not put sti(); in timing loop. - - * hosts.c: Do not reuse host numbers. - Use scsi_make_blocked_list to generate blocking list. - - * script_asm.pl: Beats me. Don't know perl. Something to do with - phase index. - - * scsi.c (scsi_make_blocked_list): New function - code copied from - hosts.c. - - * scsi.c: Update code to disable photo CD for Toshiba cdroms. - Use just manufacturer name, not model number. - - * sr.c: Fix setting density for Toshiba drives. - - * u14-34f.c: Clear target_time_out array during reset. - -Wed Feb 1 09:20:45 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.89 released. - - * Makefile, u14-34f.c: Modularize. - - * Makefile, eata.c: Modularize. Now version 1.14 - - * NCR5380.c: Update interrupt handler with new arglist. Minor - cleanups. - - * eata_dma.c: Begin to modularize. Add hooks for /proc/scsi. - New version 2.3.0a. Add code in interrupt handler to allow - certain CDROM drivers to be detected which return a - CHECK_CONDITION during SCSI bus scan. Add opcode check to get - all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag. - Improvements in HBA identification. Various other minor stuff. - - * hosts.c: Initialize ->dma_channel and ->io_port when registering - a new host. - - * qlogic.c: Modularize and add PCMCIA support. - - * scsi.c: Add Hitachi to blacklist. - - * scsi.c: Change default to no lun scan (too many problem devices). - - * scsi.h: Define QUEUE_FULL condition. - - * sd.c: Do not check for non-existent partition until after - new media check. - - * sg.c: Undo previous change which was wrong. - - * sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000. - - * st.c: Patches from Kai - improve filemark handling. - -Tue Jan 31 17:32:12 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.88 released. - - * Throughout - spelling/grammar fixups. - - * scsi.c: Make sure that all buffers are 16 byte aligned - some - drivers (buslogic) need this. - - * scsi.c (scan_scsis): Remove message printed. - - * scsi.c (scsi_init): Move message here. - -Mon Jan 30 06:40:25 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.87 released. - - * sr.c: Photo-cd related changes. (Gerd Knorr??). - - * st.c: Changes from Kai related to EOM detection. - -Mon Jan 23 23:53:10 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.86 released. - - * 53c7,8xx.h: Change SG size to 127. - - * eata_dma: Update to version 2.10i. Remove bug in the registration - of multiple HBAs and channels. Minor other improvements and stylistic - changes. - - * scsi.c: Test for Toshiba XM-3401TA and exclude from detection - as toshiba drive - photo cd does not work with this drive. - - * sr.c: Update photocd code. - -Mon Jan 23 23:53:10 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.85 released. - - * st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c: - include linux/mm.h - - * qlogic.c, buslogic.c, aha1542.c: Include linux/module.h. - -Sun Jan 22 22:08:46 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.84 released. - - * Makefile: Support for loadable QLOGIC boards. - - * aha152x.c: Update to version 1.8 from Juergen. - - * eata_dma.c: Update from Michael Neuffer. - Remove hard limit of 2 commands per lun and make it better - configurable. Improvements in HBA identification. - - * in2000.c: Fix biosparam to support large disks. - - * qlogic.c: Minor changes (change sti -> restore_flags). - -Wed Jan 18 23:33:09 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.83 released. - - * aha1542.c(aha1542_intr_handle): Use arguments handed down to find - which irq. - - * buslogic.c: Likewise. - - * eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards. - - * scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK. - - * sd.c: Fail if we are opening a non-existent partition. - - * sr.c: Bump SR_TIMEOUT to 15000. - Do not probe for media size at boot time(hard on changers). - Flag device as needing sector size instead. - - * sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl. - - * ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args). - -Mon Jan 16 07:18:23 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.82 released. - - Throughout. - - Change all interrupt handlers to accept new calling convention. - In particular, we now receive the irq number as one of the arguments. - - * More minor spelling corrections in some of the new files. - - * aha1542.c, buslogic.c: Clean up interrupt handler a little now - that we receive the irq as an arg. - - * aha274x.c: s/snarf_region/request_region/ - - * eata.c: Update to version 1.12. Fix some comments and display a - message if we cannot reserve the port addresses. - - * u14-34f.c: Update to version 1.13. Fix some comments and display a - message if we cannot reserve the port addresses. - - * eata_dma.c: Define get_board_data function (send INQUIRY command). - Use to improve detection of variants of different DPT boards. Change - version subnumber to "0g". - - * fdomain.c: Update to version 5.26. Improve detection of some boards - repackaged by IBM. - - * scsi.c (scsi_register_host): Change "name" to const char *. - - * sr.c: Fix problem in set mode command for Toshiba drives. - - * sr.c: Fix typo from patch 81. - -Fri Jan 13 12:54:46 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.81 released. Codefreeze for 1.2 release announced. - - Big changes here. - - * eata_dma.*: New files from Michael Neuffer. - (neuffer@goofy.zdv.uni-mainz.de). Should support - all eata/dpt cards. - - * hosts.c, Makefile: Add eata_dma. - - * README.st: Document MTEOM. - - Patches from me (ERY) to finish support for low-level loadable scsi. - It now works, and is actually useful. - - * Throughout - add new argument to scsi_init_malloc that takes an - additional parameter. This is used as a priority to kmalloc, - and you can specify the GFP_DMA flag if you need DMA-able memory. - - * Makefile: For source files that are loadable, always add name - to SCSI_SRCS. Fill in modules: target. - - * hosts.c: Change next_host to next_scsi_host, and make global. - Print hosts after we have identified all of them. Use info() - function if present, otherwise use name field. - - * hosts.h: Change attach function to return int, not void. - Define number of device slots to allow for loadable devices. - Define tags to tell scsi module code what type of module we - are loading. - - * scsi.c: Fix scan_scsis so that it can be run by a user process. - Do not use waiting loops - use up and down mechanism as long - as current != task[0]. - - * scsi.c(scan_scsis): Do not use stack variables for I/O - this - could be > 16Mb if we are loading a module at runtime (i.e. use - scsi_init_malloc to get some memory we know will be safe). - - * scsi.c: Change dma freelist to be a set of pages. This allows - us to dynamically adjust the size of the list by adding more pages - to the pagelist. Fix scsi_malloc and scsi_free accordingly. - - * scsi_module.c: Fix include. - - * sd.c: Declare detach function. Increment/decrement module usage - count as required. Fix init functions to allow loaded devices. - Revalidate all new disks so we get the partition tables. Define - detach function. - - * sr.c: Likewise. - - * sg.c: Declare detach function. Allow attachment of devices on - loaded drivers. - - * st.c: Declare detach function. Increment/decrement module usage - count as required. - -Tue Jan 10 10:09:58 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.79 released. - - Patch from some undetermined individual who needs to get a life :-). - - * sr.c: Attacked by spelling bee... - - Patches from Gerd Knorr: - - * sr.c: make printk messages for photoCD a little more informative. - - * sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl. - -Mon Jan 9 10:01:37 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.78 released. - - * Makefile: Add empty modules: target. - - * Wheee. Now change register_iomem to request_region. - - * in2000.c: Bugfix - apparently this is the fix that we have - all been waiting for. It fixes a problem whereby the driver - is not stable under heavy load. Race condition and all that. - Patch from Peter Lu. - -Wed Jan 4 21:17:40 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.77 released. - - * 53c7,8xx.c: Fix from Linus - emulate splx. - - Throughout: - - Change "snarf_region" with "register_iomem". - - * scsi_module.c: New file. Contains support for low-level loadable - scsi drivers. [ERY]. - - * sd.c: More s/int/long/ changes. - - * seagate.c: Explicitly include linux/config.h - - * sg.c: Increment/decrement module usage count on open/close. - - * sg.c: Be a bit more careful about the user not supplying enough - information for a valid command. Pass correct size down to - scsi_do_cmd. - - * sr.c: More changes for Photo-CD. This apparently breaks NEC drives. - - * sr_ioctl.c: Support CDROMMULTISESSION ioctl. - - -Sun Jan 1 19:55:21 1995 Eric Youngdale (eric@andante) - - * Linux 1.1.76 released. - - * constants.c: Add type cast in switch statement. - - * scsi.c (scsi_free): Change datatype of "offset" to long. - (scsi_malloc): Change a few more variables to long. Who - did this and why was it important? 64 bit machines? - - - Lots of changes to use save_state/restore_state instead of cli/sti. - Files changed include: - - * aha1542.c: - * aha1740.c: - * buslogic.c: - * in2000.c: - * scsi.c: - * scsi_debug.c: - * sd.c: - * sr.c: - * st.c: - -Wed Dec 28 16:38:29 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.75 released. - - * buslogic.c: Spelling fix. - - * scsi.c: Add HP C1790A and C2500A scanjet to blacklist. - - * scsi.c: Spelling fixup. - - * sd.c: Add support for sd_hardsizes (hard sector sizes). - - * ultrastor.c: Use save_flags/restore_flags instead of cli/sti. - -Fri Dec 23 13:36:25 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.74 released. - - * README.st: Update from Kai Makisara. - - * eata.c: New version from Dario - version 1.11. - use scsicam bios_param routine. Add support for 2011 - and 2021 boards. - - * hosts.c: Add support for blocking. Linked list automatically - generated when shpnt->block is set. - - * scsi.c: Add sankyo & HP scanjet to blacklist. Add support for - kicking things loose when we deadlock. - - * scsi.c: Recognize scanners and processors in scan_scsis. - - * scsi_ioctl.h: Increase timeout to 9 seconds. - - * st.c: New version from Kai - add better support for backspace. - - * u14-34f.c: New version from Dario. Supports blocking. - -Wed Dec 14 14:46:30 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.73 released. - - * buslogic.c: Update from Dave Gentzel. Version 1.14. - Add module related stuff. More fault tolerant if out of - DMA memory. - - * fdomain.c: New version from Rik Faith - version 5.22. Add support - for ISA-200S SCSI adapter. - - * hosts.c: Spelling. - - * qlogic.c: Update to version 0.38a. Add more support for PCMCIA. - - * scsi.c: Mask device type with 0x1f during scan_scsis. - Add support for deadlocking, err, make that getting out of - deadlock situations that are created when we allow the user - to limit requests to one host adapter at a time. - - * scsi.c: Bugfix - pass pid, not SCpnt as second arg to - scsi_times_out. - - * scsi.c: Restore interrupt state to previous value instead of using - cli/sti pairs. - - * scsi.c: Add a bunch of module stuff (all commented out for now). - - * scsi.c: Clean up scsi_dump_status. - -Tue Dec 6 12:34:20 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.72 released. - - * sg.c: Bugfix - always use sg_free, since we might have big buff. - -Fri Dec 2 11:24:53 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.71 released. - - * sg.c: Clear buff field when not in use. Only call scsi_free if - non-null. - - * scsi.h: Call wake_up(&wait_for_request) when done with a - command. - - * scsi.c (scsi_times_out): Pass pid down so that we can protect - against race conditions. - - * scsi.c (scsi_abort): Zero timeout field if we get the - NOT_RUNNING message back from low-level driver. - - - * scsi.c (scsi_done): Restore cmd_len, use_sg here. - - * scsi.c (request_sense): Not here. - - * hosts.h: Add new forbidden_addr, forbidden_size fields. Who - added these and why???? - - * hosts.c (scsi_mem_init): Mark pages as reserved if they fall in - the forbidden regions. I am not sure - I think this is so that - we can deal with boards that do incomplete decoding of their - address lines for the bios chips, but I am not entirely sure. - - * buslogic.c: Set forbidden_addr stuff if using a buggy board. - - * aha1740.c: Test for NULL pointer in SCtmp. This should not - occur, but a nice message is better than a kernel segfault. - - * 53c7,8xx.c: Add new PCI chip ID for 815. - -Fri Dec 2 11:24:53 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.70 released. - - * ChangeLog, st.c: Spelling. - -Tue Nov 29 18:48:42 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.69 released. - - * u14-34f.h: Non-functional change. [Dario]. - - * u14-34f.c: Use block field in Scsi_Host to prevent commands from - being queued to more than one host at the same time (used when - motherboard does not deal with multiple bus-masters very well). - Only when SINGLE_HOST_OPERATIONS is defined. - Use new cmd_per_lun field. [Dario] - - * eata.c: Likewise. - - * st.c: More changes from Kai. Add ready flag to indicate drive - status. - - * README.st: Document this. - - * sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd - code. - - * sg.c: Bugfix - fix problem where opcode is not correctly set up. - - * seagate.[c,h]: Use #defines to set driver name. - - * scsi_ioctl.c: Zero buffer before executing command. - - * scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate. - Add Sony CDU55S to blacklist. - - * hosts.h: Add new cmd_per_lun field to Scsi_Hosts. - - * hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template. - - * buslogic.c: Use cmd_per_lun field - initialize to different - values depending upon bus type (i.e. use 1 if ISA, so we do not - hog memory). Use other patches which got lost from 1.1.68. - - * aha1542.c: Spelling. - -Tue Nov 29 15:43:50 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.68 released. - - Add support for 12 byte vendor specific commands in scsi-generics, - more (i.e. the last mandatory) low-level changes to support - loadable modules, plus a few other changes people have requested - lately. Changes by me (ERY) unless otherwise noted. Spelling - changes appear from some unknown corner of the universe. - - * Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len. - - * Throughout: Change info() low level function to take a Scsi_Host - pointer. This way the info function can return specific - information about the host in question, if desired. - - * All low-level drivers: Add NULL in initializer for the - usage_count field added to Scsi_Host_Template. - - * aha152x.[c,h]: Remove redundant info() function. - - * aha1542.[c,h]: Likewise. - - * aha1740.[c,h]: Likewise. - - * aha274x.[c,h]: Likewise. - - * eata.[c,h]: Likewise. - - * pas16.[c,h]: Likewise. - - * scsi_debug.[c,h]: Likewise. - - * t128.[c,h]: Likewise. - - * u14-34f.[c,h]: Likewise. - - * ultrastor.[c,h]: Likewise. - - * wd7000.[c,h]: Likewise. - - * aha1542.c: Add support for command line options with lilo to set - DMA parameters, I/O port. From Matt Aarnio. - - * buslogic.[c,h]: New version (1.13) from Dave Gentzel. - - * hosts.h: Add new field to Scsi_Hosts "block" to allow blocking - all I/O to certain other cards. Helps prevent problems with some - ISA motherboards. - - * hosts.h: Add usage_count to Scsi_Host_Template. - - * hosts.h: Add n_io_port to Scsi_Host (used when releasing module). - - * hosts.c: Initialize block field. - - * in2000.c: Remove "static" declarations from exported functions. - - * in2000.h: Likewise. - - * scsi.c: Correctly set cmd_len field as required. Save and - change setting when doing a request_sense, restore when done. - Move abort timeout message. Fix panic in request_queueable to - print correct function name. - - * scsi.c: When incrementing usage count, walk block linked list - for host, and or in SCSI_HOST_BLOCK bit. When decrementing usage - count to 0, clear this bit to allow usage to continue, wake up - processes waiting. - - - * scsi_ioctl.c: If we have an info() function, call it, otherwise - if we have a "name" field, use it, else do nothing. - - * sd.c, sr.c: Clear cmd_len field prior to each command we - generate. - - * sd.h: Add "has_part_table" bit to rscsi_disks. - - * sg.[c,h]: Add support for vendor specific 12 byte commands (i.e. - override command length in COMMAND_SIZE). - - * sr.c: Bugfix from Gerd in photocd code. - - * sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer - - we cannot guarantee that the stack is < 16Mb. - -Tue Nov 22 15:40:46 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.67 released. - - * sr.c: Change spelling of manufactor to manufacturer. - - * scsi.h: Likewise. - - * scsi.c: Likewise. - - * qlogic.c: Spelling corrections. - - * in2000.h: Spelling corrections. - - * in2000.c: Update from Bill Earnest, change from - jshiffle@netcom.com. Support new bios versions. - - * README.qlogic: Spelling correction. - -Tue Nov 22 15:40:46 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.66 released. - - * u14-34f.c: Spelling corrections. - - * sr.[h,c]: Add support for multi-session CDs from Gerd Knorr. - - * scsi.h: Add manufactor field for keeping track of device - manufacturer. - - * scsi.c: More spelling corrections. - - * qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha. - - * in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest. - - * fdomain.c: Spelling correction. - - * eata.c: Spelling correction. - -Fri Nov 18 15:22:44 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.65 released. - - * eata.h: Update version string to 1.08.00. - - * eata.c: Set sg_tablesize correctly for DPT PM2012 boards. - - * aha274x.seq: Spell checking. - - * README.st: Likewise. - - * README.aha274x: Likewise. - - * ChangeLog: Likewise. - -Tue Nov 15 15:35:08 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.64 released. - - * u14-34f.h: Update version number to 1.10.01. - - * u14-34f.c: Use Scsi_Host can_queue variable instead of one from template. - - * eata.[c,h]: New driver for DPT boards from Dario Ballabio. - - * buslogic.c: Use can_queue field. - -Wed Nov 30 12:09:09 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.63 released. - - * sd.c: Give I/O error if we attempt 512 byte I/O to a disk with - 1024 byte sectors. - - * scsicam.c: Make sure we do read from whole disk (mask off - partition). - - * scsi.c: Use can_queue in Scsi_Host structure. - Fix panic message about invalid host. - - * hosts.c: Initialize can_queue from template. - - * hosts.h: Add can_queue to Scsi_Host structure. - - * aha1740.c: Print out warning about NULL ecbptr. - -Fri Nov 4 12:40:30 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.62 released. - - * fdomain.c: Update to version 5.20. (From Rik Faith). Support - BIOS version 3.5. - - * st.h: Add ST_EOD symbol. - - * st.c: Patches from Kai Makisara - support additional densities, - add support for MTFSS, MTBSS, MTWSM commands. - - * README.st: Update to document new commands. - - * scsi.c: Add Mediavision CDR-H93MV to blacklist. - -Sat Oct 29 20:57:36 1994 Eric Youngdale (eric@andante.aib.com) - - * Linux 1.1.60 released. - - * u14-34f.[c,h]: New driver from Dario Ballabio. - - * aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c, - README.aha274x: New files, new driver from John Aycock. - - -Tue Oct 11 08:47:39 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.54 released. - - * Add third PCI chip id. [Drew] - - * buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric]. - - * ultrastor.c: Fix asm directives for new GCC. - - * sr.c, sd.c: Use new end_scsi_request function. - - * scsi.h(end_scsi_request): Return pointer to block if still - active, else return NULL if inactive. Fixes race condition. - -Sun Oct 9 20:23:14 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.53 released. - - * scsi.c: Do not allocate dma bounce buffers if we have exactly - 16Mb. - -Fri Sep 9 05:35:30 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.51 released. - - * aha152x.c: Add support for disabling the parity check. Update - to version 1.4. [Juergen]. - - * seagate.c: Tweak debugging message. - -Wed Aug 31 10:15:55 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.50 released. - - * aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen]. - - * scsi.c: Add Quantum PD1225S to blacklist. - -Fri Aug 26 09:38:45 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.49 released. - - * sd.c: Fix bug when we were deleting the wrong entry if we - get an unsupported sector size device. - - * sr.c: Another spelling patch. - -Thu Aug 25 09:15:27 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.48 released. - - * Throughout: Use new semantics for request_dma, as appropriate. - - * sr.c: Print correct device number. - -Sun Aug 21 17:49:23 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.47 released. - - * NCR5380.c: Add support for LIMIT_TRANSFERSIZE. - - * constants.h: Add prototype for print_Scsi_Cmnd. - - * pas16.c: Some more minor tweaks. Test for Mediavision board. - Allow for disks > 1Gb. [Drew??] - - * sr.c: Set SCpnt->transfersize. - -Tue Aug 16 17:29:35 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.46 released. - - * Throughout: More spelling fixups. - - * buslogic.c: Add a few more fixups from Dave. Disk translation - mainly. - - * pas16.c: Add a few patches (Drew?). - - -Thu Aug 11 20:45:15 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.44 released. - - * hosts.c: Add type casts for scsi_init_malloc. - - * scsicam.c: Add type cast. - -Wed Aug 10 19:23:01 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.43 released. - - * Throughout: Spelling cleanups. [??] - - * aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c, - t128.c: Use request_irq, not irqaction. [??] - - * aha1542.c: Move test for shost before we start to use shost. - - * aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new - calling sequence for request_irq. - - * buslogic.c: Update from Dave Gentzel. - -Tue Aug 9 09:32:59 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.42 released. - - * NCR5380.c: Change NCR5380_print_status to static. - - * seagate.c: A few more bugfixes. Only Drew knows what they are - for. - - * ultrastor.c: Tweak some __asm__ directives so that it works - with newer compilers. [??] - -Sat Aug 6 21:29:36 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.40 released. - - * NCR5380.c: Return SCSI_RESET_WAKEUP from reset function. - - * aha1542.c: Reset mailbox status after a bus device reset. - - * constants.c: Fix typo (;;). - - * g_NCR5380.c: - * pas16.c: Correct usage of NCR5380_init. - - * scsi.c: Remove redundant (and unused variables). - - * sd.c: Use memset to clear all of rscsi_disks before we use it. - - * sg.c: Ditto, except for scsi_generics. - - * sr.c: Ditto, except for scsi_CDs. - - * st.c: Initialize STp->device. - - * seagate.c: Fix bug. [Drew] - -Thu Aug 4 08:47:27 1994 Eric Youngdale (eric@andante) - - * Linux 1.1.39 released. - - * Makefile: Fix typo in NCR53C7xx. - - * st.c: Print correct number for device. - -Tue Aug 2 11:29:14 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.38 released. - - Lots of changes in 1.1.38. All from Drew unless otherwise noted. - - * 53c7,8xx.c: New file from Drew. PCI driver. - - * 53c7,8xx.h: Likewise. - - * 53c7,8xx.scr: Likewise. - - * 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise. - - * scsicam.c: New file from Drew. Read block 0 on the disk and - read the partition table. Attempt to deduce the geometry from - the partition table if possible. Only used by 53c[7,8]xx right - now, but could be used by any device for which we have no way - of identifying the geometry. - - * sd.c: Use device letters instead of sd%d in a lot of messages. - - * seagate.c: Fix bug that resulted in lockups with some devices. - - * sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open - device for write. - - * hosts.c, Makefile: Update for new driver. - - * NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support - 53C400 chip. - - * constants.c: Define CONST_CMND and CONST_MSG. Other minor - cleanups along the way. Improve handling of CONST_MSG. - - * fdomain.c, fdomain.h: New version from Rik Faith. Update to - 5.18. Should now support TMC-3260 PCI card with 18C30 chip. - - * pas16.c: Update with new irq initialization. - - * t128.c: Update with minor cleanups. - - * scsi.c (scsi_pid): New variable - gives each command a unique - id. Add Quantum LPS5235S to blacklist. Change in_scan to - in_scan_scsis and make global. - - * scsi.h: Add some defines for extended message handling, - INITIATE/RELEASE_RECOVERY. Add a few new fields to support sync - transfers. - - * scsi_ioctl.h: Add ioctl to request synchronous transfers. - - -Tue Jul 26 21:36:58 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.37 released. - - * aha1542.c: Always call aha1542_mbenable, use new udelay - mechanism so we do not wait a long time if the board does not - implement this command. - - * g_NCR5380.c: Remove #include and #if - defined(CONFIG_SCSI_*). - - * seagate.c: Likewise. - - Next round of changes to support loadable modules. Getting closer - now, still not possible to do anything remotely usable. - - hosts.c: Create a linked list of detected high level devices. - (scsi_register_device): New function to insert into this list. - (scsi_init): Call scsi_register_device for each of the known high - level drivers. - - hosts.h: Add prototype for linked list header. Add structure - definition for device template structure which defines the linked - list. - - scsi.c: (scan_scsis): Use linked list instead of knowledge about - existing high level device drivers. - (scsi_dev_init): Use init functions for drivers on linked list - instead of explicit list to initialize and attach devices to high - level drivers. - - scsi.h: Add new field "attached" to scsi_device - count of number - of high level devices attached. - - sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new - scheme. - -Sat Jul 23 13:03:17 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.35 released. - - * ultrastor.c: Change constraint on asm() operand so that it works - with gcc 2.6.0. - -Thu Jul 21 10:37:39 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.33 released. - - * sr.c(sr_open): Do not allow opens with write access. - -Mon Jul 18 09:51:22 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.31 released. - - * sd.c: Increase SD_TIMEOUT from 300 to 600. - - * sr.c: Remove stray task_struct* variable that was no longer - used. - - * sr_ioctl.c: Fix typo in up() call. - -Sun Jul 17 16:25:29 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.30 released. - - * scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives - that report themselves as disk drives. - - * (Throughout): Use request.sem instead of request.waiting. - Should fix swap problem with fdomain. - -Thu Jul 14 10:51:42 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.29 released. - - * scsi.c (scan_scsis): Add new devices to end of linked list, not - to the beginning. - - * scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save - the task state before sleeping. - -Sat Jul 9 15:01:03 1994 Eric Youngdale (eric@esp22) - - More changes to eventually support loadable modules. Mainly - we want to use linked lists instead of arrays because it is easier - to dynamically add and remove things this way. - - Quite a bit more work is needed before loadable modules are - possible (and usable) with scsi, but this is most of the grunge - work. - - * Linux 1.1.28 released. - - * scsi.c, scsi.h (allocate_device, request_queueable): Change - argument from index into scsi_devices to a pointer to the - Scsi_Device struct. - - * Throughout: Change all calls to allocate_device, - request_queueable to use new calling sequence. - - * Throughout: Use SCpnt->device instead of - scsi_devices[SCpnt->index]. Ugh - the pointer was there all along - - much cleaner this way. - - * scsi.c (scsi_init_malloc, scsi_free_malloc): New functions - - allow us to pretend that we have a working malloc when we - initialize. Use this instead of passing memory_start, memory_end - around all over the place. - - * scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use - scsi_init_malloc, remove all arguments, no return value. - - * scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd - structs. - - * scsi.c (scsi_dev_init): Set up for scsi_init_malloc. - (scan_scsis): Get SDpnt from scsi_init_malloc, and refresh - when we discover a device. Free pointer before returning. - Change scsi_devices into a linked list. - - * scsi.c (scan_scsis): Change to only scan one host. - (scsi_dev_init): Loop over all detected hosts, and scan them. - - * hosts.c (scsi_init_free): Change so that number of extra bytes - is stored in struct, and we do not have to pass it each time. - - * hosts.h: Change Scsi_Host_Template struct to include "next" and - "release" functions. Initialize to NULL in all low level - adapters. - - * hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked - list scsi_hosts, linked together with the new "next" field. - -Wed Jul 6 05:45:02 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.25 released. - - * aha152x.c: Changes from Juergen - cleanups and updates. - - * sd.c, sr.c: Use new check_media_change and revalidate - file_operations fields. - - * st.c, st.h: Add changes from Kai Makisara, dated Jun 22. - - * hosts.h: Change SG_ALL back to 0xff. Apparently soft error - in /dev/brain resulted in having this bumped up. - Change first parameter in bios_param function to be Disk * instead - of index into rscsi_disks. - - * sd_ioctl.c: Pass pointer to rscsi_disks element instead of index - to array. - - * sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk. - - * scsi.c: Remove redundant Maxtor XT8760S from blacklist. - In scsi_reset, add printk when DEBUG defined. - - * All low level drivers: Modify definitions of bios_param in - appropriate way. - -Thu Jun 16 10:31:59 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.20 released. - - * scsi_ioctl.c: Only pass down the actual number of characters - required to scsi_do_cmd, not the one rounded up to a even number - of sectors. - - * ultrastor.c: Changes from Caleb Epstein for 24f cards. Support - larger SG lists. - - * ultrastor.c: Changes from me - use scsi_register to register - host. Add some consistency checking, - -Wed Jun 1 21:12:13 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.19 released. - - * scsi.h: Add new return code for reset() function: - SCSI_RESET_PUNT. - - * scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for - now. - - * aha1542.c: If the command responsible for the reset is not - pending, return SCSI_RESET_PUNT. - - * aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return - SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE. - -Tue May 31 19:36:01 1994 Eric Youngdale (eric@esp22) - - * buslogic.c: Do not print out message about "must be Adaptec" - if we have detected a buslogic card. Print out a warning message - if we are configuring for >16Mb, since the 445S at board level - D or earlier does not work right. The "D" level board can be made - to work by flipping an undocumented switch, but this is too subtle. - - Changes based upon patches in Yggdrasil distribution. - - * sg.c, sg.h: Return sense data to user. - - * aha1542.c, aha1740.c, buslogic.c: Do not panic if - sense buffer is wrong size. - - * hosts.c: Test for ultrastor card before any of the others. - - * scsi.c: Allow boot-time option for max_scsi_luns=? so that - buggy firmware has an easy work-around. - -Sun May 15 20:24:34 1994 Eric Youngdale (eric@esp22) - - * Linux 1.1.15 released. - - Post-codefreeze thaw... - - * buslogic.[c,h]: New driver from David Gentzel. - - * hosts.h: Add use_clustering field to explicitly say whether - clustering should be used for devices attached to this host - adapter. The buslogic board apparently supports large SG lists, - but it is apparently faster if sd.c condenses this into a smaller - list. - - * sd.c: Use this field instead of heuristic. - - * All host adapter include files: Add appropriate initializer for - use_clustering field. - - * scsi.h: Add #defines for return codes for the abort and reset - functions. There are now a specific set of return codes to fully - specify all of the possible things that the low-level adapter - could do. - - * scsi.c: Act based upon return codes from abort/reset functions. - - * All host adapter abort/reset functions: Return new return code. - - * Add code in scsi.c to help debug timeouts. Use #define - DEBUG_TIMEOUT to enable this. - - * scsi.c: If the host->irq field is set, use - disable_irq/enable_irq before calling queuecommand if we - are not already in an interrupt. Reduce races, and we - can be sloppier about cli/sti in the interrupt routines now - (reduce interrupt latency). - - * constants.c: Fix some things to eliminate warnings. Add some - sense descriptions that were omitted before. - - * aha1542.c: Watch for SCRD from host adapter - if we see it, set - a flag. Currently we only print out the number of pending - commands that might need to be restarted. - - * aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still - full, and attempt to recover. Otherwise give up. - - * aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass - DID_RESET back up to the upper level code for all commands running - on this target (even on different LUNs). - -Sat May 7 14:54:01 1994 - - * Linux 1.1.12 released. - - * st.c, st.h: New version from Kai. Supports boot time - specification of number of buffers. - - * wd7000.[c,h]: Updated driver from John Boyd. Now supports - more than one wd7000 board in machine at one time, among other things. - -Wed Apr 20 22:20:35 1994 - - * Linux 1.1.8 released. - - * sd.c: Add a few type casts where scsi_malloc is called. - -Wed Apr 13 12:53:29 1994 - - * Linux 1.1.4 released. - - * scsi.c: Clean up a few printks (use %p to print pointers). - -Wed Apr 13 11:33:02 1994 - - * Linux 1.1.3 released. - - * fdomain.c: Update to version 5.16 (Handle different FIFO sizes - better). - -Fri Apr 8 08:57:19 1994 - - * Linux 1.1.2 released. - - * Throughout: SCSI portion of cluster diffs added. - -Tue Apr 5 07:41:50 1994 - - * Linux 1.1 development tree initiated. - - * The linux 1.0 development tree is now effectively frozen except - for obvious bugfixes. - -****************************************************************** -****************************************************************** -****************************************************************** -****************************************************************** - -Sun Apr 17 00:17:39 1994 - - * Linux 1.0, patchlevel 9 released. - - * fdomain.c: Update to version 5.16 (Handle different FIFO sizes - better). - -Thu Apr 7 08:36:20 1994 - - * Linux 1.0, patchlevel8 released. - - * fdomain.c: Update to version 5.15 from 5.9. Handles 3.4 bios. - -Sun Apr 3 14:43:03 1994 - - * Linux 1.0, patchlevel6 released. - - * wd7000.c: Make stab at fixing race condition. - -Sat Mar 26 14:14:50 1994 - - * Linux 1.0, patchlevel5 released. - - * aha152x.c, Makefile: Fix a few bugs (too much data message). - Add a few more bios signatures. (Patches from Juergen). - - * aha1542.c: Fix race condition in aha1542_out. - -Mon Mar 21 16:36:20 1994 - - * Linux 1.0, patchlevel3 released. - - * sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt - to open a non-existent device. - - * scsi.c: Add Chinon cdrom to blacklist. - - * sr_ioctl.c: Check return status of verify_area. - -Sat Mar 6 16:06:19 1994 - - * Linux 1.0 released (technically a pre-release). - - * scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist. - -Tue Feb 15 10:58:20 1994 - - * pl15e released. - - * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned - off. - - * constants.c: Fix typo in definition of CONSTANTS. - - * pl15d released. - -Fri Feb 11 10:10:16 1994 - - * pl15c released. - - * scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist. - - * scsi.c: Allow tagged queueing for scsi 3 devices as well. - Some really old devices report a version number of 0. Disallow - LUN != 0 for these. - -Thu Feb 10 09:48:57 1994 - - * pl15b released. - -Sun Feb 6 12:19:46 1994 - - * pl15a released. - -Fri Feb 4 09:02:17 1994 - - * scsi.c: Add Teac cdrom to blacklist. - -Thu Feb 3 14:16:43 1994 - - * pl15 released. - -Tue Feb 1 15:47:43 1994 - - * pl14w released. - - * wd7000.c (wd_bases): Fix typo in last change. - -Mon Jan 24 17:37:23 1994 - - * pl14u released. - - * aha1542.c: Support 1542CF/extended bios. Different from 1542C - - * wd7000.c: Allow bios at 0xd8000 as well. - - * ultrastor.c: Do not truncate cylinders to 1024. - - * fdomain.c: Update to version 5.9 (add new bios signature). - - * NCR5380.c: Update from Drew - should work a lot better now. - -Sat Jan 8 15:13:10 1994 - - * pl14o released. - - * sr_ioctl.c: Zero reserved field before trying to set audio volume. - -Wed Jan 5 13:21:10 1994 - - * pl14m released. - - * fdomain.c: Update to version 5.8. No functional difference??? - -Tue Jan 4 14:26:13 1994 - - * pl14l released. - - * ultrastor.c: Remove outl, inl functions (now provided elsewhere). - -Mon Jan 3 12:27:25 1994 - - * pl14k released. - - * aha152x.c: Remove insw and outsw functions. - - * fdomain.c: Ditto. - -Wed Dec 29 09:47:20 1993 - - * pl14i released. - - * scsi.c: Support RECOVERED_ERROR for tape drives. - - * st.c: Update of tape driver from Kai. - -Tue Dec 21 09:18:30 1993 - - * pl14g released. - - * aha1542.[c,h]: Support extended BIOS stuff. - - * scsi.c: Clean up messages about disks, so they are displayed as - sda, sdb, etc instead of sd0, sd1, etc. - - * sr.c: Force reread of capacity if disk was changed. - Clear buffer before asking for capacity/sectorsize (some drives - do not report this properly). Set needs_sector_size flag if - drive did not return sensible sector size. - -Mon Dec 13 12:13:47 1993 - - * aha152x.c: Update to version .101 from Juergen. - -Mon Nov 29 03:03:00 1993 - - * linux 0.99.14 released. - - * All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi. - - * Throughout: Grammatical corrections to various comments. - - * Makefile: fix so that we do not need to compile things we are - not going to use. - - * NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c, - pas16.h, t128.c, t128.h: New files from Drew. - - * aha152x.c, aha152x.h: New files from Juergen Fischer. - - * aha1542.c: Support for more than one 1542 in the machine - at the same time. Make functions static that do not need - visibility. - - * aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we - know to restart the command. Change prototype of aha1740_reset - to take a command pointer. - - * constants.c: Clean up a few things. - - * fdomain.c: Update to version 5.6. Move snarf_region. Allow - board to be set at different SCSI ids. Remove support for - reselection (did not work well). Set JUMPSTART flag in reset - code. - - * hosts.c: Support new low-level adapters. Allow for more than - one adapter of a given type. - - * hosts.h: Allow for more than one adapter of a given type. - - * scsi.c: Add scsi_device_types array, if NEEDS_JUMPSTART is set - after a low-level reset, start the command again. Sort blacklist, - and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N. - - * scsi.h: Add constants for tagged queueing. - - * Throughout: Use constants from major.h instead of hardcoded - numbers for major numbers. - - * scsi_ioctl.c: Fix bug in buffer length in ioctl_command. Use - verify_area in GET_IDLUN ioctl. Add new ioctls for - TAGGED_QUEUE_ENABLE, DISABLE. Only allow IOCTL_SEND_COMMAND by - superuser. - - * sd.c: Only pay attention to UNIT_ATTENTION for removable disks. - Fix bug where sometimes portions of blocks would get lost - resulting in processes hanging. Add messages when we spin up a - disk, and fix a bug in the timing. Increase read-ahead for disks - that are on a scatter-gather capable host adapter. - - * seagate.c: Fix so that some parameters can be set from the lilo - prompt. Supply jumpstart flag if we are resetting and need the - command restarted. Fix so that we return 1 if we detect a card - so that multiple card detection works correctly. Add yet another - signature for FD cards (950). Add another signature for ST0x. - - * sg.c, sg.h: New files from Lawrence Foard for generic scsi - access. - - * sr.c: Add type casts for (void*) so that we can do pointer - arithmetic. Works with GCC without this, but it is not strictly - correct. Same bugfix as was in sd.c. Increase read-ahead a la - disk driver. - - * sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack - since we cannot guarantee that the stack is < 16Mb. - - ultrastor.c: Update to support 24f properly (JFC's driver). - - wd7000.c: Supply jumpstart flag for reset. Do not round up - number of cylinders in biosparam function. - -Sat Sep 4 20:49:56 1993 - - * 0.99pl13 released. - - * Throughout: Use check_region/snarf_region for all low-level - drivers. - - * aha1542.c: Do hard reset instead of soft (some ethercard probes - screw us up). - - * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are - in a loop whereby the device returns null sense data. - - * sd.c: Add code to spin up a drive if it is not already spinning. - Do this one at a time to make it easier on power supplies. - - * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl. - - * seagate.c: Switch around DATA/CONTROL lines. - - * st.c: Change sense to unsigned. - -Thu Aug 5 11:59:18 1993 - - * 0.99pl12 released. - - * constants.c, constants.h: New files with ascii descriptions of - various conditions. - - * Makefile: Do not try to count the number of low-level drivers, - just generate the list of .o files. - - * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer). Add tests - for addresses > 16Mb, panic if we find one. - - * aha1740.c: Ditto with sizeof(). - - * fdomain.c: Update to version 3.18. Add new signature, register IRQ - with irqaction. Use ID 7 for new board. Be more intelligent about - obtaining the h/s/c numbers for biosparam. - - * hosts.c: Do not depend upon Makefile generated count of the number - of low-level host adapters. - - * scsi.c: Use array for scsi_command_size instead of a function. Add - Texel cdrom and Maxtor XT-4380S to blacklist. Allow compile time - option for no-multi lun scan. Add semaphore for possible problems - with handshaking, assume device is faulty until we know it not to be - the case. Add DEBUG_INIT symbol to dump info as we scan for devices. - Zero sense buffer so we can tell if we need to request it. When - examining sense information, request sense if buffer is all zero. - If RESET, request sense information to see what to do next. - - * scsi_debug.c: Change some constants to use symbols like INT_MAX. - - * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl - calls from kernel space. - - * sd.c: Increase timeout to 300. Use functions in constants.h to - display info. Use scsi_malloc buffer for READ_CAPACITY, since - we cannot guarantee that a stack based buffer is < 16Mb. - - * sd_ioctl.c: Add BLKFLSBUF ioctl. - - * seagate.c: Add new compile time options for ARBITRATE, - SLOW_HANDSHAKE, and SLOW_RATE. Update assembly loops for transferring - data. Use kernel_scsi_ioctl to request mode page with geometry. - - * sr.c: Use functions in constants.c to display messages. - - * st.c: Support for variable block size. - - * ultrastor.c: Do not use cache for tape drives. Set - unchecked_isa_dma flag, even though this may not be needed (gets set - later). - -Sat Jul 17 18:32:44 1993 - - * 0.99pl11 released. C++ compilable. - - * Throughout: Add type casts all over the place, and use "ip" instead - of "info" in the various biosparam functions. - - * Makefile: Compile seagate.c with C++ compiler. - - * aha1542.c: Always set ccb pointer as this gets trashed somehow on - some systems. Add a few type casts. Update biosparam function a little. - - * aha1740.c: Add a few type casts. - - * fdomain.c: Update to version 3.17 from 3.6. Now works with - TMC-18C50. - - * scsi.c: Minor changes here and there with datatypes. Save use_sg - when requesting sense information so that this can properly be - restored if we retry the command. Set aside dma buffers assuming each - block is 1 page, not 1Kb minix block. - - * scsi_ioctl.c: Add a few type casts. Other minor changes. - - * sd.c: Correctly free all scsi_malloc'd memory if we run out of - dma_pool. Store blocksize information for each partition. - - * seagate.c: Minor cleanups here and there. - - * sr.c: Set up blocksize array for all discs. Fix bug in freeing - buffers if we run out of dma pool. - -Thu Jun 2 17:58:11 1993 - - * 0.99pl10 released. - - * aha1542.c: Support for BT 445S (VL-bus board with no dma channel). - - * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50. - - * scsi.c: First attempt to fix problem with old_use_sg. Change - NOT_READY to a SUGGEST_ABORT. Fix timeout race where time might - get decremented past zero. - - * sd.c: Add block_fsync function to dispatch table. - - * sr.c: Increase timeout to 500 from 250. Add entry for sync in - dispatch table (supply NULL). If we do not have a sectorsize, - try to get it in the sd_open function. Add new function just to - obtain sectorsize. - - * sr.h: Add needs_sector_size semaphore. - - * st.c: Add NULL for fsync in dispatch table. - - * wd7000.c: Allow another condition for power on that are normal - and do not require a panic. - -Thu Apr 22 23:10:11 1993 - - * 0.99pl9 released. - - * aha1542.c: Use (void) instead of () in setup_mailboxes. - - * scsi.c: Initialize transfersize and underflow fields in SCmd to 0. - Do not panic for unsupported message bytes. - - * scsi.h: Allocate 12 bytes instead of 10 for commands. Add - transfersize and underflow fields. - - * scsi_ioctl.c: Further bugfix to ioctl_probe. - - * sd.c: Use long instead of int for last parameter in sd_ioctl. - Initialize transfersize and underflow fields. - - * sd_ioctl.c: Ditto for sd_ioctl(,,,,); - - * seagate.c: New version from Drew. Includes new signatures for FD - cards. Support for 0ws jumper. Correctly initialize - scsi_hosts[hostnum].this_id. Improved handing of - disconnect/reconnect, and support command linking. Use - transfersize and underflow fields. Support scatter-gather. - - * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl. - Use buffer and buflength in do_ioctl. Patches from Chris Newbold for - scsi-2 audio commands. - - * ultrastor.c: Comment out in_byte (compiler warning). - - * wd7000.c: Change () to (void) in wd7000_enable_dma. - -Wed Mar 31 16:36:25 1993 - - * 0.99pl8 released. - - * aha1542.c: Handle mailboxes better for 1542C. - Do not truncate number of cylinders at 1024 for biosparam call. - - * aha1740.c: Fix a few minor bugs for multiple devices. - Same as above for biosparam. - - * scsi.c: Add lockable semaphore for removable devices that can have - media removal prevented. Add another signature for flopticals. - (allocate_device): Fix race condition. Allow more space in dma pool - for blocksizes of up to 4Kb. - - * scsi.h: Define COMMAND_SIZE. Define a SCSI specific version of - INIT_REQUEST that can run with interrupts off. - - * scsi_ioctl.c: Make ioctl_probe function more idiot-proof. If - a removable device says ILLEGAL REQUEST to a door-locking command, - clear lockable flag. Add SCSI_IOCTL_GET_IDLUN ioctl. Do not attempt - to lock door for devices that do not have lockable semaphore set. - - * sd.c: Fix race condition for multiple disks. Use INIT_SCSI_REQUEST - instead of INIT_REQUEST. Allow sector sizes of 1024 and 256. For - removable disks that are not ready, mark them as having a media change - (some drives do not report this later). - - * seagate.c: Use volatile keyword for memory-mapped register pointers. - - * sr.c: Fix race condition, a la sd.c. Increase the number of retries - to 1. Use INIT_SCSI_REQUEST. Allow 512 byte sector sizes. Do a - read_capacity when we init the device so we know the size and - sectorsize. - - * st.c: If ioctl not found in st.c, try scsi_ioctl for others. - - * ultrastor.c: Do not truncate number of cylinders at 1024 for - biosparam call. - - * wd7000.c: Ditto. - Throughout: Use COMMAND_SIZE macro to determine length of scsi - command. - - - -Sat Mar 13 17:31:29 1993 - - * 0.99pl7 released. - - Throughout: Improve punctuation in some messages, and use new - verify_area syntax. - - * aha1542.c: Handle unexpected interrupts better. - - * scsi.c: Ditto. Handle reset conditions a bit better, asking for - sense information and retrying if required. - - * scsi_ioctl.c: Allow for 12 byte scsi commands. - - * ultrastor.c: Update to use scatter-gather. - -Sat Feb 20 17:57:15 1993 - - * 0.99pl6 released. - - * fdomain.c: Update to version 3.5. Handle spurious interrupts - better. - - * sd.c: Use register_blkdev function. - - * sr.c: Ditto. - - * st.c: Use register_chrdev function. - - * wd7000.c: Undo previous change. - -Sat Feb 6 11:20:43 1993 - - * 0.99pl5 released. - - * scsi.c: Fix bug in testing for UNIT_ATTENTION. - - * wd7000.c: Check at more addresses for bios. Fix bug in biosparam - (heads & sectors turned around). - -Wed Jan 20 18:13:59 1993 - - * 0.99pl4 released. - - * scsi.c: Ignore leading spaces when looking for blacklisted devices. - - * seagate.c: Add a few new signatures for FD cards. Another patch - with SCint to fix race condition. Use recursion_depth to keep track - of how many times we have been recursively called, and do not start - another command unless we are on the outer level. Fixes bug - with Syquest cartridge drives (used to crash kernel), because - they do not disconnect with large data transfers. - -Tue Jan 12 14:33:36 1993 - - * 0.99pl3 released. - - * fdomain.c: Update to version 3.3 (a few new signatures). - - * scsi.c: Add CDU-541, Denon DRD-25X to blacklist. - (allocate_request, request_queueable): Init request.waiting to NULL if - non-buffer type of request. - - * seagate.c: Allow controller to be overridden with CONTROLLER symbol. - Set SCint=NULL when we are done, to remove race condition. - - * st.c: Changes from Kai. - -Wed Dec 30 20:03:47 1992 - - * 0.99pl2 released. - - * scsi.c: Blacklist back in. Remove Newbury drive as other bugfix - eliminates need for it here. - - * sd.c: Return ENODEV instead of EACCES if no such device available. - (sd_init) Init blkdev_fops earlier so that sd_open is available sooner. - - * sr.c: Same as above for sd.c. - - * st.c: Return ENODEV instead of ENXIO if no device. Init chrdev_fops - sooner, so that it is always there even if no tapes. - - * seagate.c (controller_type): New variable to keep track of ST0x or - FD. Modify signatures list to indicate controller type, and init - controller_type once we find a match. - - * wd7000.c (wd7000_set_sync): Remove redundant function. - -Sun Dec 20 16:26:24 1992 - - * 0.99pl1 released. - - * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against - NR_SCSI_DEVICES. - - * sr_ioctl.c: Verify that device exists before allowing an ioctl. - - * st.c: Patches from Kai - change timeout values, improve end of tape - handling. - -Sun Dec 13 18:15:23 1992 - - * 0.99 kernel released. Baseline for this ChangeLog. -- cgit v1.2.3 From 616434e2aa7091f0fc5f7838af0f8bc809c8cf85 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Mar 2018 08:37:52 +0100 Subject: scsi: remove the sym53c416 driver This driver hasn't seen any recent bug fixing and is one of the last drivers using the scsi_module.c infrastruture that has been deprecated 15 years ago. Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- Documentation/scsi/scsi-parameters.txt | 3 - drivers/scsi/Kconfig | 18 - drivers/scsi/Makefile | 1 - drivers/scsi/sym53c416.c | 844 --------------------------------- drivers/scsi/sym53c416.h | 33 -- 5 files changed, 899 deletions(-) delete mode 100644 drivers/scsi/sym53c416.c delete mode 100644 drivers/scsi/sym53c416.h (limited to 'Documentation') diff --git a/Documentation/scsi/scsi-parameters.txt b/Documentation/scsi/scsi-parameters.txt index 8f7be8a05642..2dc7f11179d1 100644 --- a/Documentation/scsi/scsi-parameters.txt +++ b/Documentation/scsi/scsi-parameters.txt @@ -108,9 +108,6 @@ parameters may be changed at runtime by the command st= [HW,SCSI] SCSI tape parameters (buffers, etc.) See Documentation/scsi/st.txt. - sym53c416= [HW,SCSI] - See header of drivers/scsi/sym53c416.c. - tmscsim= [HW,SCSI] See comment before function dc390_setup() in drivers/scsi/tmscsim.c. diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 9fa0cfd5a068..11e89e56b865 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1172,24 +1172,6 @@ config SCSI_SIM710 It currently supports Compaq EISA cards and NCR MCA cards -config SCSI_SYM53C416 - tristate "Symbios 53c416 SCSI support" - depends on ISA && SCSI - ---help--- - This is support for the sym53c416 SCSI host adapter, the SCSI - adapter that comes with some HP scanners. This driver requires that - the sym53c416 is configured first using some sort of PnP - configuration program (e.g. isapnp) or by a PnP aware BIOS. If you - are using isapnp then you need to compile this driver as a module - and then load it using insmod after isapnp has run. The parameters - of the configured card(s) should be passed to the driver. The format - is: - - insmod sym53c416 sym53c416=, [sym53c416_1=,] - - To compile this driver as a module, choose M here: the - module will be called sym53c416. - config SCSI_DC395x tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support" depends on PCI && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 192a58d7d9d9..d5135efbf9cd 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -77,7 +77,6 @@ obj-$(CONFIG_SCSI_IPS) += ips.o obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o obj-$(CONFIG_SCSI_NCR_D700) += 53c700.o NCR_D700.o obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o -obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c deleted file mode 100644 index e68bcdc75bc3..000000000000 --- a/drivers/scsi/sym53c416.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * sym53c416.c - * Low-level SCSI driver for sym53c416 chip. - * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) - * - * Changes : - * - * Marcelo Tosatti : Added io_request_lock locking - * Alan Cox : Cleaned up code formatting - * Fixed an irq locking bug - * Added ISAPnP support - * Bjoern A. Zeeb : Initial irq locking updates - * Added another card with ISAPnP support - * - * LILO command line usage: sym53c416=[,] - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "scsi.h" -#include -#include "sym53c416.h" - -#define VERSION_STRING "Version 1.0.0-ac" - -#define TC_LOW 0x00 /* Transfer counter low */ -#define TC_MID 0x01 /* Transfer counter mid */ -#define SCSI_FIFO 0x02 /* SCSI FIFO register */ -#define COMMAND_REG 0x03 /* Command Register */ -#define STATUS_REG 0x04 /* Status Register (READ) */ -#define DEST_BUS_ID 0x04 /* Destination Bus ID (WRITE) */ -#define INT_REG 0x05 /* Interrupt Register (READ) */ -#define TOM 0x05 /* Time out multiplier (WRITE) */ -#define STP 0x06 /* Synchronous Transfer period */ -#define SYNC_OFFSET 0x07 /* Synchronous Offset */ -#define CONF_REG_1 0x08 /* Configuration register 1 */ -#define CONF_REG_2 0x0B /* Configuration register 2 */ -#define CONF_REG_3 0x0C /* Configuration register 3 */ -#define CONF_REG_4 0x0D /* Configuration register 4 */ -#define TC_HIGH 0x0E /* Transfer counter high */ -#define PIO_FIFO_1 0x10 /* PIO FIFO register 1 */ -#define PIO_FIFO_2 0x11 /* PIO FIFO register 2 */ -#define PIO_FIFO_3 0x12 /* PIO FIFO register 3 */ -#define PIO_FIFO_4 0x13 /* PIO FIFO register 4 */ -#define PIO_FIFO_CNT 0x14 /* PIO FIFO count */ -#define PIO_INT_REG 0x15 /* PIO interrupt register */ -#define CONF_REG_5 0x16 /* Configuration register 5 */ -#define FEATURE_EN 0x1D /* Feature Enable register */ - -/* Configuration register 1 entries: */ -/* Bits 2-0: SCSI ID of host adapter */ -#define SCM 0x80 /* Slow Cable Mode */ -#define SRID 0x40 /* SCSI Reset Interrupt Disable */ -#define PTM 0x20 /* Parity Test Mode */ -#define EPC 0x10 /* Enable Parity Checking */ -#define CTME 0x08 /* Special Test Mode */ - -/* Configuration register 2 entries: */ -#define FE 0x40 /* Features Enable */ -#define SCSI2 0x08 /* SCSI 2 Enable */ -#define TBPA 0x04 /* Target Bad Parity Abort */ - -/* Configuration register 3 entries: */ -#define IDMRC 0x80 /* ID Message Reserved Check */ -#define QTE 0x40 /* Queue Tag Enable */ -#define CDB10 0x20 /* Command Descriptor Block 10 */ -#define FSCSI 0x10 /* FastSCSI */ -#define FCLK 0x08 /* FastClock */ - -/* Configuration register 4 entries: */ -#define RBS 0x08 /* Register bank select */ -#define EAN 0x04 /* Enable Active Negotiation */ - -/* Configuration register 5 entries: */ -#define LPSR 0x80 /* Lower Power SCSI Reset */ -#define IE 0x20 /* Interrupt Enable */ -#define LPM 0x02 /* Low Power Mode */ -#define WSE0 0x01 /* 0WS Enable */ - -/* Interrupt register entries: */ -#define SRST 0x80 /* SCSI Reset */ -#define ILCMD 0x40 /* Illegal Command */ -#define DIS 0x20 /* Disconnect */ -#define BS 0x10 /* Bus Service */ -#define FC 0x08 /* Function Complete */ -#define RESEL 0x04 /* Reselected */ -#define SI 0x03 /* Selection Interrupt */ - -/* Status Register Entries: */ -#define SCI 0x80 /* SCSI Core Int */ -#define GE 0x40 /* Gross Error */ -#define PE 0x20 /* Parity Error */ -#define TC 0x10 /* Terminal Count */ -#define VGC 0x08 /* Valid Group Code */ -#define PHBITS 0x07 /* Phase bits */ - -/* PIO Interrupt Register Entries: */ -#define SCI 0x80 /* SCSI Core Int */ -#define PFI 0x40 /* PIO FIFO Interrupt */ -#define FULL 0x20 /* PIO FIFO Full */ -#define EMPTY 0x10 /* PIO FIFO Empty */ -#define CE 0x08 /* Collision Error */ -#define OUE 0x04 /* Overflow / Underflow error */ -#define FIE 0x02 /* Full Interrupt Enable */ -#define EIE 0x01 /* Empty Interrupt Enable */ - -/* SYM53C416 SCSI phases (lower 3 bits of SYM53C416_STATUS_REG) */ -#define PHASE_DATA_OUT 0x00 -#define PHASE_DATA_IN 0x01 -#define PHASE_COMMAND 0x02 -#define PHASE_STATUS 0x03 -#define PHASE_RESERVED_1 0x04 -#define PHASE_RESERVED_2 0x05 -#define PHASE_MESSAGE_OUT 0x06 -#define PHASE_MESSAGE_IN 0x07 - -/* SYM53C416 core commands */ -#define NOOP 0x00 -#define FLUSH_FIFO 0x01 -#define RESET_CHIP 0x02 -#define RESET_SCSI_BUS 0x03 -#define DISABLE_SEL_RESEL 0x45 -#define RESEL_SEQ 0x40 -#define SEL_WITHOUT_ATN_SEQ 0x41 -#define SEL_WITH_ATN_SEQ 0x42 -#define SEL_WITH_ATN_AND_STOP_SEQ 0x43 -#define ENABLE_SEL_RESEL 0x44 -#define SEL_WITH_ATN3_SEQ 0x46 -#define RESEL3_SEQ 0x47 -#define SND_MSG 0x20 -#define SND_STAT 0x21 -#define SND_DATA 0x22 -#define DISCONNECT_SEQ 0x23 -#define TERMINATE_SEQ 0x24 -#define TARGET_COMM_COMPLETE_SEQ 0x25 -#define DISCONN 0x27 -#define RECV_MSG_SEQ 0x28 -#define RECV_CMD 0x29 -#define RECV_DATA 0x2A -#define RECV_CMD_SEQ 0x2B -#define TARGET_ABORT_PIO 0x04 -#define TRANSFER_INFORMATION 0x10 -#define INIT_COMM_COMPLETE_SEQ 0x11 -#define MSG_ACCEPTED 0x12 -#define TRANSFER_PAD 0x18 -#define SET_ATN 0x1A -#define RESET_ATN 0x1B -#define ILLEGAL 0xFF - -#define PIO_MODE 0x80 - -#define IO_RANGE 0x20 /* 0x00 - 0x1F */ -#define ID "sym53c416" /* Attention: copied to the sym53c416.h */ -#define PIO_SIZE 128 /* Size of PIO fifo is 128 bytes */ - -#define READ_TIMEOUT 150 -#define WRITE_TIMEOUT 150 - -#ifdef MODULE - -#define sym53c416_base sym53c416 -#define sym53c416_base_1 sym53c416_1 -#define sym53c416_base_2 sym53c416_2 -#define sym53c416_base_3 sym53c416_3 - -static unsigned int sym53c416_base[2]; -static unsigned int sym53c416_base_1[2]; -static unsigned int sym53c416_base_2[2]; -static unsigned int sym53c416_base_3[2]; - -#endif - -#define MAXHOSTS 4 - -#define SG_ADDRESS(buffer) ((char *) sg_virt((buffer))) - -enum phases -{ - idle, - data_out, - data_in, - command_ph, - status_ph, - message_out, - message_in -}; - -typedef struct -{ - int base; - int irq; - int scsi_id; -} host; - -static host hosts[MAXHOSTS] = { - {0, 0, SYM53C416_SCSI_ID}, - {0, 0, SYM53C416_SCSI_ID}, - {0, 0, SYM53C416_SCSI_ID}, - {0, 0, SYM53C416_SCSI_ID} - }; - -static int host_index = 0; -static char info[120]; -static Scsi_Cmnd *current_command = NULL; -static int fastpio = 1; - -static int probeaddrs[] = {0x200, 0x220, 0x240, 0}; - -static void sym53c416_set_transfer_counter(int base, unsigned int len) -{ - /* Program Transfer Counter */ - outb(len & 0x0000FF, base + TC_LOW); - outb((len & 0x00FF00) >> 8, base + TC_MID); - outb((len & 0xFF0000) >> 16, base + TC_HIGH); -} - -static DEFINE_SPINLOCK(sym53c416_lock); - -/* Returns the number of bytes read */ -static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len) -{ - unsigned int orig_len = len; - unsigned long flags = 0; - unsigned int bytes_left; - unsigned long i; - int timeout = READ_TIMEOUT; - - /* Do transfer */ - spin_lock_irqsave(&sym53c416_lock, flags); - while(len && timeout) - { - bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */ - if(fastpio && bytes_left > 3) - { - insl(base + PIO_FIFO_1, buffer, bytes_left >> 2); - buffer += bytes_left & 0xFC; - len -= bytes_left & 0xFC; - } - else if(bytes_left > 0) - { - len -= bytes_left; - for(; bytes_left > 0; bytes_left--) - *(buffer++) = inb(base + PIO_FIFO_1); - } - else - { - i = jiffies + timeout; - spin_unlock_irqrestore(&sym53c416_lock, flags); - while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & EMPTY) && timeout) - if(inb(base + PIO_INT_REG) & SCI) - timeout = 0; - spin_lock_irqsave(&sym53c416_lock, flags); - if(inb(base + PIO_INT_REG) & EMPTY) - timeout = 0; - } - } - spin_unlock_irqrestore(&sym53c416_lock, flags); - return orig_len - len; -} - -/* Returns the number of bytes written */ -static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len) -{ - unsigned int orig_len = len; - unsigned long flags = 0; - unsigned int bufferfree; - unsigned long i; - unsigned int timeout = WRITE_TIMEOUT; - - /* Do transfer */ - spin_lock_irqsave(&sym53c416_lock, flags); - while(len && timeout) - { - bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT); - if(bufferfree > len) - bufferfree = len; - if(fastpio && bufferfree > 3) - { - outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2); - buffer += bufferfree & 0xFC; - len -= bufferfree & 0xFC; - } - else if(bufferfree > 0) - { - len -= bufferfree; - for(; bufferfree > 0; bufferfree--) - outb(*(buffer++), base + PIO_FIFO_1); - } - else - { - i = jiffies + timeout; - spin_unlock_irqrestore(&sym53c416_lock, flags); - while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & FULL) && timeout) - ; - spin_lock_irqsave(&sym53c416_lock, flags); - if(inb(base + PIO_INT_REG) & FULL) - timeout = 0; - } - } - spin_unlock_irqrestore(&sym53c416_lock, flags); - return orig_len - len; -} - -static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id) -{ - struct Scsi_Host *dev = dev_id; - int base = dev->io_port; - int i; - unsigned long flags = 0; - unsigned char status_reg, pio_int_reg, int_reg; - struct scatterlist *sg; - unsigned int tot_trans = 0; - - spin_lock_irqsave(dev->host_lock,flags); - status_reg = inb(base + STATUS_REG); - pio_int_reg = inb(base + PIO_INT_REG); - int_reg = inb(base + INT_REG); - spin_unlock_irqrestore(dev->host_lock, flags); - - /* First, we handle error conditions */ - if(int_reg & SCI) /* SCSI Reset */ - { - printk(KERN_DEBUG "sym53c416: Reset received\n"); - current_command->SCp.phase = idle; - current_command->result = DID_RESET << 16; - spin_lock_irqsave(dev->host_lock, flags); - current_command->scsi_done(current_command); - spin_unlock_irqrestore(dev->host_lock, flags); - goto out; - } - if(int_reg & ILCMD) /* Illegal Command */ - { - printk(KERN_WARNING "sym53c416: Illegal Command: 0x%02x.\n", inb(base + COMMAND_REG)); - current_command->SCp.phase = idle; - current_command->result = DID_ERROR << 16; - spin_lock_irqsave(dev->host_lock, flags); - current_command->scsi_done(current_command); - spin_unlock_irqrestore(dev->host_lock, flags); - goto out; - } - if(status_reg & GE) /* Gross Error */ - { - printk(KERN_WARNING "sym53c416: Controller reports gross error.\n"); - current_command->SCp.phase = idle; - current_command->result = DID_ERROR << 16; - spin_lock_irqsave(dev->host_lock, flags); - current_command->scsi_done(current_command); - spin_unlock_irqrestore(dev->host_lock, flags); - goto out; - } - if(status_reg & PE) /* Parity Error */ - { - printk(KERN_WARNING "sym53c416:SCSI parity error.\n"); - current_command->SCp.phase = idle; - current_command->result = DID_PARITY << 16; - spin_lock_irqsave(dev->host_lock, flags); - current_command->scsi_done(current_command); - spin_unlock_irqrestore(dev->host_lock, flags); - goto out; - } - if(pio_int_reg & (CE | OUE)) - { - printk(KERN_WARNING "sym53c416: PIO interrupt error.\n"); - current_command->SCp.phase = idle; - current_command->result = DID_ERROR << 16; - spin_lock_irqsave(dev->host_lock, flags); - current_command->scsi_done(current_command); - spin_unlock_irqrestore(dev->host_lock, flags); - goto out; - } - if(int_reg & DIS) /* Disconnect */ - { - if(current_command->SCp.phase != message_in) - current_command->result = DID_NO_CONNECT << 16; - else - current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16); - current_command->SCp.phase = idle; - spin_lock_irqsave(dev->host_lock, flags); - current_command->scsi_done(current_command); - spin_unlock_irqrestore(dev->host_lock, flags); - goto out; - } - /* Now we handle SCSI phases */ - - switch(status_reg & PHBITS) /* Filter SCSI phase out of status reg */ - { - case PHASE_DATA_OUT: - { - if(int_reg & BS) - { - current_command->SCp.phase = data_out; - outb(FLUSH_FIFO, base + COMMAND_REG); - sym53c416_set_transfer_counter(base, - scsi_bufflen(current_command)); - outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG); - - scsi_for_each_sg(current_command, - sg, scsi_sg_count(current_command), i) { - tot_trans += sym53c416_write(base, - SG_ADDRESS(sg), - sg->length); - } - if(tot_trans < current_command->underflow) - printk(KERN_WARNING "sym53c416: Underflow, wrote %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow); - } - break; - } - - case PHASE_DATA_IN: - { - if(int_reg & BS) - { - current_command->SCp.phase = data_in; - outb(FLUSH_FIFO, base + COMMAND_REG); - sym53c416_set_transfer_counter(base, - scsi_bufflen(current_command)); - - outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG); - - scsi_for_each_sg(current_command, - sg, scsi_sg_count(current_command), i) { - tot_trans += sym53c416_read(base, - SG_ADDRESS(sg), - sg->length); - } - if(tot_trans < current_command->underflow) - printk(KERN_WARNING "sym53c416: Underflow, read %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow); - } - break; - } - - case PHASE_COMMAND: - { - current_command->SCp.phase = command_ph; - printk(KERN_ERR "sym53c416: Unknown interrupt in command phase.\n"); - break; - } - - case PHASE_STATUS: - { - current_command->SCp.phase = status_ph; - outb(FLUSH_FIFO, base + COMMAND_REG); - outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG); - break; - } - - case PHASE_RESERVED_1: - case PHASE_RESERVED_2: - { - printk(KERN_ERR "sym53c416: Reserved phase occurred.\n"); - break; - } - - case PHASE_MESSAGE_OUT: - { - current_command->SCp.phase = message_out; - outb(SET_ATN, base + COMMAND_REG); - outb(MSG_ACCEPTED, base + COMMAND_REG); - break; - } - - case PHASE_MESSAGE_IN: - { - current_command->SCp.phase = message_in; - current_command->SCp.Status = inb(base + SCSI_FIFO); - current_command->SCp.Message = inb(base + SCSI_FIFO); - if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT) - outb(SET_ATN, base + COMMAND_REG); - outb(MSG_ACCEPTED, base + COMMAND_REG); - break; - } - } -out: - return IRQ_HANDLED; -} - -static void sym53c416_init(int base, int scsi_id) -{ - outb(RESET_CHIP, base + COMMAND_REG); - outb(NOOP, base + COMMAND_REG); - outb(0x99, base + TOM); /* Time out of 250 ms */ - outb(0x05, base + STP); - outb(0x00, base + SYNC_OFFSET); - outb(EPC | scsi_id, base + CONF_REG_1); - outb(FE | SCSI2 | TBPA, base + CONF_REG_2); - outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3); - outb(0x83 | EAN, base + CONF_REG_4); - outb(IE | WSE0, base + CONF_REG_5); - outb(0, base + FEATURE_EN); -} - -static int sym53c416_probeirq(int base, int scsi_id) -{ - int irq, irqs; - unsigned long i; - - /* Clear interrupt register */ - inb(base + INT_REG); - /* Start probing for irq's */ - irqs = probe_irq_on(); - /* Reinit chip */ - sym53c416_init(base, scsi_id); - /* Cause interrupt */ - outb(NOOP, base + COMMAND_REG); - outb(ILLEGAL, base + COMMAND_REG); - outb(0x07, base + DEST_BUS_ID); - outb(0x00, base + DEST_BUS_ID); - /* Wait for interrupt to occur */ - i = jiffies + 20; - while(time_before(jiffies, i) && !(inb(base + STATUS_REG) & SCI)) - barrier(); - if(time_before_eq(i, jiffies)) /* timed out */ - return 0; - /* Get occurred irq */ - irq = probe_irq_off(irqs); - sym53c416_init(base, scsi_id); - return irq; -} - -/* Setup: sym53c416=base,irq */ -void sym53c416_setup(char *str, int *ints) -{ - int i; - - if(host_index >= MAXHOSTS) - { - printk(KERN_WARNING "sym53c416: Too many hosts defined\n"); - return; - } - if(ints[0] < 1 || ints[0] > 2) - { - printk(KERN_ERR "sym53c416: Wrong number of parameters:\n"); - printk(KERN_ERR "sym53c416: usage: sym53c416=[,]\n"); - return; - } - for(i = 0; i < host_index && i >= 0; i++) - if(hosts[i].base == ints[1]) - i = -2; - if(i >= 0) - { - hosts[host_index].base = ints[1]; - hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0; - host_index++; - } -} - -static int sym53c416_test(int base) -{ - outb(RESET_CHIP, base + COMMAND_REG); - outb(NOOP, base + COMMAND_REG); - if(inb(base + COMMAND_REG) != NOOP) - return 0; - if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF) - return 0; - if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY) - return 0; - return 1; -} - - -static struct isapnp_device_id id_table[] = { - { ISAPNP_ANY_ID, ISAPNP_ANY_ID, - ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4161), 0 }, - { ISAPNP_ANY_ID, ISAPNP_ANY_ID, - ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4163), 0 }, - { ISAPNP_DEVICE_SINGLE_END } -}; - -MODULE_DEVICE_TABLE(isapnp, id_table); - -static void sym53c416_probe(void) -{ - int *base = probeaddrs; - int ints[2]; - - ints[0] = 1; - for(; *base; base++) { - if (request_region(*base, IO_RANGE, ID)) { - if (sym53c416_test(*base)) { - ints[1] = *base; - sym53c416_setup(NULL, ints); - } - release_region(*base, IO_RANGE); - } - } -} - -int sym53c416_detect(struct scsi_host_template *tpnt) -{ - unsigned long flags; - struct Scsi_Host * shpnt = NULL; - int i; - int count; - struct pnp_dev *idev = NULL; - -#ifdef MODULE - int ints[3]; - - ints[0] = 2; - if(sym53c416_base[0]) - { - ints[1] = sym53c416_base[0]; - ints[2] = sym53c416_base[1]; - sym53c416_setup(NULL, ints); - } - if(sym53c416_base_1[0]) - { - ints[1] = sym53c416_base_1[0]; - ints[2] = sym53c416_base_1[1]; - sym53c416_setup(NULL, ints); - } - if(sym53c416_base_2[0]) - { - ints[1] = sym53c416_base_2[0]; - ints[2] = sym53c416_base_2[1]; - sym53c416_setup(NULL, ints); - } - if(sym53c416_base_3[0]) - { - ints[1] = sym53c416_base_3[0]; - ints[2] = sym53c416_base_3[1]; - sym53c416_setup(NULL, ints); - } -#endif - printk(KERN_INFO "sym53c416.c: %s\n", VERSION_STRING); - - for (i=0; id_table[i].vendor != 0; i++) { - while((idev=pnp_find_dev(NULL, id_table[i].vendor, - id_table[i].function, idev))!=NULL) - { - int i[3]; - - if(pnp_device_attach(idev)<0) - { - printk(KERN_WARNING "sym53c416: unable to attach PnP device.\n"); - continue; - } - if(pnp_activate_dev(idev) < 0) - { - printk(KERN_WARNING "sym53c416: unable to activate PnP device.\n"); - pnp_device_detach(idev); - continue; - - } - - i[0] = 2; - i[1] = pnp_port_start(idev, 0); - i[2] = pnp_irq(idev, 0); - - printk(KERN_INFO "sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.\n", - i[1], i[2]); - sym53c416_setup(NULL, i); - } - } - sym53c416_probe(); - - /* Now we register and set up each host adapter found... */ - for(count = 0, i = 0; i < host_index; i++) { - if (!request_region(hosts[i].base, IO_RANGE, ID)) - continue; - if (!sym53c416_test(hosts[i].base)) { - printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base); - goto fail_release_region; - } - - /* We don't have an irq yet, so we should probe for one */ - if (!hosts[i].irq) - hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id); - if (!hosts[i].irq) - goto fail_release_region; - - shpnt = scsi_register(tpnt, 0); - if (!shpnt) - goto fail_release_region; - /* Request for specified IRQ */ - if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt)) - goto fail_free_host; - - spin_lock_irqsave(&sym53c416_lock, flags); - shpnt->unique_id = hosts[i].base; - shpnt->io_port = hosts[i].base; - shpnt->n_io_port = IO_RANGE; - shpnt->irq = hosts[i].irq; - shpnt->this_id = hosts[i].scsi_id; - sym53c416_init(hosts[i].base, hosts[i].scsi_id); - count++; - spin_unlock_irqrestore(&sym53c416_lock, flags); - continue; - - fail_free_host: - scsi_unregister(shpnt); - fail_release_region: - release_region(hosts[i].base, IO_RANGE); - } - return count; -} - -const char *sym53c416_info(struct Scsi_Host *SChost) -{ - int i; - int base = SChost->io_port; - int irq = SChost->irq; - int scsi_id = 0; - int rev = inb(base + TC_HIGH); - - for(i = 0; i < host_index; i++) - if(hosts[i].base == base) - scsi_id = hosts[i].scsi_id; - sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow"); - return info; -} - -static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) -{ - int base; - unsigned long flags = 0; - int i; - - /* Store base register as we can have more than one controller in the system */ - base = SCpnt->device->host->io_port; - current_command = SCpnt; /* set current command */ - current_command->scsi_done = done; /* set ptr to done function */ - current_command->SCp.phase = command_ph; /* currect phase is the command phase */ - current_command->SCp.Status = 0; - current_command->SCp.Message = 0; - - spin_lock_irqsave(&sym53c416_lock, flags); - outb(scmd_id(SCpnt), base + DEST_BUS_ID); /* Set scsi id target */ - outb(FLUSH_FIFO, base + COMMAND_REG); /* Flush SCSI and PIO FIFO's */ - /* Write SCSI command into the SCSI fifo */ - for(i = 0; i < SCpnt->cmd_len; i++) - outb(SCpnt->cmnd[i], base + SCSI_FIFO); - /* Start selection sequence */ - outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG); - /* Now an interrupt will be generated which we will catch in out interrupt routine */ - spin_unlock_irqrestore(&sym53c416_lock, flags); - return 0; -} - -DEF_SCSI_QCMD(sym53c416_queuecommand) - -static int sym53c416_host_reset(Scsi_Cmnd *SCpnt) -{ - int base; - int scsi_id = -1; - int i; - unsigned long flags; - - spin_lock_irqsave(&sym53c416_lock, flags); - - /* printk("sym53c416_reset\n"); */ - base = SCpnt->device->host->io_port; - /* search scsi_id - fixme, we shouldn't need to iterate for this! */ - for(i = 0; i < host_index && scsi_id == -1; i++) - if(hosts[i].base == base) - scsi_id = hosts[i].scsi_id; - outb(RESET_CHIP, base + COMMAND_REG); - outb(NOOP | PIO_MODE, base + COMMAND_REG); - outb(RESET_SCSI_BUS, base + COMMAND_REG); - sym53c416_init(base, scsi_id); - - spin_unlock_irqrestore(&sym53c416_lock, flags); - return SUCCESS; -} - -static int sym53c416_release(struct Scsi_Host *shost) -{ - if (shost->irq) - free_irq(shost->irq, shost); - if (shost->io_port && shost->n_io_port) - release_region(shost->io_port, shost->n_io_port); - return 0; -} - -static int sym53c416_bios_param(struct scsi_device *sdev, - struct block_device *dev, - sector_t capacity, int *ip) -{ - int size; - - size = capacity; - ip[0] = 64; /* heads */ - ip[1] = 32; /* sectors */ - if((ip[2] = size >> 11) > 1024) /* cylinders, test for big disk */ - { - ip[0] = 255; /* heads */ - ip[1] = 63; /* sectors */ - ip[2] = size / (255 * 63); /* cylinders */ - } - return 0; -} - -/* Loadable module support */ -#ifdef MODULE - -MODULE_AUTHOR("Lieven Willems"); -MODULE_LICENSE("GPL"); - -module_param_array(sym53c416, uint, NULL, 0); -module_param_array(sym53c416_1, uint, NULL, 0); -module_param_array(sym53c416_2, uint, NULL, 0); -module_param_array(sym53c416_3, uint, NULL, 0); - -#endif - -static struct scsi_host_template driver_template = { - .proc_name = "sym53c416", - .name = "Symbios Logic 53c416", - .detect = sym53c416_detect, - .info = sym53c416_info, - .queuecommand = sym53c416_queuecommand, - .eh_host_reset_handler =sym53c416_host_reset, - .release = sym53c416_release, - .bios_param = sym53c416_bios_param, - .can_queue = 1, - .this_id = SYM53C416_SCSI_ID, - .sg_tablesize = 32, - .unchecked_isa_dma = 1, - .use_clustering = ENABLE_CLUSTERING, -}; -#include "scsi_module.c" diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h deleted file mode 100644 index 387de5d80a70..000000000000 --- a/drivers/scsi/sym53c416.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * sym53c416.h - * - * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - */ - -#ifndef _SYM53C416_H -#define _SYM53C416_H - -#include - -#define SYM53C416_SCSI_ID 7 - -static int sym53c416_detect(struct scsi_host_template *); -static const char *sym53c416_info(struct Scsi_Host *); -static int sym53c416_release(struct Scsi_Host *); -static int sym53c416_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); -static int sym53c416_host_reset(Scsi_Cmnd *); -static int sym53c416_bios_param(struct scsi_device *, struct block_device *, - sector_t, int *); -static void sym53c416_setup(char *str, int *ints); -#endif -- cgit v1.2.3 From 83c9f08e6c6a6dc668384882de4dcf5ef4ae0ba7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Mar 2018 08:37:53 +0100 Subject: scsi: remove the old scsi_module.c initialization model After more than 15 years all users of this legacy interface are finally gone. Rest in peace! Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- Documentation/driver-api/scsi.rst | 6 -- Documentation/scsi/scsi_mid_low_api.txt | 122 +------------------------------- drivers/scsi/hosts.c | 23 ------ drivers/scsi/scsi_module.c | 73 ------------------- include/scsi/scsi_host.h | 36 ---------- 5 files changed, 1 insertion(+), 259 deletions(-) delete mode 100644 drivers/scsi/scsi_module.c (limited to 'Documentation') diff --git a/Documentation/driver-api/scsi.rst b/Documentation/driver-api/scsi.rst index 3ae337929721..31ad0fed6763 100644 --- a/Documentation/driver-api/scsi.rst +++ b/Documentation/driver-api/scsi.rst @@ -154,12 +154,6 @@ lists). .. kernel-doc:: drivers/scsi/scsi_lib_dma.c :export: -drivers/scsi/scsi_module.c -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The file drivers/scsi/scsi_module.c contains legacy support for -old-style host templates. It should never be used by any new driver. - drivers/scsi/scsi_proc.c ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 2c31d9ee6776..177c031763c0 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt @@ -114,9 +114,7 @@ called "xxx" could be defined as "static int xxx_slave_alloc(struct scsi_device * sdev) { /* code */ }" ** the scsi_host_alloc() function is a replacement for the rather vaguely -named scsi_register() function in most situations. The scsi_register() -and scsi_unregister() functions remain to support legacy LLDs that use -the passive initialization model. +named scsi_register() function in most situations. Hotplug initialization model @@ -228,79 +226,6 @@ slave_configure() callbacks). Such instances are "owned" by the mid-level. struct scsi_device instances are freed after slave_destroy(). -Passive initialization model -============================ -These older LLDs include a file called "scsi_module.c" [yes the ".c" is a -little surprising] in their source code. For that file to work an -instance of struct scsi_host_template with the name "driver_template" -needs to be defined. Here is a typical code sequence used in this model: - static struct scsi_host_template driver_template = { - ... - }; - #include "scsi_module.c" - -The scsi_module.c file contains two functions: - - init_this_scsi_driver() which is executed when the LLD is - initialized (i.e. boot time or module load time) - - exit_this_scsi_driver() which is executed when the LLD is shut - down (i.e. module unload time) -Note: since these functions are tagged with __init and __exit qualifiers -an LLD should not call them explicitly (since the kernel does that). - -Here is an example of an initialization sequence when two hosts are -detected (so detect() returns 2) and the SCSI bus scan on each host -finds 1 SCSI device (and a second device does not respond). - -LLD mid level LLD -===----------------------=========-----------------===------ -init_this_scsi_driver() ----+ - | - detect() -----------------+ - | | - | scsi_register() - | scsi_register() - | - slave_alloc() - slave_configure() --> scsi_change_queue_depth() - slave_alloc() *** - slave_destroy() *** - | - slave_alloc() - slave_configure() - slave_alloc() *** - slave_destroy() *** ------------------------------------------------------------- - -The mid level invokes scsi_change_queue_depth() with "cmd_per_lun" for that -host as the queue length. These settings can be overridden by a -slave_configure() supplied by the LLD. - -*** For scsi devices that the mid level tries to scan but do not - respond, a slave_alloc(), slave_destroy() pair is called. - -Here is an LLD shutdown sequence: - -LLD mid level LLD -===----------------------=========-----------------===------ -exit_this_scsi_driver() ----+ - | - slave_destroy() - release() --> scsi_unregister() - | - slave_destroy() - release() --> scsi_unregister() ------------------------------------------------------------- - -An LLD need not define slave_destroy() (i.e. it is optional). - -The shortcoming of the "passive initialization model" is that host -registration and de-registration are (typically) tied to LLD initialization -and shutdown. Once the LLD is initialized then a new host that appears -(e.g. via hotplugging) cannot easily be added without a redundant -driver shutdown and re-initialization. It may be possible to write an LLD -that uses both initialization models. - - Reference Counting ================== The Scsi_Host structure has had reference counting infrastructure added. @@ -738,7 +663,6 @@ The interface functions are listed below in alphabetical order. Summary: bios_param - fetch head, sector, cylinder info for a disk - detect - detects HBAs this driver wants to control eh_timed_out - notify the host that a command timer expired eh_abort_handler - abort given command eh_bus_reset_handler - issue SCSI bus reset @@ -748,7 +672,6 @@ Summary: ioctl - driver can respond to ioctls proc_info - supports /proc/scsi/{driver_name}/{host_no} queuecommand - queue scsi command, invoke 'done' on completion - release - release all resources associated with given host slave_alloc - prior to any commands being sent to a new device slave_configure - driver fine tuning for given device after attach slave_destroy - given device is about to be shut down @@ -784,28 +707,6 @@ Details: sector_t capacity, int params[3]) -/** - * detect - detects HBAs this driver wants to control - * @shtp: host template for this driver. - * - * Returns number of hosts this driver wants to control. 0 means no - * suitable hosts found. - * - * Locks: none held - * - * Calling context: process [invoked from init_this_scsi_driver()] - * - * Notes: First function called from the SCSI mid level on this - * driver. Upper level drivers (e.g. sd) may not (yet) be present. - * For each host found, this method should call scsi_register() - * [see hosts.c]. - * - * Defined in: LLD (required if "passive initialization mode" is used, - * not invoked in "hotplug initialization mode") - **/ - int detect(struct scsi_host_template * shtp) - - /** * eh_timed_out - The timer for the command has just fired * @scp: identifies command timing out @@ -1073,27 +974,6 @@ Details: int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp) -/** - * release - release all resources associated with given host - * @shp: host to be released. - * - * Return value ignored (could soon be a function returning void). - * - * Locks: none held - * - * Calling context: process - * - * Notes: Invoked from scsi_module.c's exit_this_scsi_driver(). - * LLD's implementation of this function should call - * scsi_unregister(shp) prior to returning. - * Only needed for old-style host templates. - * - * Defined in: LLD (required in "passive initialization model", - * should not be defined in hotplug model) - **/ - int release(struct Scsi_Host * shp) - - /** * slave_alloc - prior to any commands being sent to a new device * (i.e. just prior to scan) this call is made diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 0a5362822ed6..ffd1030b6c91 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -518,29 +518,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) } EXPORT_SYMBOL(scsi_host_alloc); -struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize) -{ - struct Scsi_Host *shost = scsi_host_alloc(sht, privsize); - - if (!sht->detect) { - printk(KERN_WARNING "scsi_register() called on new-style " - "template for driver %s\n", sht->name); - dump_stack(); - } - - if (shost) - list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts); - return shost; -} -EXPORT_SYMBOL(scsi_register); - -void scsi_unregister(struct Scsi_Host *shost) -{ - list_del(&shost->sht_legacy_list); - scsi_host_put(shost); -} -EXPORT_SYMBOL(scsi_unregister); - static int __scsi_host_match(struct device *dev, const void *data) { struct Scsi_Host *p; diff --git a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c deleted file mode 100644 index 489175833709..000000000000 --- a/drivers/scsi/scsi_module.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2003 Christoph Hellwig. - * Released under GPL v2. - * - * Support for old-style host templates. - * - * NOTE: Do not use this for new drivers ever. - */ - -#include -#include -#include - -#include - - -static int __init init_this_scsi_driver(void) -{ - struct scsi_host_template *sht = &driver_template; - struct Scsi_Host *shost; - struct list_head *l; - int error; - - if (!sht->release) { - printk(KERN_ERR - "scsi HBA driver %s didn't set a release method.\n", - sht->name); - return -EINVAL; - } - - sht->module = THIS_MODULE; - INIT_LIST_HEAD(&sht->legacy_hosts); - - sht->detect(sht); - if (list_empty(&sht->legacy_hosts)) - return -ENODEV; - - list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) { - error = scsi_add_host(shost, NULL); - if (error) - goto fail; - scsi_scan_host(shost); - } - return 0; - fail: - l = &shost->sht_legacy_list; - while ((l = l->prev) != &sht->legacy_hosts) - scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list)); - return error; -} - -static void __exit exit_this_scsi_driver(void) -{ - struct scsi_host_template *sht = &driver_template; - struct Scsi_Host *shost, *s; - - list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) - scsi_remove_host(shost); - list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list) - sht->release(shost); - - if (list_empty(&sht->legacy_hosts)) - return; - - printk(KERN_WARNING "%s did not call scsi_unregister\n", sht->name); - dump_stack(); - - list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list) - scsi_unregister(shost); -} - -module_init(init_this_scsi_driver); -module_exit(exit_this_scsi_driver); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 19317585ae48..4e418fb539f8 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -51,21 +51,6 @@ struct scsi_host_template { struct module *module; const char *name; - /* - * Used to initialize old-style drivers. For new-style drivers - * just perform all work in your module initialization function. - * - * Status: OBSOLETE - */ - int (* detect)(struct scsi_host_template *); - - /* - * Used as unload callback for hosts with old-style drivers. - * - * Status: OBSOLETE - */ - int (* release)(struct Scsi_Host *); - /* * The info function will return whatever useful information the * developer sees fit. If not provided, then the name field will @@ -482,15 +467,6 @@ struct scsi_host_template { */ const struct attribute_group **sdev_groups; - /* - * List of hosts per template. - * - * This is only for use by scsi_module.c for legacy templates. - * For these access to it is synchronized implicitly by - * module_init/module_exit. - */ - struct list_head legacy_hosts; - /* * Vendor Identifier associated with the host * @@ -713,15 +689,6 @@ struct Scsi_Host { /* ldm bits */ struct device shost_gendev, shost_dev; - /* - * List of hosts per template. - * - * This is only for use by scsi_module.c for legacy templates. - * For these access to it is synchronized implicitly by - * module_init/module_exit. - */ - struct list_head sht_legacy_list; - /* * Points to the transport data (if any) which is allocated * separately @@ -922,9 +889,6 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) return shost->prot_guard_type; } -/* legacy interfaces */ -extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); -extern void scsi_unregister(struct Scsi_Host *); extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state); #endif /* _SCSI_SCSI_HOST_H */ -- cgit v1.2.3 From c121107d0f8473bf9aa5fe1c32adab0a40f093e2 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Mon, 19 Mar 2018 23:01:58 -0400 Subject: scsi: documentation: Obsolete documentation references Remove references to fdomain, ncr53c400a, tmscsim, and DAC960 from Documentation/scsi. Signed-off-by: Martin K. Petersen --- Documentation/scsi/Mylex.txt | 5 - Documentation/scsi/scsi-parameters.txt | 9 - Documentation/scsi/tmscsim.txt | 443 --------------------------------- 3 files changed, 457 deletions(-) delete mode 100644 Documentation/scsi/Mylex.txt delete mode 100644 Documentation/scsi/tmscsim.txt (limited to 'Documentation') diff --git a/Documentation/scsi/Mylex.txt b/Documentation/scsi/Mylex.txt deleted file mode 100644 index 3797f3e6c2b5..000000000000 --- a/Documentation/scsi/Mylex.txt +++ /dev/null @@ -1,5 +0,0 @@ -Please see the file README.BusLogic for information about Linux support for -Mylex (formerly BusLogic) MultiMaster and FlashPoint SCSI Host Adapters. - -The Mylex DAC960 PCI RAID Controllers are now supported. Please consult -http://sourceforge.net/projects/dandelion for further information on the DAC960 driver. diff --git a/Documentation/scsi/scsi-parameters.txt b/Documentation/scsi/scsi-parameters.txt index 2dc7f11179d1..25a4b4cf04a6 100644 --- a/Documentation/scsi/scsi-parameters.txt +++ b/Documentation/scsi/scsi-parameters.txt @@ -34,9 +34,6 @@ parameters may be changed at runtime by the command See drivers/scsi/BusLogic.c, comment before function BusLogic_ParseDriverOptions(). - fdomain= [HW,SCSI] - See header of drivers/scsi/fdomain.c. - gdth= [HW,SCSI] See header of drivers/scsi/gdth.c. @@ -68,8 +65,6 @@ parameters may be changed at runtime by the command ncr53c400a= [HW,SCSI] See Documentation/scsi/g_NCR5380.txt. - ncr53c406a= [HW,SCSI] - ncr53c8xx= [HW,SCSI] osst= [HW,SCSI] SCSI Tape Driver @@ -108,9 +103,5 @@ parameters may be changed at runtime by the command st= [HW,SCSI] SCSI tape parameters (buffers, etc.) See Documentation/scsi/st.txt. - tmscsim= [HW,SCSI] - See comment before function dc390_setup() in - drivers/scsi/tmscsim.c. - wd33c93= [HW,SCSI] See header of drivers/scsi/wd33c93.c. diff --git a/Documentation/scsi/tmscsim.txt b/Documentation/scsi/tmscsim.txt deleted file mode 100644 index 0e0322bf0020..000000000000 --- a/Documentation/scsi/tmscsim.txt +++ /dev/null @@ -1,443 +0,0 @@ -The tmscsim driver -================== - -1. Purpose and history -2. Installation -3. Features -4. Configuration via /proc/scsi/tmscsim/? -5. Configuration via boot/module params -6. Potential improvements -7. Bug reports, debugging and updates -8. Acknowledgements -9. Copyright - - -1. Purpose and history ----------------------- -The tmscsim driver supports PCI SCSI Host Adapters based on the AM53C974 -chip. AM53C974 based SCSI adapters include: - Tekram DC390, DC390T - Dawicontrol 2974 - QLogic Fast! PCI Basic - some on-board adapters -(This is most probably not a complete list) - -It has originally written by C.L. Huang from the Tekram corp. to support the -Tekram DC390(T) adapter. This is where the name comes from: tm = Tekram -scsi = SCSI driver, m = AMD (?) as opposed to w for the DC390W/U/F -(NCR53c8X5, X=2/7) driver. Yes, there was also a driver for the latter, -tmscsiw, which supported DC390W/U/F adapters. It's not maintained any more, -as the ncr53c8xx is perfectly supporting these adapters since some time. - -The driver first appeared in April 1996, exclusively supported the DC390 -and has been enhanced since then in various steps. In May 1998 support for -general AM53C974 based adapters and some possibilities to configure it were -added. The non-DC390 support works by assuming some values for the data -normally taken from the DC390 EEPROM. See below (chapter 5) for details. - -When using the DC390, the configuration is still be done using the DC390 -BIOS setup. The DC390 EEPROM is read and used by the driver, any boot or -module parameters (chapter 5) are ignored! However, you can change settings -dynamically, as described in chapter 4. - -For a more detailed description of the driver's history, see the first lines -of tmscsim.c. -The numbering scheme isn't consistent. The first versions went from 1.00 to -1.12, then 1.20a to 1.20t. Finally I decided to use the ncr53c8xx scheme. So -the next revisions will be 2.0a to 2.0X (stable), 2.1a to 2.1X (experimental), -2.2a to 2.2X (stable, again) etc. (X = anything between a and z.) If I send -fixes to people for testing, I create intermediate versions with a digit -appended, e.g. 2.0c3. - - -2. Installation ---------------- -If you got any recent kernel with this driver and document included in -linux/drivers/scsi, you basically have to do nothing special to use this -driver. Of course you have to choose to compile SCSI support and DC390(T) -support into your kernel or as module when configuring your kernel for -compiling. -NEW: You may as well compile this module outside your kernel, using the -supplied Makefile. - - If you got an old kernel (pre 2.1.127, pre 2.0.37p1) with an old version of - this driver: Get dc390-21125-20b.diff.gz or dc390-2036p21-20b1.diff.gz from - my web page and apply the patch. Apply further patches to upgrade to the - latest version of the driver. - - If you want to do it manually, you should copy the files (dc390.h, - tmscsim.h, tmscsim.c, scsiiom.c and README.tmscsim) from this directory to - linux/drivers/scsi. You have to recompile your kernel/module of course. - - You should apply the three patches included in dc390-120-kernel.diff - (Applying them: cd /usr/src; patch -p0 <~/dc390-120-kernel.diff) - The patches are against 2.1.125, so you might have to manually resolve - rejections when applying to another kernel version. - - The patches will update the kernel startup code to allow boot parameters to - be passed to the driver, update the Documentation and finally offer you the - possibility to omit the non-DC390 parts of the driver. - (By selecting "Omit support for non DC390" you basically disable the - emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes - of memory.) - -If you got a very old kernel without the tmscsim driver (pre 2.0.31) -I recommend upgrading your kernel. However, if you don't want to, please -contact me to get the appropriate patches. - - -Upgrading a SCSI driver is always a delicate thing to do. The 2.0 driver has -proven stable on many systems, but it's still a good idea to take some -precautions. In an ideal world you would have a full backup of your disks. -The world isn't ideal and most people don't have full backups (me neither). -So take at least the following measures: -* make your kernel remount the FS read-only on detecting an error: - tune2fs -e remount-ro /dev/sd?? -* have copies of your SCSI disk's partition tables on some safe location: - dd if=/dev/sda of=/mnt/floppy/sda bs=512 count=1 - or just print it with: - fdisk -l | lpr -* make sure you are able to boot Linux (e.g. from floppy disk using InitRD) - if your SCSI disk gets corrupted. You can use - ftp://student.physik.uni-dortmund.de/pub/linux/kernel/bootdisk.gz - -One more warning: I used to overclock my PCI bus to 41.67 MHz. My Tekram -DC390F (Sym53c875) accepted this as well as my Millennium. But the Am53C974 -produced errors and started to corrupt my disks. So don't do that! A 37.50 -MHz PCI bus works for me, though, but I don't recommend using higher clocks -than the 33.33 MHz being in the PCI spec. - - -3.Features ----------- -- SCSI - * Tagged command queueing - * Sync speed up to 10 MHz - * Disconnection - * Multiple LUNs - -- General / Linux interface - * Support for up to 4 AM53C974 adapters. - * DC390 EEPROM usage or boot/module params - * Information via cat /proc/scsi/tmscsim/? - * Dynamically configurable by writing to /proc/scsi/tmscsim/? - * Dynamic allocation of resources - * SMP support: Locking on io_request lock (Linux 2.1/2.2) or adapter - specific locks (Linux 2.5?) - * Uniform source code for Linux-2.x.y - * Support for dyn. addition/removal of devices via add/remove-single-device - (Try: echo "scsi add-single-device C B T U" >/proc/scsi/scsi - C = Controller, B = Bus, T = Target SCSI ID, U = Unit SCSI LUN.) - Use with care! - * Try to use the partition table for the determination of the mapping - - -4. Configuration via /proc/scsi/tmscsim/? ------------------------------------------ -First of all look at the output of /proc/scsi/tmscsim/? by typing - cat /proc/scsi/tmscsim/? -The "?" should be replaced by the SCSI host number. (The shell might do this -for you.) -You will see some info regarding the adapter and, at the end, a listing of -the attached devices and their settings. - -Here's an example: -garloff@kurt:/home/garloff > cat /proc/scsi/tmscsim/0 -Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 2.0e7 2000-11-28 -SCSI Host Nr 1, AM53C974 Adapter Nr 0 -IOPortBase 0xb000, IRQ 10 -MaxID 8, MaxLUN 8, AdapterID 6, SelTimeout 250 ms, DelayReset 1 s -TagMaxNum 16, Status 0x00, ACBFlag 0x00, GlitchEater 24 ns -Statistics: Cmnds 1470165, Cmnds not sent directly 0, Out of SRB conds 0 - Lost arbitrations 587, Sel. connected 0, Connected: No -Nr of attached devices: 4, Nr of DCBs: 4 -Map of attached LUNs: 01 00 00 03 01 00 00 00 -Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd -00 00 00 Yes Yes Yes Yes Yes 100 ns 10.0 M 15 16 -01 03 00 Yes Yes Yes Yes No 100 ns 10.0 M 15 01 -02 03 01 Yes Yes Yes Yes No 100 ns 10.0 M 15 01 -03 04 00 Yes Yes Yes Yes No 100 ns 10.0 M 15 01 - -Note that the settings MaxID and MaxLUN are not zero- but one-based, which -means that a setting MaxLUN=4, will result in the support of LUNs 0..3. This -is somehow inconvenient, but the way the mid-level SCSI code expects it to be. - -ACB and DCB are acronyms for Adapter Control Block and Device Control Block. -These are data structures of the driver containing information about the -adapter and the connected SCSI devices respectively. - -Idx is the device index (just a consecutive number for the driver), ID and -LUN are the SCSI ID and LUN, Prty means Parity checking, Sync synchronous -negotiation, DsCn Disconnection, SndS Send Start command on startup (not -used by the driver) and TagQ Tagged Command Queueing. NegoPeriod and -SyncSpeed are somehow redundant, because they are reciprocal values -(1 / 112 ns = 8.9 MHz). At least in theory. The driver is able to adjust the -NegoPeriod more accurate (4ns) than the SyncSpeed (1 / 25ns). I don't know -if certain devices will have problems with this discrepancy. Max. speed is -10 MHz corresp. to a min. NegoPeriod of 100 ns. -(The driver allows slightly higher speeds if the devices (Ultra SCSI) accept -it, but that's out of adapter spec, on your own risk and unlikely to improve -performance. You're likely to crash your disks.) -SyncOffs is the offset used for synchronous negotiations; max. is 15. -The last values are only shown, if Sync is enabled. (NegoPeriod is still -displayed in brackets to show the values which will be used after enabling -Sync.) -MaxCmd ist the number of commands (=tags) which can be processed at the same -time by the device. - -If you want to change a setting, you can do that by writing to -/proc/scsi/tmscsim/?. Basically you have to imitate the output of driver. -(Don't use the brackets for NegoPeriod on Sync disabled devices.) -You don't have to care about capitalisation. The driver will accept space, -tab, comma, = and : as separators. - -There are three kinds of changes: - -(1) Change driver settings: - You type the names of the parameters and the params following it. - Example: - echo "MaxLUN=8 seltimeout 200" >/proc/scsi/tmscsim/0 - - Note that you can only change MaxID, MaxLUN, AdapterID, SelTimeOut, - TagMaxNum, ACBFlag, GlitchEater and DelayReset. Don't change ACBFlag - unless you want to see what happens, if the driver hangs. - -(2) Change device settings: You write a config line to the driver. The Nr - must match the ID and LUN given. If you give "-" as parameter, it is - ignored and the corresponding setting won't be changed. - You can use "y" or "n" instead of "Yes" and "No" if you want to. - You don't need to specify a full line. The driver automatically performs - an INQUIRY on the device if necessary to check if it is capable to operate - with the given settings (Sync, TagQ). - Examples: - echo "0 0 0 y y y - y - 10 " >/proc/scsi/tmscsim/0 - echo "3 5 0 y n y " >/proc/scsi/tmscsim/0 - - To give a short explanation of the first example: - The first three numbers, "0 0 0" (Device index 0, SCSI ID 0, SCSI LUN 0), - select the device to which the following parameters apply. Note that it - would be sufficient to use the index or both SCSI ID and LUN, but I chose - to require all three to have a syntax similar to the output. - The following "y y y - y" enables Parity checking, enables Synchronous - transfers, Disconnection, leaves Send Start (not used) untouched and - enables Tagged Command Queueing for the selected device. The "-" skips - the Negotiation Period setting but the "10" sets the max sync. speed to - 10 MHz. It's useless to specify both NegoPeriod and SyncSpeed as - discussed above. The values used in this example will result in maximum - performance. - -(3) Special commands: You can force a SCSI bus reset, an INQUIRY command, the - removal or the addition of a device's DCB and a SCSI register dump. - This is only used for debugging when you meet problems. The parameter of - the INQUIRY and REMOVE commands is the device index as shown by the - output of /proc/scsi/tmscsim/? in the device listing in the first column - (Idx). ADD takes the SCSI ID and LUN. - Examples: - echo "reset" >/proc/scsi/tmscsim/0 - echo "inquiry 1" >/proc/scsi/tmscsim/0 - echo "remove 2" >/proc/scsi/tmscsim/1 - echo "add 2 3" >/proc/scsi/tmscsim/? - echo "dump" >/proc/scsi/tmscsim/0 - - Note that you will meet problems when you REMOVE a device's DCB with the - remove command if it contains partitions which are mounted. Only use it - after unmounting its partitions, telling the SCSI mid-level code to - remove it (scsi remove-single-device) and you really need a few bytes of - memory. - The ADD command allows you to configure a device before you tell the - mid-level code to try detection. - - -I'd suggest reviewing the output of /proc/scsi/tmscsim/? after changing -settings to see if everything changed as requested. - - -5. Configuration via boot/module parameters -------------------------------------------- -With the DC390, the driver reads its EEPROM settings and tries to use them. -But you may want to override the settings prior to being able to change the -driver configuration via /proc/scsi/tmscsim/?. -If you do have another AM53C974 based adapter, that's even the only -possibility to adjust settings before you are able to write to the -/proc/scsi/tmscsim/? pseudo-file, e.g. if you want to use another -adapter ID than 7. -(BTW, the log message "DC390: No EEPROM found!" is normal without a DC390.) -For this purpose, you can pass options to the driver before it is initialised -by using kernel or module parameters. See lilo(8) or modprobe(1) manual -pages on how to pass params to the kernel or a module. -[NOTE: Formerly, it was not possible to override the EEPROM supplied - settings of the DC390 with cmd line parameters. This has changed since - 2.0e7] - -The syntax of the params is much shorter than the syntax of the /proc/... -interface. This makes it a little bit more difficult to use. However, long -parameter lines have the risk to be misinterpreted and the length of kernel -parameters is limited. - -As the support for non-DC390 adapters works by simulating the values of the -DC390 EEPROM, the settings are given in a DC390 BIOS' way. - -Here's the syntax: -tmscsim=AdaptID,SpdIdx,DevMode,AdaptMode,TaggedCmnds,DelayReset - -Each of the parameters is a number, containing the described information: - -* AdaptID: The SCSI ID of the host adapter. Must be in the range 0..7 - Default is 7. - -* SpdIdx: The index of the maximum speed as in the DC390 BIOS. The values - 0..7 mean 10, 8.0, 6.7, 5.7, 5.0, 4.0, 3.1 and 2 MHz resp. Default is - 0 (10.0 MHz). - -* DevMode is a bit mapped value describing the per-device features. It - applies to all devices. (Sync, Disc and TagQ will only apply, if the - device supports it.) The meaning of the bits (* = default): - - Bit Val(hex) Val(dec) Meaning - *0 0x01 1 Parity check - *1 0x02 2 Synchronous Negotiation - *2 0x04 4 Disconnection - *3 0x08 8 Send Start command on startup. (Not used) - *4 0x10 16 Tagged Command Queueing - - As usual, the desired value is obtained by adding the wanted values. If - you want to enable all values, e.g., you would use 31(0x1f). Default is 31. - -* AdaptMode is a bit mapped value describing the enabled adapter features. - - Bit Val(hex) Val(dec) Meaning - *0 0x01 1 Support more than two drives. (Not used) - *1 0x02 2 Use DOS compatible mapping for HDs greater than 1GB. - *2 0x04 4 Reset SCSI Bus on startup. - *3 0x08 8 Active Negation: Improves SCSI Bus noise immunity. - 4 0x10 16 Immediate return on BIOS seek command. (Not used) - (*)5 0x20 32 Check for LUNs >= 1. - -* TaggedCmnds is a number indicating the maximum number of Tagged Commands. - It is the binary logarithm - 1 of the actual number. Max is 4 (32). - Value Number of Tagged Commands - 0 2 - 1 4 - 2 8 - *3 16 - 4 32 - -* DelayReset is the time in seconds (minus 0.5s), the adapter waits, after a - bus reset. Default is 1 (corresp. to 1.5s). - -Example: - modprobe tmscsim tmscsim=6,2,31 -would set the adapter ID to 6, max. speed to 6.7 MHz, enable all device -features and leave the adapter features, the number of Tagged Commands -and the Delay after a reset to the defaults. - -As you can see, you don't need to specify all of the six params. -If you want values to be ignored (i.e. the EEprom settings or the defaults -will be used), you may pass -2 (not 0!) at the corresponding position. - -The defaults (7,0,31,15,3,1) are aggressive to allow good performance. You -can use tmscsim=7,0,31,63,4,0 for maximum performance, if your SCSI chain -allows it. If you meet problems, you can use tmscsim=-1 which is a shortcut -for tmscsim=7,4,9,15,2,10. - - -6. Potential improvements -------------------------- -Most of the intended work on the driver has been done. Here are a few ideas -to further improve its usability: - -* Cleanly separate per-Target and per-LUN properties (DCB) -* More intelligent abort() routine -* Use new_eh code (Linux-2.1+) -* Have the mid-level (ML) code (and not the driver) handle more of the - various conditions. -* Command queueing in the driver: Eliminate Query list and use ML instead. -* More user friendly boot/module param syntax - -Further investigation on these problems: - -* Driver hangs with sync readcdda (xcdroast) (most probably VIA PCI error) - -Known problems: -Please see http://www.garloff.de/kurt/linux/dc390/problems.html - -* Changing the parameters of multi-lun by the tmscsim/? interface will - cause problems, cause these settings are mostly per Target and not per LUN - and should be updated accordingly. To be fixed for 2.0d24. -* CDRs (eg Yam CRW4416) not recognized, because some buggy devices don't - recover from a SCSI reset in time. Use a higher delay or don't issue - a SCSI bus reset on driver initialization. See problems page. - For the CRW4416S, this seems to be solved with firmware 1.0g (reported by - Jean-Yves Barbier). -* TEAC CD-532S not being recognized. (Works with 1.11). -* Scanners (eg. Astra UMAX 1220S) don't work: Disable Sync Negotiation. - If this does not help, try echo "INQUIRY t" >/proc/scsi/tmscsim/? (t - replaced by the dev index of your scanner). You may try to reset your SCSI - bus afterwards (echo "RESET" >/proc/scsi/tmscsim/?). - The problem seems to be solved as of 2.0d18, thanks to Andreas Rick. -* If there is a valid partition table, the driver will use it for determining - the mapping. If there's none, a reasonable mapping (Symbios-like) will be - assumed. Other operating systems may not like this mapping, though - it's consistent with the BIOS' behaviour. Old DC390 drivers ignored the - partition table and used a H/S = 64/32 or 255/63 translation. So if you - want to be compatible to those, use this old mapping when creating - partition tables. Even worse, on bootup the DC390 might complain if other - mappings are found, so auto rebooting may fail. -* In some situations, the driver will get stuck in an abort loop. This is a - bad interaction between the Mid-Layer of Linux' SCSI code and the driver. - Try to disable DsCn, if you meet this problem. Please contact me for - further debugging. - - -7. Bug reports, debugging and updates -------------------------------------- -Whenever you have problems with the driver, you are invited to ask the -author for help. However, I'd suggest reading the docs and trying to solve -the problem yourself, first. -If you find something, which you believe to be a bug, please report it to me. -Please append the output of /proc/scsi/scsi, /proc/scsi/tmscsim/? and -maybe the DC390 log messages to the report. - -Bug reports should be send to me (Kurt Garloff ) as well -as to the linux-scsi list (), as sometimes bugs -are caused by the SCSI mid-level code. - -I will ask you for some more details and probably I will also ask you to -enable some of the DEBUG options in the driver (tmscsim.c:DC390_DEBUGXXX -defines). The driver will produce some data for the syslog facility then. -Beware: If your syslog gets written to a SCSI disk connected to your -AM53C974, the logging might produce log output again, and you might end -having your box spending most of its time doing the logging. - -The latest version of the driver can be found at: - http://www.garloff.de/kurt/linux/dc390/ - ftp://ftp.suse.com/pub/people/garloff/linux/dc390/ - - -8. Acknowledgements -------------------- -Thanks to Linus Torvalds, Alan Cox, the FSF people, the XFree86 team and -all the others for the wonderful OS and software. -Thanks to C.L. Huang and Philip Giang (Tekram) for the initial driver -release and support. -Thanks to Doug Ledford, Gérard Roudier for support with SCSI coding. -Thanks to a lot of people (espec. Chiaki Ishikawa, Andreas Haumer, Hubert -Tonneau) for intensively testing the driver (and even risking data loss -doing this during early revisions). -Recently, SuSE GmbH, Nuernberg, FRG, has been paying me for the driver -development and maintenance. Special thanks! - - -9. Copyright ------------- - This driver is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - If you want to use any later version of the GNU GPL, you will probably - be allowed to, but you have to ask me and Tekram - before. - -------------------------------------------------------------------------- -Written by Kurt Garloff 1998/06/11 -Last updated 2000/11/28, driver revision 2.0e7 -$Id: README.tmscsim,v 2.25.2.7 2000/12/20 01:07:12 garloff Exp $ -- cgit v1.2.3 From 114c1aa210494a02c26aa33f793e5b641df01989 Mon Sep 17 00:00:00 2001 From: Stanislav Nijnikov Date: Thu, 1 Mar 2018 12:48:06 +0200 Subject: scsi: ufs: sysfs: reworking of the rpm_lvl and spm_lvl entries Read from these files will return the integer value of the chosen power management level now. Separate entries were added to show the target UFS device and UIC link states. The description of the possible power managements levels was added to the ABI file. The on-write behaviour of these entries wasn't changed. [mkp: typo] Signed-off-by: Stanislav Nijnikov Acked-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 67 ++++++++++++++++++++++ drivers/scsi/ufs/ufs-sysfs.c | 92 +++++++++++++++--------------- 2 files changed, 114 insertions(+), 45 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 07f1c2f8dbfc..83735f79e572 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -802,3 +802,70 @@ Description: This file shows the The amount of physical memory needed the particular logical unit. The full information about the attribute could be found at UFS specifications 2.1. The file is read only. + + +What: /sys/bus/platform/drivers/ufshcd/*/rpm_lvl +Date: September 2014 +Contact: Subhash Jadavani +Description: This entry could be used to set or show the UFS device + runtime power management level. The current driver + implementation supports 6 levels with next target states: + 0 - an UFS device will stay active, an UIC link will + stay active + 1 - an UFS device will stay active, an UIC link will + hibernate + 2 - an UFS device will moved to sleep, an UIC link will + stay active + 3 - an UFS device will moved to sleep, an UIC link will + hibernate + 4 - an UFS device will be powered off, an UIC link will + hibernate + 5 - an UFS device will be powered off, an UIC link will + be powered off + +What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state +Date: February 2018 +Contact: Subhash Jadavani +Description: This entry shows the target power mode of an UFS device + for the chosen runtime power management level. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_link_state +Date: February 2018 +Contact: Subhash Jadavani +Description: This entry shows the target state of an UFS UIC link + for the chosen runtime power management level. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/spm_lvl +Date: September 2014 +Contact: Subhash Jadavani +Description: This entry could be used to set or show the UFS device + system power management level. The current driver + implementation supports 6 levels with next target states: + 0 - an UFS device will stay active, an UIC link will + stay active + 1 - an UFS device will stay active, an UIC link will + hibernate + 2 - an UFS device will moved to sleep, an UIC link will + stay active + 3 - an UFS device will moved to sleep, an UIC link will + hibernate + 4 - an UFS device will be powered off, an UIC link will + hibernate + 5 - an UFS device will be powered off, an UIC link will + be powered off + +What: /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state +Date: February 2018 +Contact: Subhash Jadavani +Description: This entry shows the target power mode of an UFS device + for the chosen system power management level. + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/spm_target_link_state +Date: February 2018 +Contact: Subhash Jadavani +Description: This entry shows the target state of an UFS UIC link + for the chosen system power management level. + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index cd7174d2d225..4ff9e0b7eba1 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -57,29 +57,8 @@ static ssize_t rpm_lvl_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); - int curr_len; - u8 lvl; - - curr_len = snprintf(buf, PAGE_SIZE, - "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n", - hba->rpm_lvl, - ufschd_ufs_dev_pwr_mode_to_string( - ufs_pm_lvl_states[hba->rpm_lvl].dev_state), - ufschd_uic_link_state_to_string( - ufs_pm_lvl_states[hba->rpm_lvl].link_state)); - - curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), - "\nAll available Runtime PM levels info:\n"); - for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++) - curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), - "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n", - lvl, - ufschd_ufs_dev_pwr_mode_to_string( - ufs_pm_lvl_states[lvl].dev_state), - ufschd_uic_link_state_to_string( - ufs_pm_lvl_states[lvl].link_state)); - - return curr_len; + + return sprintf(buf, "%d\n", hba->rpm_lvl); } static ssize_t rpm_lvl_store(struct device *dev, @@ -88,33 +67,30 @@ static ssize_t rpm_lvl_store(struct device *dev, return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, true); } +static ssize_t rpm_target_dev_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string( + ufs_pm_lvl_states[hba->rpm_lvl].dev_state)); +} + +static ssize_t rpm_target_link_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ufschd_uic_link_state_to_string( + ufs_pm_lvl_states[hba->rpm_lvl].link_state)); +} + static ssize_t spm_lvl_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); - int curr_len; - u8 lvl; - - curr_len = snprintf(buf, PAGE_SIZE, - "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n", - hba->spm_lvl, - ufschd_ufs_dev_pwr_mode_to_string( - ufs_pm_lvl_states[hba->spm_lvl].dev_state), - ufschd_uic_link_state_to_string( - ufs_pm_lvl_states[hba->spm_lvl].link_state)); - curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), - "\nAll available System PM levels info:\n"); - for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++) - curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), - "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n", - lvl, - ufschd_ufs_dev_pwr_mode_to_string( - ufs_pm_lvl_states[lvl].dev_state), - ufschd_uic_link_state_to_string( - ufs_pm_lvl_states[lvl].link_state)); - - return curr_len; + return sprintf(buf, "%d\n", hba->spm_lvl); } static ssize_t spm_lvl_store(struct device *dev, @@ -123,12 +99,38 @@ static ssize_t spm_lvl_store(struct device *dev, return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false); } +static ssize_t spm_target_dev_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string( + ufs_pm_lvl_states[hba->spm_lvl].dev_state)); +} + +static ssize_t spm_target_link_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ufschd_uic_link_state_to_string( + ufs_pm_lvl_states[hba->spm_lvl].link_state)); +} + static DEVICE_ATTR_RW(rpm_lvl); +static DEVICE_ATTR_RO(rpm_target_dev_state); +static DEVICE_ATTR_RO(rpm_target_link_state); static DEVICE_ATTR_RW(spm_lvl); +static DEVICE_ATTR_RO(spm_target_dev_state); +static DEVICE_ATTR_RO(spm_target_link_state); static struct attribute *ufs_sysfs_ufshcd_attrs[] = { &dev_attr_rpm_lvl.attr, + &dev_attr_rpm_target_dev_state.attr, + &dev_attr_rpm_target_link_state.attr, &dev_attr_spm_lvl.attr, + &dev_attr_spm_target_dev_state.attr, + &dev_attr_spm_target_link_state.attr, NULL }; -- cgit v1.2.3 From ad448378825f5746c5fa37718724bc8f4e7b6945 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 20 Mar 2018 15:07:38 +0200 Subject: scsi: ufs: Add support for Auto-Hibernate Idle Timer UFS host controllers may support an autonomous power management feature called the Auto-Hibernate Idle Timer. The timer is set to the number of microseconds of idle time before the UFS host controller will autonomously put the link into Hibernate state. That will save power at the expense of increased latency. Any access to the host controller interface registers will automatically put the link out of Hibernate state. So once configured, the feature is transparent to the driver. Expose the Auto-Hibernate Idle Timer value via SysFS to allow users to choose between power efficiency or lower latency. Set a default value of 150 ms. Signed-off-by: Adrian Hunter Acked-by: Stanislav Nijnikov Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 14 ++++++ drivers/scsi/ufs/ufs-sysfs.c | 76 ++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd.c | 26 ++++++++++ drivers/scsi/ufs/ufshcd.h | 3 ++ drivers/scsi/ufs/ufshci.h | 7 +++ 5 files changed, 126 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 83735f79e572..016724ec26d5 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -1,3 +1,17 @@ +What: /sys/bus/*/drivers/ufshcd/*/auto_hibern8 +Date: March 2018 +Contact: linux-scsi@vger.kernel.org +Description: + This file contains the auto-hibernate idle timer setting of a + UFS host controller. A value of '0' means auto-hibernate is not + enabled. Otherwise the value is the number of microseconds of + idle time before the UFS host controller will autonomously put + the link into hibernate state. That will save power at the + expense of increased latency. Note that the hardware supports + 10-bit values with a power-of-ten multiplier which allows a + maximum value of 102300000. Refer to the UFS Host Controller + Interface specification for more details. + What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type Date: February 2018 Contact: Stanislav Nijnikov diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 4ff9e0b7eba1..8d9332bb7d0c 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -3,6 +3,7 @@ #include #include +#include #include #include "ufs.h" @@ -117,12 +118,86 @@ static ssize_t spm_target_link_state_show(struct device *dev, ufs_pm_lvl_states[hba->spm_lvl].link_state)); } +static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) +{ + unsigned long flags; + + if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) + return; + + spin_lock_irqsave(hba->host->host_lock, flags); + if (hba->ahit == ahit) + goto out_unlock; + hba->ahit = ahit; + if (!pm_runtime_suspended(hba->dev)) + ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); +out_unlock: + spin_unlock_irqrestore(hba->host->host_lock, flags); +} + +/* Convert Auto-Hibernate Idle Timer register value to microseconds */ +static int ufshcd_ahit_to_us(u32 ahit) +{ + int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit); + int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit); + + for (; scale > 0; --scale) + timer *= UFSHCI_AHIBERN8_SCALE_FACTOR; + + return timer; +} + +/* Convert microseconds to Auto-Hibernate Idle Timer register value */ +static u32 ufshcd_us_to_ahit(unsigned int timer) +{ + unsigned int scale; + + for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale) + timer /= UFSHCI_AHIBERN8_SCALE_FACTOR; + + return FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, timer) | + FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, scale); +} + +static ssize_t auto_hibern8_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) + return -EOPNOTSUPP; + + return snprintf(buf, PAGE_SIZE, "%d\n", ufshcd_ahit_to_us(hba->ahit)); +} + +static ssize_t auto_hibern8_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + unsigned int timer; + + if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &timer)) + return -EINVAL; + + if (timer > UFSHCI_AHIBERN8_MAX) + return -EINVAL; + + ufshcd_auto_hibern8_update(hba, ufshcd_us_to_ahit(timer)); + + return count; +} + static DEVICE_ATTR_RW(rpm_lvl); static DEVICE_ATTR_RO(rpm_target_dev_state); static DEVICE_ATTR_RO(rpm_target_link_state); static DEVICE_ATTR_RW(spm_lvl); static DEVICE_ATTR_RO(spm_target_dev_state); static DEVICE_ATTR_RO(spm_target_link_state); +static DEVICE_ATTR_RW(auto_hibern8); static struct attribute *ufs_sysfs_ufshcd_attrs[] = { &dev_attr_rpm_lvl.attr, @@ -131,6 +206,7 @@ static struct attribute *ufs_sysfs_ufshcd_attrs[] = { &dev_attr_spm_lvl.attr, &dev_attr_spm_target_dev_state.attr, &dev_attr_spm_target_link_state.attr, + &dev_attr_auto_hibern8.attr, NULL }; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3abcd31646eb..facee2b97926 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "ufshcd.h" #include "ufs_quirks.h" #include "unipro.h" @@ -3708,6 +3709,18 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) return ret; } +static void ufshcd_auto_hibern8_enable(struct ufs_hba *hba) +{ + unsigned long flags; + + if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) || !hba->ahit) + return; + + spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); + spin_unlock_irqrestore(hba->host->host_lock, flags); +} + /** * ufshcd_init_pwr_info - setting the POR (power on reset) * values in hba power info @@ -6307,6 +6320,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) /* UniPro link is active now */ ufshcd_set_link_active(hba); + /* Enable Auto-Hibernate if configured */ + ufshcd_auto_hibern8_enable(hba); + ret = ufshcd_verify_dev_init(hba); if (ret) goto out; @@ -7391,6 +7407,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) /* Schedule clock gating in case of no access to UFS device yet */ ufshcd_release(hba); + + /* Enable Auto-Hibernate if configured */ + ufshcd_auto_hibern8_enable(hba); + goto out; set_old_link_state: @@ -7834,6 +7854,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) UFS_SLEEP_PWR_MODE, UIC_LINK_HIBERN8_STATE); + /* Set the default auto-hiberate idle timer value to 150 ms */ + if (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) { + hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 150) | + FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3); + } + /* Hold auto suspend until async scan completes */ pm_runtime_get_sync(dev); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index deb3c5d382e9..8110dcd04d22 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -531,6 +531,9 @@ struct ufs_hba { struct device_attribute spm_lvl_attr; int pm_op_in_progress; + /* Auto-Hibernate Idle Timer register value */ + u32 ahit; + struct ufshcd_lrb *lrb; unsigned long lrb_in_use; diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 1a1b5d9fe514..bb5d9c7f3353 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -86,6 +86,7 @@ enum { enum { MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F, MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000, + MASK_AUTO_HIBERN8_SUPPORT = 0x00800000, MASK_64_ADDRESSING_SUPPORT = 0x01000000, MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, @@ -119,6 +120,12 @@ enum { #define MANUFACTURE_ID_MASK UFS_MASK(0xFFFF, 0) #define PRODUCT_ID_MASK UFS_MASK(0xFFFF, 16) +/* AHIT - Auto-Hibernate Idle Timer */ +#define UFSHCI_AHIBERN8_TIMER_MASK GENMASK(9, 0) +#define UFSHCI_AHIBERN8_SCALE_MASK GENMASK(12, 10) +#define UFSHCI_AHIBERN8_SCALE_FACTOR 10 +#define UFSHCI_AHIBERN8_MAX (1023 * 100000) + /* * IS - Interrupt Status - 20h */ -- cgit v1.2.3