SCSI queue for 4.4.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIVAwUAVkP2pu7pYBp1xd49AQL+dg/6Atk5KH17IKE+SGIAaIqS9rhckwqOB6qK 7pT5gbvuyA8nB4eXUFPFk6VejYa6PdHL5wVf7a2w9pPJAoIogTkiYb9PvlRLbzBB OrBFfm8h00psQd8YpzEAIdPvVQGsR/OTqYVMXnrNN0pra81iFWwaiB5QcJukadYl +0d/2wJnw4887ZReO/51n9fJkPwIvs+jtCj7k36yX9NL9SRm8s/JlH3aVGRSzIBy ip7ahtdcw7ncqXCWJVzQ1HCdEiwcWkbMNI8gTFpJ4V5GR6A1ZkN+jNn88C/f5qQF 1uAsIBy9B99mU5Rz7Vrbl8710DjT2SkVgQ43rC54MzszTuj34y4GNS+sCZyTfzFG vnEVWyX7Jzg1SLbp8KxjhhCrhegG8vXnyr6RJDfEzHsUHLxbnMKNGclDOny5NG4n TmXGFTfDKBVcHwFLOwwKXsjKicyirBDIRb2eKnqC0j56kFNQp9pWhFA62Xi/AOe6 vqMj2I2t30za5X3iZv5XEvhv63fFMx2nflcYIA+rCqq1AMaC7T0X170czKb5g1v+ aSZZ0qCFhMFUWETlHjOQSbHkZ6fsWJlgaPZS0ODsiGrbxXPtrHXH1lbLAh6ECveu O8dYKqC2kJbBoolqD2e59z1fQ6cW45sUHxiDjaeqgTlexwVEy25+t8uIBPUnRNwI 1YTHKn3U+ug= =g6ZL -----END PGP SIGNATURE----- Merge tag '4.4-scsi-mkp' into misc SCSI queue for 4.4. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Коммит
febdfbd213
|
@ -0,0 +1,58 @@
|
|||
* Qualcomm Technologies Inc Universal Flash Storage (UFS) PHY
|
||||
|
||||
UFSPHY nodes are defined to describe on-chip UFS PHY hardware macro.
|
||||
Each UFS PHY node should have its own node.
|
||||
|
||||
To bind UFS PHY with UFS host controller, the controller node should
|
||||
contain a phandle reference to UFS PHY node.
|
||||
|
||||
Required properties:
|
||||
- compatible : compatible list, contains "qcom,ufs-phy-qmp-20nm"
|
||||
or "qcom,ufs-phy-qmp-14nm" according to the relevant phy in use.
|
||||
- reg : should contain PHY register address space (mandatory),
|
||||
- reg-names : indicates various resources passed to driver (via reg proptery) by name.
|
||||
Required "reg-names" is "phy_mem".
|
||||
- #phy-cells : This property shall be set to 0
|
||||
- vdda-phy-supply : phandle to main PHY supply for analog domain
|
||||
- vdda-pll-supply : phandle to PHY PLL and Power-Gen block power supply
|
||||
- clocks : List of phandle and clock specifier pairs
|
||||
- clock-names : List of clock input name strings sorted in the same
|
||||
order as the clocks property. "ref_clk_src", "ref_clk",
|
||||
"tx_iface_clk" & "rx_iface_clk" are mandatory but
|
||||
"ref_clk_parent" is optional
|
||||
|
||||
Optional properties:
|
||||
- vdda-phy-max-microamp : specifies max. load that can be drawn from phy supply
|
||||
- vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply
|
||||
- vddp-ref-clk-supply : phandle to UFS device ref_clk pad power supply
|
||||
- vddp-ref-clk-max-microamp : specifies max. load that can be drawn from this supply
|
||||
- vddp-ref-clk-always-on : specifies if this supply needs to be kept always on
|
||||
|
||||
Example:
|
||||
|
||||
ufsphy1: ufsphy@0xfc597000 {
|
||||
compatible = "qcom,ufs-phy-qmp-20nm";
|
||||
reg = <0xfc597000 0x800>;
|
||||
reg-names = "phy_mem";
|
||||
#phy-cells = <0>;
|
||||
vdda-phy-supply = <&pma8084_l4>;
|
||||
vdda-pll-supply = <&pma8084_l12>;
|
||||
vdda-phy-max-microamp = <50000>;
|
||||
vdda-pll-max-microamp = <1000>;
|
||||
clock-names = "ref_clk_src",
|
||||
"ref_clk_parent",
|
||||
"ref_clk",
|
||||
"tx_iface_clk",
|
||||
"rx_iface_clk";
|
||||
clocks = <&clock_rpm clk_ln_bb_clk>,
|
||||
<&clock_gcc clk_pcie_1_phy_ldo >,
|
||||
<&clock_gcc clk_ufs_phy_ldo>,
|
||||
<&clock_gcc clk_gcc_ufs_tx_cfg_clk>,
|
||||
<&clock_gcc clk_gcc_ufs_rx_cfg_clk>;
|
||||
};
|
||||
|
||||
ufshc@0xfc598000 {
|
||||
...
|
||||
phys = <&ufsphy1>;
|
||||
phy-names = "ufsphy";
|
||||
};
|
|
@ -4,11 +4,18 @@ UFSHC nodes are defined to describe on-chip UFS host controllers.
|
|||
Each UFS controller instance should have its own node.
|
||||
|
||||
Required properties:
|
||||
- compatible : compatible list, contains "jedec,ufs-1.1"
|
||||
- compatible : must contain "jedec,ufs-1.1", may also list one or more
|
||||
of the following:
|
||||
"qcom,msm8994-ufshc"
|
||||
"qcom,msm8996-ufshc"
|
||||
"qcom,ufshc"
|
||||
- interrupts : <interrupt mapping for UFS host controller IRQ>
|
||||
- reg : <registers mapping>
|
||||
|
||||
Optional properties:
|
||||
- phys : phandle to UFS PHY node
|
||||
- phy-names : the string "ufsphy" when is found in a node, along
|
||||
with "phys" attribute, provides phandle to UFS PHY node
|
||||
- vdd-hba-supply : phandle to UFS host controller supply regulator node
|
||||
- vcc-supply : phandle to VCC supply regulator node
|
||||
- vccq-supply : phandle to VCCQ supply regulator node
|
||||
|
@ -54,4 +61,6 @@ Example:
|
|||
clocks = <&core 0>, <&ref 0>, <&iface 0>;
|
||||
clock-names = "core_clk", "ref_clk", "iface_clk";
|
||||
freq-table-hz = <100000000 200000000>, <0 0>, <0 0>;
|
||||
phys = <&ufsphy1>;
|
||||
phy-names = "ufsphy";
|
||||
};
|
||||
|
|
|
@ -1038,6 +1038,10 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
|
|||
int i, buflist_ent;
|
||||
int sg_spill = MAX_FRAGS_SPILL1;
|
||||
int dir;
|
||||
|
||||
if (bytes < 0)
|
||||
return NULL;
|
||||
|
||||
/* initialization */
|
||||
*frags = 0;
|
||||
*blp = NULL;
|
||||
|
|
|
@ -432,6 +432,7 @@ out_disable_src:
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_ref_clk);
|
||||
|
||||
static
|
||||
int ufs_qcom_phy_disable_vreg(struct phy *phy,
|
||||
|
@ -474,6 +475,7 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
|
|||
phy->is_ref_clk_enabled = false;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_ref_clk);
|
||||
|
||||
#define UFS_REF_CLK_EN (1 << 5)
|
||||
|
||||
|
@ -517,11 +519,13 @@ void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy)
|
|||
{
|
||||
ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_dev_ref_clk);
|
||||
|
||||
void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
|
||||
{
|
||||
ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_dev_ref_clk);
|
||||
|
||||
/* Turn ON M-PHY RMMI interface clocks */
|
||||
int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
|
||||
|
@ -550,6 +554,7 @@ int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_iface_clk);
|
||||
|
||||
/* Turn OFF M-PHY RMMI interface clocks */
|
||||
void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
|
||||
|
@ -562,6 +567,7 @@ void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
|
|||
phy->is_iface_clk_enabled = false;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_iface_clk);
|
||||
|
||||
int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
|
||||
{
|
||||
|
@ -578,6 +584,7 @@ int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_start_serdes);
|
||||
|
||||
int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
|
||||
{
|
||||
|
@ -595,6 +602,7 @@ int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_set_tx_lane_enable);
|
||||
|
||||
void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
|
||||
u8 major, u16 minor, u16 step)
|
||||
|
@ -605,6 +613,7 @@ void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
|
|||
ufs_qcom_phy->host_ctrl_rev_minor = minor;
|
||||
ufs_qcom_phy->host_ctrl_rev_step = step;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_save_controller_version);
|
||||
|
||||
int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
|
||||
{
|
||||
|
@ -625,6 +634,7 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
|
||||
|
||||
int ufs_qcom_phy_remove(struct phy *generic_phy,
|
||||
struct ufs_qcom_phy *ufs_qcom_phy)
|
||||
|
@ -662,6 +672,7 @@ int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy)
|
|||
return ufs_qcom_phy->phy_spec_ops->
|
||||
is_physical_coding_sublayer_ready(ufs_qcom_phy);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufs_qcom_phy_is_pcs_ready);
|
||||
|
||||
int ufs_qcom_phy_power_on(struct phy *generic_phy)
|
||||
{
|
||||
|
|
|
@ -541,7 +541,6 @@ config SCSI_ARCMSR
|
|||
|
||||
source "drivers/scsi/esas2r/Kconfig"
|
||||
source "drivers/scsi/megaraid/Kconfig.megaraid"
|
||||
source "drivers/scsi/mpt2sas/Kconfig"
|
||||
source "drivers/scsi/mpt3sas/Kconfig"
|
||||
source "drivers/scsi/ufs/Kconfig"
|
||||
|
||||
|
|
|
@ -106,7 +106,6 @@ obj-$(CONFIG_CXLFLASH) += cxlflash/
|
|||
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
|
||||
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
|
||||
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
|
||||
obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/
|
||||
obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/
|
||||
obj-$(CONFIG_SCSI_UFSHCD) += ufs/
|
||||
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
|
||||
|
|
|
@ -703,10 +703,10 @@ static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha)
|
|||
{
|
||||
int err;
|
||||
|
||||
scsi_remove_host(asd_ha->sas_ha.core.shost);
|
||||
err = sas_unregister_ha(&asd_ha->sas_ha);
|
||||
|
||||
sas_remove_host(asd_ha->sas_ha.core.shost);
|
||||
scsi_remove_host(asd_ha->sas_ha.core.shost);
|
||||
scsi_host_put(asd_ha->sas_ha.core.shost);
|
||||
|
||||
kfree(asd_ha->sas_ha.sas_phy);
|
||||
|
|
|
@ -3186,7 +3186,7 @@ be_sgl_create_contiguous(void *virtual_address,
|
|||
{
|
||||
WARN_ON(!virtual_address);
|
||||
WARN_ON(!physical_address);
|
||||
WARN_ON(!length > 0);
|
||||
WARN_ON(!length);
|
||||
WARN_ON(!sgl);
|
||||
|
||||
sgl->va = virtual_address;
|
||||
|
|
1336
drivers/scsi/hpsa.c
1336
drivers/scsi/hpsa.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -33,12 +33,38 @@ struct access_method {
|
|||
unsigned long (*command_completed)(struct ctlr_info *h, u8 q);
|
||||
};
|
||||
|
||||
/* for SAS hosts and SAS expanders */
|
||||
struct hpsa_sas_node {
|
||||
struct device *parent_dev;
|
||||
struct list_head port_list_head;
|
||||
};
|
||||
|
||||
struct hpsa_sas_port {
|
||||
struct list_head port_list_entry;
|
||||
u64 sas_address;
|
||||
struct sas_port *port;
|
||||
int next_phy_index;
|
||||
struct list_head phy_list_head;
|
||||
struct hpsa_sas_node *parent_node;
|
||||
struct sas_rphy *rphy;
|
||||
};
|
||||
|
||||
struct hpsa_sas_phy {
|
||||
struct list_head phy_list_entry;
|
||||
struct sas_phy *phy;
|
||||
struct hpsa_sas_port *parent_port;
|
||||
bool added_to_port;
|
||||
};
|
||||
|
||||
struct hpsa_scsi_dev_t {
|
||||
int devtype;
|
||||
unsigned int devtype;
|
||||
int bus, target, lun; /* as presented to the OS */
|
||||
unsigned char scsi3addr[8]; /* as presented to the HW */
|
||||
u8 physical_device : 1;
|
||||
u8 expose_device;
|
||||
#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
|
||||
unsigned char device_id[16]; /* from inquiry pg. 0x83 */
|
||||
u64 sas_address;
|
||||
unsigned char vendor[8]; /* bytes 8-15 of inquiry data */
|
||||
unsigned char model[16]; /* bytes 16-31 of inquiry data */
|
||||
unsigned char raid_level; /* from inquiry page 0xC1 */
|
||||
|
@ -75,11 +101,8 @@ struct hpsa_scsi_dev_t {
|
|||
struct hpsa_scsi_dev_t *phys_disk[RAID_MAP_MAX_ENTRIES];
|
||||
int nphysical_disks;
|
||||
int supports_aborts;
|
||||
#define HPSA_DO_NOT_EXPOSE 0x0
|
||||
#define HPSA_SG_ATTACH 0x1
|
||||
#define HPSA_ULD_ATTACH 0x2
|
||||
#define HPSA_SCSI_ADD (HPSA_SG_ATTACH | HPSA_ULD_ATTACH)
|
||||
u8 expose_state;
|
||||
struct hpsa_sas_port *sas_port;
|
||||
int external; /* 1-from external array 0-not <0-unknown */
|
||||
};
|
||||
|
||||
struct reply_queue_buffer {
|
||||
|
@ -136,6 +159,7 @@ struct ctlr_info {
|
|||
char *product_name;
|
||||
struct pci_dev *pdev;
|
||||
u32 board_id;
|
||||
u64 sas_address;
|
||||
void __iomem *vaddr;
|
||||
unsigned long paddr;
|
||||
int nr_cmds; /* Number of commands allowed on this controller */
|
||||
|
@ -262,7 +286,10 @@ struct ctlr_info {
|
|||
spinlock_t offline_device_lock;
|
||||
struct list_head offline_device_list;
|
||||
int acciopath_status;
|
||||
int drv_req_rescan;
|
||||
int raid_offload_debug;
|
||||
int discovery_polling;
|
||||
struct ReportLUNdata *lastlogicals;
|
||||
int needs_abort_tags_swizzled;
|
||||
struct workqueue_struct *resubmit_wq;
|
||||
struct workqueue_struct *rescan_ctlr_wq;
|
||||
|
@ -270,6 +297,8 @@ struct ctlr_info {
|
|||
wait_queue_head_t abort_cmd_wait_queue;
|
||||
wait_queue_head_t event_sync_wait_queue;
|
||||
struct mutex reset_mutex;
|
||||
u8 reset_in_progress;
|
||||
struct hpsa_sas_node *sas_host;
|
||||
};
|
||||
|
||||
struct offline_device_entry {
|
||||
|
@ -283,6 +312,7 @@ struct offline_device_entry {
|
|||
#define HPSA_RESET_TYPE_BUS 0x01
|
||||
#define HPSA_RESET_TYPE_TARGET 0x03
|
||||
#define HPSA_RESET_TYPE_LUN 0x04
|
||||
#define HPSA_PHYS_TARGET_RESET 0x99 /* not defined by cciss spec */
|
||||
#define HPSA_MSG_SEND_RETRY_LIMIT 10
|
||||
#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
|
||||
|
||||
|
@ -367,6 +397,11 @@ struct offline_device_entry {
|
|||
#define IOACCEL2_INBOUND_POSTQ_64_LOW 0xd0
|
||||
#define IOACCEL2_INBOUND_POSTQ_64_HI 0xd4
|
||||
|
||||
#define HPSA_PHYSICAL_DEVICE_BUS 0
|
||||
#define HPSA_RAID_VOLUME_BUS 1
|
||||
#define HPSA_EXTERNAL_RAID_VOLUME_BUS 2
|
||||
#define HPSA_HBA_BUS 3
|
||||
|
||||
/*
|
||||
Send the command to the hardware
|
||||
*/
|
||||
|
|
|
@ -260,8 +260,6 @@ struct ext_report_lun_entry {
|
|||
u8 wwid[8];
|
||||
u8 device_type;
|
||||
u8 device_flags;
|
||||
#define NON_DISK_PHYS_DEV(x) ((x)[17] & 0x01)
|
||||
#define PHYS_IOACCEL(x) ((x)[17] & 0x08)
|
||||
u8 lun_count; /* multi-lun device, how many luns */
|
||||
u8 redundant_paths;
|
||||
u32 ioaccel_handle; /* ioaccel1 only uses lower 16 bits */
|
||||
|
@ -288,6 +286,11 @@ struct SenseSubsystem_info {
|
|||
#define BMIC_FLASH_FIRMWARE 0xF7
|
||||
#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
|
||||
#define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15
|
||||
#define BMIC_IDENTIFY_CONTROLLER 0x11
|
||||
#define BMIC_SET_DIAG_OPTIONS 0xF4
|
||||
#define BMIC_SENSE_DIAG_OPTIONS 0xF5
|
||||
#define HPSA_DIAG_OPTS_DISABLE_RLD_CACHING 0x40000000
|
||||
#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
|
||||
|
||||
/* Command List Structure */
|
||||
union SCSI3Addr {
|
||||
|
@ -684,6 +687,16 @@ struct hpsa_pci_info {
|
|||
u32 board_id;
|
||||
};
|
||||
|
||||
struct bmic_identify_controller {
|
||||
u8 configured_logical_drive_count; /* offset 0 */
|
||||
u8 pad1[153];
|
||||
__le16 extended_logical_unit_count; /* offset 154 */
|
||||
u8 pad2[136];
|
||||
u8 controller_mode; /* offset 292 */
|
||||
u8 pad3[32];
|
||||
};
|
||||
|
||||
|
||||
struct bmic_identify_physical_device {
|
||||
u8 scsi_bus; /* SCSI Bus number on controller */
|
||||
u8 scsi_id; /* SCSI ID on this bus */
|
||||
|
@ -816,5 +829,18 @@ struct bmic_identify_physical_device {
|
|||
u8 padding[112];
|
||||
};
|
||||
|
||||
struct bmic_sense_subsystem_info {
|
||||
u8 primary_slot_number;
|
||||
u8 reserved[3];
|
||||
u8 chasis_serial_number[32];
|
||||
u8 primary_world_wide_id[8];
|
||||
u8 primary_array_serial_number[32]; /* NULL terminated */
|
||||
u8 primary_cache_serial_number[32]; /* NULL terminated */
|
||||
u8 reserved_2[8];
|
||||
u8 secondary_array_serial_number[32];
|
||||
u8 secondary_cache_serial_number[32];
|
||||
u8 pad[332];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
#endif /* HPSA_CMD_H */
|
||||
|
|
|
@ -106,9 +106,9 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_VERSION(IBMVSCSI_VERSION);
|
||||
|
||||
module_param_named(max_id, max_id, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(max_id, "Largest ID value for each channel");
|
||||
MODULE_PARM_DESC(max_id, "Largest ID value for each channel [Default=64]");
|
||||
module_param_named(max_channel, max_channel, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(max_channel, "Largest channel value");
|
||||
MODULE_PARM_DESC(max_channel, "Largest channel value [Default=3]");
|
||||
module_param_named(init_timeout, init_timeout, int, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(init_timeout, "Initialization timeout in seconds");
|
||||
module_param_named(max_requests, max_requests, int, S_IRUGO);
|
||||
|
@ -2289,11 +2289,15 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
|||
goto init_pool_failed;
|
||||
}
|
||||
|
||||
host->max_lun = 8;
|
||||
host->max_lun = IBMVSCSI_MAX_LUN;
|
||||
host->max_id = max_id;
|
||||
host->max_channel = max_channel;
|
||||
host->max_cmd_len = 16;
|
||||
|
||||
dev_info(dev,
|
||||
"Maximum ID: %d Maximum LUN: %llu Maximum Channel: %d\n",
|
||||
host->max_id, host->max_lun, host->max_channel);
|
||||
|
||||
if (scsi_add_host(hostdata->host, hostdata->dev))
|
||||
goto add_host_failed;
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ struct Scsi_Host;
|
|||
#define IBMVSCSI_CMDS_PER_LUN_DEFAULT 16
|
||||
#define IBMVSCSI_MAX_SECTORS_DEFAULT 256 /* 32 * 8 = default max I/O 32 pages */
|
||||
#define IBMVSCSI_MAX_CMDS_PER_LUN 64
|
||||
#define IBMVSCSI_MAX_LUN 32
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Data Structures
|
||||
|
|
|
@ -6363,15 +6363,19 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
|
|||
ipr_cmd->scsi_cmd = scsi_cmd;
|
||||
ipr_cmd->done = ipr_scsi_eh_done;
|
||||
|
||||
if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
|
||||
if (ipr_is_gscsi(res)) {
|
||||
if (scsi_cmd->underflow == 0)
|
||||
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
|
||||
|
||||
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
|
||||
if (ipr_is_gscsi(res) && res->reset_occurred) {
|
||||
if (res->reset_occurred) {
|
||||
res->reset_occurred = 0;
|
||||
ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST;
|
||||
}
|
||||
}
|
||||
|
||||
if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
|
||||
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
|
||||
|
||||
ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_ALIGNED_BFR;
|
||||
if (scsi_cmd->flags & SCMD_TAGGED)
|
||||
ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_SIMPLE_TASK;
|
||||
|
@ -7670,6 +7674,63 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
|
|||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
|
||||
static int ipr_ioa_service_action_failed(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
|
||||
|
||||
if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT)
|
||||
return IPR_RC_JOB_CONTINUE;
|
||||
|
||||
return ipr_reset_cmd_failed(ipr_cmd);
|
||||
}
|
||||
|
||||
static void ipr_build_ioa_service_action(struct ipr_cmnd *ipr_cmd,
|
||||
__be32 res_handle, u8 sa_code)
|
||||
{
|
||||
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
|
||||
|
||||
ioarcb->res_handle = res_handle;
|
||||
ioarcb->cmd_pkt.cdb[0] = IPR_IOA_SERVICE_ACTION;
|
||||
ioarcb->cmd_pkt.cdb[1] = sa_code;
|
||||
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_ioafp_set_caching_parameters - Issue Set Cache parameters service
|
||||
* action
|
||||
*
|
||||
* Return value:
|
||||
* none
|
||||
**/
|
||||
static int ipr_ioafp_set_caching_parameters(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
|
||||
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
|
||||
struct ipr_inquiry_pageC4 *pageC4 = &ioa_cfg->vpd_cbs->pageC4_data;
|
||||
|
||||
ENTER;
|
||||
|
||||
ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
|
||||
|
||||
if (pageC4->cache_cap[0] & IPR_CAP_SYNC_CACHE) {
|
||||
ipr_build_ioa_service_action(ipr_cmd,
|
||||
cpu_to_be32(IPR_IOA_RES_HANDLE),
|
||||
IPR_IOA_SA_CHANGE_CACHE_PARAMS);
|
||||
|
||||
ioarcb->cmd_pkt.cdb[2] = 0x40;
|
||||
|
||||
ipr_cmd->job_step_failed = ipr_ioa_service_action_failed;
|
||||
ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
|
||||
IPR_SET_SUP_DEVICE_TIMEOUT);
|
||||
|
||||
LEAVE;
|
||||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
|
||||
LEAVE;
|
||||
return IPR_RC_JOB_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_ioafp_inquiry - Send an Inquiry to the adapter.
|
||||
* @ipr_cmd: ipr command struct
|
||||
|
@ -7720,6 +7781,39 @@ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_ioafp_pageC4_inquiry - Send a Page 0xC4 Inquiry to the adapter.
|
||||
* @ipr_cmd: ipr command struct
|
||||
*
|
||||
* This function sends a Page 0xC4 inquiry to the adapter
|
||||
* to retrieve software VPD information.
|
||||
*
|
||||
* Return value:
|
||||
* IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
|
||||
**/
|
||||
static int ipr_ioafp_pageC4_inquiry(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
|
||||
struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
|
||||
struct ipr_inquiry_pageC4 *pageC4 = &ioa_cfg->vpd_cbs->pageC4_data;
|
||||
|
||||
ENTER;
|
||||
ipr_cmd->job_step = ipr_ioafp_set_caching_parameters;
|
||||
memset(pageC4, 0, sizeof(*pageC4));
|
||||
|
||||
if (ipr_inquiry_page_supported(page0, 0xC4)) {
|
||||
ipr_ioafp_inquiry(ipr_cmd, 1, 0xC4,
|
||||
(ioa_cfg->vpd_cbs_dma
|
||||
+ offsetof(struct ipr_misc_cbs,
|
||||
pageC4_data)),
|
||||
sizeof(struct ipr_inquiry_pageC4));
|
||||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
|
||||
LEAVE;
|
||||
return IPR_RC_JOB_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter.
|
||||
* @ipr_cmd: ipr command struct
|
||||
|
@ -7737,7 +7831,7 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd)
|
|||
struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
|
||||
|
||||
ENTER;
|
||||
ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg;
|
||||
ipr_cmd->job_step = ipr_ioafp_pageC4_inquiry;
|
||||
memset(cap, 0, sizeof(*cap));
|
||||
|
||||
if (ipr_inquiry_page_supported(page0, 0xD0)) {
|
||||
|
@ -8276,6 +8370,42 @@ static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd)
|
|||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
|
||||
static int ipr_dump_mailbox_wait(struct ipr_cmnd *ipr_cmd)
|
||||
{
|
||||
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
|
||||
|
||||
ENTER;
|
||||
|
||||
if (ioa_cfg->sdt_state != GET_DUMP)
|
||||
return IPR_RC_JOB_RETURN;
|
||||
|
||||
if (!ioa_cfg->sis64 || !ipr_cmd->u.time_left ||
|
||||
(readl(ioa_cfg->regs.sense_interrupt_reg) &
|
||||
IPR_PCII_MAILBOX_STABLE)) {
|
||||
|
||||
if (!ipr_cmd->u.time_left)
|
||||
dev_err(&ioa_cfg->pdev->dev,
|
||||
"Timed out waiting for Mailbox register.\n");
|
||||
|
||||
ioa_cfg->sdt_state = READ_DUMP;
|
||||
ioa_cfg->dump_timeout = 0;
|
||||
if (ioa_cfg->sis64)
|
||||
ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
|
||||
else
|
||||
ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
|
||||
ipr_cmd->job_step = ipr_reset_wait_for_dump;
|
||||
schedule_work(&ioa_cfg->work_q);
|
||||
|
||||
} else {
|
||||
ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT;
|
||||
ipr_reset_start_timer(ipr_cmd,
|
||||
IPR_CHECK_FOR_RESET_TIMEOUT);
|
||||
}
|
||||
|
||||
LEAVE;
|
||||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_reset_restore_cfg_space - Restore PCI config space.
|
||||
* @ipr_cmd: ipr command struct
|
||||
|
@ -8325,20 +8455,11 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
|
|||
|
||||
if (ioa_cfg->in_ioa_bringdown) {
|
||||
ipr_cmd->job_step = ipr_ioa_bringdown_done;
|
||||
} else if (ioa_cfg->sdt_state == GET_DUMP) {
|
||||
ipr_cmd->job_step = ipr_dump_mailbox_wait;
|
||||
ipr_cmd->u.time_left = IPR_WAIT_FOR_MAILBOX;
|
||||
} else {
|
||||
ipr_cmd->job_step = ipr_reset_enable_ioa;
|
||||
|
||||
if (GET_DUMP == ioa_cfg->sdt_state) {
|
||||
ioa_cfg->sdt_state = READ_DUMP;
|
||||
ioa_cfg->dump_timeout = 0;
|
||||
if (ioa_cfg->sis64)
|
||||
ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
|
||||
else
|
||||
ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
|
||||
ipr_cmd->job_step = ipr_reset_wait_for_dump;
|
||||
schedule_work(&ioa_cfg->work_q);
|
||||
return IPR_RC_JOB_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
LEAVE;
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
/*
|
||||
* Literals
|
||||
*/
|
||||
#define IPR_DRIVER_VERSION "2.6.2"
|
||||
#define IPR_DRIVER_DATE "(June 11, 2015)"
|
||||
#define IPR_DRIVER_VERSION "2.6.3"
|
||||
#define IPR_DRIVER_DATE "(October 17, 2015)"
|
||||
|
||||
/*
|
||||
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
|
||||
|
@ -216,6 +216,10 @@
|
|||
#define IPR_SET_ALL_SUPPORTED_DEVICES 0x80
|
||||
#define IPR_IOA_SHUTDOWN 0xF7
|
||||
#define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05
|
||||
#define IPR_IOA_SERVICE_ACTION 0xD2
|
||||
|
||||
/* IOA Service Actions */
|
||||
#define IPR_IOA_SA_CHANGE_CACHE_PARAMS 0x14
|
||||
|
||||
/*
|
||||
* Timeouts
|
||||
|
@ -279,6 +283,9 @@
|
|||
#define IPR_IPL_INIT_STAGE_TIME_MASK 0x0000ffff
|
||||
#define IPR_PCII_IPL_STAGE_CHANGE (0x80000000 >> 0)
|
||||
|
||||
#define IPR_PCII_MAILBOX_STABLE (0x80000000 >> 4)
|
||||
#define IPR_WAIT_FOR_MAILBOX (2 * HZ)
|
||||
|
||||
#define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0)
|
||||
#define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3)
|
||||
#define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4)
|
||||
|
@ -846,6 +853,16 @@ struct ipr_inquiry_page0 {
|
|||
u8 page[IPR_INQUIRY_PAGE0_ENTRIES];
|
||||
}__attribute__((packed));
|
||||
|
||||
struct ipr_inquiry_pageC4 {
|
||||
u8 peri_qual_dev_type;
|
||||
u8 page_code;
|
||||
u8 reserved1;
|
||||
u8 len;
|
||||
u8 cache_cap[4];
|
||||
#define IPR_CAP_SYNC_CACHE 0x08
|
||||
u8 reserved2[20];
|
||||
} __packed;
|
||||
|
||||
struct ipr_hostrcb_device_data_entry {
|
||||
struct ipr_vpd vpd;
|
||||
struct ipr_res_addr dev_res_addr;
|
||||
|
@ -1319,6 +1336,7 @@ struct ipr_misc_cbs {
|
|||
struct ipr_inquiry_page0 page0_data;
|
||||
struct ipr_inquiry_page3 page3_data;
|
||||
struct ipr_inquiry_cap cap;
|
||||
struct ipr_inquiry_pageC4 pageC4_data;
|
||||
struct ipr_mode_pages mode_pages;
|
||||
struct ipr_supported_device supp_dev;
|
||||
};
|
||||
|
|
|
@ -271,11 +271,11 @@ static void isci_unregister(struct isci_host *isci_host)
|
|||
if (!isci_host)
|
||||
return;
|
||||
|
||||
shost = to_shost(isci_host);
|
||||
scsi_remove_host(shost);
|
||||
sas_unregister_ha(&isci_host->sas_ha);
|
||||
|
||||
shost = to_shost(isci_host);
|
||||
sas_remove_host(shost);
|
||||
scsi_remove_host(shost);
|
||||
scsi_host_put(shost);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
/*
|
||||
* MegaRAID SAS Driver meta data
|
||||
*/
|
||||
#define MEGASAS_VERSION "06.807.10.00-rc1"
|
||||
#define MEGASAS_RELDATE "March 6, 2015"
|
||||
#define MEGASAS_VERSION "06.808.16.00-rc1"
|
||||
#define MEGASAS_RELDATE "Oct. 8, 2015"
|
||||
|
||||
/*
|
||||
* Device IDs
|
||||
|
@ -52,6 +52,10 @@
|
|||
#define PCI_DEVICE_ID_LSI_PLASMA 0x002f
|
||||
#define PCI_DEVICE_ID_LSI_INVADER 0x005d
|
||||
#define PCI_DEVICE_ID_LSI_FURY 0x005f
|
||||
#define PCI_DEVICE_ID_LSI_INTRUDER 0x00ce
|
||||
#define PCI_DEVICE_ID_LSI_INTRUDER_24 0x00cf
|
||||
#define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052
|
||||
#define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053
|
||||
|
||||
/*
|
||||
* Intel HBA SSDIDs
|
||||
|
@ -62,6 +66,14 @@
|
|||
#define MEGARAID_INTEL_RS3MC044_SSDID 0x9381
|
||||
#define MEGARAID_INTEL_RS3WC080_SSDID 0x9341
|
||||
#define MEGARAID_INTEL_RS3WC040_SSDID 0x9343
|
||||
#define MEGARAID_INTEL_RMS3BC160_SSDID 0x352B
|
||||
|
||||
/*
|
||||
* Intruder HBA SSDIDs
|
||||
*/
|
||||
#define MEGARAID_INTRUDER_SSDID1 0x9371
|
||||
#define MEGARAID_INTRUDER_SSDID2 0x9390
|
||||
#define MEGARAID_INTRUDER_SSDID3 0x9370
|
||||
|
||||
/*
|
||||
* Intel HBA branding
|
||||
|
@ -78,6 +90,8 @@
|
|||
"Intel(R) RAID Controller RS3WC080"
|
||||
#define MEGARAID_INTEL_RS3WC040_BRANDING \
|
||||
"Intel(R) RAID Controller RS3WC040"
|
||||
#define MEGARAID_INTEL_RMS3BC160_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS3BC160"
|
||||
|
||||
/*
|
||||
* =====================================
|
||||
|
@ -273,6 +287,16 @@ enum MFI_STAT {
|
|||
MFI_STAT_INVALID_STATUS = 0xFF
|
||||
};
|
||||
|
||||
enum mfi_evt_class {
|
||||
MFI_EVT_CLASS_DEBUG = -2,
|
||||
MFI_EVT_CLASS_PROGRESS = -1,
|
||||
MFI_EVT_CLASS_INFO = 0,
|
||||
MFI_EVT_CLASS_WARNING = 1,
|
||||
MFI_EVT_CLASS_CRITICAL = 2,
|
||||
MFI_EVT_CLASS_FATAL = 3,
|
||||
MFI_EVT_CLASS_DEAD = 4
|
||||
};
|
||||
|
||||
/*
|
||||
* Crash dump related defines
|
||||
*/
|
||||
|
@ -364,6 +388,8 @@ enum MR_EVT_ARGS {
|
|||
MR_EVT_ARGS_GENERIC,
|
||||
};
|
||||
|
||||
|
||||
#define SGE_BUFFER_SIZE 4096
|
||||
/*
|
||||
* define constants for device list query options
|
||||
*/
|
||||
|
@ -394,6 +420,7 @@ enum MR_LD_QUERY_TYPE {
|
|||
#define MR_EVT_FOREIGN_CFG_IMPORTED 0x00db
|
||||
#define MR_EVT_LD_OFFLINE 0x00fc
|
||||
#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152
|
||||
#define MR_EVT_CTRL_PROP_CHANGED 0x012f
|
||||
|
||||
enum MR_PD_STATE {
|
||||
MR_PD_STATE_UNCONFIGURED_GOOD = 0x00,
|
||||
|
@ -973,7 +1000,12 @@ struct megasas_ctrl_info {
|
|||
|
||||
struct {
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
u32 reserved:12;
|
||||
u32 reserved:7;
|
||||
u32 useSeqNumJbodFP:1;
|
||||
u32 supportExtendedSSCSize:1;
|
||||
u32 supportDiskCacheSettingForSysPDs:1;
|
||||
u32 supportCPLDUpdate:1;
|
||||
u32 supportTTYLogCompression:1;
|
||||
u32 discardCacheDuringLDDelete:1;
|
||||
u32 supportSecurityonJBOD:1;
|
||||
u32 supportCacheBypassModes:1;
|
||||
|
@ -1013,7 +1045,12 @@ struct megasas_ctrl_info {
|
|||
u32 supportCacheBypassModes:1;
|
||||
u32 supportSecurityonJBOD:1;
|
||||
u32 discardCacheDuringLDDelete:1;
|
||||
u32 reserved:12;
|
||||
u32 supportTTYLogCompression:1;
|
||||
u32 supportCPLDUpdate:1;
|
||||
u32 supportDiskCacheSettingForSysPDs:1;
|
||||
u32 supportExtendedSSCSize:1;
|
||||
u32 useSeqNumJbodFP:1;
|
||||
u32 reserved:7;
|
||||
#endif
|
||||
} adapterOperations3;
|
||||
|
||||
|
@ -1229,7 +1266,9 @@ union megasas_sgl_frame {
|
|||
typedef union _MFI_CAPABILITIES {
|
||||
struct {
|
||||
#if defined(__BIG_ENDIAN_BITFIELD)
|
||||
u32 reserved:25;
|
||||
u32 reserved:23;
|
||||
u32 support_ext_io_size:1;
|
||||
u32 support_ext_queue_depth:1;
|
||||
u32 security_protocol_cmds_fw:1;
|
||||
u32 support_core_affinity:1;
|
||||
u32 support_ndrive_r1_lb:1;
|
||||
|
@ -1245,7 +1284,9 @@ typedef union _MFI_CAPABILITIES {
|
|||
u32 support_ndrive_r1_lb:1;
|
||||
u32 support_core_affinity:1;
|
||||
u32 security_protocol_cmds_fw:1;
|
||||
u32 reserved:25;
|
||||
u32 support_ext_queue_depth:1;
|
||||
u32 support_ext_io_size:1;
|
||||
u32 reserved:23;
|
||||
#endif
|
||||
} mfi_capabilities;
|
||||
__le32 reg;
|
||||
|
@ -1690,6 +1731,7 @@ struct megasas_instance {
|
|||
u32 crash_dump_drv_support;
|
||||
u32 crash_dump_app_support;
|
||||
u32 secure_jbod_support;
|
||||
bool use_seqnum_jbod_fp; /* Added for PD sequence */
|
||||
spinlock_t crashdump_lock;
|
||||
|
||||
struct megasas_register_set __iomem *reg_set;
|
||||
|
@ -1748,6 +1790,7 @@ struct megasas_instance {
|
|||
u8 UnevenSpanSupport;
|
||||
|
||||
u8 supportmax256vd;
|
||||
u8 allow_fw_scan;
|
||||
u16 fw_supported_vd_count;
|
||||
u16 fw_supported_pd_count;
|
||||
|
||||
|
@ -1769,7 +1812,9 @@ struct megasas_instance {
|
|||
struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES];
|
||||
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
|
||||
u64 map_id;
|
||||
u64 pd_seq_map_id;
|
||||
struct megasas_cmd *map_update_cmd;
|
||||
struct megasas_cmd *jbod_seq_cmd;
|
||||
unsigned long bar;
|
||||
long reset_flags;
|
||||
struct mutex reset_mutex;
|
||||
|
@ -1780,6 +1825,7 @@ struct megasas_instance {
|
|||
char mpio;
|
||||
u16 throttlequeuedepth;
|
||||
u8 mask_interrupts;
|
||||
u16 max_chain_frame_sz;
|
||||
u8 is_imr;
|
||||
bool dev_handle;
|
||||
};
|
||||
|
@ -1985,6 +2031,9 @@ __le16 get_updated_dev_handle(struct megasas_instance *instance,
|
|||
void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
|
||||
struct LD_LOAD_BALANCE_INFO *lbInfo);
|
||||
int megasas_get_ctrl_info(struct megasas_instance *instance);
|
||||
/* PD sequence */
|
||||
int
|
||||
megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend);
|
||||
int megasas_set_crash_dump_params(struct megasas_instance *instance,
|
||||
u8 crash_buf_state);
|
||||
void megasas_free_host_crash_buffer(struct megasas_instance *instance);
|
||||
|
@ -2000,5 +2049,6 @@ void __megasas_return_cmd(struct megasas_instance *instance,
|
|||
void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
|
||||
struct megasas_cmd *cmd_mfi, struct megasas_cmd_fusion *cmd_fusion);
|
||||
int megasas_cmd_type(struct scsi_cmnd *cmd);
|
||||
void megasas_setup_jbod_map(struct megasas_instance *instance);
|
||||
|
||||
#endif /*LSI_MEGARAID_SAS_H */
|
||||
|
|
|
@ -135,6 +135,12 @@ static struct pci_device_id megasas_pci_table[] = {
|
|||
/* Invader */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
|
||||
/* Fury */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER)},
|
||||
/* Intruder */
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER_24)},
|
||||
/* Intruder 24 port*/
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -260,6 +266,66 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
|
|||
|
||||
}
|
||||
|
||||
static const char *
|
||||
format_timestamp(uint32_t timestamp)
|
||||
{
|
||||
static char buffer[32];
|
||||
|
||||
if ((timestamp & 0xff000000) == 0xff000000)
|
||||
snprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
|
||||
0x00ffffff);
|
||||
else
|
||||
snprintf(buffer, sizeof(buffer), "%us", timestamp);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
format_class(int8_t class)
|
||||
{
|
||||
static char buffer[6];
|
||||
|
||||
switch (class) {
|
||||
case MFI_EVT_CLASS_DEBUG:
|
||||
return "debug";
|
||||
case MFI_EVT_CLASS_PROGRESS:
|
||||
return "progress";
|
||||
case MFI_EVT_CLASS_INFO:
|
||||
return "info";
|
||||
case MFI_EVT_CLASS_WARNING:
|
||||
return "WARN";
|
||||
case MFI_EVT_CLASS_CRITICAL:
|
||||
return "CRIT";
|
||||
case MFI_EVT_CLASS_FATAL:
|
||||
return "FATAL";
|
||||
case MFI_EVT_CLASS_DEAD:
|
||||
return "DEAD";
|
||||
default:
|
||||
snprintf(buffer, sizeof(buffer), "%d", class);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_decode_evt: Decode FW AEN event and print critical event
|
||||
* for information.
|
||||
* @instance: Adapter soft state
|
||||
*/
|
||||
static void
|
||||
megasas_decode_evt(struct megasas_instance *instance)
|
||||
{
|
||||
struct megasas_evt_detail *evt_detail = instance->evt_detail;
|
||||
union megasas_evt_class_locale class_locale;
|
||||
class_locale.word = le32_to_cpu(evt_detail->cl.word);
|
||||
|
||||
if (class_locale.members.class >= MFI_EVT_CLASS_CRITICAL)
|
||||
dev_info(&instance->pdev->dev, "%d (%s/0x%04x/%s) - %s\n",
|
||||
le32_to_cpu(evt_detail->seq_num),
|
||||
format_timestamp(le32_to_cpu(evt_detail->time_stamp)),
|
||||
(class_locale.members.locale),
|
||||
format_class(class_locale.members.class),
|
||||
evt_detail->description);
|
||||
}
|
||||
|
||||
/**
|
||||
* The following functions are defined for xscale
|
||||
* (deviceid : 1064R, PERC5) controllers
|
||||
|
@ -1659,8 +1725,56 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* megasas_set_dma_alignment - Set DMA alignment for PI enabled VD
|
||||
*
|
||||
* @sdev: OS provided scsi device
|
||||
*
|
||||
* Returns void
|
||||
*/
|
||||
static void megasas_set_dma_alignment(struct scsi_device *sdev)
|
||||
{
|
||||
u32 device_id, ld;
|
||||
struct megasas_instance *instance;
|
||||
struct fusion_context *fusion;
|
||||
struct MR_LD_RAID *raid;
|
||||
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
|
||||
|
||||
instance = megasas_lookup_instance(sdev->host->host_no);
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
if (!fusion)
|
||||
return;
|
||||
|
||||
if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) {
|
||||
device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
|
||||
+ sdev->id;
|
||||
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
|
||||
ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
|
||||
raid = MR_LdRaidGet(ld, local_map_ptr);
|
||||
|
||||
if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
|
||||
blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
|
||||
}
|
||||
}
|
||||
|
||||
static int megasas_slave_configure(struct scsi_device *sdev)
|
||||
{
|
||||
u16 pd_index = 0;
|
||||
struct megasas_instance *instance;
|
||||
|
||||
instance = megasas_lookup_instance(sdev->host->host_no);
|
||||
if (instance->allow_fw_scan) {
|
||||
if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
|
||||
sdev->type == TYPE_DISK) {
|
||||
pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
|
||||
sdev->id;
|
||||
if (instance->pd_list[pd_index].driveState !=
|
||||
MR_PD_STATE_SYSTEM)
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
megasas_set_dma_alignment(sdev);
|
||||
/*
|
||||
* The RAID firmware may require extended timeouts.
|
||||
*/
|
||||
|
@ -1683,8 +1797,8 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
|
|||
pd_index =
|
||||
(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
|
||||
sdev->id;
|
||||
if (instance->pd_list[pd_index].driveState ==
|
||||
MR_PD_STATE_SYSTEM) {
|
||||
if ((instance->allow_fw_scan || instance->pd_list[pd_index].driveState ==
|
||||
MR_PD_STATE_SYSTEM)) {
|
||||
return 0;
|
||||
}
|
||||
return -ENXIO;
|
||||
|
@ -1736,10 +1850,7 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
|
|||
msleep(1000);
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
(instance->ctrl_context)) {
|
||||
writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
|
||||
/* Flush */
|
||||
readl(&instance->reg_set->doorbell);
|
||||
|
@ -2506,10 +2617,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
|
|||
/*
|
||||
* First wait for all commands to complete
|
||||
*/
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
if (instance->ctrl_context)
|
||||
ret = megasas_reset_fusion(scmd->device->host, 1);
|
||||
else
|
||||
ret = megasas_generic_reset(scmd);
|
||||
|
@ -2837,7 +2945,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
|||
struct megasas_header *hdr = &cmd->frame->hdr;
|
||||
unsigned long flags;
|
||||
struct fusion_context *fusion = instance->ctrl_context;
|
||||
u32 opcode;
|
||||
u32 opcode, status;
|
||||
|
||||
/* flag for the retry reset */
|
||||
cmd->retry_for_fw_reset = 0;
|
||||
|
@ -2945,6 +3053,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
|||
&& (cmd->frame->dcmd.mbox.b[1] == 1)) {
|
||||
fusion->fast_path_io = 0;
|
||||
spin_lock_irqsave(instance->host->host_lock, flags);
|
||||
instance->map_update_cmd = NULL;
|
||||
if (cmd->frame->hdr.cmd_status != 0) {
|
||||
if (cmd->frame->hdr.cmd_status !=
|
||||
MFI_STAT_NOT_FOUND)
|
||||
|
@ -2982,6 +3091,27 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
|||
spin_unlock_irqrestore(&poll_aen_lock, flags);
|
||||
}
|
||||
|
||||
/* FW has an updated PD sequence */
|
||||
if ((opcode == MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
|
||||
(cmd->frame->dcmd.mbox.b[0] == 1)) {
|
||||
|
||||
spin_lock_irqsave(instance->host->host_lock, flags);
|
||||
status = cmd->frame->hdr.cmd_status;
|
||||
instance->jbod_seq_cmd = NULL;
|
||||
megasas_return_cmd(instance, cmd);
|
||||
|
||||
if (status == MFI_STAT_OK) {
|
||||
instance->pd_seq_map_id++;
|
||||
/* Re-register a pd sync seq num cmd */
|
||||
if (megasas_sync_pd_seq_num(instance, true))
|
||||
instance->use_seqnum_jbod_fp = false;
|
||||
} else
|
||||
instance->use_seqnum_jbod_fp = false;
|
||||
|
||||
spin_unlock_irqrestore(instance->host->host_lock, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if got an event notification
|
||||
*/
|
||||
|
@ -3348,22 +3478,14 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
|||
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FURY)) {
|
||||
(instance->ctrl_context))
|
||||
writel(
|
||||
MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
|
||||
&instance->reg_set->doorbell);
|
||||
} else {
|
||||
else
|
||||
writel(
|
||||
MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
|
||||
&instance->reg_set->inbound_doorbell);
|
||||
}
|
||||
|
||||
max_wait = MEGASAS_RESET_WAIT_TIME;
|
||||
cur_state = MFI_STATE_WAIT_HANDSHAKE;
|
||||
|
@ -3374,17 +3496,10 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
|||
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FURY)) {
|
||||
(instance->ctrl_context))
|
||||
writel(MFI_INIT_HOTPLUG,
|
||||
&instance->reg_set->doorbell);
|
||||
} else
|
||||
else
|
||||
writel(MFI_INIT_HOTPLUG,
|
||||
&instance->reg_set->inbound_doorbell);
|
||||
|
||||
|
@ -3401,24 +3516,11 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
|||
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
|
||||
(instance->pdev->device
|
||||
== PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device
|
||||
== PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device
|
||||
== PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device
|
||||
== PCI_DEVICE_ID_LSI_FURY)) {
|
||||
(instance->ctrl_context)) {
|
||||
writel(MFI_RESET_FLAGS,
|
||||
&instance->reg_set->doorbell);
|
||||
if ((instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FURY)) {
|
||||
|
||||
if (instance->ctrl_context) {
|
||||
for (i = 0; i < (10 * 1000); i += 20) {
|
||||
if (readl(
|
||||
&instance->
|
||||
|
@ -3639,11 +3741,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
|
|||
memset(cmd->frame, 0, total_sz);
|
||||
cmd->frame->io.context = cpu_to_le32(cmd->index);
|
||||
cmd->frame->io.pad_0 = 0;
|
||||
if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
|
||||
(instance->pdev->device != PCI_DEVICE_ID_LSI_PLASMA) &&
|
||||
(instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
|
||||
(instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
|
||||
(reset_devices))
|
||||
if (!instance->ctrl_context && reset_devices)
|
||||
cmd->frame->hdr.cmd = MFI_CMD_INVALID;
|
||||
}
|
||||
|
||||
|
@ -4136,11 +4234,21 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
|
|||
le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
|
||||
le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
|
||||
megasas_update_ext_vd_details(instance);
|
||||
instance->use_seqnum_jbod_fp =
|
||||
ctrl_info->adapterOperations3.useSeqNumJbodFP;
|
||||
instance->is_imr = (ctrl_info->memory_size ? 0 : 1);
|
||||
dev_info(&instance->pdev->dev,
|
||||
"controller type\t: %s(%dMB)\n",
|
||||
instance->is_imr ? "iMR" : "MR",
|
||||
le16_to_cpu(ctrl_info->memory_size));
|
||||
instance->disableOnlineCtrlReset =
|
||||
ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
|
||||
dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
|
||||
instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
|
||||
instance->secure_jbod_support =
|
||||
ctrl_info->adapterOperations3.supportSecurityonJBOD;
|
||||
dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
|
||||
instance->secure_jbod_support ? "Yes" : "No");
|
||||
}
|
||||
|
||||
pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
|
||||
|
@ -4480,6 +4588,62 @@ megasas_destroy_irqs(struct megasas_instance *instance) {
|
|||
free_irq(instance->pdev->irq, &instance->irq_context[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_setup_jbod_map - setup jbod map for FP seq_number.
|
||||
* @instance: Adapter soft state
|
||||
* @is_probe: Driver probe check
|
||||
*
|
||||
* Return 0 on success.
|
||||
*/
|
||||
void
|
||||
megasas_setup_jbod_map(struct megasas_instance *instance)
|
||||
{
|
||||
int i;
|
||||
struct fusion_context *fusion = instance->ctrl_context;
|
||||
u32 pd_seq_map_sz;
|
||||
|
||||
pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
|
||||
(sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
|
||||
|
||||
if (reset_devices || !fusion ||
|
||||
!instance->ctrl_info->adapterOperations3.useSeqNumJbodFP) {
|
||||
dev_info(&instance->pdev->dev,
|
||||
"Jbod map is not supported %s %d\n",
|
||||
__func__, __LINE__);
|
||||
instance->use_seqnum_jbod_fp = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fusion->pd_seq_sync[0])
|
||||
goto skip_alloc;
|
||||
|
||||
for (i = 0; i < JBOD_MAPS_COUNT; i++) {
|
||||
fusion->pd_seq_sync[i] = dma_alloc_coherent
|
||||
(&instance->pdev->dev, pd_seq_map_sz,
|
||||
&fusion->pd_seq_phys[i], GFP_KERNEL);
|
||||
if (!fusion->pd_seq_sync[i]) {
|
||||
dev_err(&instance->pdev->dev,
|
||||
"Failed to allocate memory from %s %d\n",
|
||||
__func__, __LINE__);
|
||||
if (i == 1) {
|
||||
dma_free_coherent(&instance->pdev->dev,
|
||||
pd_seq_map_sz, fusion->pd_seq_sync[0],
|
||||
fusion->pd_seq_phys[0]);
|
||||
fusion->pd_seq_sync[0] = NULL;
|
||||
}
|
||||
instance->use_seqnum_jbod_fp = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
skip_alloc:
|
||||
if (!megasas_sync_pd_seq_num(instance, false) &&
|
||||
!megasas_sync_pd_seq_num(instance, true))
|
||||
instance->use_seqnum_jbod_fp = true;
|
||||
else
|
||||
instance->use_seqnum_jbod_fp = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_init_fw - Initializes the FW
|
||||
* @instance: Adapter soft state
|
||||
|
@ -4498,6 +4662,9 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
unsigned long bar_list;
|
||||
int i, loop, fw_msix_count = 0;
|
||||
struct IOV_111 *iovPtr;
|
||||
struct fusion_context *fusion;
|
||||
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
/* Find first memory bar */
|
||||
bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
|
||||
|
@ -4523,6 +4690,10 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
case PCI_DEVICE_ID_LSI_PLASMA:
|
||||
case PCI_DEVICE_ID_LSI_INVADER:
|
||||
case PCI_DEVICE_ID_LSI_FURY:
|
||||
case PCI_DEVICE_ID_LSI_INTRUDER:
|
||||
case PCI_DEVICE_ID_LSI_INTRUDER_24:
|
||||
case PCI_DEVICE_ID_LSI_CUTLASS_52:
|
||||
case PCI_DEVICE_ID_LSI_CUTLASS_53:
|
||||
instance->instancet = &megasas_instance_template_fusion;
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_SAS1078R:
|
||||
|
@ -4541,6 +4712,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
case PCI_DEVICE_ID_DELL_PERC5:
|
||||
default:
|
||||
instance->instancet = &megasas_instance_template_xscale;
|
||||
instance->allow_fw_scan = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4575,37 +4747,32 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
scratch_pad_2 = readl
|
||||
(&instance->reg_set->outbound_scratch_pad_2);
|
||||
/* Check max MSI-X vectors */
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) {
|
||||
instance->msix_vectors = (scratch_pad_2
|
||||
& MR_MAX_REPLY_QUEUES_OFFSET) + 1;
|
||||
fw_msix_count = instance->msix_vectors;
|
||||
if (msix_vectors)
|
||||
instance->msix_vectors =
|
||||
min(msix_vectors,
|
||||
instance->msix_vectors);
|
||||
} else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
|
||||
|| (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
/* Invader/Fury supports more than 8 MSI-X */
|
||||
instance->msix_vectors = ((scratch_pad_2
|
||||
& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
|
||||
>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
|
||||
fw_msix_count = instance->msix_vectors;
|
||||
/* Save 1-15 reply post index address to local memory
|
||||
* Index 0 is already saved from reg offset
|
||||
* MPI2_REPLY_POST_HOST_INDEX_OFFSET
|
||||
*/
|
||||
for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
|
||||
instance->reply_post_host_index_addr[loop] =
|
||||
(u32 __iomem *)
|
||||
((u8 __iomem *)instance->reg_set +
|
||||
MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
|
||||
+ (loop * 0x10));
|
||||
if (fusion) {
|
||||
if (fusion->adapter_type == THUNDERBOLT_SERIES) { /* Thunderbolt Series*/
|
||||
instance->msix_vectors = (scratch_pad_2
|
||||
& MR_MAX_REPLY_QUEUES_OFFSET) + 1;
|
||||
fw_msix_count = instance->msix_vectors;
|
||||
} else { /* Invader series supports more than 8 MSI-x vectors*/
|
||||
instance->msix_vectors = ((scratch_pad_2
|
||||
& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
|
||||
>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
|
||||
fw_msix_count = instance->msix_vectors;
|
||||
/* Save 1-15 reply post index address to local memory
|
||||
* Index 0 is already saved from reg offset
|
||||
* MPI2_REPLY_POST_HOST_INDEX_OFFSET
|
||||
*/
|
||||
for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
|
||||
instance->reply_post_host_index_addr[loop] =
|
||||
(u32 __iomem *)
|
||||
((u8 __iomem *)instance->reg_set +
|
||||
MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
|
||||
+ (loop * 0x10));
|
||||
}
|
||||
}
|
||||
if (msix_vectors)
|
||||
instance->msix_vectors = min(msix_vectors,
|
||||
instance->msix_vectors);
|
||||
} else
|
||||
} else /* MFI adapters */
|
||||
instance->msix_vectors = 1;
|
||||
/* Don't bother allocating more MSI-X vectors than cpus */
|
||||
instance->msix_vectors = min(instance->msix_vectors,
|
||||
|
@ -4626,6 +4793,9 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
"current msix/online cpus\t: (%d/%d)\n",
|
||||
instance->msix_vectors, (unsigned int)num_online_cpus());
|
||||
|
||||
tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
|
||||
(unsigned long)instance);
|
||||
|
||||
if (instance->msix_vectors ?
|
||||
megasas_setup_irqs_msix(instance, 1) :
|
||||
megasas_setup_irqs_ioapic(instance))
|
||||
|
@ -4646,13 +4816,13 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
if (instance->instancet->init_adapter(instance))
|
||||
goto fail_init_adapter;
|
||||
|
||||
tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
|
||||
(unsigned long)instance);
|
||||
|
||||
instance->instancet->enable_intr(instance);
|
||||
|
||||
dev_err(&instance->pdev->dev, "INIT adapter done\n");
|
||||
|
||||
megasas_setup_jbod_map(instance);
|
||||
|
||||
/** for passthrough
|
||||
* the following function will get the PD LIST.
|
||||
*/
|
||||
|
@ -4686,8 +4856,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
|
||||
tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
|
||||
|
||||
instance->disableOnlineCtrlReset =
|
||||
ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
|
||||
instance->mpio = ctrl_info->adapterOperations2.mpio;
|
||||
instance->UnevenSpanSupport =
|
||||
ctrl_info->adapterOperations2.supportUnevenSpans;
|
||||
|
@ -4700,18 +4868,22 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
|
||||
}
|
||||
if (ctrl_info->host_interface.SRIOV) {
|
||||
if (!ctrl_info->adapterOperations2.activePassive)
|
||||
instance->PlasmaFW111 = 1;
|
||||
instance->requestorId = ctrl_info->iov.requestorId;
|
||||
if (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) {
|
||||
if (!ctrl_info->adapterOperations2.activePassive)
|
||||
instance->PlasmaFW111 = 1;
|
||||
|
||||
if (!instance->PlasmaFW111)
|
||||
instance->requestorId =
|
||||
ctrl_info->iov.requestorId;
|
||||
else {
|
||||
iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET);
|
||||
instance->requestorId = iovPtr->requestorId;
|
||||
dev_info(&instance->pdev->dev, "SR-IOV: firmware type: %s\n",
|
||||
instance->PlasmaFW111 ? "1.11" : "new");
|
||||
|
||||
if (instance->PlasmaFW111) {
|
||||
iovPtr = (struct IOV_111 *)
|
||||
((unsigned char *)ctrl_info + IOV_111_OFFSET);
|
||||
instance->requestorId = iovPtr->requestorId;
|
||||
}
|
||||
}
|
||||
dev_warn(&instance->pdev->dev, "I am VF "
|
||||
"requestorId %d\n", instance->requestorId);
|
||||
dev_info(&instance->pdev->dev, "SRIOV: VF requestorId %d\n",
|
||||
instance->requestorId);
|
||||
}
|
||||
|
||||
instance->crash_dump_fw_support =
|
||||
|
@ -4732,8 +4904,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
instance->crash_dump_buf = NULL;
|
||||
}
|
||||
|
||||
instance->secure_jbod_support =
|
||||
ctrl_info->adapterOperations3.supportSecurityonJBOD;
|
||||
|
||||
dev_info(&instance->pdev->dev,
|
||||
"pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n",
|
||||
|
@ -4743,16 +4913,14 @@ static int megasas_init_fw(struct megasas_instance *instance)
|
|||
le16_to_cpu(ctrl_info->pci.sub_device_id));
|
||||
dev_info(&instance->pdev->dev, "unevenspan support : %s\n",
|
||||
instance->UnevenSpanSupport ? "yes" : "no");
|
||||
dev_info(&instance->pdev->dev, "disable ocr : %s\n",
|
||||
instance->disableOnlineCtrlReset ? "yes" : "no");
|
||||
dev_info(&instance->pdev->dev, "firmware crash dump : %s\n",
|
||||
instance->crash_dump_drv_support ? "yes" : "no");
|
||||
dev_info(&instance->pdev->dev, "secure jbod : %s\n",
|
||||
instance->secure_jbod_support ? "yes" : "no");
|
||||
dev_info(&instance->pdev->dev, "jbod sync map : %s\n",
|
||||
instance->use_seqnum_jbod_fp ? "yes" : "no");
|
||||
|
||||
|
||||
instance->max_sectors_per_req = instance->max_num_sge *
|
||||
PAGE_SIZE / 512;
|
||||
SGE_BUFFER_SIZE / 512;
|
||||
if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
|
||||
instance->max_sectors_per_req = tmp_sectors;
|
||||
|
||||
|
@ -5091,10 +5259,7 @@ static int megasas_io_attach(struct megasas_instance *instance)
|
|||
host->max_cmd_len = 16;
|
||||
|
||||
/* Fusion only supports host reset */
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (instance->ctrl_context) {
|
||||
host->hostt->eh_device_reset_handler = NULL;
|
||||
host->hostt->eh_bus_reset_handler = NULL;
|
||||
}
|
||||
|
@ -5210,6 +5375,10 @@ static int megasas_probe_one(struct pci_dev *pdev,
|
|||
case PCI_DEVICE_ID_LSI_PLASMA:
|
||||
case PCI_DEVICE_ID_LSI_INVADER:
|
||||
case PCI_DEVICE_ID_LSI_FURY:
|
||||
case PCI_DEVICE_ID_LSI_INTRUDER:
|
||||
case PCI_DEVICE_ID_LSI_INTRUDER_24:
|
||||
case PCI_DEVICE_ID_LSI_CUTLASS_52:
|
||||
case PCI_DEVICE_ID_LSI_CUTLASS_53:
|
||||
{
|
||||
instance->ctrl_context_pages =
|
||||
get_order(sizeof(struct fusion_context));
|
||||
|
@ -5223,6 +5392,11 @@ static int megasas_probe_one(struct pci_dev *pdev,
|
|||
fusion = instance->ctrl_context;
|
||||
memset(fusion, 0,
|
||||
((1 << PAGE_SHIFT) << instance->ctrl_context_pages));
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA))
|
||||
fusion->adapter_type = THUNDERBOLT_SERIES;
|
||||
else
|
||||
fusion->adapter_type = INVADER_SERIES;
|
||||
}
|
||||
break;
|
||||
default: /* For all other supported controllers */
|
||||
|
@ -5325,10 +5499,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
|
|||
instance->disableOnlineCtrlReset = 1;
|
||||
instance->UnevenSpanSupport = 0;
|
||||
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (instance->ctrl_context) {
|
||||
INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
|
||||
INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq);
|
||||
} else
|
||||
|
@ -5408,10 +5579,7 @@ fail_io_attach:
|
|||
instance->instancet->disable_intr(instance);
|
||||
megasas_destroy_irqs(instance);
|
||||
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
if (instance->ctrl_context)
|
||||
megasas_release_fusion(instance);
|
||||
else
|
||||
megasas_release_mfi(instance);
|
||||
|
@ -5498,10 +5666,14 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
|
|||
|
||||
if (instance->aen_cmd)
|
||||
megasas_issue_blocked_abort_cmd(instance,
|
||||
instance->aen_cmd, 30);
|
||||
instance->aen_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
|
||||
if (instance->map_update_cmd)
|
||||
megasas_issue_blocked_abort_cmd(instance,
|
||||
instance->map_update_cmd, 30);
|
||||
instance->map_update_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
|
||||
if (instance->jbod_seq_cmd)
|
||||
megasas_issue_blocked_abort_cmd(instance,
|
||||
instance->jbod_seq_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
|
||||
|
||||
dcmd = &cmd->frame->dcmd;
|
||||
|
||||
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
|
||||
|
@ -5620,12 +5792,7 @@ megasas_resume(struct pci_dev *pdev)
|
|||
instance->msix_vectors))
|
||||
goto fail_reenable_msix;
|
||||
|
||||
switch (instance->pdev->device) {
|
||||
case PCI_DEVICE_ID_LSI_FUSION:
|
||||
case PCI_DEVICE_ID_LSI_PLASMA:
|
||||
case PCI_DEVICE_ID_LSI_INVADER:
|
||||
case PCI_DEVICE_ID_LSI_FURY:
|
||||
{
|
||||
if (instance->ctrl_context) {
|
||||
megasas_reset_reply_desc(instance);
|
||||
if (megasas_ioc_init_fusion(instance)) {
|
||||
megasas_free_cmds(instance);
|
||||
|
@ -5634,14 +5801,11 @@ megasas_resume(struct pci_dev *pdev)
|
|||
}
|
||||
if (!megasas_get_map_info(instance))
|
||||
megasas_sync_map_info(instance);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
*instance->producer = 0;
|
||||
*instance->consumer = 0;
|
||||
if (megasas_issue_init_mfi(instance))
|
||||
goto fail_init_mfi;
|
||||
break;
|
||||
}
|
||||
|
||||
tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
|
||||
|
@ -5666,6 +5830,7 @@ megasas_resume(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
instance->instancet->enable_intr(instance);
|
||||
megasas_setup_jbod_map(instance);
|
||||
instance->unload = 0;
|
||||
|
||||
/*
|
||||
|
@ -5713,6 +5878,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
|
|||
struct Scsi_Host *host;
|
||||
struct megasas_instance *instance;
|
||||
struct fusion_context *fusion;
|
||||
u32 pd_seq_map_sz;
|
||||
|
||||
instance = pci_get_drvdata(pdev);
|
||||
instance->unload = 1;
|
||||
|
@ -5761,12 +5927,11 @@ static void megasas_detach_one(struct pci_dev *pdev)
|
|||
if (instance->msix_vectors)
|
||||
pci_disable_msix(instance->pdev);
|
||||
|
||||
switch (instance->pdev->device) {
|
||||
case PCI_DEVICE_ID_LSI_FUSION:
|
||||
case PCI_DEVICE_ID_LSI_PLASMA:
|
||||
case PCI_DEVICE_ID_LSI_INVADER:
|
||||
case PCI_DEVICE_ID_LSI_FURY:
|
||||
if (instance->ctrl_context) {
|
||||
megasas_release_fusion(instance);
|
||||
pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
|
||||
(sizeof(struct MR_PD_CFG_SEQ) *
|
||||
(MAX_PHYSICAL_DEVICES - 1));
|
||||
for (i = 0; i < 2 ; i++) {
|
||||
if (fusion->ld_map[i])
|
||||
dma_free_coherent(&instance->pdev->dev,
|
||||
|
@ -5776,11 +5941,15 @@ static void megasas_detach_one(struct pci_dev *pdev)
|
|||
if (fusion->ld_drv_map[i])
|
||||
free_pages((ulong)fusion->ld_drv_map[i],
|
||||
fusion->drv_map_pages);
|
||||
if (fusion->pd_seq_sync)
|
||||
dma_free_coherent(&instance->pdev->dev,
|
||||
pd_seq_map_sz,
|
||||
fusion->pd_seq_sync[i],
|
||||
fusion->pd_seq_phys[i]);
|
||||
}
|
||||
free_pages((ulong)instance->ctrl_context,
|
||||
instance->ctrl_context_pages);
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
megasas_release_mfi(instance);
|
||||
pci_free_consistent(pdev, sizeof(u32),
|
||||
instance->producer,
|
||||
|
@ -5788,7 +5957,6 @@ static void megasas_detach_one(struct pci_dev *pdev)
|
|||
pci_free_consistent(pdev, sizeof(u32),
|
||||
instance->consumer,
|
||||
instance->consumer_h);
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(instance->ctrl_info);
|
||||
|
@ -6308,6 +6476,9 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
|
|||
int i;
|
||||
int error = 0;
|
||||
compat_uptr_t ptr;
|
||||
unsigned long local_raw_ptr;
|
||||
u32 local_sense_off;
|
||||
u32 local_sense_len;
|
||||
|
||||
if (clear_user(ioc, sizeof(*ioc)))
|
||||
return -EFAULT;
|
||||
|
@ -6325,9 +6496,15 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
|
|||
* sense_len is not null, so prepare the 64bit value under
|
||||
* the same condition.
|
||||
*/
|
||||
if (ioc->sense_len) {
|
||||
if (get_user(local_raw_ptr, ioc->frame.raw) ||
|
||||
get_user(local_sense_off, &ioc->sense_off) ||
|
||||
get_user(local_sense_len, &ioc->sense_len))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
if (local_sense_len) {
|
||||
void __user **sense_ioc_ptr =
|
||||
(void __user **)(ioc->frame.raw + ioc->sense_off);
|
||||
(void __user **)((u8*)local_raw_ptr + local_sense_off);
|
||||
compat_uptr_t *sense_cioc_ptr =
|
||||
(compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
|
||||
if (get_user(ptr, sense_cioc_ptr) ||
|
||||
|
@ -6496,6 +6673,7 @@ megasas_aen_polling(struct work_struct *work)
|
|||
instance->ev = NULL;
|
||||
host = instance->host;
|
||||
if (instance->evt_detail) {
|
||||
megasas_decode_evt(instance);
|
||||
|
||||
switch (le32_to_cpu(instance->evt_detail->code)) {
|
||||
case MR_EVT_PD_INSERTED:
|
||||
|
@ -6556,8 +6734,7 @@ megasas_aen_polling(struct work_struct *work)
|
|||
case MR_EVT_CFG_CLEARED:
|
||||
case MR_EVT_LD_DELETED:
|
||||
if (!instance->requestorId ||
|
||||
(instance->requestorId &&
|
||||
megasas_get_ld_vf_affiliation(instance, 0))) {
|
||||
megasas_get_ld_vf_affiliation(instance, 0)) {
|
||||
if (megasas_ld_list_query(instance,
|
||||
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
|
||||
megasas_get_ld_list(instance);
|
||||
|
@ -6588,8 +6765,7 @@ megasas_aen_polling(struct work_struct *work)
|
|||
break;
|
||||
case MR_EVT_LD_CREATED:
|
||||
if (!instance->requestorId ||
|
||||
(instance->requestorId &&
|
||||
megasas_get_ld_vf_affiliation(instance, 0))) {
|
||||
megasas_get_ld_vf_affiliation(instance, 0)) {
|
||||
if (megasas_ld_list_query(instance,
|
||||
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
|
||||
megasas_get_ld_list(instance);
|
||||
|
@ -6619,6 +6795,9 @@ megasas_aen_polling(struct work_struct *work)
|
|||
case MR_EVT_LD_STATE_CHANGE:
|
||||
doscan = 1;
|
||||
break;
|
||||
case MR_EVT_CTRL_PROP_CHANGED:
|
||||
megasas_get_ctrl_info(instance);
|
||||
break;
|
||||
default:
|
||||
doscan = 0;
|
||||
break;
|
||||
|
@ -6655,8 +6834,7 @@ megasas_aen_polling(struct work_struct *work)
|
|||
}
|
||||
|
||||
if (!instance->requestorId ||
|
||||
(instance->requestorId &&
|
||||
megasas_get_ld_vf_affiliation(instance, 0))) {
|
||||
megasas_get_ld_vf_affiliation(instance, 0)) {
|
||||
if (megasas_ld_list_query(instance,
|
||||
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
|
||||
megasas_get_ld_list(instance);
|
||||
|
|
|
@ -741,14 +741,12 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
|
|||
u8 physArm, span;
|
||||
u64 row;
|
||||
u8 retval = TRUE;
|
||||
u8 do_invader = 0;
|
||||
u64 *pdBlock = &io_info->pdBlock;
|
||||
__le16 *pDevHandle = &io_info->devHandle;
|
||||
u32 logArm, rowMod, armQ, arm;
|
||||
struct fusion_context *fusion;
|
||||
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
|
||||
instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
do_invader = 1;
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
/*Get row and span from io_info for Uneven Span IO.*/
|
||||
row = io_info->start_row;
|
||||
|
@ -779,7 +777,8 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
|
|||
else {
|
||||
*pDevHandle = cpu_to_le16(MR_PD_INVALID);
|
||||
if ((raid->level >= 5) &&
|
||||
(!do_invader || (do_invader &&
|
||||
((fusion->adapter_type == THUNDERBOLT_SERIES) ||
|
||||
((fusion->adapter_type == INVADER_SERIES) &&
|
||||
(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
|
||||
pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
|
||||
else if (raid->level == 1) {
|
||||
|
@ -823,13 +822,12 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
|
|||
u8 physArm, span;
|
||||
u64 row;
|
||||
u8 retval = TRUE;
|
||||
u8 do_invader = 0;
|
||||
u64 *pdBlock = &io_info->pdBlock;
|
||||
__le16 *pDevHandle = &io_info->devHandle;
|
||||
struct fusion_context *fusion;
|
||||
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
|
||||
instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
do_invader = 1;
|
||||
|
||||
row = mega_div64_32(stripRow, raid->rowDataSize);
|
||||
|
||||
|
@ -875,7 +873,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
|
|||
/* set dev handle as invalid. */
|
||||
*pDevHandle = cpu_to_le16(MR_PD_INVALID);
|
||||
if ((raid->level >= 5) &&
|
||||
(!do_invader || (do_invader &&
|
||||
((fusion->adapter_type == THUNDERBOLT_SERIES) ||
|
||||
((fusion->adapter_type == INVADER_SERIES) &&
|
||||
(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
|
||||
pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
|
||||
else if (raid->level == 1) {
|
||||
|
@ -909,6 +908,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
|
|||
struct RAID_CONTEXT *pRAID_Context,
|
||||
struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN)
|
||||
{
|
||||
struct fusion_context *fusion;
|
||||
struct MR_LD_RAID *raid;
|
||||
u32 ld, stripSize, stripe_mask;
|
||||
u64 endLba, endStrip, endRow, start_row, start_strip;
|
||||
|
@ -929,6 +929,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
|
|||
isRead = io_info->isRead;
|
||||
io_info->IoforUnevenSpan = 0;
|
||||
io_info->start_span = SPAN_INVALID;
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
ld = MR_TargetIdToLdGet(ldTgtId, map);
|
||||
raid = MR_LdRaidGet(ld, map);
|
||||
|
@ -1092,8 +1093,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
|
|||
cpu_to_le16(raid->fpIoTimeoutForLd ?
|
||||
raid->fpIoTimeoutForLd :
|
||||
map->raidMap.fpPdIoTimeoutSec);
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
if (fusion->adapter_type == INVADER_SERIES)
|
||||
pRAID_Context->regLockFlags = (isRead) ?
|
||||
raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
|
||||
else
|
||||
|
@ -1198,10 +1198,6 @@ void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map,
|
|||
span_row_width +=
|
||||
MR_LdSpanPtrGet
|
||||
(ld, count, map)->spanRowDataSize;
|
||||
printk(KERN_INFO "megasas:"
|
||||
"span %x rowDataSize %x\n",
|
||||
count, MR_LdSpanPtrGet
|
||||
(ld, count, map)->spanRowDataSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -316,26 +316,23 @@ static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
|
|||
u32 max_cmd;
|
||||
struct fusion_context *fusion;
|
||||
struct megasas_cmd_fusion *cmd;
|
||||
u32 total_sz_chain_frame;
|
||||
|
||||
fusion = instance->ctrl_context;
|
||||
max_cmd = instance->max_fw_cmds;
|
||||
|
||||
total_sz_chain_frame = MEGASAS_MAX_SZ_CHAIN_FRAME;
|
||||
|
||||
/*
|
||||
* Use DMA pool facility provided by PCI layer
|
||||
*/
|
||||
|
||||
fusion->sg_dma_pool = pci_pool_create("megasas sg pool fusion",
|
||||
instance->pdev,
|
||||
total_sz_chain_frame, 4,
|
||||
0);
|
||||
fusion->sg_dma_pool = pci_pool_create("sg_pool_fusion", instance->pdev,
|
||||
instance->max_chain_frame_sz,
|
||||
4, 0);
|
||||
if (!fusion->sg_dma_pool) {
|
||||
dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup request pool fusion\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
fusion->sense_dma_pool = pci_pool_create("megasas sense pool fusion",
|
||||
fusion->sense_dma_pool = pci_pool_create("sense pool fusion",
|
||||
instance->pdev,
|
||||
SCSI_SENSE_BUFFERSIZE, 64, 0);
|
||||
|
||||
|
@ -605,6 +602,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
|
|||
int i;
|
||||
struct megasas_header *frame_hdr;
|
||||
const char *sys_info;
|
||||
MFI_CAPABILITIES *drv_ops;
|
||||
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
|
@ -652,20 +650,21 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
|
|||
init_frame->cmd = MFI_CMD_INIT;
|
||||
init_frame->cmd_status = 0xFF;
|
||||
|
||||
drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations);
|
||||
|
||||
/* driver support Extended MSIX */
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
init_frame->driver_operations.
|
||||
mfi_capabilities.support_additional_msix = 1;
|
||||
if (fusion->adapter_type == INVADER_SERIES)
|
||||
drv_ops->mfi_capabilities.support_additional_msix = 1;
|
||||
/* driver supports HA / Remote LUN over Fast Path interface */
|
||||
init_frame->driver_operations.mfi_capabilities.support_fp_remote_lun
|
||||
= 1;
|
||||
init_frame->driver_operations.mfi_capabilities.support_max_255lds
|
||||
= 1;
|
||||
init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb
|
||||
= 1;
|
||||
init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw
|
||||
= 1;
|
||||
drv_ops->mfi_capabilities.support_fp_remote_lun = 1;
|
||||
|
||||
drv_ops->mfi_capabilities.support_max_255lds = 1;
|
||||
drv_ops->mfi_capabilities.support_ndrive_r1_lb = 1;
|
||||
drv_ops->mfi_capabilities.security_protocol_cmds_fw = 1;
|
||||
|
||||
if (instance->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
|
||||
drv_ops->mfi_capabilities.support_ext_io_size = 1;
|
||||
|
||||
/* Convert capability to LE32 */
|
||||
cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
|
||||
|
||||
|
@ -726,6 +725,83 @@ fail_get_cmd:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* megasas_sync_pd_seq_num - JBOD SEQ MAP
|
||||
* @instance: Adapter soft state
|
||||
* @pend: set to 1, if it is pended jbod map.
|
||||
*
|
||||
* Issue Jbod map to the firmware. If it is pended command,
|
||||
* issue command and return. If it is first instance of jbod map
|
||||
* issue and receive command.
|
||||
*/
|
||||
int
|
||||
megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) {
|
||||
int ret = 0;
|
||||
u32 pd_seq_map_sz;
|
||||
struct megasas_cmd *cmd;
|
||||
struct megasas_dcmd_frame *dcmd;
|
||||
struct fusion_context *fusion = instance->ctrl_context;
|
||||
struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
|
||||
dma_addr_t pd_seq_h;
|
||||
|
||||
pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id & 1)];
|
||||
pd_seq_h = fusion->pd_seq_phys[(instance->pd_seq_map_id & 1)];
|
||||
pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
|
||||
(sizeof(struct MR_PD_CFG_SEQ) *
|
||||
(MAX_PHYSICAL_DEVICES - 1));
|
||||
|
||||
cmd = megasas_get_cmd(instance);
|
||||
if (!cmd) {
|
||||
dev_err(&instance->pdev->dev,
|
||||
"Could not get mfi cmd. Fail from %s %d\n",
|
||||
__func__, __LINE__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dcmd = &cmd->frame->dcmd;
|
||||
|
||||
memset(pd_sync, 0, pd_seq_map_sz);
|
||||
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
|
||||
dcmd->cmd = MFI_CMD_DCMD;
|
||||
dcmd->cmd_status = 0xFF;
|
||||
dcmd->sge_count = 1;
|
||||
dcmd->timeout = 0;
|
||||
dcmd->pad_0 = 0;
|
||||
dcmd->data_xfer_len = cpu_to_le32(pd_seq_map_sz);
|
||||
dcmd->opcode = cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO);
|
||||
dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(pd_seq_h);
|
||||
dcmd->sgl.sge32[0].length = cpu_to_le32(pd_seq_map_sz);
|
||||
|
||||
if (pend) {
|
||||
dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG;
|
||||
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE);
|
||||
instance->jbod_seq_cmd = cmd;
|
||||
instance->instancet->issue_dcmd(instance, cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
|
||||
|
||||
/* Below code is only for non pended DCMD */
|
||||
if (instance->ctrl_context && !instance->mask_interrupts)
|
||||
ret = megasas_issue_blocked_cmd(instance, cmd, 60);
|
||||
else
|
||||
ret = megasas_issue_polled(instance, cmd);
|
||||
|
||||
if (le32_to_cpu(pd_sync->count) > MAX_PHYSICAL_DEVICES) {
|
||||
dev_warn(&instance->pdev->dev,
|
||||
"driver supports max %d JBOD, but FW reports %d\n",
|
||||
MAX_PHYSICAL_DEVICES, le32_to_cpu(pd_sync->count));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
instance->pd_seq_map_id++;
|
||||
|
||||
megasas_return_cmd(instance, cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* megasas_get_ld_map_info - Returns FW's ld_map structure
|
||||
* @instance: Adapter soft state
|
||||
|
@ -961,6 +1037,18 @@ megasas_display_intel_branding(struct megasas_instance *instance)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case PCI_DEVICE_ID_LSI_CUTLASS_52:
|
||||
case PCI_DEVICE_ID_LSI_CUTLASS_53:
|
||||
switch (instance->pdev->subsystem_device) {
|
||||
case MEGARAID_INTEL_RMS3BC160_SSDID:
|
||||
dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
|
||||
instance->host->host_no,
|
||||
MEGARAID_INTEL_RMS3BC160_BRANDING);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -977,7 +1065,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
|
|||
{
|
||||
struct megasas_register_set __iomem *reg_set;
|
||||
struct fusion_context *fusion;
|
||||
u32 max_cmd;
|
||||
u32 max_cmd, scratch_pad_2;
|
||||
int i = 0, count;
|
||||
|
||||
fusion = instance->ctrl_context;
|
||||
|
@ -1016,15 +1104,40 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
|
|||
(MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE *
|
||||
(max_cmd + 1)); /* Extra 1 for SMID 0 */
|
||||
|
||||
scratch_pad_2 = readl(&instance->reg_set->outbound_scratch_pad_2);
|
||||
/* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set,
|
||||
* Firmware support extended IO chain frame which is 4 times more than
|
||||
* legacy Firmware.
|
||||
* Legacy Firmware - Frame size is (8 * 128) = 1K
|
||||
* 1M IO Firmware - Frame size is (8 * 128 * 4) = 4K
|
||||
*/
|
||||
if (scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK)
|
||||
instance->max_chain_frame_sz =
|
||||
((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >>
|
||||
MEGASAS_MAX_CHAIN_SHIFT) * MEGASAS_1MB_IO;
|
||||
else
|
||||
instance->max_chain_frame_sz =
|
||||
((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >>
|
||||
MEGASAS_MAX_CHAIN_SHIFT) * MEGASAS_256K_IO;
|
||||
|
||||
if (instance->max_chain_frame_sz < MEGASAS_CHAIN_FRAME_SZ_MIN) {
|
||||
dev_warn(&instance->pdev->dev, "frame size %d invalid, fall back to legacy max frame size %d\n",
|
||||
instance->max_chain_frame_sz,
|
||||
MEGASAS_CHAIN_FRAME_SZ_MIN);
|
||||
instance->max_chain_frame_sz = MEGASAS_CHAIN_FRAME_SZ_MIN;
|
||||
}
|
||||
|
||||
fusion->max_sge_in_main_msg =
|
||||
(MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
|
||||
offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
|
||||
(MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE
|
||||
- offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
|
||||
|
||||
fusion->max_sge_in_chain =
|
||||
MEGASAS_MAX_SZ_CHAIN_FRAME / sizeof(union MPI2_SGE_IO_UNION);
|
||||
instance->max_chain_frame_sz
|
||||
/ sizeof(union MPI2_SGE_IO_UNION);
|
||||
|
||||
instance->max_num_sge = rounddown_pow_of_two(
|
||||
fusion->max_sge_in_main_msg + fusion->max_sge_in_chain - 2);
|
||||
instance->max_num_sge =
|
||||
rounddown_pow_of_two(fusion->max_sge_in_main_msg
|
||||
+ fusion->max_sge_in_chain - 2);
|
||||
|
||||
/* Used for pass thru MFI frame (DCMD) */
|
||||
fusion->chain_offset_mfi_pthru =
|
||||
|
@ -1186,8 +1299,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
|
|||
|
||||
fusion = instance->ctrl_context;
|
||||
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (fusion->adapter_type == INVADER_SERIES) {
|
||||
struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr;
|
||||
sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
|
||||
sgl_ptr_end->Flags = 0;
|
||||
|
@ -1204,11 +1316,9 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
|
|||
sgl_ptr->Length = cpu_to_le32(sg_dma_len(os_sgl));
|
||||
sgl_ptr->Address = cpu_to_le64(sg_dma_address(os_sgl));
|
||||
sgl_ptr->Flags = 0;
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (fusion->adapter_type == INVADER_SERIES)
|
||||
if (i == sge_count - 1)
|
||||
sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST;
|
||||
}
|
||||
sgl_ptr++;
|
||||
|
||||
sg_processed = i + 1;
|
||||
|
@ -1217,10 +1327,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
|
|||
(sge_count > fusion->max_sge_in_main_msg)) {
|
||||
|
||||
struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
|
||||
if ((instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (fusion->adapter_type == INVADER_SERIES) {
|
||||
if ((le16_to_cpu(cmd->io_request->IoFlags) &
|
||||
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
|
||||
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)
|
||||
|
@ -1236,10 +1343,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
|
|||
sg_chain = sgl_ptr;
|
||||
/* Prepare chain element */
|
||||
sg_chain->NextChainOffset = 0;
|
||||
if ((instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FURY))
|
||||
if (fusion->adapter_type == INVADER_SERIES)
|
||||
sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT;
|
||||
else
|
||||
sg_chain->Flags =
|
||||
|
@ -1250,7 +1354,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
|
|||
|
||||
sgl_ptr =
|
||||
(struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame;
|
||||
memset(sgl_ptr, 0, MEGASAS_MAX_SZ_CHAIN_FRAME);
|
||||
memset(sgl_ptr, 0, instance->max_chain_frame_sz);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1556,8 +1660,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
|
|||
cmd->request_desc->SCSIIO.RequestFlags =
|
||||
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
|
||||
<< MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (fusion->adapter_type == INVADER_SERIES) {
|
||||
if (io_request->RaidContext.regLockFlags ==
|
||||
REGION_TYPE_UNUSED)
|
||||
cmd->request_desc->SCSIIO.RequestFlags =
|
||||
|
@ -1582,7 +1685,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
|
|||
scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
|
||||
|
||||
if ((raidLUN[0] == 1) &&
|
||||
(local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 2)) {
|
||||
(local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 1)) {
|
||||
instance->dev_handle = !(instance->dev_handle);
|
||||
io_info.devHandle =
|
||||
local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].devHandle[instance->dev_handle];
|
||||
|
@ -1598,8 +1701,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
|
|||
cmd->request_desc->SCSIIO.RequestFlags =
|
||||
(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
|
||||
<< MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (fusion->adapter_type == INVADER_SERIES) {
|
||||
if (io_request->RaidContext.regLockFlags ==
|
||||
REGION_TYPE_UNUSED)
|
||||
cmd->request_desc->SCSIIO.RequestFlags =
|
||||
|
@ -1722,7 +1824,9 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
|
|||
u16 timeout_limit;
|
||||
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
|
||||
struct RAID_CONTEXT *pRAID_Context;
|
||||
struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
|
||||
struct fusion_context *fusion = instance->ctrl_context;
|
||||
pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id - 1) & 1];
|
||||
|
||||
device_id = MEGASAS_DEV_INDEX(scmd);
|
||||
pd_index = MEGASAS_PD_INDEX(scmd);
|
||||
|
@ -1731,16 +1835,38 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
|
|||
io_request = cmd->io_request;
|
||||
/* get RAID_Context pointer */
|
||||
pRAID_Context = &io_request->RaidContext;
|
||||
pRAID_Context->regLockFlags = 0;
|
||||
pRAID_Context->regLockRowLBA = 0;
|
||||
pRAID_Context->regLockLength = 0;
|
||||
io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
|
||||
io_request->LUN[1] = scmd->device->lun;
|
||||
pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
|
||||
<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
|
||||
|
||||
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
|
||||
pRAID_Context->configSeqNum = 0;
|
||||
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
|
||||
io_request->DevHandle =
|
||||
local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
|
||||
/* If FW supports PD sequence number */
|
||||
if (instance->use_seqnum_jbod_fp &&
|
||||
instance->pd_list[pd_index].driveType == TYPE_DISK) {
|
||||
/* TgtId must be incremented by 255 as jbod seq number is index
|
||||
* below raid map
|
||||
*/
|
||||
pRAID_Context->VirtualDiskTgtId =
|
||||
cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
|
||||
pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
|
||||
io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
|
||||
pRAID_Context->regLockFlags |=
|
||||
(MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
|
||||
} else if (fusion->fast_path_io) {
|
||||
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
|
||||
pRAID_Context->configSeqNum = 0;
|
||||
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
|
||||
io_request->DevHandle =
|
||||
local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
|
||||
} else {
|
||||
/* Want to send all IO via FW path */
|
||||
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
|
||||
pRAID_Context->configSeqNum = 0;
|
||||
io_request->DevHandle = cpu_to_le16(0xFFFF);
|
||||
}
|
||||
|
||||
cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
|
||||
cmd->request_desc->SCSIIO.MSIxIndex =
|
||||
|
@ -1755,22 +1881,16 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
|
|||
(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
|
||||
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||
pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
|
||||
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
|
||||
} else {
|
||||
/* system pd Fast Path */
|
||||
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
||||
pRAID_Context->regLockFlags = 0;
|
||||
pRAID_Context->regLockRowLBA = 0;
|
||||
pRAID_Context->regLockLength = 0;
|
||||
timeout_limit = (scmd->device->type == TYPE_DISK) ?
|
||||
255 : 0xFFFF;
|
||||
pRAID_Context->timeoutValue =
|
||||
cpu_to_le16((os_timeout_value > timeout_limit) ?
|
||||
timeout_limit : os_timeout_value);
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
cmd->request_desc->SCSIIO.RequestFlags |=
|
||||
(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
|
||||
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||
if (fusion->adapter_type == INVADER_SERIES) {
|
||||
pRAID_Context->Type = MPI2_TYPE_CUDA;
|
||||
pRAID_Context->nseg = 0x1;
|
||||
io_request->IoFlags |=
|
||||
|
@ -1796,7 +1916,7 @@ megasas_build_io_fusion(struct megasas_instance *instance,
|
|||
struct scsi_cmnd *scp,
|
||||
struct megasas_cmd_fusion *cmd)
|
||||
{
|
||||
u32 sge_count;
|
||||
u16 sge_count;
|
||||
u8 cmd_type;
|
||||
struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
|
||||
|
||||
|
@ -1854,7 +1974,11 @@ megasas_build_io_fusion(struct megasas_instance *instance,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* numSGE store lower 8 bit of sge_count.
|
||||
* numSGEExt store higher 8 bit of sge_count
|
||||
*/
|
||||
io_request->RaidContext.numSGE = sge_count;
|
||||
io_request->RaidContext.numSGEExt = (u8)(sge_count >> 8);
|
||||
|
||||
io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
|
||||
|
||||
|
@ -2084,10 +2208,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
|
|||
* pending to be completed
|
||||
*/
|
||||
if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
|
||||
if ((instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device ==
|
||||
PCI_DEVICE_ID_LSI_FURY))
|
||||
if (fusion->adapter_type == INVADER_SERIES)
|
||||
writel(((MSIxIndex & 0x7) << 24) |
|
||||
fusion->last_reply_idx[MSIxIndex],
|
||||
instance->reply_post_host_index_addr[MSIxIndex/8]);
|
||||
|
@ -2103,8 +2224,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
|
|||
return IRQ_NONE;
|
||||
|
||||
wmb();
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
|
||||
if (fusion->adapter_type == INVADER_SERIES)
|
||||
writel(((MSIxIndex & 0x7) << 24) |
|
||||
fusion->last_reply_idx[MSIxIndex],
|
||||
instance->reply_post_host_index_addr[MSIxIndex/8]);
|
||||
|
@ -2227,8 +2347,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
|
|||
|
||||
io_req = cmd->io_request;
|
||||
|
||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
|
||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
|
||||
if (fusion->adapter_type == INVADER_SERIES) {
|
||||
struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end =
|
||||
(struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL;
|
||||
sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
|
||||
|
@ -2248,7 +2367,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
|
|||
mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
|
||||
MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
|
||||
|
||||
mpi25_ieee_chain->Length = cpu_to_le32(MEGASAS_MAX_SZ_CHAIN_FRAME);
|
||||
mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2384,6 +2503,70 @@ static int
|
|||
megasas_adp_reset_fusion(struct megasas_instance *instance,
|
||||
struct megasas_register_set __iomem *regs)
|
||||
{
|
||||
u32 host_diag, abs_state, retry;
|
||||
|
||||
/* Now try to reset the chip */
|
||||
writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_1ST_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_2ND_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_3RD_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_4TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_5TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_6TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
|
||||
|
||||
/* Check that the diag write enable (DRWE) bit is on */
|
||||
host_diag = readl(&instance->reg_set->fusion_host_diag);
|
||||
retry = 0;
|
||||
while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
|
||||
msleep(100);
|
||||
host_diag = readl(&instance->reg_set->fusion_host_diag);
|
||||
if (retry++ == 100) {
|
||||
dev_warn(&instance->pdev->dev,
|
||||
"Host diag unlock failed from %s %d\n",
|
||||
__func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
|
||||
return -1;
|
||||
|
||||
/* Send chip reset command */
|
||||
writel(host_diag | HOST_DIAG_RESET_ADAPTER,
|
||||
&instance->reg_set->fusion_host_diag);
|
||||
msleep(3000);
|
||||
|
||||
/* Make sure reset adapter bit is cleared */
|
||||
host_diag = readl(&instance->reg_set->fusion_host_diag);
|
||||
retry = 0;
|
||||
while (host_diag & HOST_DIAG_RESET_ADAPTER) {
|
||||
msleep(100);
|
||||
host_diag = readl(&instance->reg_set->fusion_host_diag);
|
||||
if (retry++ == 1000) {
|
||||
dev_warn(&instance->pdev->dev,
|
||||
"Diag reset adapter never cleared %s %d\n",
|
||||
__func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (host_diag & HOST_DIAG_RESET_ADAPTER)
|
||||
return -1;
|
||||
|
||||
abs_state = instance->instancet->read_fw_status_reg(instance->reg_set)
|
||||
& MFI_STATE_MASK;
|
||||
retry = 0;
|
||||
|
||||
while ((abs_state <= MFI_STATE_FW_INIT) && (retry++ < 1000)) {
|
||||
msleep(100);
|
||||
abs_state = instance->instancet->
|
||||
read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
|
||||
}
|
||||
if (abs_state <= MFI_STATE_FW_INIT) {
|
||||
dev_warn(&instance->pdev->dev,
|
||||
"fw state < MFI_STATE_FW_INIT, state = 0x%x %s %d\n",
|
||||
abs_state, __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2512,8 +2695,10 @@ void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
|
|||
continue;
|
||||
req_desc = megasas_get_request_descriptor
|
||||
(instance, smid - 1);
|
||||
if (req_desc && (cmd_mfi->frame->dcmd.opcode !=
|
||||
cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)))
|
||||
if (req_desc && ((cmd_mfi->frame->dcmd.opcode !=
|
||||
cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)) &&
|
||||
(cmd_mfi->frame->dcmd.opcode !=
|
||||
cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO))))
|
||||
megasas_fire_cmd_fusion(instance, req_desc);
|
||||
else
|
||||
megasas_return_cmd(instance, cmd_mfi);
|
||||
|
@ -2547,11 +2732,11 @@ out:
|
|||
/* Core fusion reset function */
|
||||
int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
|
||||
{
|
||||
int retval = SUCCESS, i, retry = 0, convert = 0;
|
||||
int retval = SUCCESS, i, convert = 0;
|
||||
struct megasas_instance *instance;
|
||||
struct megasas_cmd_fusion *cmd_fusion;
|
||||
struct fusion_context *fusion;
|
||||
u32 host_diag, abs_state, status_reg, reset_adapter;
|
||||
u32 abs_state, status_reg, reset_adapter;
|
||||
u32 io_timeout_in_crash_mode = 0;
|
||||
struct scsi_cmnd *scmd_local = NULL;
|
||||
|
||||
|
@ -2705,82 +2890,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
|
|||
|
||||
/* Now try to reset the chip */
|
||||
for (i = 0; i < MEGASAS_FUSION_MAX_RESET_TRIES; i++) {
|
||||
writel(MPI2_WRSEQ_FLUSH_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_1ST_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_2ND_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_3RD_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_4TH_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_5TH_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
writel(MPI2_WRSEQ_6TH_KEY_VALUE,
|
||||
&instance->reg_set->fusion_seq_offset);
|
||||
|
||||
/* Check that the diag write enable (DRWE) bit is on */
|
||||
host_diag = readl(&instance->reg_set->fusion_host_diag);
|
||||
retry = 0;
|
||||
while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
|
||||
msleep(100);
|
||||
host_diag =
|
||||
readl(&instance->reg_set->fusion_host_diag);
|
||||
if (retry++ == 100) {
|
||||
dev_warn(&instance->pdev->dev,
|
||||
"Host diag unlock failed! "
|
||||
"for scsi%d\n",
|
||||
instance->host->host_no);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
|
||||
if (instance->instancet->adp_reset
|
||||
(instance, instance->reg_set))
|
||||
continue;
|
||||
|
||||
/* Send chip reset command */
|
||||
writel(host_diag | HOST_DIAG_RESET_ADAPTER,
|
||||
&instance->reg_set->fusion_host_diag);
|
||||
msleep(3000);
|
||||
|
||||
/* Make sure reset adapter bit is cleared */
|
||||
host_diag = readl(&instance->reg_set->fusion_host_diag);
|
||||
retry = 0;
|
||||
while (host_diag & HOST_DIAG_RESET_ADAPTER) {
|
||||
msleep(100);
|
||||
host_diag =
|
||||
readl(&instance->reg_set->fusion_host_diag);
|
||||
if (retry++ == 1000) {
|
||||
dev_warn(&instance->pdev->dev,
|
||||
"Diag reset adapter never "
|
||||
"cleared for scsi%d!\n",
|
||||
instance->host->host_no);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (host_diag & HOST_DIAG_RESET_ADAPTER)
|
||||
continue;
|
||||
|
||||
abs_state =
|
||||
instance->instancet->read_fw_status_reg(
|
||||
instance->reg_set) & MFI_STATE_MASK;
|
||||
retry = 0;
|
||||
|
||||
while ((abs_state <= MFI_STATE_FW_INIT) &&
|
||||
(retry++ < 1000)) {
|
||||
msleep(100);
|
||||
abs_state =
|
||||
instance->instancet->read_fw_status_reg(
|
||||
instance->reg_set) & MFI_STATE_MASK;
|
||||
}
|
||||
if (abs_state <= MFI_STATE_FW_INIT) {
|
||||
dev_warn(&instance->pdev->dev, "firmware "
|
||||
"state < MFI_STATE_FW_INIT, state = "
|
||||
"0x%x for scsi%d\n", abs_state,
|
||||
instance->host->host_no);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wait for FW to become ready */
|
||||
if (megasas_transition_to_ready(instance, 1)) {
|
||||
dev_warn(&instance->pdev->dev, "Failed to "
|
||||
|
@ -2816,6 +2930,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
|
|||
if (!megasas_get_map_info(instance))
|
||||
megasas_sync_map_info(instance);
|
||||
|
||||
megasas_setup_jbod_map(instance);
|
||||
|
||||
clear_bit(MEGASAS_FUSION_IN_RESET,
|
||||
&instance->reset_flags);
|
||||
instance->instancet->enable_intr(instance);
|
||||
|
|
|
@ -35,8 +35,13 @@
|
|||
#define _MEGARAID_SAS_FUSION_H_
|
||||
|
||||
/* Fusion defines */
|
||||
#define MEGASAS_MAX_SZ_CHAIN_FRAME 1024
|
||||
#define MEGASAS_CHAIN_FRAME_SZ_MIN 1024
|
||||
#define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000009)
|
||||
#define MEGASAS_MAX_CHAIN_SHIFT 5
|
||||
#define MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK 0x400000
|
||||
#define MEGASAS_MAX_CHAIN_SIZE_MASK 0x3E0
|
||||
#define MEGASAS_256K_IO 128
|
||||
#define MEGASAS_1MB_IO (MEGASAS_256K_IO * 4)
|
||||
#define MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE 256
|
||||
#define MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST 0xF0
|
||||
#define MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST 0xF1
|
||||
|
@ -89,6 +94,12 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
|
|||
#define MEGASAS_FP_CMD_LEN 16
|
||||
#define MEGASAS_FUSION_IN_RESET 0
|
||||
#define THRESHOLD_REPLY_COUNT 50
|
||||
#define JBOD_MAPS_COUNT 2
|
||||
|
||||
enum MR_FUSION_ADAPTER_TYPE {
|
||||
THUNDERBOLT_SERIES = 0,
|
||||
INVADER_SERIES = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Raid Context structure which describes MegaRAID specific IO Parameters
|
||||
|
@ -117,7 +128,9 @@ struct RAID_CONTEXT {
|
|||
u8 numSGE;
|
||||
__le16 configSeqNum;
|
||||
u8 spanArm;
|
||||
u8 resvd2[3];
|
||||
u8 priority;
|
||||
u8 numSGEExt;
|
||||
u8 resvd2;
|
||||
};
|
||||
|
||||
#define RAID_CTX_SPANARM_ARM_SHIFT (0)
|
||||
|
@ -486,6 +499,7 @@ struct MPI2_IOC_INIT_REQUEST {
|
|||
#define MAX_PHYSICAL_DEVICES 256
|
||||
#define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
|
||||
#define MR_DCMD_LD_MAP_GET_INFO 0x0300e101
|
||||
#define MR_DCMD_SYSTEM_PD_MAP_GET_INFO 0x0200e102
|
||||
#define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC 0x010e8485 /* SR-IOV HB alloc*/
|
||||
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111 0x03200200
|
||||
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS 0x03150200
|
||||
|
@ -789,6 +803,21 @@ struct MR_FW_RAID_MAP_EXT {
|
|||
struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_EXT];
|
||||
};
|
||||
|
||||
/*
|
||||
* * define MR_PD_CFG_SEQ structure for system PDs
|
||||
* */
|
||||
struct MR_PD_CFG_SEQ {
|
||||
__le16 seqNum;
|
||||
__le16 devHandle;
|
||||
u8 reserved[4];
|
||||
} __packed;
|
||||
|
||||
struct MR_PD_CFG_SEQ_NUM_SYNC {
|
||||
__le32 size;
|
||||
__le32 count;
|
||||
struct MR_PD_CFG_SEQ seq[1];
|
||||
} __packed;
|
||||
|
||||
struct fusion_context {
|
||||
struct megasas_cmd_fusion **cmd_list;
|
||||
dma_addr_t req_frames_desc_phys;
|
||||
|
@ -828,9 +857,12 @@ struct fusion_context {
|
|||
u32 current_map_sz;
|
||||
u32 drv_map_sz;
|
||||
u32 drv_map_pages;
|
||||
struct MR_PD_CFG_SEQ_NUM_SYNC *pd_seq_sync[JBOD_MAPS_COUNT];
|
||||
dma_addr_t pd_seq_phys[JBOD_MAPS_COUNT];
|
||||
u8 fast_path_io;
|
||||
struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
|
||||
LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
|
||||
u8 adapter_type;
|
||||
};
|
||||
|
||||
union desc_value {
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
#
|
||||
# Kernel configuration file for the MPT2SAS
|
||||
#
|
||||
# This code is based on drivers/scsi/mpt2sas/Kconfig
|
||||
# Copyright (C) 2007-2014 LSI Corporation
|
||||
# (mailto:DL-MPTFusionLinux@lsi.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
|
||||
# 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.
|
||||
|
||||
# NO WARRANTY
|
||||
# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
# solely responsible for determining the appropriateness of using and
|
||||
# distributing the Program and assumes all risks associated with its
|
||||
# exercise of rights under this Agreement, including but not limited to
|
||||
# the risks and costs of program errors, damage to or loss of data,
|
||||
# programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
# DISCLAIMER OF LIABILITY
|
||||
# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
|
||||
config SCSI_MPT2SAS
|
||||
tristate "LSI MPT Fusion SAS 2.0 Device Driver"
|
||||
depends on PCI && SCSI
|
||||
select SCSI_SAS_ATTRS
|
||||
select RAID_ATTRS
|
||||
---help---
|
||||
This driver supports PCI-Express SAS 6Gb/s Host Adapters.
|
||||
|
||||
config SCSI_MPT2SAS_MAX_SGE
|
||||
int "LSI MPT Fusion Max number of SG Entries (16 - 128)"
|
||||
depends on PCI && SCSI && SCSI_MPT2SAS
|
||||
default "128"
|
||||
range 16 128
|
||||
---help---
|
||||
This option allows you to specify the maximum number of scatter-
|
||||
gather entries per I/O. The driver default is 128, which matches
|
||||
SAFE_PHYS_SEGMENTS. However, it may decreased down to 16.
|
||||
Decreasing this parameter will reduce memory requirements
|
||||
on a per controller instance.
|
||||
|
||||
config SCSI_MPT2SAS_LOGGING
|
||||
bool "LSI MPT Fusion logging facility"
|
||||
depends on PCI && SCSI && SCSI_MPT2SAS
|
||||
---help---
|
||||
This turns on a logging facility.
|
|
@ -1,7 +0,0 @@
|
|||
# mpt2sas makefile
|
||||
obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o
|
||||
mpt2sas-y += mpt2sas_base.o \
|
||||
mpt2sas_config.o \
|
||||
mpt2sas_scsih.o \
|
||||
mpt2sas_transport.o \
|
||||
mpt2sas_ctl.o
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,461 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2014 LSI Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi2_init.h
|
||||
* Title: MPI SCSI initiator mode messages and structures
|
||||
* Creation Date: June 23, 2006
|
||||
*
|
||||
* mpi2_init.h Version: 02.00.15
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
|
||||
* 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t.
|
||||
* 12-18-07 02.00.02 Modified Task Management Target Reset Method defines.
|
||||
* 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention.
|
||||
* 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY.
|
||||
* 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t.
|
||||
* 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO
|
||||
* Control field Task Attribute flags.
|
||||
* Moved LUN field defines to mpi2.h because they are
|
||||
* common to many structures.
|
||||
* 05-06-09 02.00.07 Changed task management type of Query Unit Attention to
|
||||
* Query Asynchronous Event.
|
||||
* Defined two new bits in the SlotStatus field of the SCSI
|
||||
* Enclosure Processor Request and Reply.
|
||||
* 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for
|
||||
* both SCSI IO Error Reply and SCSI Task Management Reply.
|
||||
* Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY.
|
||||
* Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define.
|
||||
* 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it.
|
||||
* 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request.
|
||||
* 11-10-10 02.00.11 Added MPI2_SCSIIO_NUM_SGLOFFSETS define.
|
||||
* 02-06-12 02.00.13 Added alternate defines for Task Priority / Command
|
||||
* Priority to match SAM-4.
|
||||
* 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION.
|
||||
* 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY,
|
||||
* replacing the Reserved4 field.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI2_INIT_H
|
||||
#define MPI2_INIT_H
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* SCSI Initiator Messages
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* SCSI IO messages and associated structures
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 CDB[20]; /* 0x00 */
|
||||
U32 PrimaryReferenceTag; /* 0x14 */
|
||||
U16 PrimaryApplicationTag; /* 0x18 */
|
||||
U16 PrimaryApplicationTagMask; /* 0x1A */
|
||||
U32 TransferLength; /* 0x1C */
|
||||
} MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32,
|
||||
Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
U8 CDB32[32];
|
||||
MPI2_SCSI_IO_CDB_EEDP32 EEDP32;
|
||||
MPI2_SGE_SIMPLE_UNION SGE;
|
||||
} MPI2_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_UNION,
|
||||
Mpi2ScsiIoCdb_t, MPI2_POINTER pMpi2ScsiIoCdb_t;
|
||||
|
||||
/* SCSI IO Request Message */
|
||||
typedef struct _MPI2_SCSI_IO_REQUEST
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved1; /* 0x04 */
|
||||
U8 Reserved2; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved3; /* 0x0A */
|
||||
U32 SenseBufferLowAddress; /* 0x0C */
|
||||
U16 SGLFlags; /* 0x10 */
|
||||
U8 SenseBufferLength; /* 0x12 */
|
||||
U8 Reserved4; /* 0x13 */
|
||||
U8 SGLOffset0; /* 0x14 */
|
||||
U8 SGLOffset1; /* 0x15 */
|
||||
U8 SGLOffset2; /* 0x16 */
|
||||
U8 SGLOffset3; /* 0x17 */
|
||||
U32 SkipCount; /* 0x18 */
|
||||
U32 DataLength; /* 0x1C */
|
||||
U32 BidirectionalDataLength; /* 0x20 */
|
||||
U16 IoFlags; /* 0x24 */
|
||||
U16 EEDPFlags; /* 0x26 */
|
||||
U32 EEDPBlockSize; /* 0x28 */
|
||||
U32 SecondaryReferenceTag; /* 0x2C */
|
||||
U16 SecondaryApplicationTag; /* 0x30 */
|
||||
U16 ApplicationTagTranslationMask; /* 0x32 */
|
||||
U8 LUN[8]; /* 0x34 */
|
||||
U32 Control; /* 0x3C */
|
||||
MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
|
||||
|
||||
#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /* typically this is left undefined */
|
||||
MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion;
|
||||
#endif
|
||||
|
||||
MPI2_SGE_IO_UNION SGL; /* 0x60 */
|
||||
|
||||
} MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST,
|
||||
Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t;
|
||||
|
||||
/* SCSI IO MsgFlags bits */
|
||||
|
||||
/* MsgFlags for SenseBufferAddressSpace */
|
||||
#define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR (0x0C)
|
||||
#define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR (0x00)
|
||||
#define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR (0x04)
|
||||
#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08)
|
||||
#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C)
|
||||
|
||||
/* SCSI IO SGLFlags bits */
|
||||
|
||||
/* base values for Data Location Address Space */
|
||||
#define MPI2_SCSIIO_SGLFLAGS_ADDR_MASK (0x0C)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR (0x00)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_IOCDDR_ADDR (0x04)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_IOCPLB_ADDR (0x08)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_IOCPLBNTA_ADDR (0x0C)
|
||||
|
||||
/* base values for Type */
|
||||
#define MPI2_SCSIIO_SGLFLAGS_TYPE_MASK (0x03)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_TYPE_MPI (0x00)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE32 (0x01)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE64 (0x02)
|
||||
|
||||
/* shift values for each sub-field */
|
||||
#define MPI2_SCSIIO_SGLFLAGS_SGL3_SHIFT (12)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_SGL2_SHIFT (8)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_SGL1_SHIFT (4)
|
||||
#define MPI2_SCSIIO_SGLFLAGS_SGL0_SHIFT (0)
|
||||
|
||||
/* number of SGLOffset fields */
|
||||
#define MPI2_SCSIIO_NUM_SGLOFFSETS (4)
|
||||
|
||||
/* SCSI IO IoFlags bits */
|
||||
|
||||
/* Large CDB Address Space */
|
||||
#define MPI2_SCSIIO_CDB_ADDR_MASK (0x6000)
|
||||
#define MPI2_SCSIIO_CDB_ADDR_SYSTEM (0x0000)
|
||||
#define MPI2_SCSIIO_CDB_ADDR_IOCDDR (0x2000)
|
||||
#define MPI2_SCSIIO_CDB_ADDR_IOCPLB (0x4000)
|
||||
#define MPI2_SCSIIO_CDB_ADDR_IOCPLBNTA (0x6000)
|
||||
|
||||
#define MPI2_SCSIIO_IOFLAGS_LARGE_CDB (0x1000)
|
||||
#define MPI2_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800)
|
||||
#define MPI2_SCSIIO_IOFLAGS_MULTICAST (0x0400)
|
||||
#define MPI2_SCSIIO_IOFLAGS_CMD_DETERMINES_DATA_DIR (0x0200)
|
||||
#define MPI2_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF)
|
||||
|
||||
/* SCSI IO EEDPFlags bits */
|
||||
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_REFTAG (0x4000)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_APPTAG (0x2000)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_APPTAG (0x1000)
|
||||
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100)
|
||||
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_PASSTHRU_REFTAG (0x0008)
|
||||
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_MASK_OP (0x0007)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_NOOP_OP (0x0000)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_CHECK_OP (0x0001)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_STRIP_OP (0x0002)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_REPLACE_OP (0x0006)
|
||||
#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REGEN_OP (0x0007)
|
||||
|
||||
/* SCSI IO LUN fields: use MPI2_LUN_ from mpi2.h */
|
||||
|
||||
/* SCSI IO Control bits */
|
||||
#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_MASK (0xFC000000)
|
||||
#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT (26)
|
||||
|
||||
#define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK (0x03000000)
|
||||
#define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24)
|
||||
#define MPI2_SCSIIO_CONTROL_NODATATRANSFER (0x00000000)
|
||||
#define MPI2_SCSIIO_CONTROL_WRITE (0x01000000)
|
||||
#define MPI2_SCSIIO_CONTROL_READ (0x02000000)
|
||||
#define MPI2_SCSIIO_CONTROL_BIDIRECTIONAL (0x03000000)
|
||||
|
||||
#define MPI2_SCSIIO_CONTROL_TASKPRI_MASK (0x00007800)
|
||||
#define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT (11)
|
||||
/* alternate name for the previous field; called Command Priority in SAM-4 */
|
||||
#define MPI2_SCSIIO_CONTROL_CMDPRI_MASK (0x00007800)
|
||||
#define MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT (11)
|
||||
|
||||
#define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK (0x00000700)
|
||||
#define MPI2_SCSIIO_CONTROL_SIMPLEQ (0x00000000)
|
||||
#define MPI2_SCSIIO_CONTROL_HEADOFQ (0x00000100)
|
||||
#define MPI2_SCSIIO_CONTROL_ORDEREDQ (0x00000200)
|
||||
#define MPI2_SCSIIO_CONTROL_ACAQ (0x00000400)
|
||||
|
||||
#define MPI2_SCSIIO_CONTROL_TLR_MASK (0x000000C0)
|
||||
#define MPI2_SCSIIO_CONTROL_NO_TLR (0x00000000)
|
||||
#define MPI2_SCSIIO_CONTROL_TLR_ON (0x00000040)
|
||||
#define MPI2_SCSIIO_CONTROL_TLR_OFF (0x00000080)
|
||||
|
||||
|
||||
/* SCSI IO Error Reply Message */
|
||||
typedef struct _MPI2_SCSI_IO_REPLY
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved1; /* 0x04 */
|
||||
U8 Reserved2; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved3; /* 0x0A */
|
||||
U8 SCSIStatus; /* 0x0C */
|
||||
U8 SCSIState; /* 0x0D */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U32 TransferCount; /* 0x14 */
|
||||
U32 SenseCount; /* 0x18 */
|
||||
U32 ResponseInfo; /* 0x1C */
|
||||
U16 TaskTag; /* 0x20 */
|
||||
U16 SCSIStatusQualifier; /* 0x22 */
|
||||
U32 BidirectionalTransferCount; /* 0x24 */
|
||||
U32 Reserved5; /* 0x28 */
|
||||
U32 Reserved6; /* 0x2C */
|
||||
} MPI2_SCSI_IO_REPLY, MPI2_POINTER PTR_MPI2_SCSI_IO_REPLY,
|
||||
Mpi2SCSIIOReply_t, MPI2_POINTER pMpi2SCSIIOReply_t;
|
||||
|
||||
/* SCSI IO Reply SCSIStatus values (SAM-4 status codes) */
|
||||
|
||||
#define MPI2_SCSI_STATUS_GOOD (0x00)
|
||||
#define MPI2_SCSI_STATUS_CHECK_CONDITION (0x02)
|
||||
#define MPI2_SCSI_STATUS_CONDITION_MET (0x04)
|
||||
#define MPI2_SCSI_STATUS_BUSY (0x08)
|
||||
#define MPI2_SCSI_STATUS_INTERMEDIATE (0x10)
|
||||
#define MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET (0x14)
|
||||
#define MPI2_SCSI_STATUS_RESERVATION_CONFLICT (0x18)
|
||||
#define MPI2_SCSI_STATUS_COMMAND_TERMINATED (0x22) /* obsolete */
|
||||
#define MPI2_SCSI_STATUS_TASK_SET_FULL (0x28)
|
||||
#define MPI2_SCSI_STATUS_ACA_ACTIVE (0x30)
|
||||
#define MPI2_SCSI_STATUS_TASK_ABORTED (0x40)
|
||||
|
||||
/* SCSI IO Reply SCSIState flags */
|
||||
|
||||
#define MPI2_SCSI_STATE_RESPONSE_INFO_VALID (0x10)
|
||||
#define MPI2_SCSI_STATE_TERMINATED (0x08)
|
||||
#define MPI2_SCSI_STATE_NO_SCSI_STATUS (0x04)
|
||||
#define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02)
|
||||
#define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01)
|
||||
|
||||
/* masks and shifts for the ResponseInfo field */
|
||||
|
||||
#define MPI2_SCSI_RI_MASK_REASONCODE (0x000000FF)
|
||||
#define MPI2_SCSI_RI_SHIFT_REASONCODE (0)
|
||||
|
||||
#define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* SCSI Task Management messages
|
||||
****************************************************************************/
|
||||
|
||||
/* SCSI Task Management Request Message */
|
||||
typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U8 Reserved1; /* 0x04 */
|
||||
U8 TaskType; /* 0x05 */
|
||||
U8 Reserved2; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved3; /* 0x0A */
|
||||
U8 LUN[8]; /* 0x0C */
|
||||
U32 Reserved4[7]; /* 0x14 */
|
||||
U16 TaskMID; /* 0x30 */
|
||||
U16 Reserved5; /* 0x32 */
|
||||
} MPI2_SCSI_TASK_MANAGE_REQUEST,
|
||||
MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REQUEST,
|
||||
Mpi2SCSITaskManagementRequest_t,
|
||||
MPI2_POINTER pMpi2SCSITaskManagementRequest_t;
|
||||
|
||||
/* TaskType values */
|
||||
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09)
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A)
|
||||
|
||||
/* obsolete TaskType name */
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION \
|
||||
(MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT)
|
||||
|
||||
/* MsgFlags bits */
|
||||
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10)
|
||||
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01)
|
||||
|
||||
|
||||
|
||||
/* SCSI Task Management Reply Message */
|
||||
typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U8 ResponseCode; /* 0x04 */
|
||||
U8 TaskType; /* 0x05 */
|
||||
U8 Reserved1; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U16 Reserved3; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U32 TerminationCount; /* 0x14 */
|
||||
U32 ResponseInfo; /* 0x18 */
|
||||
} MPI2_SCSI_TASK_MANAGE_REPLY,
|
||||
MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY,
|
||||
Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t;
|
||||
|
||||
/* ResponseCode values */
|
||||
|
||||
#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE (0x00)
|
||||
#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME (0x02)
|
||||
#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04)
|
||||
#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05)
|
||||
#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08)
|
||||
#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09)
|
||||
#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A)
|
||||
#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80)
|
||||
|
||||
/* masks and shifts for the ResponseInfo field */
|
||||
|
||||
#define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE (0x000000FF)
|
||||
#define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE (0)
|
||||
#define MPI2_SCSITASKMGMT_RI_MASK_ARI2 (0x0000FF00)
|
||||
#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2 (8)
|
||||
#define MPI2_SCSITASKMGMT_RI_MASK_ARI1 (0x00FF0000)
|
||||
#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1 (16)
|
||||
#define MPI2_SCSITASKMGMT_RI_MASK_ARI0 (0xFF000000)
|
||||
#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0 (24)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* SCSI Enclosure Processor messages
|
||||
****************************************************************************/
|
||||
|
||||
/* SCSI Enclosure Processor Request Message */
|
||||
typedef struct _MPI2_SEP_REQUEST
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U8 Action; /* 0x04 */
|
||||
U8 Flags; /* 0x05 */
|
||||
U8 Reserved1; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U32 SlotStatus; /* 0x0C */
|
||||
U32 Reserved3; /* 0x10 */
|
||||
U32 Reserved4; /* 0x14 */
|
||||
U32 Reserved5; /* 0x18 */
|
||||
U16 Slot; /* 0x1C */
|
||||
U16 EnclosureHandle; /* 0x1E */
|
||||
} MPI2_SEP_REQUEST, MPI2_POINTER PTR_MPI2_SEP_REQUEST,
|
||||
Mpi2SepRequest_t, MPI2_POINTER pMpi2SepRequest_t;
|
||||
|
||||
/* Action defines */
|
||||
#define MPI2_SEP_REQ_ACTION_WRITE_STATUS (0x00)
|
||||
#define MPI2_SEP_REQ_ACTION_READ_STATUS (0x01)
|
||||
|
||||
/* Flags defines */
|
||||
#define MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS (0x00)
|
||||
#define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01)
|
||||
|
||||
/* SlotStatus defines */
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002)
|
||||
#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001)
|
||||
|
||||
|
||||
/* SCSI Enclosure Processor Reply Message */
|
||||
typedef struct _MPI2_SEP_REPLY
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U8 Action; /* 0x04 */
|
||||
U8 Flags; /* 0x05 */
|
||||
U8 Reserved1; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U16 Reserved3; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U32 SlotStatus; /* 0x14 */
|
||||
U32 Reserved4; /* 0x18 */
|
||||
U16 Slot; /* 0x1C */
|
||||
U16 EnclosureHandle; /* 0x1E */
|
||||
} MPI2_SEP_REPLY, MPI2_POINTER PTR_MPI2_SEP_REPLY,
|
||||
Mpi2SepReply_t, MPI2_POINTER pMpi2SepReply_t;
|
||||
|
||||
/* SlotStatus defines */
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002)
|
||||
#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,366 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2014 LSI Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi2_raid.h
|
||||
* Title: MPI Integrated RAID messages and structures
|
||||
* Creation Date: April 26, 2007
|
||||
*
|
||||
* mpi2_raid.h Version: 02.00.10
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
|
||||
* 08-31-07 02.00.01 Modifications to RAID Action request and reply,
|
||||
* including the Actions and ActionData.
|
||||
* 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD.
|
||||
* 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
|
||||
* the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
|
||||
* can be sized by the build environment.
|
||||
* 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
|
||||
* VolumeCreationFlags and marked the old one as obsolete.
|
||||
* 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
|
||||
* 08-24-10 02.00.06 Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with
|
||||
* related structures and defines.
|
||||
* Added product-specific range to RAID Action values.
|
||||
* 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN.
|
||||
* 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
|
||||
* Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
|
||||
* 04-17-13 02.00.10 Added MPI25_RAID_ACTION_ADATA_ALLOW_PI.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI2_RAID_H
|
||||
#define MPI2_RAID_H
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Integrated RAID Messages
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* RAID Action messages
|
||||
****************************************************************************/
|
||||
|
||||
/* ActionDataWord defines for use with MPI2_RAID_ACTION_CREATE_VOLUME action */
|
||||
#define MPI25_RAID_ACTION_ADATA_ALLOW_PI (0x80000000)
|
||||
|
||||
/* ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */
|
||||
#define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000)
|
||||
#define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001)
|
||||
|
||||
/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */
|
||||
|
||||
/* ActionDataWord defines for use with MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */
|
||||
#define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD (0x00000001)
|
||||
|
||||
/* ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */
|
||||
typedef struct _MPI2_RAID_ACTION_RATE_DATA
|
||||
{
|
||||
U8 RateToChange; /* 0x00 */
|
||||
U8 RateOrMode; /* 0x01 */
|
||||
U16 DataScrubDuration; /* 0x02 */
|
||||
} MPI2_RAID_ACTION_RATE_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_RATE_DATA,
|
||||
Mpi2RaidActionRateData_t, MPI2_POINTER pMpi2RaidActionRateData_t;
|
||||
|
||||
#define MPI2_RAID_ACTION_SET_RATE_RESYNC (0x00)
|
||||
#define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB (0x01)
|
||||
#define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE (0x02)
|
||||
|
||||
/* ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */
|
||||
typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION
|
||||
{
|
||||
U8 RAIDFunction; /* 0x00 */
|
||||
U8 Flags; /* 0x01 */
|
||||
U16 Reserved1; /* 0x02 */
|
||||
} MPI2_RAID_ACTION_START_RAID_FUNCTION,
|
||||
MPI2_POINTER PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION,
|
||||
Mpi2RaidActionStartRaidFunction_t,
|
||||
MPI2_POINTER pMpi2RaidActionStartRaidFunction_t;
|
||||
|
||||
/* defines for the RAIDFunction field */
|
||||
#define MPI2_RAID_ACTION_START_BACKGROUND_INIT (0x00)
|
||||
#define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01)
|
||||
#define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK (0x02)
|
||||
|
||||
/* defines for the Flags field */
|
||||
#define MPI2_RAID_ACTION_START_NEW (0x00)
|
||||
#define MPI2_RAID_ACTION_START_RESUME (0x01)
|
||||
|
||||
/* ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */
|
||||
typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION
|
||||
{
|
||||
U8 RAIDFunction; /* 0x00 */
|
||||
U8 Flags; /* 0x01 */
|
||||
U16 Reserved1; /* 0x02 */
|
||||
} MPI2_RAID_ACTION_STOP_RAID_FUNCTION,
|
||||
MPI2_POINTER PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION,
|
||||
Mpi2RaidActionStopRaidFunction_t,
|
||||
MPI2_POINTER pMpi2RaidActionStopRaidFunction_t;
|
||||
|
||||
/* defines for the RAIDFunction field */
|
||||
#define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT (0x00)
|
||||
#define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION (0x01)
|
||||
#define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK (0x02)
|
||||
|
||||
/* defines for the Flags field */
|
||||
#define MPI2_RAID_ACTION_STOP_ABORT (0x00)
|
||||
#define MPI2_RAID_ACTION_STOP_PAUSE (0x01)
|
||||
|
||||
/* ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */
|
||||
typedef struct _MPI2_RAID_ACTION_HOT_SPARE
|
||||
{
|
||||
U8 HotSparePool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U16 DevHandle; /* 0x02 */
|
||||
} MPI2_RAID_ACTION_HOT_SPARE, MPI2_POINTER PTR_MPI2_RAID_ACTION_HOT_SPARE,
|
||||
Mpi2RaidActionHotSpare_t, MPI2_POINTER pMpi2RaidActionHotSpare_t;
|
||||
|
||||
/* ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */
|
||||
typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE
|
||||
{
|
||||
U8 Flags; /* 0x00 */
|
||||
U8 DeviceFirmwareUpdateModeTimeout; /* 0x01 */
|
||||
U16 Reserved1; /* 0x02 */
|
||||
} MPI2_RAID_ACTION_FW_UPDATE_MODE,
|
||||
MPI2_POINTER PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE,
|
||||
Mpi2RaidActionFwUpdateMode_t, MPI2_POINTER pMpi2RaidActionFwUpdateMode_t;
|
||||
|
||||
/* ActionDataWord defines for use with MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */
|
||||
#define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE (0x00)
|
||||
#define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE (0x01)
|
||||
|
||||
typedef union _MPI2_RAID_ACTION_DATA
|
||||
{
|
||||
U32 Word;
|
||||
MPI2_RAID_ACTION_RATE_DATA Rates;
|
||||
MPI2_RAID_ACTION_START_RAID_FUNCTION StartRaidFunction;
|
||||
MPI2_RAID_ACTION_STOP_RAID_FUNCTION StopRaidFunction;
|
||||
MPI2_RAID_ACTION_HOT_SPARE HotSpare;
|
||||
MPI2_RAID_ACTION_FW_UPDATE_MODE FwUpdateMode;
|
||||
} MPI2_RAID_ACTION_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_DATA,
|
||||
Mpi2RaidActionData_t, MPI2_POINTER pMpi2RaidActionData_t;
|
||||
|
||||
|
||||
/* RAID Action Request Message */
|
||||
typedef struct _MPI2_RAID_ACTION_REQUEST
|
||||
{
|
||||
U8 Action; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 VolDevHandle; /* 0x04 */
|
||||
U8 PhysDiskNum; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U32 Reserved3; /* 0x0C */
|
||||
MPI2_RAID_ACTION_DATA ActionDataWord; /* 0x10 */
|
||||
MPI2_SGE_SIMPLE_UNION ActionDataSGE; /* 0x14 */
|
||||
} MPI2_RAID_ACTION_REQUEST, MPI2_POINTER PTR_MPI2_RAID_ACTION_REQUEST,
|
||||
Mpi2RaidActionRequest_t, MPI2_POINTER pMpi2RaidActionRequest_t;
|
||||
|
||||
/* RAID Action request Action values */
|
||||
|
||||
#define MPI2_RAID_ACTION_INDICATOR_STRUCT (0x01)
|
||||
#define MPI2_RAID_ACTION_CREATE_VOLUME (0x02)
|
||||
#define MPI2_RAID_ACTION_DELETE_VOLUME (0x03)
|
||||
#define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES (0x04)
|
||||
#define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES (0x05)
|
||||
#define MPI2_RAID_ACTION_PHYSDISK_OFFLINE (0x0A)
|
||||
#define MPI2_RAID_ACTION_PHYSDISK_ONLINE (0x0B)
|
||||
#define MPI2_RAID_ACTION_FAIL_PHYSDISK (0x0F)
|
||||
#define MPI2_RAID_ACTION_ACTIVATE_VOLUME (0x11)
|
||||
#define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15)
|
||||
#define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE (0x17)
|
||||
#define MPI2_RAID_ACTION_SET_VOLUME_NAME (0x18)
|
||||
#define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE (0x19)
|
||||
#define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME (0x1C)
|
||||
#define MPI2_RAID_ACTION_CREATE_HOT_SPARE (0x1D)
|
||||
#define MPI2_RAID_ACTION_DELETE_HOT_SPARE (0x1E)
|
||||
#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20)
|
||||
#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21)
|
||||
#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22)
|
||||
#define MPI2_RAID_ACTION_COMPATIBILITY_CHECK (0x23)
|
||||
#define MPI2_RAID_ACTION_PHYSDISK_HIDDEN (0x24)
|
||||
#define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC (0x80)
|
||||
#define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC (0xFF)
|
||||
|
||||
/* RAID Volume Creation Structure */
|
||||
|
||||
/*
|
||||
* The following define can be customized for the targeted product.
|
||||
*/
|
||||
#ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS
|
||||
#define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS (1)
|
||||
#endif
|
||||
|
||||
typedef struct _MPI2_RAID_VOLUME_PHYSDISK
|
||||
{
|
||||
U8 RAIDSetNum; /* 0x00 */
|
||||
U8 PhysDiskMap; /* 0x01 */
|
||||
U16 PhysDiskDevHandle; /* 0x02 */
|
||||
} MPI2_RAID_VOLUME_PHYSDISK, MPI2_POINTER PTR_MPI2_RAID_VOLUME_PHYSDISK,
|
||||
Mpi2RaidVolumePhysDisk_t, MPI2_POINTER pMpi2RaidVolumePhysDisk_t;
|
||||
|
||||
/* defines for the PhysDiskMap field */
|
||||
#define MPI2_RAIDACTION_PHYSDISK_PRIMARY (0x01)
|
||||
#define MPI2_RAIDACTION_PHYSDISK_SECONDARY (0x02)
|
||||
|
||||
typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT
|
||||
{
|
||||
U8 NumPhysDisks; /* 0x00 */
|
||||
U8 VolumeType; /* 0x01 */
|
||||
U16 Reserved1; /* 0x02 */
|
||||
U32 VolumeCreationFlags; /* 0x04 */
|
||||
U32 VolumeSettings; /* 0x08 */
|
||||
U8 Reserved2; /* 0x0C */
|
||||
U8 ResyncRate; /* 0x0D */
|
||||
U16 DataScrubDuration; /* 0x0E */
|
||||
U64 VolumeMaxLBA; /* 0x10 */
|
||||
U32 StripeSize; /* 0x18 */
|
||||
U8 Name[16]; /* 0x1C */
|
||||
MPI2_RAID_VOLUME_PHYSDISK PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS];/* 0x2C */
|
||||
} MPI2_RAID_VOLUME_CREATION_STRUCT,
|
||||
MPI2_POINTER PTR_MPI2_RAID_VOLUME_CREATION_STRUCT,
|
||||
Mpi2RaidVolumeCreationStruct_t, MPI2_POINTER pMpi2RaidVolumeCreationStruct_t;
|
||||
|
||||
/* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */
|
||||
|
||||
/* defines for the VolumeCreationFlags field */
|
||||
#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS (0x80000000)
|
||||
#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x00000004)
|
||||
#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x00000002)
|
||||
#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x00000001)
|
||||
/* The following is an obsolete define.
|
||||
* It must be shifted left 24 bits in order to set the proper bit.
|
||||
*/
|
||||
#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80)
|
||||
|
||||
|
||||
/* RAID Online Capacity Expansion Structure */
|
||||
|
||||
typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION
|
||||
{
|
||||
U32 Flags; /* 0x00 */
|
||||
U16 DevHandle0; /* 0x04 */
|
||||
U16 Reserved1; /* 0x06 */
|
||||
U16 DevHandle1; /* 0x08 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
} MPI2_RAID_ONLINE_CAPACITY_EXPANSION,
|
||||
MPI2_POINTER PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION,
|
||||
Mpi2RaidOnlineCapacityExpansion_t,
|
||||
MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t;
|
||||
|
||||
/* RAID Compatibility Input Structure */
|
||||
|
||||
typedef struct _MPI2_RAID_COMPATIBILITY_INPUT_STRUCT {
|
||||
U16 SourceDevHandle; /* 0x00 */
|
||||
U16 CandidateDevHandle; /* 0x02 */
|
||||
U32 Flags; /* 0x04 */
|
||||
U32 Reserved1; /* 0x08 */
|
||||
U32 Reserved2; /* 0x0C */
|
||||
} MPI2_RAID_COMPATIBILITY_INPUT_STRUCT,
|
||||
MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_INPUT_STRUCT,
|
||||
Mpi2RaidCompatibilityInputStruct_t,
|
||||
MPI2_POINTER pMpi2RaidCompatibilityInputStruct_t;
|
||||
|
||||
/* defines for RAID Compatibility Structure Flags field */
|
||||
#define MPI2_RAID_COMPAT_SOURCE_IS_VOLUME_FLAG (0x00000002)
|
||||
#define MPI2_RAID_COMPAT_REPORT_SOURCE_INFO_FLAG (0x00000001)
|
||||
|
||||
|
||||
/* RAID Volume Indicator Structure */
|
||||
|
||||
typedef struct _MPI2_RAID_VOL_INDICATOR
|
||||
{
|
||||
U64 TotalBlocks; /* 0x00 */
|
||||
U64 BlocksRemaining; /* 0x08 */
|
||||
U32 Flags; /* 0x10 */
|
||||
U32 ElapsedSeconds; /* 0x14 */
|
||||
} MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR,
|
||||
Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t;
|
||||
|
||||
/* defines for RAID Volume Indicator Flags field */
|
||||
#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000)
|
||||
|
||||
#define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F)
|
||||
#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000)
|
||||
#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
|
||||
#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002)
|
||||
#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003)
|
||||
#define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004)
|
||||
|
||||
/* RAID Compatibility Result Structure */
|
||||
|
||||
typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT {
|
||||
U8 State; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U16 Reserved2; /* 0x02 */
|
||||
U32 GenericAttributes; /* 0x04 */
|
||||
U32 OEMSpecificAttributes; /* 0x08 */
|
||||
U32 Reserved3; /* 0x0C */
|
||||
U32 Reserved4; /* 0x10 */
|
||||
} MPI2_RAID_COMPATIBILITY_RESULT_STRUCT,
|
||||
MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_RESULT_STRUCT,
|
||||
Mpi2RaidCompatibilityResultStruct_t,
|
||||
MPI2_POINTER pMpi2RaidCompatibilityResultStruct_t;
|
||||
|
||||
/* defines for RAID Compatibility Result Structure State field */
|
||||
#define MPI2_RAID_COMPAT_STATE_COMPATIBLE (0x00)
|
||||
#define MPI2_RAID_COMPAT_STATE_NOT_COMPATIBLE (0x01)
|
||||
|
||||
/* defines for RAID Compatibility Result Structure GenericAttributes field */
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_4K_SECTOR (0x00000010)
|
||||
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_MEDIA_MASK (0x0000000C)
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_SOLID_STATE_DRIVE (0x00000008)
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_HARD_DISK_DRIVE (0x00000004)
|
||||
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_PROTOCOL_MASK (0x00000003)
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_SAS_PROTOCOL (0x00000002)
|
||||
#define MPI2_RAID_COMPAT_GENATTRIB_SATA_PROTOCOL (0x00000001)
|
||||
|
||||
/* RAID Action Reply ActionData union */
|
||||
typedef union _MPI2_RAID_ACTION_REPLY_DATA
|
||||
{
|
||||
U32 Word[6];
|
||||
MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator;
|
||||
U16 VolDevHandle;
|
||||
U8 VolumeState;
|
||||
U8 PhysDiskNum;
|
||||
MPI2_RAID_COMPATIBILITY_RESULT_STRUCT RaidCompatibilityResult;
|
||||
} MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA,
|
||||
Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t;
|
||||
|
||||
/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */
|
||||
|
||||
|
||||
/* RAID Action Reply Message */
|
||||
typedef struct _MPI2_RAID_ACTION_REPLY
|
||||
{
|
||||
U8 Action; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 VolDevHandle; /* 0x04 */
|
||||
U8 PhysDiskNum; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U16 Reserved3; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
MPI2_RAID_ACTION_REPLY_DATA ActionData; /* 0x14 */
|
||||
} MPI2_RAID_ACTION_REPLY, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY,
|
||||
Mpi2RaidActionReply_t, MPI2_POINTER pMpi2RaidActionReply_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,288 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2014 LSI Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi2_sas.h
|
||||
* Title: MPI Serial Attached SCSI structures and definitions
|
||||
* Creation Date: February 9, 2007
|
||||
*
|
||||
* mpi2_sas.h Version: 02.00.05
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
|
||||
* 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit
|
||||
* Control Request.
|
||||
* 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control
|
||||
* Request.
|
||||
* 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST
|
||||
* to MPI2_SGE_IO_UNION since it supports chained SGLs.
|
||||
* 05-12-10 02.00.04 Modified some comments.
|
||||
* 08-11-10 02.00.05 Added NCQ operations to SAS IO Unit Control.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI2_SAS_H
|
||||
#define MPI2_SAS_H
|
||||
|
||||
/*
|
||||
* Values for SASStatus.
|
||||
*/
|
||||
#define MPI2_SASSTATUS_SUCCESS (0x00)
|
||||
#define MPI2_SASSTATUS_UNKNOWN_ERROR (0x01)
|
||||
#define MPI2_SASSTATUS_INVALID_FRAME (0x02)
|
||||
#define MPI2_SASSTATUS_UTC_BAD_DEST (0x03)
|
||||
#define MPI2_SASSTATUS_UTC_BREAK_RECEIVED (0x04)
|
||||
#define MPI2_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05)
|
||||
#define MPI2_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06)
|
||||
#define MPI2_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07)
|
||||
#define MPI2_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08)
|
||||
#define MPI2_SASSTATUS_UTC_WRONG_DESTINATION (0x09)
|
||||
#define MPI2_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A)
|
||||
#define MPI2_SASSTATUS_LONG_INFORMATION_UNIT (0x0B)
|
||||
#define MPI2_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C)
|
||||
#define MPI2_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D)
|
||||
#define MPI2_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E)
|
||||
#define MPI2_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F)
|
||||
#define MPI2_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10)
|
||||
#define MPI2_SASSTATUS_DATA_OFFSET_ERROR (0x11)
|
||||
#define MPI2_SASSTATUS_SDSF_NAK_RECEIVED (0x12)
|
||||
#define MPI2_SASSTATUS_SDSF_CONNECTION_FAILED (0x13)
|
||||
#define MPI2_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14)
|
||||
|
||||
|
||||
/*
|
||||
* Values for the SAS DeviceInfo field used in SAS Device Status Change Event
|
||||
* data and SAS Configuration pages.
|
||||
*/
|
||||
#define MPI2_SAS_DEVICE_INFO_SEP (0x00004000)
|
||||
#define MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)
|
||||
#define MPI2_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)
|
||||
#define MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)
|
||||
#define MPI2_SAS_DEVICE_INFO_SSP_TARGET (0x00000400)
|
||||
#define MPI2_SAS_DEVICE_INFO_STP_TARGET (0x00000200)
|
||||
#define MPI2_SAS_DEVICE_INFO_SMP_TARGET (0x00000100)
|
||||
#define MPI2_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080)
|
||||
#define MPI2_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040)
|
||||
#define MPI2_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020)
|
||||
#define MPI2_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010)
|
||||
#define MPI2_SAS_DEVICE_INFO_SATA_HOST (0x00000008)
|
||||
|
||||
#define MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007)
|
||||
#define MPI2_SAS_DEVICE_INFO_NO_DEVICE (0x00000000)
|
||||
#define MPI2_SAS_DEVICE_INFO_END_DEVICE (0x00000001)
|
||||
#define MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002)
|
||||
#define MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* SAS Messages
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* SMP Passthrough messages
|
||||
****************************************************************************/
|
||||
|
||||
/* SMP Passthrough Request Message */
|
||||
typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST
|
||||
{
|
||||
U8 PassthroughFlags; /* 0x00 */
|
||||
U8 PhysicalPort; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 RequestDataLength; /* 0x04 */
|
||||
U8 SGLFlags; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved1; /* 0x0A */
|
||||
U32 Reserved2; /* 0x0C */
|
||||
U64 SASAddress; /* 0x10 */
|
||||
U32 Reserved3; /* 0x18 */
|
||||
U32 Reserved4; /* 0x1C */
|
||||
MPI2_SIMPLE_SGE_UNION SGL; /* 0x20 */
|
||||
} MPI2_SMP_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REQUEST,
|
||||
Mpi2SmpPassthroughRequest_t, MPI2_POINTER pMpi2SmpPassthroughRequest_t;
|
||||
|
||||
/* values for PassthroughFlags field */
|
||||
#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80)
|
||||
|
||||
/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
|
||||
|
||||
|
||||
/* SMP Passthrough Reply Message */
|
||||
typedef struct _MPI2_SMP_PASSTHROUGH_REPLY
|
||||
{
|
||||
U8 PassthroughFlags; /* 0x00 */
|
||||
U8 PhysicalPort; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 ResponseDataLength; /* 0x04 */
|
||||
U8 SGLFlags; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved1; /* 0x0A */
|
||||
U8 Reserved2; /* 0x0C */
|
||||
U8 SASStatus; /* 0x0D */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U32 Reserved3; /* 0x14 */
|
||||
U8 ResponseData[4]; /* 0x18 */
|
||||
} MPI2_SMP_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REPLY,
|
||||
Mpi2SmpPassthroughReply_t, MPI2_POINTER pMpi2SmpPassthroughReply_t;
|
||||
|
||||
/* values for PassthroughFlags field */
|
||||
#define MPI2_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80)
|
||||
|
||||
/* values for SASStatus field are at the top of this file */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* SATA Passthrough messages
|
||||
****************************************************************************/
|
||||
|
||||
/* SATA Passthrough Request Message */
|
||||
typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 PassthroughFlags; /* 0x04 */
|
||||
U8 SGLFlags; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved1; /* 0x0A */
|
||||
U32 Reserved2; /* 0x0C */
|
||||
U32 Reserved3; /* 0x10 */
|
||||
U32 Reserved4; /* 0x14 */
|
||||
U32 DataLength; /* 0x18 */
|
||||
U8 CommandFIS[20]; /* 0x1C */
|
||||
MPI2_SGE_IO_UNION SGL; /* 0x30 */
|
||||
} MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST,
|
||||
Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t;
|
||||
|
||||
/* values for PassthroughFlags field */
|
||||
#define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100)
|
||||
#define MPI2_SATA_PT_REQ_PT_FLAGS_DMA (0x0020)
|
||||
#define MPI2_SATA_PT_REQ_PT_FLAGS_PIO (0x0010)
|
||||
#define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004)
|
||||
#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002)
|
||||
#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001)
|
||||
|
||||
/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
|
||||
|
||||
|
||||
/* SATA Passthrough Reply Message */
|
||||
typedef struct _MPI2_SATA_PASSTHROUGH_REPLY
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 PassthroughFlags; /* 0x04 */
|
||||
U8 SGLFlags; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved1; /* 0x0A */
|
||||
U8 Reserved2; /* 0x0C */
|
||||
U8 SASStatus; /* 0x0D */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U8 StatusFIS[20]; /* 0x14 */
|
||||
U32 StatusControlRegisters; /* 0x28 */
|
||||
U32 TransferCount; /* 0x2C */
|
||||
} MPI2_SATA_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REPLY,
|
||||
Mpi2SataPassthroughReply_t, MPI2_POINTER pMpi2SataPassthroughReply_t;
|
||||
|
||||
/* values for SASStatus field are at the top of this file */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* SAS IO Unit Control messages
|
||||
****************************************************************************/
|
||||
|
||||
/* SAS IO Unit Control Request Message */
|
||||
typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST
|
||||
{
|
||||
U8 Operation; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 DevHandle; /* 0x04 */
|
||||
U8 IOCParameter; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved3; /* 0x0A */
|
||||
U16 Reserved4; /* 0x0C */
|
||||
U8 PhyNum; /* 0x0E */
|
||||
U8 PrimFlags; /* 0x0F */
|
||||
U32 Primitive; /* 0x10 */
|
||||
U8 LookupMethod; /* 0x14 */
|
||||
U8 Reserved5; /* 0x15 */
|
||||
U16 SlotNumber; /* 0x16 */
|
||||
U64 LookupAddress; /* 0x18 */
|
||||
U32 IOCParameterValue; /* 0x20 */
|
||||
U32 Reserved7; /* 0x24 */
|
||||
U32 Reserved8; /* 0x28 */
|
||||
} MPI2_SAS_IOUNIT_CONTROL_REQUEST,
|
||||
MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REQUEST,
|
||||
Mpi2SasIoUnitControlRequest_t, MPI2_POINTER pMpi2SasIoUnitControlRequest_t;
|
||||
|
||||
/* values for the Operation field */
|
||||
#define MPI2_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
|
||||
#define MPI2_SAS_OP_PHY_LINK_RESET (0x06)
|
||||
#define MPI2_SAS_OP_PHY_HARD_RESET (0x07)
|
||||
#define MPI2_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
|
||||
#define MPI2_SAS_OP_SEND_PRIMITIVE (0x0A)
|
||||
#define MPI2_SAS_OP_FORCE_FULL_DISCOVERY (0x0B)
|
||||
#define MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
|
||||
#define MPI2_SAS_OP_REMOVE_DEVICE (0x0D)
|
||||
#define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E)
|
||||
#define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F)
|
||||
#define MPI2_SAS_OP_DEV_ENABLE_NCQ (0x14)
|
||||
#define MPI2_SAS_OP_DEV_DISABLE_NCQ (0x15)
|
||||
#define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80)
|
||||
|
||||
/* values for the PrimFlags field */
|
||||
#define MPI2_SAS_PRIMFLAGS_SINGLE (0x08)
|
||||
#define MPI2_SAS_PRIMFLAGS_TRIPLE (0x02)
|
||||
#define MPI2_SAS_PRIMFLAGS_REDUNDANT (0x01)
|
||||
|
||||
/* values for the LookupMethod field */
|
||||
#define MPI2_SAS_LOOKUP_METHOD_SAS_ADDRESS (0x01)
|
||||
#define MPI2_SAS_LOOKUP_METHOD_SAS_ENCLOSURE_SLOT (0x02)
|
||||
#define MPI2_SAS_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03)
|
||||
|
||||
|
||||
/* SAS IO Unit Control Reply Message */
|
||||
typedef struct _MPI2_SAS_IOUNIT_CONTROL_REPLY
|
||||
{
|
||||
U8 Operation; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 DevHandle; /* 0x04 */
|
||||
U8 IOCParameter; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved3; /* 0x0A */
|
||||
U16 Reserved4; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
} MPI2_SAS_IOUNIT_CONTROL_REPLY,
|
||||
MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REPLY,
|
||||
Mpi2SasIoUnitControlReply_t, MPI2_POINTER pMpi2SasIoUnitControlReply_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,481 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2014 LSI Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi2_tool.h
|
||||
* Title: MPI diagnostic tool structures and definitions
|
||||
* Creation Date: March 26, 2007
|
||||
*
|
||||
* mpi2_tool.h Version: 02.00.12
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
|
||||
* 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release
|
||||
* structures and defines.
|
||||
* 02-29-08 02.00.02 Modified various names to make them 32-character unique.
|
||||
* 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool.
|
||||
* 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request
|
||||
* and reply messages.
|
||||
* Added MPI2_DIAG_BUF_TYPE_EXTENDED.
|
||||
* Incremented MPI2_DIAG_BUF_TYPE_COUNT.
|
||||
* 05-12-10 02.00.05 Added Diagnostic Data Upload tool.
|
||||
* 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer
|
||||
* Post Request.
|
||||
* 05-25-11 02.00.07 Added Flags field and related defines to
|
||||
* MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST.
|
||||
* 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
|
||||
* it uses MPI Chain SGE as well as MPI Simple SGE.
|
||||
* 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
|
||||
* 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI2_TOOL_H
|
||||
#define MPI2_TOOL_H
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Toolbox Messages
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* defines for the Tools */
|
||||
#define MPI2_TOOLBOX_CLEAN_TOOL (0x00)
|
||||
#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01)
|
||||
#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02)
|
||||
#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03)
|
||||
#define MPI2_TOOLBOX_BEACON_TOOL (0x05)
|
||||
#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06)
|
||||
#define MPI2_TOOLBOX_TEXT_DISPLAY_TOOL (0x07)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox reply
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_TOOLBOX_REPLY
|
||||
{
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U16 Reserved5; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
} MPI2_TOOLBOX_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_REPLY,
|
||||
Mpi2ToolboxReply_t, MPI2_POINTER pMpi2ToolboxReply_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox Clean Tool request
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
|
||||
{
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U32 Flags; /* 0x0C */
|
||||
} MPI2_TOOLBOX_CLEAN_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_CLEAN_REQUEST,
|
||||
Mpi2ToolboxCleanRequest_t, MPI2_POINTER pMpi2ToolboxCleanRequest_t;
|
||||
|
||||
/* values for the Flags field */
|
||||
#define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004)
|
||||
#define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002)
|
||||
#define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox Memory Move request
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
MPI2_SGE_SIMPLE_UNION SGL; /* 0x0C */
|
||||
} MPI2_TOOLBOX_MEM_MOVE_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST,
|
||||
Mpi2ToolboxMemMoveRequest_t, MPI2_POINTER pMpi2ToolboxMemMoveRequest_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox Diagnostic Data Upload request
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U8 SGLFlags; /* 0x0C */
|
||||
U8 Reserved5; /* 0x0D */
|
||||
U16 Reserved6; /* 0x0E */
|
||||
U32 Flags; /* 0x10 */
|
||||
U32 DataLength; /* 0x14 */
|
||||
MPI2_SGE_SIMPLE_UNION SGL; /* 0x18 */
|
||||
} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
|
||||
MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST,
|
||||
Mpi2ToolboxDiagDataUploadRequest_t,
|
||||
MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t;
|
||||
|
||||
/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
|
||||
|
||||
|
||||
typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER {
|
||||
U32 DiagDataLength; /* 00h */
|
||||
U8 FormatCode; /* 04h */
|
||||
U8 Reserved1; /* 05h */
|
||||
U16 Reserved2; /* 06h */
|
||||
} MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER,
|
||||
Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox ISTWI Read Write Tool
|
||||
****************************************************************************/
|
||||
|
||||
/* Toolbox ISTWI Read Write Tool request message */
|
||||
typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U32 Reserved5; /* 0x0C */
|
||||
U32 Reserved6; /* 0x10 */
|
||||
U8 DevIndex; /* 0x14 */
|
||||
U8 Action; /* 0x15 */
|
||||
U8 SGLFlags; /* 0x16 */
|
||||
U8 Flags; /* 0x17 */
|
||||
U16 TxDataLength; /* 0x18 */
|
||||
U16 RxDataLength; /* 0x1A */
|
||||
U32 Reserved8; /* 0x1C */
|
||||
U32 Reserved9; /* 0x20 */
|
||||
U32 Reserved10; /* 0x24 */
|
||||
U32 Reserved11; /* 0x28 */
|
||||
U32 Reserved12; /* 0x2C */
|
||||
MPI2_SGE_SIMPLE_UNION SGL; /* 0x30 */
|
||||
} MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
|
||||
MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
|
||||
Mpi2ToolboxIstwiReadWriteRequest_t,
|
||||
MPI2_POINTER pMpi2ToolboxIstwiReadWriteRequest_t;
|
||||
|
||||
/* values for the Action field */
|
||||
#define MPI2_TOOL_ISTWI_ACTION_READ_DATA (0x01)
|
||||
#define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA (0x02)
|
||||
#define MPI2_TOOL_ISTWI_ACTION_SEQUENCE (0x03)
|
||||
#define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS (0x10)
|
||||
#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11)
|
||||
#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12)
|
||||
|
||||
/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
|
||||
|
||||
/* values for the Flags field */
|
||||
#define MPI2_TOOL_ISTWI_FLAG_AUTO_RESERVE_RELEASE (0x80)
|
||||
#define MPI2_TOOL_ISTWI_FLAG_PAGE_ADDR_MASK (0x07)
|
||||
|
||||
/* Toolbox ISTWI Read Write Tool reply message */
|
||||
typedef struct _MPI2_TOOLBOX_ISTWI_REPLY {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U16 Reserved5; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U8 DevIndex; /* 0x14 */
|
||||
U8 Action; /* 0x15 */
|
||||
U8 IstwiStatus; /* 0x16 */
|
||||
U8 Reserved6; /* 0x17 */
|
||||
U16 TxDataCount; /* 0x18 */
|
||||
U16 RxDataCount; /* 0x1A */
|
||||
} MPI2_TOOLBOX_ISTWI_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_REPLY,
|
||||
Mpi2ToolboxIstwiReply_t, MPI2_POINTER pMpi2ToolboxIstwiReply_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox Beacon Tool request
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_TOOLBOX_BEACON_REQUEST
|
||||
{
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U8 Reserved5; /* 0x0C */
|
||||
U8 PhysicalPort; /* 0x0D */
|
||||
U8 Reserved6; /* 0x0E */
|
||||
U8 Flags; /* 0x0F */
|
||||
} MPI2_TOOLBOX_BEACON_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_BEACON_REQUEST,
|
||||
Mpi2ToolboxBeaconRequest_t, MPI2_POINTER pMpi2ToolboxBeaconRequest_t;
|
||||
|
||||
/* values for the Flags field */
|
||||
#define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF (0x00)
|
||||
#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox Diagnostic CLI Tool
|
||||
****************************************************************************/
|
||||
|
||||
#define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C)
|
||||
|
||||
/* MPI v2.0 Toolbox Diagnostic CLI Tool request message */
|
||||
typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U8 SGLFlags; /* 0x0C */
|
||||
U8 Reserved5; /* 0x0D */
|
||||
U16 Reserved6; /* 0x0E */
|
||||
U32 DataLength; /* 0x10 */
|
||||
U8 DiagnosticCliCommand
|
||||
[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH]; /* 0x14 */
|
||||
MPI2_MPI_SGE_IO_UNION SGL; /* 0x70 */
|
||||
} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
|
||||
MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
|
||||
Mpi2ToolboxDiagnosticCliRequest_t,
|
||||
MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t;
|
||||
|
||||
/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
|
||||
|
||||
|
||||
/* Toolbox Diagnostic CLI Tool reply message */
|
||||
typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U16 Reserved5; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U32 ReturnedDataLength; /* 0x14 */
|
||||
} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY,
|
||||
MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY,
|
||||
Mpi2ToolboxDiagnosticCliReply_t,
|
||||
MPI2_POINTER pMpi2ToolboxDiagnosticCliReply_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Toolbox Console Text Display Tool
|
||||
****************************************************************************/
|
||||
|
||||
/* Toolbox Console Text Display Tool request message */
|
||||
typedef struct _MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST {
|
||||
U8 Tool; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U8 Console; /* 0x0C */
|
||||
U8 Flags; /* 0x0D */
|
||||
U16 Reserved6; /* 0x0E */
|
||||
U8 TextToDisplay[4]; /* 0x10 */
|
||||
} MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST,
|
||||
MPI2_POINTER PTR_MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST,
|
||||
Mpi2ToolboxTextDisplayRequest_t,
|
||||
MPI2_POINTER pMpi2ToolboxTextDisplayRequest_t;
|
||||
|
||||
/* defines for the Console field */
|
||||
#define MPI2_TOOLBOX_CONSOLE_TYPE_MASK (0xF0)
|
||||
#define MPI2_TOOLBOX_CONSOLE_TYPE_DEFAULT (0x00)
|
||||
#define MPI2_TOOLBOX_CONSOLE_TYPE_UART (0x10)
|
||||
#define MPI2_TOOLBOX_CONSOLE_TYPE_ETHERNET (0x20)
|
||||
|
||||
#define MPI2_TOOLBOX_CONSOLE_NUMBER_MASK (0x0F)
|
||||
|
||||
/* defines for the Flags field */
|
||||
#define MPI2_TOOLBOX_CONSOLE_FLAG_TIMESTAMP (0x01)
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Diagnostic Buffer Messages
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Diagnostic Buffer Post request
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST
|
||||
{
|
||||
U8 ExtendedType; /* 0x00 */
|
||||
U8 BufferType; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U64 BufferAddress; /* 0x0C */
|
||||
U32 BufferLength; /* 0x14 */
|
||||
U32 Reserved5; /* 0x18 */
|
||||
U32 Reserved6; /* 0x1C */
|
||||
U32 Flags; /* 0x20 */
|
||||
U32 ProductSpecific[23]; /* 0x24 */
|
||||
} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST,
|
||||
Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t;
|
||||
|
||||
/* values for the ExtendedType field */
|
||||
#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02)
|
||||
|
||||
/* values for the BufferType field */
|
||||
#define MPI2_DIAG_BUF_TYPE_TRACE (0x00)
|
||||
#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01)
|
||||
#define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02)
|
||||
/* count of the number of buffer types */
|
||||
#define MPI2_DIAG_BUF_TYPE_COUNT (0x03)
|
||||
|
||||
/* values for the Flags field */
|
||||
#define MPI2_DIAG_BUF_FLAG_RELEASE_ON_FULL (0x00000002)
|
||||
#define MPI2_DIAG_BUF_FLAG_IMMEDIATE_RELEASE (0x00000001)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Diagnostic Buffer Post reply
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_DIAG_BUFFER_POST_REPLY
|
||||
{
|
||||
U8 ExtendedType; /* 0x00 */
|
||||
U8 BufferType; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U16 Reserved5; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U32 TransferLength; /* 0x14 */
|
||||
} MPI2_DIAG_BUFFER_POST_REPLY, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REPLY,
|
||||
Mpi2DiagBufferPostReply_t, MPI2_POINTER pMpi2DiagBufferPostReply_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Diagnostic Release request
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_DIAG_RELEASE_REQUEST
|
||||
{
|
||||
U8 Reserved1; /* 0x00 */
|
||||
U8 BufferType; /* 0x01 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
} MPI2_DIAG_RELEASE_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REQUEST,
|
||||
Mpi2DiagReleaseRequest_t, MPI2_POINTER pMpi2DiagReleaseRequest_t;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Diagnostic Buffer Post reply
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct _MPI2_DIAG_RELEASE_REPLY
|
||||
{
|
||||
U8 Reserved1; /* 0x00 */
|
||||
U8 BufferType; /* 0x01 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 Reserved2; /* 0x04 */
|
||||
U8 Reserved3; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved4; /* 0x0A */
|
||||
U16 Reserved5; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
} MPI2_DIAG_RELEASE_REPLY, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REPLY,
|
||||
Mpi2DiagReleaseReply_t, MPI2_POINTER pMpi2DiagReleaseReply_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2014 LSI Corporation.
|
||||
*
|
||||
*
|
||||
* Name: mpi2_type.h
|
||||
* Title: MPI basic type definitions
|
||||
* Creation Date: August 16, 2006
|
||||
*
|
||||
* mpi2_type.h Version: 02.00.00
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI2_TYPE_H
|
||||
#define MPI2_TYPE_H
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Define MPI2_POINTER if it hasn't already been defined. By default
|
||||
* MPI2_POINTER is defined to be a near pointer. MPI2_POINTER can be defined as
|
||||
* a far pointer by defining MPI2_POINTER as "far *" before this header file is
|
||||
* included.
|
||||
*/
|
||||
#ifndef MPI2_POINTER
|
||||
#define MPI2_POINTER *
|
||||
#endif
|
||||
|
||||
/* the basic types may have already been included by mpi_type.h */
|
||||
#ifndef MPI_TYPE_H
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Basic Types
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
typedef u8 U8;
|
||||
typedef __le16 U16;
|
||||
typedef __le32 U32;
|
||||
typedef __le64 U64 __attribute__((aligned(4)));
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Pointer Types
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
typedef U8 *PU8;
|
||||
typedef U16 *PU16;
|
||||
typedef U32 *PU32;
|
||||
typedef U64 *PU64;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,419 +0,0 @@
|
|||
/*
|
||||
* Management Module Support for MPT (Message Passing Technology) based
|
||||
* controllers
|
||||
*
|
||||
* This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
|
||||
* Copyright (C) 2007-2014 LSI Corporation
|
||||
* Copyright (C) 20013-2014 Avago Technologies
|
||||
* (mailto: MPT-FusionLinux.pdl@avagotech.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
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef MPT2SAS_CTL_H_INCLUDED
|
||||
#define MPT2SAS_CTL_H_INCLUDED
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/miscdevice.h>
|
||||
#endif
|
||||
|
||||
#define MPT2SAS_DEV_NAME "mpt2ctl"
|
||||
#define MPT2_MAGIC_NUMBER 'L'
|
||||
#define MPT2_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */
|
||||
|
||||
/**
|
||||
* IOCTL opcodes
|
||||
*/
|
||||
#define MPT2IOCINFO _IOWR(MPT2_MAGIC_NUMBER, 17, \
|
||||
struct mpt2_ioctl_iocinfo)
|
||||
#define MPT2COMMAND _IOWR(MPT2_MAGIC_NUMBER, 20, \
|
||||
struct mpt2_ioctl_command)
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define MPT2COMMAND32 _IOWR(MPT2_MAGIC_NUMBER, 20, \
|
||||
struct mpt2_ioctl_command32)
|
||||
#endif
|
||||
#define MPT2EVENTQUERY _IOWR(MPT2_MAGIC_NUMBER, 21, \
|
||||
struct mpt2_ioctl_eventquery)
|
||||
#define MPT2EVENTENABLE _IOWR(MPT2_MAGIC_NUMBER, 22, \
|
||||
struct mpt2_ioctl_eventenable)
|
||||
#define MPT2EVENTREPORT _IOWR(MPT2_MAGIC_NUMBER, 23, \
|
||||
struct mpt2_ioctl_eventreport)
|
||||
#define MPT2HARDRESET _IOWR(MPT2_MAGIC_NUMBER, 24, \
|
||||
struct mpt2_ioctl_diag_reset)
|
||||
#define MPT2BTDHMAPPING _IOWR(MPT2_MAGIC_NUMBER, 31, \
|
||||
struct mpt2_ioctl_btdh_mapping)
|
||||
|
||||
/* diag buffer support */
|
||||
#define MPT2DIAGREGISTER _IOWR(MPT2_MAGIC_NUMBER, 26, \
|
||||
struct mpt2_diag_register)
|
||||
#define MPT2DIAGRELEASE _IOWR(MPT2_MAGIC_NUMBER, 27, \
|
||||
struct mpt2_diag_release)
|
||||
#define MPT2DIAGUNREGISTER _IOWR(MPT2_MAGIC_NUMBER, 28, \
|
||||
struct mpt2_diag_unregister)
|
||||
#define MPT2DIAGQUERY _IOWR(MPT2_MAGIC_NUMBER, 29, \
|
||||
struct mpt2_diag_query)
|
||||
#define MPT2DIAGREADBUFFER _IOWR(MPT2_MAGIC_NUMBER, 30, \
|
||||
struct mpt2_diag_read_buffer)
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_header - main header structure
|
||||
* @ioc_number - IOC unit number
|
||||
* @port_number - IOC port number
|
||||
* @max_data_size - maximum number bytes to transfer on read
|
||||
*/
|
||||
struct mpt2_ioctl_header {
|
||||
uint32_t ioc_number;
|
||||
uint32_t port_number;
|
||||
uint32_t max_data_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_diag_reset - diagnostic reset
|
||||
* @hdr - generic header
|
||||
*/
|
||||
struct mpt2_ioctl_diag_reset {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_pci_info - pci device info
|
||||
* @device - pci device id
|
||||
* @function - pci function id
|
||||
* @bus - pci bus id
|
||||
* @segment_id - pci segment id
|
||||
*/
|
||||
struct mpt2_ioctl_pci_info {
|
||||
union {
|
||||
struct {
|
||||
uint32_t device:5;
|
||||
uint32_t function:3;
|
||||
uint32_t bus:24;
|
||||
} bits;
|
||||
uint32_t word;
|
||||
} u;
|
||||
uint32_t segment_id;
|
||||
};
|
||||
|
||||
|
||||
#define MPT2_IOCTL_INTERFACE_SCSI (0x00)
|
||||
#define MPT2_IOCTL_INTERFACE_FC (0x01)
|
||||
#define MPT2_IOCTL_INTERFACE_FC_IP (0x02)
|
||||
#define MPT2_IOCTL_INTERFACE_SAS (0x03)
|
||||
#define MPT2_IOCTL_INTERFACE_SAS2 (0x04)
|
||||
#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05)
|
||||
#define MPT2_IOCTL_VERSION_LENGTH (32)
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_iocinfo - generic controller info
|
||||
* @hdr - generic header
|
||||
* @adapter_type - type of adapter (spi, fc, sas)
|
||||
* @port_number - port number
|
||||
* @pci_id - PCI Id
|
||||
* @hw_rev - hardware revision
|
||||
* @sub_system_device - PCI subsystem Device ID
|
||||
* @sub_system_vendor - PCI subsystem Vendor ID
|
||||
* @rsvd0 - reserved
|
||||
* @firmware_version - firmware version
|
||||
* @bios_version - BIOS version
|
||||
* @driver_version - driver version - 32 ASCII characters
|
||||
* @rsvd1 - reserved
|
||||
* @scsi_id - scsi id of adapter 0
|
||||
* @rsvd2 - reserved
|
||||
* @pci_information - pci info (2nd revision)
|
||||
*/
|
||||
struct mpt2_ioctl_iocinfo {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t adapter_type;
|
||||
uint32_t port_number;
|
||||
uint32_t pci_id;
|
||||
uint32_t hw_rev;
|
||||
uint32_t subsystem_device;
|
||||
uint32_t subsystem_vendor;
|
||||
uint32_t rsvd0;
|
||||
uint32_t firmware_version;
|
||||
uint32_t bios_version;
|
||||
uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH];
|
||||
uint8_t rsvd1;
|
||||
uint8_t scsi_id;
|
||||
uint16_t rsvd2;
|
||||
struct mpt2_ioctl_pci_info pci_information;
|
||||
};
|
||||
|
||||
|
||||
/* number of event log entries */
|
||||
#define MPT2SAS_CTL_EVENT_LOG_SIZE (50)
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_eventquery - query event count and type
|
||||
* @hdr - generic header
|
||||
* @event_entries - number of events returned by get_event_report
|
||||
* @rsvd - reserved
|
||||
* @event_types - type of events currently being captured
|
||||
*/
|
||||
struct mpt2_ioctl_eventquery {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint16_t event_entries;
|
||||
uint16_t rsvd;
|
||||
uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_eventenable - enable/disable event capturing
|
||||
* @hdr - generic header
|
||||
* @event_types - toggle off/on type of events to be captured
|
||||
*/
|
||||
struct mpt2_ioctl_eventenable {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t event_types[4];
|
||||
};
|
||||
|
||||
#define MPT2_EVENT_DATA_SIZE (192)
|
||||
/**
|
||||
* struct MPT2_IOCTL_EVENTS -
|
||||
* @event - the event that was reported
|
||||
* @context - unique value for each event assigned by driver
|
||||
* @data - event data returned in fw reply message
|
||||
*/
|
||||
struct MPT2_IOCTL_EVENTS {
|
||||
uint32_t event;
|
||||
uint32_t context;
|
||||
uint8_t data[MPT2_EVENT_DATA_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_eventreport - returing event log
|
||||
* @hdr - generic header
|
||||
* @event_data - (see struct MPT2_IOCTL_EVENTS)
|
||||
*/
|
||||
struct mpt2_ioctl_eventreport {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
struct MPT2_IOCTL_EVENTS event_data[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_command - generic mpt firmware passthru ioctl
|
||||
* @hdr - generic header
|
||||
* @timeout - command timeout in seconds. (if zero then use driver default
|
||||
* value).
|
||||
* @reply_frame_buf_ptr - reply location
|
||||
* @data_in_buf_ptr - destination for read
|
||||
* @data_out_buf_ptr - data source for write
|
||||
* @sense_data_ptr - sense data location
|
||||
* @max_reply_bytes - maximum number of reply bytes to be sent to app.
|
||||
* @data_in_size - number bytes for data transfer in (read)
|
||||
* @data_out_size - number bytes for data transfer out (write)
|
||||
* @max_sense_bytes - maximum number of bytes for auto sense buffers
|
||||
* @data_sge_offset - offset in words from the start of the request message to
|
||||
* the first SGL
|
||||
* @mf[1];
|
||||
*/
|
||||
struct mpt2_ioctl_command {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t timeout;
|
||||
void __user *reply_frame_buf_ptr;
|
||||
void __user *data_in_buf_ptr;
|
||||
void __user *data_out_buf_ptr;
|
||||
void __user *sense_data_ptr;
|
||||
uint32_t max_reply_bytes;
|
||||
uint32_t data_in_size;
|
||||
uint32_t data_out_size;
|
||||
uint32_t max_sense_bytes;
|
||||
uint32_t data_sge_offset;
|
||||
uint8_t mf[1];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct mpt2_ioctl_command32 {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t timeout;
|
||||
uint32_t reply_frame_buf_ptr;
|
||||
uint32_t data_in_buf_ptr;
|
||||
uint32_t data_out_buf_ptr;
|
||||
uint32_t sense_data_ptr;
|
||||
uint32_t max_reply_bytes;
|
||||
uint32_t data_in_size;
|
||||
uint32_t data_out_size;
|
||||
uint32_t max_sense_bytes;
|
||||
uint32_t data_sge_offset;
|
||||
uint8_t mf[1];
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct mpt2_ioctl_btdh_mapping - mapping info
|
||||
* @hdr - generic header
|
||||
* @id - target device identification number
|
||||
* @bus - SCSI bus number that the target device exists on
|
||||
* @handle - device handle for the target device
|
||||
* @rsvd - reserved
|
||||
*
|
||||
* To obtain a bus/id the application sets
|
||||
* handle to valid handle, and bus/id to 0xFFFF.
|
||||
*
|
||||
* To obtain the device handle the application sets
|
||||
* bus/id valid value, and the handle to 0xFFFF.
|
||||
*/
|
||||
struct mpt2_ioctl_btdh_mapping {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t id;
|
||||
uint32_t bus;
|
||||
uint16_t handle;
|
||||
uint16_t rsvd;
|
||||
};
|
||||
|
||||
|
||||
/* status bits for ioc->diag_buffer_status */
|
||||
#define MPT2_DIAG_BUFFER_IS_REGISTERED (0x01)
|
||||
#define MPT2_DIAG_BUFFER_IS_RELEASED (0x02)
|
||||
#define MPT2_DIAG_BUFFER_IS_DIAG_RESET (0x04)
|
||||
|
||||
/* application flags for mpt2_diag_register, mpt2_diag_query */
|
||||
#define MPT2_APP_FLAGS_APP_OWNED (0x0001)
|
||||
#define MPT2_APP_FLAGS_BUFFER_VALID (0x0002)
|
||||
#define MPT2_APP_FLAGS_FW_BUFFER_ACCESS (0x0004)
|
||||
|
||||
/* flags for mpt2_diag_read_buffer */
|
||||
#define MPT2_FLAGS_REREGISTER (0x0001)
|
||||
|
||||
#define MPT2_PRODUCT_SPECIFIC_DWORDS 23
|
||||
|
||||
/**
|
||||
* struct mpt2_diag_register - application register with driver
|
||||
* @hdr - generic header
|
||||
* @reserved -
|
||||
* @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
|
||||
* @application_flags - misc flags
|
||||
* @diagnostic_flags - specifies flags affecting command processing
|
||||
* @product_specific - product specific information
|
||||
* @requested_buffer_size - buffers size in bytes
|
||||
* @unique_id - tag specified by application that is used to signal ownership
|
||||
* of the buffer.
|
||||
*
|
||||
* This will allow the driver to setup any required buffers that will be
|
||||
* needed by firmware to communicate with the driver.
|
||||
*/
|
||||
struct mpt2_diag_register {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint8_t reserved;
|
||||
uint8_t buffer_type;
|
||||
uint16_t application_flags;
|
||||
uint32_t diagnostic_flags;
|
||||
uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS];
|
||||
uint32_t requested_buffer_size;
|
||||
uint32_t unique_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_diag_unregister - application unregister with driver
|
||||
* @hdr - generic header
|
||||
* @unique_id - tag uniquely identifies the buffer to be unregistered
|
||||
*
|
||||
* This will allow the driver to cleanup any memory allocated for diag
|
||||
* messages and to free up any resources.
|
||||
*/
|
||||
struct mpt2_diag_unregister {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t unique_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_diag_query - query relevant info associated with diag buffers
|
||||
* @hdr - generic header
|
||||
* @reserved -
|
||||
* @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
|
||||
* @application_flags - misc flags
|
||||
* @diagnostic_flags - specifies flags affecting command processing
|
||||
* @product_specific - product specific information
|
||||
* @total_buffer_size - diag buffer size in bytes
|
||||
* @driver_added_buffer_size - size of extra space appended to end of buffer
|
||||
* @unique_id - unique id associated with this buffer.
|
||||
*
|
||||
* The application will send only buffer_type and unique_id. Driver will
|
||||
* inspect unique_id first, if valid, fill in all the info. If unique_id is
|
||||
* 0x00, the driver will return info specified by Buffer Type.
|
||||
*/
|
||||
struct mpt2_diag_query {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint8_t reserved;
|
||||
uint8_t buffer_type;
|
||||
uint16_t application_flags;
|
||||
uint32_t diagnostic_flags;
|
||||
uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS];
|
||||
uint32_t total_buffer_size;
|
||||
uint32_t driver_added_buffer_size;
|
||||
uint32_t unique_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_diag_release - request to send Diag Release Message to firmware
|
||||
* @hdr - generic header
|
||||
* @unique_id - tag uniquely identifies the buffer to be released
|
||||
*
|
||||
* This allows ownership of the specified buffer to returned to the driver,
|
||||
* allowing an application to read the buffer without fear that firmware is
|
||||
* overwritting information in the buffer.
|
||||
*/
|
||||
struct mpt2_diag_release {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint32_t unique_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mpt2_diag_read_buffer - request for copy of the diag buffer
|
||||
* @hdr - generic header
|
||||
* @status -
|
||||
* @reserved -
|
||||
* @flags - misc flags
|
||||
* @starting_offset - starting offset within drivers buffer where to start
|
||||
* reading data at into the specified application buffer
|
||||
* @bytes_to_read - number of bytes to copy from the drivers buffer into the
|
||||
* application buffer starting at starting_offset.
|
||||
* @unique_id - unique id associated with this buffer.
|
||||
* @diagnostic_data - data payload
|
||||
*/
|
||||
struct mpt2_diag_read_buffer {
|
||||
struct mpt2_ioctl_header hdr;
|
||||
uint8_t status;
|
||||
uint8_t reserved;
|
||||
uint16_t flags;
|
||||
uint32_t starting_offset;
|
||||
uint32_t bytes_to_read;
|
||||
uint32_t unique_id;
|
||||
uint32_t diagnostic_data[1];
|
||||
};
|
||||
|
||||
#endif /* MPT2SAS_CTL_H_INCLUDED */
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* Logging Support for MPT (Message Passing Technology) based controllers
|
||||
*
|
||||
* This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
|
||||
* Copyright (C) 2007-2014 LSI Corporation
|
||||
* Copyright (C) 20013-2014 Avago Technologies
|
||||
* (mailto: MPT-FusionLinux.pdl@avagotech.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
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef MPT2SAS_DEBUG_H_INCLUDED
|
||||
#define MPT2SAS_DEBUG_H_INCLUDED
|
||||
|
||||
#define MPT_DEBUG 0x00000001
|
||||
#define MPT_DEBUG_MSG_FRAME 0x00000002
|
||||
#define MPT_DEBUG_SG 0x00000004
|
||||
#define MPT_DEBUG_EVENTS 0x00000008
|
||||
#define MPT_DEBUG_EVENT_WORK_TASK 0x00000010
|
||||
#define MPT_DEBUG_INIT 0x00000020
|
||||
#define MPT_DEBUG_EXIT 0x00000040
|
||||
#define MPT_DEBUG_FAIL 0x00000080
|
||||
#define MPT_DEBUG_TM 0x00000100
|
||||
#define MPT_DEBUG_REPLY 0x00000200
|
||||
#define MPT_DEBUG_HANDSHAKE 0x00000400
|
||||
#define MPT_DEBUG_CONFIG 0x00000800
|
||||
#define MPT_DEBUG_DL 0x00001000
|
||||
#define MPT_DEBUG_RESET 0x00002000
|
||||
#define MPT_DEBUG_SCSI 0x00004000
|
||||
#define MPT_DEBUG_IOCTL 0x00008000
|
||||
#define MPT_DEBUG_CSMISAS 0x00010000
|
||||
#define MPT_DEBUG_SAS 0x00020000
|
||||
#define MPT_DEBUG_TRANSPORT 0x00040000
|
||||
#define MPT_DEBUG_TASK_SET_FULL 0x00080000
|
||||
|
||||
#define MPT_DEBUG_TARGET_MODE 0x00100000
|
||||
|
||||
|
||||
/*
|
||||
* CONFIG_SCSI_MPT2SAS_LOGGING - enabled in Kconfig
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
|
||||
#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \
|
||||
{ \
|
||||
if (IOC->logging_level & BITS) \
|
||||
CMD; \
|
||||
}
|
||||
#else
|
||||
#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
|
||||
#endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
|
||||
|
||||
|
||||
/*
|
||||
* debug macros
|
||||
*/
|
||||
|
||||
#define dprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG)
|
||||
|
||||
#define dsgprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SG)
|
||||
|
||||
#define devtprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENTS)
|
||||
|
||||
#define dewtprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENT_WORK_TASK)
|
||||
|
||||
#define dinitprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_INIT)
|
||||
|
||||
#define dexitprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EXIT)
|
||||
|
||||
#define dfailprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_FAIL)
|
||||
|
||||
#define dtmprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TM)
|
||||
|
||||
#define dreplyprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_REPLY)
|
||||
|
||||
#define dhsprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_HANDSHAKE)
|
||||
|
||||
#define dcprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CONFIG)
|
||||
|
||||
#define ddlprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_DL)
|
||||
|
||||
#define drsprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_RESET)
|
||||
|
||||
#define dsprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SCSI)
|
||||
|
||||
#define dctlprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_IOCTL)
|
||||
|
||||
#define dcsmisasprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CSMISAS)
|
||||
|
||||
#define dsasprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS)
|
||||
|
||||
#define dsastransport(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE)
|
||||
|
||||
#define dmfprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_MSG_FRAME)
|
||||
|
||||
#define dtsfprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TASK_SET_FULL)
|
||||
|
||||
#define dtransportprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRANSPORT)
|
||||
|
||||
#define dTMprintk(IOC, CMD) \
|
||||
MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TARGET_MODE)
|
||||
|
||||
/* inline functions for dumping debug data*/
|
||||
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
|
||||
/**
|
||||
* _debug_dump_mf - print message frame contents
|
||||
* @mpi_request: pointer to message frame
|
||||
* @sz: number of dwords
|
||||
*/
|
||||
static inline void
|
||||
_debug_dump_mf(void *mpi_request, int sz)
|
||||
{
|
||||
int i;
|
||||
__le32 *mfp = (__le32 *)mpi_request;
|
||||
|
||||
printk(KERN_INFO "mf:\n\t");
|
||||
for (i = 0; i < sz; i++) {
|
||||
if (i && ((i % 8) == 0))
|
||||
printk("\n\t");
|
||||
printk("%08x ", le32_to_cpu(mfp[i]));
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
#else
|
||||
#define _debug_dump_mf(mpi_request, sz)
|
||||
#endif /* CONFIG_SCSI_MPT2SAS_LOGGING */
|
||||
|
||||
#endif /* MPT2SAS_DEBUG_H_INCLUDED */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -41,15 +41,15 @@
|
|||
# USA.
|
||||
|
||||
config SCSI_MPT3SAS
|
||||
tristate "LSI MPT Fusion SAS 3.0 Device Driver"
|
||||
tristate "LSI MPT Fusion SAS 3.0 & SAS 2.0 Device Driver"
|
||||
depends on PCI && SCSI
|
||||
select SCSI_SAS_ATTRS
|
||||
select RAID_ATTRS
|
||||
---help---
|
||||
This driver supports PCI-Express SAS 12Gb/s Host Adapters.
|
||||
|
||||
config SCSI_MPT3SAS_MAX_SGE
|
||||
int "LSI MPT Fusion Max number of SG Entries (16 - 256)"
|
||||
config SCSI_MPT2SAS_MAX_SGE
|
||||
int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)"
|
||||
depends on PCI && SCSI && SCSI_MPT3SAS
|
||||
default "128"
|
||||
range 16 256
|
||||
|
@ -60,8 +60,14 @@ config SCSI_MPT3SAS_MAX_SGE
|
|||
can be 256. However, it may decreased down to 16. Decreasing this
|
||||
parameter will reduce memory requirements on a per controller instance.
|
||||
|
||||
config SCSI_MPT3SAS_LOGGING
|
||||
bool "LSI MPT Fusion logging facility"
|
||||
config SCSI_MPT3SAS_MAX_SGE
|
||||
int "LSI MPT Fusion SAS 3.0 Max number of SG Entries (16 - 256)"
|
||||
depends on PCI && SCSI && SCSI_MPT3SAS
|
||||
default "128"
|
||||
range 16 256
|
||||
---help---
|
||||
This turns on a logging facility.
|
||||
This option allows you to specify the maximum number of scatter-
|
||||
gather entries per I/O. The driver default is 128, which matches
|
||||
MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this
|
||||
can be 256. However, it may decreased down to 16. Decreasing this
|
||||
parameter will reduce memory requirements on a per controller instance.
|
||||
|
|
|
@ -5,4 +5,5 @@ mpt3sas-y += mpt3sas_base.o \
|
|||
mpt3sas_scsih.o \
|
||||
mpt3sas_transport.o \
|
||||
mpt3sas_ctl.o \
|
||||
mpt3sas_trigger_diag.o
|
||||
mpt3sas_trigger_diag.o \
|
||||
mpt3sas_warpdrive.o
|
||||
|
|
|
@ -108,9 +108,12 @@ _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* global ioc spinlock to protect controller list on list operations */
|
||||
pr_info("setting fwfault_debug(%d)\n", mpt3sas_fwfault_debug);
|
||||
spin_lock(&gioc_lock);
|
||||
list_for_each_entry(ioc, &mpt3sas_ioc_list, list)
|
||||
ioc->fwfault_debug = mpt3sas_fwfault_debug;
|
||||
spin_unlock(&gioc_lock);
|
||||
return 0;
|
||||
}
|
||||
module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug,
|
||||
|
@ -157,7 +160,7 @@ _base_fault_reset_work(struct work_struct *work)
|
|||
|
||||
|
||||
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
|
||||
if (ioc->shost_recovery)
|
||||
if (ioc->shost_recovery || ioc->pci_error_recovery)
|
||||
goto rearm_timer;
|
||||
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
|
||||
|
||||
|
@ -166,6 +169,20 @@ _base_fault_reset_work(struct work_struct *work)
|
|||
pr_err(MPT3SAS_FMT "SAS host is non-operational !!!!\n",
|
||||
ioc->name);
|
||||
|
||||
/* It may be possible that EEH recovery can resolve some of
|
||||
* pci bus failure issues rather removing the dead ioc function
|
||||
* by considering controller is in a non-operational state. So
|
||||
* here priority is given to the EEH recovery. If it doesn't
|
||||
* not resolve this issue, mpt3sas driver will consider this
|
||||
* controller to non-operational state and remove the dead ioc
|
||||
* function.
|
||||
*/
|
||||
if (ioc->non_operational_loop++ < 5) {
|
||||
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock,
|
||||
flags);
|
||||
goto rearm_timer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call _scsih_flush_pending_cmds callback so that we flush all
|
||||
* pending commands back to OS. This call is required to aovid
|
||||
|
@ -181,7 +198,7 @@ _base_fault_reset_work(struct work_struct *work)
|
|||
ioc->remove_host = 1;
|
||||
/*Remove the Dead Host */
|
||||
p = kthread_run(mpt3sas_remove_dead_ioc_func, ioc,
|
||||
"mpt3sas_dead_ioc_%d", ioc->id);
|
||||
"%s_dead_ioc_%d", ioc->driver_name, ioc->id);
|
||||
if (IS_ERR(p))
|
||||
pr_err(MPT3SAS_FMT
|
||||
"%s: Running mpt3sas_dead_ioc thread failed !!!!\n",
|
||||
|
@ -193,6 +210,8 @@ _base_fault_reset_work(struct work_struct *work)
|
|||
return; /* don't rearm timer */
|
||||
}
|
||||
|
||||
ioc->non_operational_loop = 0;
|
||||
|
||||
if ((doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) {
|
||||
rc = mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||
FORCE_BIG_HAMMER);
|
||||
|
@ -235,7 +254,8 @@ mpt3sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc)
|
|||
|
||||
INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
|
||||
snprintf(ioc->fault_reset_work_q_name,
|
||||
sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
|
||||
sizeof(ioc->fault_reset_work_q_name), "poll_%s%d_status",
|
||||
ioc->driver_name, ioc->id);
|
||||
ioc->fault_reset_work_q =
|
||||
create_singlethread_workqueue(ioc->fault_reset_work_q_name);
|
||||
if (!ioc->fault_reset_work_q) {
|
||||
|
@ -324,7 +344,6 @@ mpt3sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc)
|
|||
panic("panic in %s\n", __func__);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
/**
|
||||
* _base_sas_ioc_info - verbose translation of the ioc status
|
||||
* @ioc: per adapter object
|
||||
|
@ -578,7 +597,8 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
|
|||
desc = "Device Status Change";
|
||||
break;
|
||||
case MPI2_EVENT_IR_OPERATION_STATUS:
|
||||
desc = "IR Operation Status";
|
||||
if (!ioc->hide_ir_msg)
|
||||
desc = "IR Operation Status";
|
||||
break;
|
||||
case MPI2_EVENT_SAS_DISCOVERY:
|
||||
{
|
||||
|
@ -609,16 +629,20 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
|
|||
desc = "SAS Enclosure Device Status Change";
|
||||
break;
|
||||
case MPI2_EVENT_IR_VOLUME:
|
||||
desc = "IR Volume";
|
||||
if (!ioc->hide_ir_msg)
|
||||
desc = "IR Volume";
|
||||
break;
|
||||
case MPI2_EVENT_IR_PHYSICAL_DISK:
|
||||
desc = "IR Physical Disk";
|
||||
if (!ioc->hide_ir_msg)
|
||||
desc = "IR Physical Disk";
|
||||
break;
|
||||
case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
|
||||
desc = "IR Configuration Change List";
|
||||
if (!ioc->hide_ir_msg)
|
||||
desc = "IR Configuration Change List";
|
||||
break;
|
||||
case MPI2_EVENT_LOG_ENTRY_ADDED:
|
||||
desc = "Log Entry Added";
|
||||
if (!ioc->hide_ir_msg)
|
||||
desc = "Log Entry Added";
|
||||
break;
|
||||
case MPI2_EVENT_TEMP_THRESHOLD:
|
||||
desc = "Temperature Threshold";
|
||||
|
@ -630,7 +654,6 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
|
|||
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name, desc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* _base_sas_log_info - verbose translation of firmware log info
|
||||
|
@ -675,7 +698,10 @@ _base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info)
|
|||
originator_str = "PL";
|
||||
break;
|
||||
case 2:
|
||||
originator_str = "IR";
|
||||
if (!ioc->hide_ir_msg)
|
||||
originator_str = "IR";
|
||||
else
|
||||
originator_str = "WarpDrive";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -710,13 +736,13 @@ _base_display_reply_info(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||
return;
|
||||
}
|
||||
ioc_status = le16_to_cpu(mpi_reply->IOCStatus);
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
|
||||
if ((ioc_status & MPI2_IOCSTATUS_MASK) &&
|
||||
(ioc->logging_level & MPT_DEBUG_REPLY)) {
|
||||
_base_sas_ioc_info(ioc , mpi_reply,
|
||||
mpt3sas_base_get_msg_frame(ioc, smid));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
|
||||
loginfo = le32_to_cpu(mpi_reply->IOCLogInfo);
|
||||
_base_sas_log_info(ioc, loginfo);
|
||||
|
@ -783,9 +809,9 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
|
|||
return 1;
|
||||
if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
|
||||
return 1;
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
|
||||
_base_display_event_data(ioc, mpi_reply);
|
||||
#endif
|
||||
|
||||
if (!(mpi_reply->AckRequired & MPI2_EVENT_NOTIFICATION_ACK_REQUIRED))
|
||||
goto out;
|
||||
smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
|
||||
|
@ -1009,6 +1035,12 @@ _base_interrupt(int irq, void *bus_id)
|
|||
}
|
||||
|
||||
wmb();
|
||||
if (ioc->is_warpdrive) {
|
||||
writel(reply_q->reply_post_host_index,
|
||||
ioc->reply_post_host_index[msix_index]);
|
||||
atomic_dec(&reply_q->busy);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Update Reply Post Host Index.
|
||||
* For those HBA's which support combined reply queue feature
|
||||
|
@ -1319,6 +1351,149 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
|
|||
_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* _base_build_sg_scmd - main sg creation routine
|
||||
* @ioc: per adapter object
|
||||
* @scmd: scsi command
|
||||
* @smid: system request message index
|
||||
* Context: none.
|
||||
*
|
||||
* The main routine that builds scatter gather table from a given
|
||||
* scsi request sent via the .queuecommand main handler.
|
||||
*
|
||||
* Returns 0 success, anything else error
|
||||
*/
|
||||
static int
|
||||
_base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
|
||||
struct scsi_cmnd *scmd, u16 smid)
|
||||
{
|
||||
Mpi2SCSIIORequest_t *mpi_request;
|
||||
dma_addr_t chain_dma;
|
||||
struct scatterlist *sg_scmd;
|
||||
void *sg_local, *chain;
|
||||
u32 chain_offset;
|
||||
u32 chain_length;
|
||||
u32 chain_flags;
|
||||
int sges_left;
|
||||
u32 sges_in_segment;
|
||||
u32 sgl_flags;
|
||||
u32 sgl_flags_last_element;
|
||||
u32 sgl_flags_end_buffer;
|
||||
struct chain_tracker *chain_req;
|
||||
|
||||
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
||||
|
||||
/* init scatter gather flags */
|
||||
sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT;
|
||||
if (scmd->sc_data_direction == DMA_TO_DEVICE)
|
||||
sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC;
|
||||
sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT)
|
||||
<< MPI2_SGE_FLAGS_SHIFT;
|
||||
sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT |
|
||||
MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST)
|
||||
<< MPI2_SGE_FLAGS_SHIFT;
|
||||
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
|
||||
|
||||
sg_scmd = scsi_sglist(scmd);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
if (sges_left < 0) {
|
||||
sdev_printk(KERN_ERR, scmd->device,
|
||||
"pci_map_sg failed: request for %d bytes!\n",
|
||||
scsi_bufflen(scmd));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sg_local = &mpi_request->SGL;
|
||||
sges_in_segment = ioc->max_sges_in_main_message;
|
||||
if (sges_left <= sges_in_segment)
|
||||
goto fill_in_last_segment;
|
||||
|
||||
mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) +
|
||||
(sges_in_segment * ioc->sge_size))/4;
|
||||
|
||||
/* fill in main message segment when there is a chain following */
|
||||
while (sges_in_segment) {
|
||||
if (sges_in_segment == 1)
|
||||
ioc->base_add_sg_single(sg_local,
|
||||
sgl_flags_last_element | sg_dma_len(sg_scmd),
|
||||
sg_dma_address(sg_scmd));
|
||||
else
|
||||
ioc->base_add_sg_single(sg_local, sgl_flags |
|
||||
sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
|
||||
sg_scmd = sg_next(sg_scmd);
|
||||
sg_local += ioc->sge_size;
|
||||
sges_left--;
|
||||
sges_in_segment--;
|
||||
}
|
||||
|
||||
/* initializing the chain flags and pointers */
|
||||
chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT;
|
||||
chain_req = _base_get_chain_buffer_tracker(ioc, smid);
|
||||
if (!chain_req)
|
||||
return -1;
|
||||
chain = chain_req->chain_buffer;
|
||||
chain_dma = chain_req->chain_buffer_dma;
|
||||
do {
|
||||
sges_in_segment = (sges_left <=
|
||||
ioc->max_sges_in_chain_message) ? sges_left :
|
||||
ioc->max_sges_in_chain_message;
|
||||
chain_offset = (sges_left == sges_in_segment) ?
|
||||
0 : (sges_in_segment * ioc->sge_size)/4;
|
||||
chain_length = sges_in_segment * ioc->sge_size;
|
||||
if (chain_offset) {
|
||||
chain_offset = chain_offset <<
|
||||
MPI2_SGE_CHAIN_OFFSET_SHIFT;
|
||||
chain_length += ioc->sge_size;
|
||||
}
|
||||
ioc->base_add_sg_single(sg_local, chain_flags | chain_offset |
|
||||
chain_length, chain_dma);
|
||||
sg_local = chain;
|
||||
if (!chain_offset)
|
||||
goto fill_in_last_segment;
|
||||
|
||||
/* fill in chain segments */
|
||||
while (sges_in_segment) {
|
||||
if (sges_in_segment == 1)
|
||||
ioc->base_add_sg_single(sg_local,
|
||||
sgl_flags_last_element |
|
||||
sg_dma_len(sg_scmd),
|
||||
sg_dma_address(sg_scmd));
|
||||
else
|
||||
ioc->base_add_sg_single(sg_local, sgl_flags |
|
||||
sg_dma_len(sg_scmd),
|
||||
sg_dma_address(sg_scmd));
|
||||
sg_scmd = sg_next(sg_scmd);
|
||||
sg_local += ioc->sge_size;
|
||||
sges_left--;
|
||||
sges_in_segment--;
|
||||
}
|
||||
|
||||
chain_req = _base_get_chain_buffer_tracker(ioc, smid);
|
||||
if (!chain_req)
|
||||
return -1;
|
||||
chain = chain_req->chain_buffer;
|
||||
chain_dma = chain_req->chain_buffer_dma;
|
||||
} while (1);
|
||||
|
||||
|
||||
fill_in_last_segment:
|
||||
|
||||
/* fill the last segment */
|
||||
while (sges_left) {
|
||||
if (sges_left == 1)
|
||||
ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer |
|
||||
sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
|
||||
else
|
||||
ioc->base_add_sg_single(sg_local, sgl_flags |
|
||||
sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));
|
||||
sg_scmd = sg_next(sg_scmd);
|
||||
sg_local += ioc->sge_size;
|
||||
sges_left--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _base_build_sg_scmd_ieee - main sg creation routine for IEEE format
|
||||
* @ioc: per adapter object
|
||||
|
@ -1571,6 +1746,14 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
|
|||
int base;
|
||||
u16 message_control;
|
||||
|
||||
/* Check whether controller SAS2008 B0 controller,
|
||||
* if it is SAS2008 B0 controller use IO-APIC instead of MSIX
|
||||
*/
|
||||
if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 &&
|
||||
ioc->pdev->revision == SAS2_PCI_DEVICE_B0_REVISION) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
|
||||
if (!base) {
|
||||
dfailprintk(ioc, pr_info(MPT3SAS_FMT "msix not supported\n",
|
||||
|
@ -1579,9 +1762,19 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
|
|||
}
|
||||
|
||||
/* get msix vector count */
|
||||
|
||||
pci_read_config_word(ioc->pdev, base + 2, &message_control);
|
||||
ioc->msix_vector_count = (message_control & 0x3FF) + 1;
|
||||
/* NUMA_IO not supported for older controllers */
|
||||
if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2004 ||
|
||||
ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 ||
|
||||
ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_1 ||
|
||||
ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_2 ||
|
||||
ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_3 ||
|
||||
ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_1 ||
|
||||
ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_2)
|
||||
ioc->msix_vector_count = 1;
|
||||
else {
|
||||
pci_read_config_word(ioc->pdev, base + 2, &message_control);
|
||||
ioc->msix_vector_count = (message_control & 0x3FF) + 1;
|
||||
}
|
||||
dinitprintk(ioc, pr_info(MPT3SAS_FMT
|
||||
"msix is supported, vector_count(%d)\n",
|
||||
ioc->name, ioc->msix_vector_count));
|
||||
|
@ -1643,10 +1836,10 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector)
|
|||
atomic_set(&reply_q->busy, 0);
|
||||
if (ioc->msix_enable)
|
||||
snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d",
|
||||
MPT3SAS_DRIVER_NAME, ioc->id, index);
|
||||
ioc->driver_name, ioc->id, index);
|
||||
else
|
||||
snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d",
|
||||
MPT3SAS_DRIVER_NAME, ioc->id);
|
||||
ioc->driver_name, ioc->id);
|
||||
r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name,
|
||||
reply_q);
|
||||
if (r) {
|
||||
|
@ -1872,7 +2065,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
|
|||
|
||||
|
||||
if (pci_request_selected_regions(pdev, ioc->bars,
|
||||
MPT3SAS_DRIVER_NAME)) {
|
||||
ioc->driver_name)) {
|
||||
pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n",
|
||||
ioc->name);
|
||||
ioc->bars = 0;
|
||||
|
@ -2158,6 +2351,7 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid)
|
|||
}
|
||||
ioc->scsi_lookup[i].cb_idx = 0xFF;
|
||||
ioc->scsi_lookup[i].scmd = NULL;
|
||||
ioc->scsi_lookup[i].direct_io = 0;
|
||||
list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list);
|
||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||
|
||||
|
@ -2318,143 +2512,261 @@ mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid)
|
|||
}
|
||||
|
||||
/**
|
||||
* _base_display_intel_branding - Display branding string
|
||||
* _base_display_OEMs_branding - Display branding string
|
||||
* @ioc: per adapter object
|
||||
*
|
||||
* Return nothing.
|
||||
*/
|
||||
static void
|
||||
_base_display_intel_branding(struct MPT3SAS_ADAPTER *ioc)
|
||||
_base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc)
|
||||
{
|
||||
if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL)
|
||||
return;
|
||||
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI25_MFGPAGE_DEVID_SAS3008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_INTEL_RMS3JC080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RMS3JC080_BRANDING);
|
||||
break;
|
||||
switch (ioc->pdev->subsystem_vendor) {
|
||||
case PCI_VENDOR_ID_INTEL:
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI2_MFGPAGE_DEVID_SAS2008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT2SAS_INTEL_RMS2LL080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS2LL080_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS2LL040_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS2LL040_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_SSD910_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_SSD910_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Intel(R) Controller: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
case MPI2_MFGPAGE_DEVID_SAS2308_2:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT2SAS_INTEL_RS25GB008_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RS25GB008_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS25JB080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS25JB080_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS25JB040_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS25JB040_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS25KB080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS25KB080_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS25KB040_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS25KB040_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS25LB040_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS25LB040_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_INTEL_RMS25LB080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_INTEL_RMS25LB080_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Intel(R) Controller: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
case MPI25_MFGPAGE_DEVID_SAS3008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_INTEL_RMS3JC080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RMS3JC080_BRANDING);
|
||||
break;
|
||||
|
||||
case MPT3SAS_INTEL_RS3GC008_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RS3GC008_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_INTEL_RS3FC044_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RS3FC044_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_INTEL_RS3UC080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RS3UC080_BRANDING);
|
||||
case MPT3SAS_INTEL_RS3GC008_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RS3GC008_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_INTEL_RS3FC044_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RS3FC044_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_INTEL_RS3UC080_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_INTEL_RS3UC080_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Intel(R) Controller: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Intel(R) Controller: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Intel(R) Controller: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* _base_display_dell_branding - Display branding string
|
||||
* @ioc: per adapter object
|
||||
*
|
||||
* Return nothing.
|
||||
*/
|
||||
static void
|
||||
_base_display_dell_branding(struct MPT3SAS_ADAPTER *ioc)
|
||||
{
|
||||
if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_DELL)
|
||||
return;
|
||||
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI25_MFGPAGE_DEVID_SAS3008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_DELL_12G_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_DELL_12G_HBA_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ioc->name,
|
||||
ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ioc->name,
|
||||
ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _base_display_cisco_branding - Display branding string
|
||||
* @ioc: per adapter object
|
||||
*
|
||||
* Return nothing.
|
||||
*/
|
||||
static void
|
||||
_base_display_cisco_branding(struct MPT3SAS_ADAPTER *ioc)
|
||||
{
|
||||
if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_CISCO)
|
||||
return;
|
||||
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI25_MFGPAGE_DEVID_SAS3008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_CISCO_12G_8E_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_8E_HBA_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_CISCO_12G_8I_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_8I_HBA_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MPI25_MFGPAGE_DEVID_SAS3108_1:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
"Intel(R) Controller: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PCI_VENDOR_ID_DELL:
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI2_MFGPAGE_DEVID_SAS2008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_DELL_PERC_H200_MODULAR_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_DELL_PERC_H200_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_PERC_H200_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_DELL_6GBPS_SAS_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_DELL_6GBPS_SAS_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Dell 6Gbps HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MPI25_MFGPAGE_DEVID_SAS3008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_DELL_12G_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_DELL_12G_HBA_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Dell 12Gbps HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Dell HBA: Subsystem ID: 0x%X\n", ioc->name,
|
||||
ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PCI_VENDOR_ID_CISCO:
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI25_MFGPAGE_DEVID_SAS3008:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_CISCO_12G_8E_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_8E_HBA_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_CISCO_12G_8I_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_8I_HBA_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MPI25_MFGPAGE_DEVID_SAS3108_1:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING);
|
||||
break;
|
||||
case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING
|
||||
);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Cisco SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MPT2SAS_HP_3PAR_SSVID:
|
||||
switch (ioc->pdev->device) {
|
||||
case MPI2_MFGPAGE_DEVID_SAS2004:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
case MPI2_MFGPAGE_DEVID_SAS2308_2:
|
||||
switch (ioc->pdev->subsystem_device) {
|
||||
case MPT2SAS_HP_2_4_INTERNAL_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_HP_2_4_INTERNAL_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_HP_2_4_EXTERNAL_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_HP_2_4_EXTERNAL_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING);
|
||||
break;
|
||||
case MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID:
|
||||
pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING);
|
||||
break;
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"HP SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pr_info(MPT3SAS_FMT
|
||||
"Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n",
|
||||
ioc->name, ioc->pdev->subsystem_device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2488,9 +2800,7 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
|
|||
(bios_version & 0x0000FF00) >> 8,
|
||||
bios_version & 0x000000FF);
|
||||
|
||||
_base_display_intel_branding(ioc);
|
||||
_base_display_dell_branding(ioc);
|
||||
_base_display_cisco_branding(ioc);
|
||||
_base_display_OEMs_branding(ioc);
|
||||
|
||||
pr_info(MPT3SAS_FMT "Protocol=(", ioc->name);
|
||||
|
||||
|
@ -2508,10 +2818,12 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
|
|||
pr_info("), ");
|
||||
pr_info("Capabilities=(");
|
||||
|
||||
if (ioc->facts.IOCCapabilities &
|
||||
if (!ioc->hide_ir_msg) {
|
||||
if (ioc->facts.IOCCapabilities &
|
||||
MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
|
||||
pr_info("Raid");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
|
||||
|
@ -2852,18 +3164,22 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
|
|||
/* command line tunables for max sgl entries */
|
||||
if (max_sgl_entries != -1)
|
||||
sg_tablesize = max_sgl_entries;
|
||||
else
|
||||
sg_tablesize = MPT3SAS_SG_DEPTH;
|
||||
else {
|
||||
if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
|
||||
sg_tablesize = MPT2SAS_SG_DEPTH;
|
||||
else
|
||||
sg_tablesize = MPT3SAS_SG_DEPTH;
|
||||
}
|
||||
|
||||
if (sg_tablesize < MPT3SAS_MIN_PHYS_SEGMENTS)
|
||||
sg_tablesize = MPT3SAS_MIN_PHYS_SEGMENTS;
|
||||
else if (sg_tablesize > MPT3SAS_MAX_PHYS_SEGMENTS) {
|
||||
if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS)
|
||||
sg_tablesize = MPT_MIN_PHYS_SEGMENTS;
|
||||
else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) {
|
||||
sg_tablesize = min_t(unsigned short, sg_tablesize,
|
||||
SCSI_MAX_SG_CHAIN_SEGMENTS);
|
||||
pr_warn(MPT3SAS_FMT
|
||||
"sg_tablesize(%u) is bigger than kernel"
|
||||
" defined SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name,
|
||||
sg_tablesize, MPT3SAS_MAX_PHYS_SEGMENTS);
|
||||
sg_tablesize, MPT_MAX_PHYS_SEGMENTS);
|
||||
}
|
||||
ioc->shost->sg_tablesize = sg_tablesize;
|
||||
|
||||
|
@ -4021,7 +4337,7 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
|
|||
mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER;
|
||||
mpi_request.VF_ID = 0; /* TODO */
|
||||
mpi_request.VP_ID = 0;
|
||||
mpi_request.MsgVersion = cpu_to_le16(MPI25_VERSION);
|
||||
mpi_request.MsgVersion = cpu_to_le16(ioc->hba_mpi_version_belonged);
|
||||
mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
|
||||
|
||||
if (_base_is_controller_msix_enabled(ioc))
|
||||
|
@ -4655,6 +4971,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
|
|||
u32 reply_address;
|
||||
u16 smid;
|
||||
struct _tr_list *delayed_tr, *delayed_tr_next;
|
||||
u8 hide_flag;
|
||||
struct adapter_reply_queue *reply_q;
|
||||
long reply_post_free;
|
||||
u32 reply_post_free_sz, index = 0;
|
||||
|
@ -4685,6 +5002,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
|
|||
ioc->scsi_lookup[i].cb_idx = 0xFF;
|
||||
ioc->scsi_lookup[i].smid = smid;
|
||||
ioc->scsi_lookup[i].scmd = NULL;
|
||||
ioc->scsi_lookup[i].direct_io = 0;
|
||||
list_add_tail(&ioc->scsi_lookup[i].tracker_list,
|
||||
&ioc->free_list);
|
||||
}
|
||||
|
@ -4787,6 +5105,16 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
|
|||
|
||||
|
||||
if (ioc->is_driver_loading) {
|
||||
|
||||
if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier
|
||||
== 0x80) {
|
||||
hide_flag = (u8) (
|
||||
le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) &
|
||||
MFG_PAGE10_HIDE_SSDS_MASK);
|
||||
if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
|
||||
ioc->mfg_pg10_hide_flag = hide_flag;
|
||||
}
|
||||
|
||||
ioc->wait_for_discovery_to_complete =
|
||||
_base_determine_wait_on_discovery(ioc);
|
||||
|
||||
|
@ -4812,6 +5140,8 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
|
|||
dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
__func__));
|
||||
|
||||
/* synchronizing freeing resource with pci_access_mutex lock */
|
||||
mutex_lock(&ioc->pci_access_mutex);
|
||||
if (ioc->chip_phys && ioc->chip) {
|
||||
_base_mask_interrupts(ioc);
|
||||
ioc->shost_recovery = 1;
|
||||
|
@ -4820,6 +5150,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
|
|||
}
|
||||
|
||||
mpt3sas_base_unmap_resources(ioc);
|
||||
mutex_unlock(&ioc->pci_access_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4834,7 +5165,6 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
|
|||
{
|
||||
int r, i;
|
||||
int cpu_id, last_cpu_id = 0;
|
||||
u8 revision;
|
||||
|
||||
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
|
||||
__func__));
|
||||
|
@ -4854,19 +5184,16 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
|
|||
goto out_free_resources;
|
||||
}
|
||||
|
||||
/* Check whether the controller revision is C0 or above.
|
||||
* only C0 and above revision controllers support 96 MSI-X vectors.
|
||||
*/
|
||||
revision = ioc->pdev->revision;
|
||||
|
||||
if ((ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3004 ||
|
||||
ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3008 ||
|
||||
ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_1 ||
|
||||
ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_2 ||
|
||||
ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_5 ||
|
||||
ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_6) &&
|
||||
(revision >= 0x02))
|
||||
ioc->msix96_vector = 1;
|
||||
if (ioc->is_warpdrive) {
|
||||
ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz,
|
||||
sizeof(resource_size_t *), GFP_KERNEL);
|
||||
if (!ioc->reply_post_host_index) {
|
||||
dfailprintk(ioc, pr_info(MPT3SAS_FMT "allocation "
|
||||
"for cpu_msix_table failed!!!\n", ioc->name));
|
||||
r = -ENOMEM;
|
||||
goto out_free_resources;
|
||||
}
|
||||
}
|
||||
|
||||
ioc->rdpq_array_enable_assigned = 0;
|
||||
ioc->dma_mask = 0;
|
||||
|
@ -4874,23 +5201,41 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
|
|||
if (r)
|
||||
goto out_free_resources;
|
||||
|
||||
if (ioc->is_warpdrive) {
|
||||
ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
|
||||
&ioc->chip->ReplyPostHostIndex;
|
||||
|
||||
for (i = 1; i < ioc->cpu_msix_table_sz; i++)
|
||||
ioc->reply_post_host_index[i] =
|
||||
(resource_size_t __iomem *)
|
||||
((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
|
||||
* 4)));
|
||||
}
|
||||
|
||||
pci_set_drvdata(ioc->pdev, ioc->shost);
|
||||
r = _base_get_ioc_facts(ioc, CAN_SLEEP);
|
||||
if (r)
|
||||
goto out_free_resources;
|
||||
|
||||
/*
|
||||
* In SAS3.0,
|
||||
* SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and
|
||||
* Target Status - all require the IEEE formated scatter gather
|
||||
* elements.
|
||||
*/
|
||||
|
||||
ioc->build_sg_scmd = &_base_build_sg_scmd_ieee;
|
||||
ioc->build_sg = &_base_build_sg_ieee;
|
||||
ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee;
|
||||
ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t);
|
||||
switch (ioc->hba_mpi_version_belonged) {
|
||||
case MPI2_VERSION:
|
||||
ioc->build_sg_scmd = &_base_build_sg_scmd;
|
||||
ioc->build_sg = &_base_build_sg;
|
||||
ioc->build_zero_len_sge = &_base_build_zero_len_sge;
|
||||
break;
|
||||
case MPI25_VERSION:
|
||||
/*
|
||||
* In SAS3.0,
|
||||
* SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and
|
||||
* Target Status - all require the IEEE formated scatter gather
|
||||
* elements.
|
||||
*/
|
||||
ioc->build_sg_scmd = &_base_build_sg_scmd_ieee;
|
||||
ioc->build_sg = &_base_build_sg_ieee;
|
||||
ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee;
|
||||
ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* These function pointers for other requests that don't
|
||||
|
@ -5006,6 +5351,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
|
|||
if (r)
|
||||
goto out_free_resources;
|
||||
|
||||
ioc->non_operational_loop = 0;
|
||||
return 0;
|
||||
|
||||
out_free_resources:
|
||||
|
@ -5016,6 +5362,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
|
|||
_base_release_memory_pools(ioc);
|
||||
pci_set_drvdata(ioc->pdev, NULL);
|
||||
kfree(ioc->cpu_msix_table);
|
||||
if (ioc->is_warpdrive)
|
||||
kfree(ioc->reply_post_host_index);
|
||||
kfree(ioc->pd_handles);
|
||||
kfree(ioc->blocking_handles);
|
||||
kfree(ioc->tm_cmds.reply);
|
||||
|
@ -5055,6 +5403,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
|
|||
_base_release_memory_pools(ioc);
|
||||
pci_set_drvdata(ioc->pdev, NULL);
|
||||
kfree(ioc->cpu_msix_table);
|
||||
if (ioc->is_warpdrive)
|
||||
kfree(ioc->reply_post_host_index);
|
||||
kfree(ioc->pd_handles);
|
||||
kfree(ioc->blocking_handles);
|
||||
kfree(ioc->pfacts);
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
#include <scsi/scsi_transport_sas.h>
|
||||
#include <scsi/scsi_dbg.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/poll.h>
|
||||
|
||||
#include "mpt3sas_debug.h"
|
||||
#include "mpt3sas_trigger_diag.h"
|
||||
|
@ -71,23 +73,37 @@
|
|||
#define MPT3SAS_DRIVER_NAME "mpt3sas"
|
||||
#define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
|
||||
#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver"
|
||||
#define MPT3SAS_DRIVER_VERSION "09.100.00.00"
|
||||
#define MPT3SAS_DRIVER_VERSION "09.102.00.00"
|
||||
#define MPT3SAS_MAJOR_VERSION 9
|
||||
#define MPT3SAS_MINOR_VERSION 100
|
||||
#define MPT3SAS_MINOR_VERSION 102
|
||||
#define MPT3SAS_BUILD_VERSION 0
|
||||
#define MPT3SAS_RELEASE_VERSION 00
|
||||
|
||||
#define MPT2SAS_DRIVER_NAME "mpt2sas"
|
||||
#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
|
||||
#define MPT2SAS_DRIVER_VERSION "20.102.00.00"
|
||||
#define MPT2SAS_MAJOR_VERSION 20
|
||||
#define MPT2SAS_MINOR_VERSION 102
|
||||
#define MPT2SAS_BUILD_VERSION 0
|
||||
#define MPT2SAS_RELEASE_VERSION 00
|
||||
|
||||
/*
|
||||
* Set MPT3SAS_SG_DEPTH value based on user input.
|
||||
*/
|
||||
#define MPT3SAS_MAX_PHYS_SEGMENTS SCSI_MAX_SG_SEGMENTS
|
||||
#define MPT3SAS_MIN_PHYS_SEGMENTS 16
|
||||
#define MPT_MAX_PHYS_SEGMENTS SCSI_MAX_SG_SEGMENTS
|
||||
#define MPT_MIN_PHYS_SEGMENTS 16
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE
|
||||
#define MPT3SAS_SG_DEPTH CONFIG_SCSI_MPT3SAS_MAX_SGE
|
||||
#else
|
||||
#define MPT3SAS_SG_DEPTH MPT3SAS_MAX_PHYS_SEGMENTS
|
||||
#define MPT3SAS_SG_DEPTH MPT_MAX_PHYS_SEGMENTS
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT2SAS_MAX_SGE
|
||||
#define MPT2SAS_SG_DEPTH CONFIG_SCSI_MPT2SAS_MAX_SGE
|
||||
#else
|
||||
#define MPT2SAS_SG_DEPTH MPT_MAX_PHYS_SEGMENTS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generic Defines
|
||||
|
@ -123,6 +139,16 @@
|
|||
*/
|
||||
#define MPT3SAS_FMT "%s: "
|
||||
|
||||
/*
|
||||
* WarpDrive Specific Log codes
|
||||
*/
|
||||
|
||||
#define MPT2_WARPDRIVE_LOGENTRY (0x8002)
|
||||
#define MPT2_WARPDRIVE_LC_SSDT (0x41)
|
||||
#define MPT2_WARPDRIVE_LC_SSDLW (0x43)
|
||||
#define MPT2_WARPDRIVE_LC_SSDLF (0x44)
|
||||
#define MPT2_WARPDRIVE_LC_BRMF (0x4D)
|
||||
|
||||
/*
|
||||
* per target private data
|
||||
*/
|
||||
|
@ -131,9 +157,33 @@
|
|||
#define MPT_TARGET_FLAGS_DELETED 0x04
|
||||
#define MPT_TARGET_FASTPATH_IO 0x08
|
||||
|
||||
#define SAS2_PCI_DEVICE_B0_REVISION (0x01)
|
||||
#define SAS3_PCI_DEVICE_C0_REVISION (0x02)
|
||||
|
||||
/*
|
||||
* Intel HBA branding
|
||||
*/
|
||||
#define MPT2SAS_INTEL_RMS25JB080_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS25JB080"
|
||||
#define MPT2SAS_INTEL_RMS25JB040_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS25JB040"
|
||||
#define MPT2SAS_INTEL_RMS25KB080_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS25KB080"
|
||||
#define MPT2SAS_INTEL_RMS25KB040_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS25KB040"
|
||||
#define MPT2SAS_INTEL_RMS25LB040_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS25LB040"
|
||||
#define MPT2SAS_INTEL_RMS25LB080_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS25LB080"
|
||||
#define MPT2SAS_INTEL_RMS2LL080_BRANDING \
|
||||
"Intel Integrated RAID Module RMS2LL080"
|
||||
#define MPT2SAS_INTEL_RMS2LL040_BRANDING \
|
||||
"Intel Integrated RAID Module RMS2LL040"
|
||||
#define MPT2SAS_INTEL_RS25GB008_BRANDING \
|
||||
"Intel(R) RAID Controller RS25GB008"
|
||||
#define MPT2SAS_INTEL_SSD910_BRANDING \
|
||||
"Intel(R) SSD 910 Series"
|
||||
|
||||
#define MPT3SAS_INTEL_RMS3JC080_BRANDING \
|
||||
"Intel(R) Integrated RAID Module RMS3JC080"
|
||||
#define MPT3SAS_INTEL_RS3GC008_BRANDING \
|
||||
|
@ -146,33 +196,62 @@
|
|||
/*
|
||||
* Intel HBA SSDIDs
|
||||
*/
|
||||
#define MPT3SAS_INTEL_RMS3JC080_SSDID 0x3521
|
||||
#define MPT3SAS_INTEL_RS3GC008_SSDID 0x3522
|
||||
#define MPT3SAS_INTEL_RS3FC044_SSDID 0x3523
|
||||
#define MPT3SAS_INTEL_RS3UC080_SSDID 0x3524
|
||||
#define MPT2SAS_INTEL_RMS25JB080_SSDID 0x3516
|
||||
#define MPT2SAS_INTEL_RMS25JB040_SSDID 0x3517
|
||||
#define MPT2SAS_INTEL_RMS25KB080_SSDID 0x3518
|
||||
#define MPT2SAS_INTEL_RMS25KB040_SSDID 0x3519
|
||||
#define MPT2SAS_INTEL_RMS25LB040_SSDID 0x351A
|
||||
#define MPT2SAS_INTEL_RMS25LB080_SSDID 0x351B
|
||||
#define MPT2SAS_INTEL_RMS2LL080_SSDID 0x350E
|
||||
#define MPT2SAS_INTEL_RMS2LL040_SSDID 0x350F
|
||||
#define MPT2SAS_INTEL_RS25GB008_SSDID 0x3000
|
||||
#define MPT2SAS_INTEL_SSD910_SSDID 0x3700
|
||||
|
||||
#define MPT3SAS_INTEL_RMS3JC080_SSDID 0x3521
|
||||
#define MPT3SAS_INTEL_RS3GC008_SSDID 0x3522
|
||||
#define MPT3SAS_INTEL_RS3FC044_SSDID 0x3523
|
||||
#define MPT3SAS_INTEL_RS3UC080_SSDID 0x3524
|
||||
|
||||
/*
|
||||
* Dell HBA branding
|
||||
*/
|
||||
#define MPT2SAS_DELL_BRANDING_SIZE 32
|
||||
|
||||
#define MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING "Dell 6Gbps SAS HBA"
|
||||
#define MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING "Dell PERC H200 Adapter"
|
||||
#define MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING "Dell PERC H200 Integrated"
|
||||
#define MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING "Dell PERC H200 Modular"
|
||||
#define MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING "Dell PERC H200 Embedded"
|
||||
#define MPT2SAS_DELL_PERC_H200_BRANDING "Dell PERC H200"
|
||||
#define MPT2SAS_DELL_6GBPS_SAS_BRANDING "Dell 6Gbps SAS"
|
||||
|
||||
#define MPT3SAS_DELL_12G_HBA_BRANDING \
|
||||
"Dell 12Gbps HBA"
|
||||
|
||||
/*
|
||||
* Dell HBA SSDIDs
|
||||
*/
|
||||
#define MPT3SAS_DELL_12G_HBA_SSDID 0x1F46
|
||||
#define MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID 0x1F1C
|
||||
#define MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID 0x1F1D
|
||||
#define MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID 0x1F1E
|
||||
#define MPT2SAS_DELL_PERC_H200_MODULAR_SSDID 0x1F1F
|
||||
#define MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID 0x1F20
|
||||
#define MPT2SAS_DELL_PERC_H200_SSDID 0x1F21
|
||||
#define MPT2SAS_DELL_6GBPS_SAS_SSDID 0x1F22
|
||||
|
||||
#define MPT3SAS_DELL_12G_HBA_SSDID 0x1F46
|
||||
|
||||
/*
|
||||
* Cisco HBA branding
|
||||
*/
|
||||
#define MPT3SAS_CISCO_12G_8E_HBA_BRANDING \
|
||||
"Cisco 9300-8E 12G SAS HBA"
|
||||
"Cisco 9300-8E 12G SAS HBA"
|
||||
#define MPT3SAS_CISCO_12G_8I_HBA_BRANDING \
|
||||
"Cisco 9300-8i 12G SAS HBA"
|
||||
"Cisco 9300-8i 12G SAS HBA"
|
||||
#define MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING \
|
||||
"Cisco 12G Modular SAS Pass through Controller"
|
||||
"Cisco 12G Modular SAS Pass through Controller"
|
||||
#define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING \
|
||||
"UCS C3X60 12G SAS Pass through Controller"
|
||||
"UCS C3X60 12G SAS Pass through Controller"
|
||||
/*
|
||||
* Cisco HBA SSSDIDs
|
||||
*/
|
||||
|
@ -188,6 +267,31 @@
|
|||
#define MPT3_DIAG_BUFFER_IS_RELEASED (0x02)
|
||||
#define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04)
|
||||
|
||||
/*
|
||||
* HP HBA branding
|
||||
*/
|
||||
#define MPT2SAS_HP_3PAR_SSVID 0x1590
|
||||
|
||||
#define MPT2SAS_HP_2_4_INTERNAL_BRANDING \
|
||||
"HP H220 Host Bus Adapter"
|
||||
#define MPT2SAS_HP_2_4_EXTERNAL_BRANDING \
|
||||
"HP H221 Host Bus Adapter"
|
||||
#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING \
|
||||
"HP H222 Host Bus Adapter"
|
||||
#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING \
|
||||
"HP H220i Host Bus Adapter"
|
||||
#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING \
|
||||
"HP H210i Host Bus Adapter"
|
||||
|
||||
/*
|
||||
* HO HBA SSDIDs
|
||||
*/
|
||||
#define MPT2SAS_HP_2_4_INTERNAL_SSDID 0x0041
|
||||
#define MPT2SAS_HP_2_4_EXTERNAL_SSDID 0x0042
|
||||
#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID 0x0043
|
||||
#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID 0x0044
|
||||
#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046
|
||||
|
||||
/*
|
||||
* Combined Reply Queue constants,
|
||||
* There are twelve Supplemental Reply Post Host Index Registers
|
||||
|
@ -243,20 +347,24 @@ struct Mpi2ManufacturingPage11_t {
|
|||
* struct MPT3SAS_TARGET - starget private hostdata
|
||||
* @starget: starget object
|
||||
* @sas_address: target sas address
|
||||
* @raid_device: raid_device pointer to access volume data
|
||||
* @handle: device handle
|
||||
* @num_luns: number luns
|
||||
* @flags: MPT_TARGET_FLAGS_XXX flags
|
||||
* @deleted: target flaged for deletion
|
||||
* @tm_busy: target is busy with TM request.
|
||||
* @sdev: The sas_device associated with this target
|
||||
*/
|
||||
struct MPT3SAS_TARGET {
|
||||
struct scsi_target *starget;
|
||||
u64 sas_address;
|
||||
struct _raid_device *raid_device;
|
||||
u16 handle;
|
||||
int num_luns;
|
||||
u32 flags;
|
||||
u8 deleted;
|
||||
u8 tm_busy;
|
||||
struct _sas_device *sdev;
|
||||
};
|
||||
|
||||
|
||||
|
@ -266,6 +374,11 @@ struct MPT3SAS_TARGET {
|
|||
#define MPT_DEVICE_FLAGS_INIT 0x01
|
||||
#define MPT_DEVICE_TLR_ON 0x02
|
||||
|
||||
#define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003)
|
||||
#define MFG_PAGE10_HIDE_ALL_DISKS (0x00)
|
||||
#define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01)
|
||||
#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02)
|
||||
|
||||
/**
|
||||
* struct MPT3SAS_DEVICE - sdev private hostdata
|
||||
* @sas_target: starget private hostdata
|
||||
|
@ -358,8 +471,24 @@ struct _sas_device {
|
|||
u8 pend_sas_rphy_add;
|
||||
u8 enclosure_level;
|
||||
u8 connector_name[4];
|
||||
struct kref refcount;
|
||||
};
|
||||
|
||||
static inline void sas_device_get(struct _sas_device *s)
|
||||
{
|
||||
kref_get(&s->refcount);
|
||||
}
|
||||
|
||||
static inline void sas_device_free(struct kref *r)
|
||||
{
|
||||
kfree(container_of(r, struct _sas_device, refcount));
|
||||
}
|
||||
|
||||
static inline void sas_device_put(struct _sas_device *s)
|
||||
{
|
||||
kref_put(&s->refcount, sas_device_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct _raid_device - raid volume link list
|
||||
* @list: sas device list
|
||||
|
@ -367,6 +496,7 @@ struct _sas_device {
|
|||
* @sdev: scsi device struct (volumes are single lun)
|
||||
* @wwid: unique identifier for the volume
|
||||
* @handle: device handle
|
||||
* @block_size: Block size of the volume
|
||||
* @id: target id
|
||||
* @channel: target channel
|
||||
* @volume_type: the raid level
|
||||
|
@ -374,6 +504,13 @@ struct _sas_device {
|
|||
* @num_pds: number of hidden raid components
|
||||
* @responding: used in _scsih_raid_device_mark_responding
|
||||
* @percent_complete: resync percent complete
|
||||
* @direct_io_enabled: Whether direct io to PDs are allowed or not
|
||||
* @stripe_exponent: X where 2powX is the stripe sz in blocks
|
||||
* @block_exponent: X where 2powX is the block sz in bytes
|
||||
* @max_lba: Maximum number of LBA in the volume
|
||||
* @stripe_sz: Stripe Size of the volume
|
||||
* @device_info: Device info of the volume member disk
|
||||
* @pd_handle: Array of handles of the physical drives for direct I/O in le16
|
||||
*/
|
||||
#define MPT_MAX_WARPDRIVE_PDS 8
|
||||
struct _raid_device {
|
||||
|
@ -382,13 +519,20 @@ struct _raid_device {
|
|||
struct scsi_device *sdev;
|
||||
u64 wwid;
|
||||
u16 handle;
|
||||
u16 block_sz;
|
||||
int id;
|
||||
int channel;
|
||||
u8 volume_type;
|
||||
u8 num_pds;
|
||||
u8 responding;
|
||||
u8 percent_complete;
|
||||
u8 direct_io_enabled;
|
||||
u8 stripe_exponent;
|
||||
u8 block_exponent;
|
||||
u64 max_lba;
|
||||
u32 stripe_sz;
|
||||
u32 device_info;
|
||||
u16 pd_handle[MPT_MAX_WARPDRIVE_PDS];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -497,12 +641,14 @@ struct chain_tracker {
|
|||
* @smid: system message id
|
||||
* @scmd: scsi request pointer
|
||||
* @cb_idx: callback index
|
||||
* @direct_io: To indicate whether I/O is direct (WARPDRIVE)
|
||||
* @tracker_list: list of free request (ioc->free_list)
|
||||
*/
|
||||
struct scsiio_tracker {
|
||||
u16 smid;
|
||||
struct scsi_cmnd *scmd;
|
||||
u8 cb_idx;
|
||||
u8 direct_io;
|
||||
struct list_head chain_list;
|
||||
struct list_head tracker_list;
|
||||
};
|
||||
|
@ -775,7 +921,13 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
|
|||
* @replyPostRegisterIndex: index of next position in Reply Desc Post Queue
|
||||
* @delayed_tr_list: target reset link list
|
||||
* @delayed_tr_volume_list: volume target reset link list
|
||||
* @@temp_sensors_count: flag to carry the number of temperature sensors
|
||||
* @temp_sensors_count: flag to carry the number of temperature sensors
|
||||
* @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and
|
||||
* pci resource handling. PCI resource freeing will lead to free
|
||||
* vital hardware/memory resource, which might be in use by cli/sysfs
|
||||
* path functions resulting in Null pointer reference followed by kernel
|
||||
* crash. To avoid the above race condition we use mutex syncrhonization
|
||||
* which ensures the syncrhonization between cli/sysfs_show path.
|
||||
*/
|
||||
struct MPT3SAS_ADAPTER {
|
||||
struct list_head list;
|
||||
|
@ -783,6 +935,7 @@ struct MPT3SAS_ADAPTER {
|
|||
u8 id;
|
||||
int cpu_count;
|
||||
char name[MPT_NAME_LENGTH];
|
||||
char driver_name[MPT_NAME_LENGTH];
|
||||
char tmp_string[MPT_STRING_LENGTH];
|
||||
struct pci_dev *pdev;
|
||||
Mpi2SystemInterfaceRegs_t __iomem *chip;
|
||||
|
@ -829,8 +982,10 @@ struct MPT3SAS_ADAPTER {
|
|||
u16 msix_vector_count;
|
||||
u8 *cpu_msix_table;
|
||||
u16 cpu_msix_table_sz;
|
||||
resource_size_t __iomem **reply_post_host_index;
|
||||
u32 ioc_reset_count;
|
||||
MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
|
||||
u32 non_operational_loop;
|
||||
|
||||
/* internal commands, callback index */
|
||||
u8 scsi_io_cb_idx;
|
||||
|
@ -859,6 +1014,7 @@ struct MPT3SAS_ADAPTER {
|
|||
MPT_BUILD_SG build_sg;
|
||||
MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge;
|
||||
u16 sge_size_ieee;
|
||||
u16 hba_mpi_version_belonged;
|
||||
|
||||
/* function ptr for MPI sg elements only */
|
||||
MPT_BUILD_SG build_sg_mpi;
|
||||
|
@ -987,6 +1143,7 @@ struct MPT3SAS_ADAPTER {
|
|||
struct list_head delayed_tr_list;
|
||||
struct list_head delayed_tr_volume_list;
|
||||
u8 temp_sensors_count;
|
||||
struct mutex pci_access_mutex;
|
||||
|
||||
/* diag buffer support */
|
||||
u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
|
||||
|
@ -998,6 +1155,10 @@ struct MPT3SAS_ADAPTER {
|
|||
u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
|
||||
u32 ring_buffer_offset;
|
||||
u32 ring_buffer_sz;
|
||||
u8 is_warpdrive;
|
||||
u8 hide_ir_msg;
|
||||
u8 mfg_pg10_hide_flag;
|
||||
u8 hide_drives;
|
||||
spinlock_t diag_trigger_lock;
|
||||
u8 diag_trigger_active;
|
||||
struct SL_WH_MASTER_TRIGGER_T diag_trigger_master;
|
||||
|
@ -1012,6 +1173,19 @@ typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||
|
||||
/* base shared API */
|
||||
extern struct list_head mpt3sas_ioc_list;
|
||||
extern char driver_name[MPT_NAME_LENGTH];
|
||||
/* spinlock on list operations over IOCs
|
||||
* Case: when multiple warpdrive cards(IOCs) are in use
|
||||
* Each IOC will added to the ioc list structure on initialization.
|
||||
* Watchdog threads run at regular intervals to check IOC for any
|
||||
* fault conditions which will trigger the dead_ioc thread to
|
||||
* deallocate pci resource, resulting deleting the IOC netry from list,
|
||||
* this deletion need to protected by spinlock to enusre that
|
||||
* ioc removal is syncrhonized, if not synchronized it might lead to
|
||||
* list_del corruption as the ioc list is traversed in cli path.
|
||||
*/
|
||||
extern spinlock_t gioc_lock;
|
||||
|
||||
void mpt3sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc);
|
||||
void mpt3sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc);
|
||||
|
||||
|
@ -1090,10 +1264,14 @@ struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
|
|||
struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||
struct _sas_node *mpt3sas_scsih_expander_find_by_sas_address(
|
||||
struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
||||
struct _sas_device *mpt3sas_scsih_sas_device_find_by_sas_address(
|
||||
struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
||||
struct _sas_device *mpt3sas_get_sdev_by_addr(
|
||||
struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
||||
struct _sas_device *__mpt3sas_get_sdev_by_addr(
|
||||
struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
||||
|
||||
void mpt3sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc);
|
||||
struct _raid_device *
|
||||
mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||
|
||||
/* config shared API */
|
||||
u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
||||
|
@ -1133,6 +1311,8 @@ int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
|
|||
u16 sz);
|
||||
int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
|
||||
*mpi_reply, Mpi2IOUnitPage1_t *config_page);
|
||||
int mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
|
||||
Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
|
||||
int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
|
||||
*mpi_reply, Mpi2IOUnitPage1_t *config_page);
|
||||
int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
|
||||
|
@ -1177,8 +1357,8 @@ int mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc,
|
|||
/* ctl shared API */
|
||||
extern struct device_attribute *mpt3sas_host_attrs[];
|
||||
extern struct device_attribute *mpt3sas_dev_attrs[];
|
||||
void mpt3sas_ctl_init(void);
|
||||
void mpt3sas_ctl_exit(void);
|
||||
void mpt3sas_ctl_init(ushort hbas_to_enumerate);
|
||||
void mpt3sas_ctl_exit(ushort hbas_to_enumerate);
|
||||
u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
||||
u32 reply);
|
||||
void mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
|
||||
|
@ -1193,6 +1373,7 @@ int mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type,
|
|||
u8 *issue_reset);
|
||||
|
||||
/* transport shared API */
|
||||
extern struct scsi_transport_template *mpt3sas_transport_template;
|
||||
u8 mpt3sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
||||
u32 reply);
|
||||
struct _sas_port *mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc,
|
||||
|
@ -1224,4 +1405,18 @@ void mpt3sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key,
|
|||
u8 asc, u8 ascq);
|
||||
void mpt3sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status,
|
||||
u32 loginfo);
|
||||
|
||||
/* warpdrive APIs */
|
||||
u8 mpt3sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc);
|
||||
void mpt3sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
|
||||
struct _raid_device *raid_device);
|
||||
inline u8
|
||||
mpt3sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
||||
inline void
|
||||
mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
|
||||
void
|
||||
mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
||||
struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
|
||||
u16 smid);
|
||||
|
||||
#endif /* MPT3SAS_BASE_H_INCLUDED */
|
||||
|
|
|
@ -83,7 +83,6 @@ struct config_request {
|
|||
dma_addr_t page_dma;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
/**
|
||||
* _config_display_some_debug - debug routine
|
||||
* @ioc: per adapter object
|
||||
|
@ -173,7 +172,6 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
|
|||
ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
|
||||
le32_to_cpu(mpi_reply->IOCLogInfo));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* _config_alloc_config_dma_memory - obtain physical memory
|
||||
|
@ -255,9 +253,7 @@ mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||
mpi_reply->MsgLength*4);
|
||||
}
|
||||
ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
|
||||
#endif
|
||||
ioc->config_cmds.smid = USHRT_MAX;
|
||||
complete(&ioc->config_cmds.done);
|
||||
return 1;
|
||||
|
@ -387,9 +383,7 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
|||
config_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
||||
ioc->config_cmds.smid = smid;
|
||||
memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
_config_display_some_debug(ioc, smid, "config_request", NULL);
|
||||
#endif
|
||||
init_completion(&ioc->config_cmds.done);
|
||||
mpt3sas_base_put_smid_default(ioc, smid);
|
||||
timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
|
||||
|
@ -871,6 +865,42 @@ mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
|
||||
* @ioc: per adapter object
|
||||
* @mpi_reply: reply mf payload returned from firmware
|
||||
* @config_page: contents of the config page
|
||||
* @sz: size of buffer passed in config_page
|
||||
* Context: sleep.
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*/
|
||||
int
|
||||
mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
|
||||
Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
|
||||
{
|
||||
Mpi2ConfigRequest_t mpi_request;
|
||||
int r;
|
||||
|
||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
|
||||
mpi_request.Header.PageNumber = 3;
|
||||
mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
|
||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
|
||||
* @ioc: per adapter object
|
||||
|
|
|
@ -78,7 +78,6 @@ enum block_state {
|
|||
BLOCKING,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
/**
|
||||
* _ctl_sas_device_find_by_handle - sas device search
|
||||
* @ioc: per adapter object
|
||||
|
@ -254,8 +253,6 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* mpt3sas_ctl_done - ctl module completion routine
|
||||
* @ioc: per adapter object
|
||||
|
@ -302,9 +299,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
_ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
|
||||
#endif
|
||||
ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING;
|
||||
complete(&ioc->ctl_cmds.done);
|
||||
return 1;
|
||||
|
@ -414,20 +409,31 @@ mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
|
|||
* _ctl_verify_adapter - validates ioc_number passed from application
|
||||
* @ioc: per adapter object
|
||||
* @iocpp: The ioc pointer is returned in this.
|
||||
* @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
|
||||
* MPI25_VERSION for mpt3ctl ioctl device.
|
||||
*
|
||||
* Return (-1) means error, else ioc_number.
|
||||
*/
|
||||
static int
|
||||
_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp)
|
||||
_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp,
|
||||
int mpi_version)
|
||||
{
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
|
||||
/* global ioc lock to protect controller on list operations */
|
||||
spin_lock(&gioc_lock);
|
||||
list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
|
||||
if (ioc->id != ioc_number)
|
||||
continue;
|
||||
/* Check whether this ioctl command is from right
|
||||
* ioctl device or not, if not continue the search.
|
||||
*/
|
||||
if (ioc->hba_mpi_version_belonged != mpi_version)
|
||||
continue;
|
||||
spin_unlock(&gioc_lock);
|
||||
*iocpp = ioc;
|
||||
return ioc_number;
|
||||
}
|
||||
spin_unlock(&gioc_lock);
|
||||
*iocpp = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -497,7 +503,7 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
|
|||
*
|
||||
* Called when application request fasyn callback handler.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
_ctl_fasync(int fd, struct file *filep, int mode)
|
||||
{
|
||||
return fasync_helper(fd, filep, mode, &async_queue);
|
||||
|
@ -509,17 +515,22 @@ _ctl_fasync(int fd, struct file *filep, int mode)
|
|||
* @wait -
|
||||
*
|
||||
*/
|
||||
static unsigned int
|
||||
unsigned int
|
||||
_ctl_poll(struct file *filep, poll_table *wait)
|
||||
{
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
|
||||
poll_wait(filep, &ctl_poll_wait, wait);
|
||||
|
||||
/* global ioc lock to protect controller on list operations */
|
||||
spin_lock(&gioc_lock);
|
||||
list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
|
||||
if (ioc->aen_event_read_flag)
|
||||
if (ioc->aen_event_read_flag) {
|
||||
spin_unlock(&gioc_lock);
|
||||
return POLLIN | POLLRDNORM;
|
||||
}
|
||||
}
|
||||
spin_unlock(&gioc_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -759,9 +770,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
|||
psge = (void *)request + (karg.data_sge_offset*4);
|
||||
|
||||
/* send command to firmware */
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
_ctl_display_some_debug(ioc, smid, "ctl_request", NULL);
|
||||
#endif
|
||||
|
||||
init_completion(&ioc->ctl_cmds.done);
|
||||
switch (mpi_request->Function) {
|
||||
|
@ -916,7 +925,6 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
|||
mpi_reply = ioc->ctl_cmds.reply;
|
||||
ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT &&
|
||||
(ioc->logging_level & MPT_DEBUG_TM)) {
|
||||
Mpi2SCSITaskManagementReply_t *tm_reply =
|
||||
|
@ -929,7 +937,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
|||
le32_to_cpu(tm_reply->IOCLogInfo),
|
||||
le32_to_cpu(tm_reply->TerminationCount));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* copy out xdata to user */
|
||||
if (data_in_sz) {
|
||||
if (copy_to_user(karg.data_in_buf_ptr, data_in,
|
||||
|
@ -1023,7 +1031,6 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
|||
__func__));
|
||||
|
||||
memset(&karg, 0 , sizeof(karg));
|
||||
karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
|
||||
if (ioc->pfacts)
|
||||
karg.port_number = ioc->pfacts[0].PortNumber;
|
||||
karg.hw_rev = ioc->pdev->revision;
|
||||
|
@ -1035,9 +1042,21 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
|||
karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);
|
||||
karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);
|
||||
karg.firmware_version = ioc->facts.FWVersion.Word;
|
||||
strcpy(karg.driver_version, MPT3SAS_DRIVER_NAME);
|
||||
strcpy(karg.driver_version, ioc->driver_name);
|
||||
strcat(karg.driver_version, "-");
|
||||
strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
|
||||
switch (ioc->hba_mpi_version_belonged) {
|
||||
case MPI2_VERSION:
|
||||
if (ioc->is_warpdrive)
|
||||
karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;
|
||||
else
|
||||
karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
|
||||
strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
|
||||
break;
|
||||
case MPI25_VERSION:
|
||||
karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3;
|
||||
strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
|
||||
break;
|
||||
}
|
||||
karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
|
||||
|
||||
if (copy_to_user(arg, &karg, sizeof(karg))) {
|
||||
|
@ -2181,12 +2200,14 @@ _ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd,
|
|||
* _ctl_ioctl_main - main ioctl entry point
|
||||
* @file - (struct file)
|
||||
* @cmd - ioctl opcode
|
||||
* @arg -
|
||||
* compat - handles 32 bit applications in 64bit os
|
||||
* @arg - user space data buffer
|
||||
* @compat - handles 32 bit applications in 64bit os
|
||||
* @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
|
||||
* MPI25_VERSION for mpt3ctl ioctl device.
|
||||
*/
|
||||
static long
|
||||
_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
||||
u8 compat)
|
||||
u8 compat, u16 mpi_version)
|
||||
{
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
struct mpt3_ioctl_header ioctl_header;
|
||||
|
@ -2201,19 +2222,29 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
|
||||
if (_ctl_verify_adapter(ioctl_header.ioc_number,
|
||||
&ioc, mpi_version) == -1 || !ioc)
|
||||
return -ENODEV;
|
||||
|
||||
/* pci_access_mutex lock acquired by ioctl path */
|
||||
mutex_lock(&ioc->pci_access_mutex);
|
||||
|
||||
if (ioc->shost_recovery || ioc->pci_error_recovery ||
|
||||
ioc->is_driver_loading)
|
||||
return -EAGAIN;
|
||||
ioc->is_driver_loading || ioc->remove_host) {
|
||||
ret = -EAGAIN;
|
||||
goto out_unlock_pciaccess;
|
||||
}
|
||||
|
||||
state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
|
||||
if (state == NON_BLOCKING) {
|
||||
if (!mutex_trylock(&ioc->ctl_cmds.mutex))
|
||||
return -EAGAIN;
|
||||
} else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
|
||||
return -ERESTARTSYS;
|
||||
if (!mutex_trylock(&ioc->ctl_cmds.mutex)) {
|
||||
ret = -EAGAIN;
|
||||
goto out_unlock_pciaccess;
|
||||
}
|
||||
} else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto out_unlock_pciaccess;
|
||||
}
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -2294,39 +2325,78 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
|||
}
|
||||
|
||||
mutex_unlock(&ioc->ctl_cmds.mutex);
|
||||
out_unlock_pciaccess:
|
||||
mutex_unlock(&ioc->pci_access_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* _ctl_ioctl - main ioctl entry point (unlocked)
|
||||
* _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked)
|
||||
* @file - (struct file)
|
||||
* @cmd - ioctl opcode
|
||||
* @arg -
|
||||
*/
|
||||
static long
|
||||
long
|
||||
_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0);
|
||||
/* pass MPI25_VERSION value, to indicate that this ioctl cmd
|
||||
* came from mpt3ctl ioctl device.
|
||||
*/
|
||||
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI25_VERSION);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* _ctl_mpt2_ioctl - mpt2ctl main ioctl entry point (unlocked)
|
||||
* @file - (struct file)
|
||||
* @cmd - ioctl opcode
|
||||
* @arg -
|
||||
*/
|
||||
long
|
||||
_ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
long ret;
|
||||
|
||||
/* pass MPI2_VERSION value, to indicate that this ioctl cmd
|
||||
* came from mpt2ctl ioctl device.
|
||||
*/
|
||||
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION);
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
/**
|
||||
* _ctl_ioctl_compat - main ioctl entry point (compat)
|
||||
*_ ctl_ioctl_compat - main ioctl entry point (compat)
|
||||
* @file -
|
||||
* @cmd -
|
||||
* @arg -
|
||||
*
|
||||
* This routine handles 32 bit applications in 64bit os.
|
||||
*/
|
||||
static long
|
||||
long
|
||||
_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1);
|
||||
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI25_VERSION);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat)
|
||||
* @file -
|
||||
* @cmd -
|
||||
* @arg -
|
||||
*
|
||||
* This routine handles 32 bit applications in 64bit os.
|
||||
*/
|
||||
long
|
||||
_ctl_mpt2_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
@ -2713,6 +2783,82 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
|
|||
static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show,
|
||||
NULL);
|
||||
|
||||
/**
|
||||
* _ctl_BRM_status_show - Backup Rail Monitor Status
|
||||
* @cdev - pointer to embedded class device
|
||||
* @buf - the buffer returned
|
||||
*
|
||||
* This is number of reply queues
|
||||
*
|
||||
* A sysfs 'read-only' shost attribute.
|
||||
*/
|
||||
static ssize_t
|
||||
_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||
Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
u16 backup_rail_monitor_status = 0;
|
||||
u16 ioc_status;
|
||||
int sz;
|
||||
ssize_t rc = 0;
|
||||
|
||||
if (!ioc->is_warpdrive) {
|
||||
pr_err(MPT3SAS_FMT "%s: BRM attribute is only for"
|
||||
" warpdrive\n", ioc->name, __func__);
|
||||
goto out;
|
||||
}
|
||||
/* pci_access_mutex lock acquired by sysfs show path */
|
||||
mutex_lock(&ioc->pci_access_mutex);
|
||||
if (ioc->pci_error_recovery || ioc->remove_host) {
|
||||
mutex_unlock(&ioc->pci_access_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate upto GPIOVal 36 entries */
|
||||
sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
|
||||
io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
|
||||
if (!io_unit_pg3) {
|
||||
pr_err(MPT3SAS_FMT "%s: failed allocating memory "
|
||||
"for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
|
||||
0) {
|
||||
pr_err(MPT3SAS_FMT
|
||||
"%s: failed reading iounit_pg3\n", ioc->name,
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
pr_err(MPT3SAS_FMT "%s: iounit_pg3 failed with "
|
||||
"ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (io_unit_pg3->GPIOCount < 25) {
|
||||
pr_err(MPT3SAS_FMT "%s: iounit_pg3->GPIOCount less than "
|
||||
"25 entries, detected (%d) entries\n", ioc->name, __func__,
|
||||
io_unit_pg3->GPIOCount);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* BRM status is in bit zero of GPIOVal[24] */
|
||||
backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
|
||||
rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
|
||||
|
||||
out:
|
||||
kfree(io_unit_pg3);
|
||||
mutex_unlock(&ioc->pci_access_mutex);
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
|
||||
|
||||
struct DIAG_BUFFER_START {
|
||||
__le32 Size;
|
||||
__le32 DiagVersion;
|
||||
|
@ -3165,6 +3311,7 @@ struct device_attribute *mpt3sas_host_attrs[] = {
|
|||
&dev_attr_diag_trigger_event,
|
||||
&dev_attr_diag_trigger_scsi,
|
||||
&dev_attr_diag_trigger_mpi,
|
||||
&dev_attr_BRM_status,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -3218,6 +3365,7 @@ struct device_attribute *mpt3sas_dev_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
/* file operations table for mpt3ctl device */
|
||||
static const struct file_operations ctl_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = _ctl_ioctl,
|
||||
|
@ -3228,23 +3376,53 @@ static const struct file_operations ctl_fops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
/* file operations table for mpt2ctl device */
|
||||
static const struct file_operations ctl_gen2_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = _ctl_mpt2_ioctl,
|
||||
.poll = _ctl_poll,
|
||||
.fasync = _ctl_fasync,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = _ctl_mpt2_ioctl_compat,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct miscdevice ctl_dev = {
|
||||
.minor = MPT3SAS_MINOR,
|
||||
.name = MPT3SAS_DEV_NAME,
|
||||
.fops = &ctl_fops,
|
||||
};
|
||||
|
||||
static struct miscdevice gen2_ctl_dev = {
|
||||
.minor = MPT2SAS_MINOR,
|
||||
.name = MPT2SAS_DEV_NAME,
|
||||
.fops = &ctl_gen2_fops,
|
||||
};
|
||||
|
||||
/**
|
||||
* mpt3sas_ctl_init - main entry point for ctl.
|
||||
*
|
||||
*/
|
||||
void
|
||||
mpt3sas_ctl_init(void)
|
||||
mpt3sas_ctl_init(ushort hbas_to_enumerate)
|
||||
{
|
||||
async_queue = NULL;
|
||||
if (misc_register(&ctl_dev) < 0)
|
||||
pr_err("%s can't register misc device [minor=%d]\n",
|
||||
MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
|
||||
|
||||
/* Don't register mpt3ctl ioctl device if
|
||||
* hbas_to_enumarate is one.
|
||||
*/
|
||||
if (hbas_to_enumerate != 1)
|
||||
if (misc_register(&ctl_dev) < 0)
|
||||
pr_err("%s can't register misc device [minor=%d]\n",
|
||||
MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
|
||||
|
||||
/* Don't register mpt3ctl ioctl device if
|
||||
* hbas_to_enumarate is two.
|
||||
*/
|
||||
if (hbas_to_enumerate != 2)
|
||||
if (misc_register(&gen2_ctl_dev) < 0)
|
||||
pr_err("%s can't register misc device [minor=%d]\n",
|
||||
MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
|
||||
|
||||
init_waitqueue_head(&ctl_poll_wait);
|
||||
}
|
||||
|
@ -3254,7 +3432,7 @@ mpt3sas_ctl_init(void)
|
|||
*
|
||||
*/
|
||||
void
|
||||
mpt3sas_ctl_exit(void)
|
||||
mpt3sas_ctl_exit(ushort hbas_to_enumerate)
|
||||
{
|
||||
struct MPT3SAS_ADAPTER *ioc;
|
||||
int i;
|
||||
|
@ -3279,5 +3457,8 @@ mpt3sas_ctl_exit(void)
|
|||
|
||||
kfree(ioc->event_log);
|
||||
}
|
||||
misc_deregister(&ctl_dev);
|
||||
if (hbas_to_enumerate != 1)
|
||||
misc_deregister(&ctl_dev);
|
||||
if (hbas_to_enumerate != 2)
|
||||
misc_deregister(&gen2_ctl_dev);
|
||||
}
|
||||
|
|
|
@ -50,10 +50,13 @@
|
|||
#include <linux/miscdevice.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MPT2SAS_MINOR
|
||||
#define MPT2SAS_MINOR (MPT_MINOR + 1)
|
||||
#endif
|
||||
#ifndef MPT3SAS_MINOR
|
||||
#define MPT3SAS_MINOR (MPT_MINOR + 2)
|
||||
#endif
|
||||
#define MPT2SAS_DEV_NAME "mpt2ctl"
|
||||
#define MPT3SAS_DEV_NAME "mpt3ctl"
|
||||
#define MPT3_MAGIC_NUMBER 'L'
|
||||
#define MPT3_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */
|
||||
|
@ -138,6 +141,7 @@ struct mpt3_ioctl_pci_info {
|
|||
#define MPT2_IOCTL_INTERFACE_FC_IP (0x02)
|
||||
#define MPT2_IOCTL_INTERFACE_SAS (0x03)
|
||||
#define MPT2_IOCTL_INTERFACE_SAS2 (0x04)
|
||||
#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05)
|
||||
#define MPT3_IOCTL_INTERFACE_SAS3 (0x06)
|
||||
#define MPT2_IOCTL_VERSION_LENGTH (32)
|
||||
|
||||
|
|
|
@ -68,20 +68,11 @@
|
|||
#define MPT_DEBUG_TRIGGER_DIAG 0x00200000
|
||||
|
||||
|
||||
/*
|
||||
* CONFIG_SCSI_MPT3SAS_LOGGING - enabled in Kconfig
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \
|
||||
{ \
|
||||
if (IOC->logging_level & BITS) \
|
||||
CMD; \
|
||||
}
|
||||
#else
|
||||
#define MPT_CHECK_LOGGING(IOC, CMD, BITS)
|
||||
#endif /* CONFIG_SCSI_MPT3SAS_LOGGING */
|
||||
|
||||
|
||||
/*
|
||||
* debug macros
|
||||
|
@ -153,7 +144,7 @@
|
|||
|
||||
|
||||
/* inline functions for dumping debug data*/
|
||||
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
|
||||
|
||||
/**
|
||||
* _debug_dump_mf - print message frame contents
|
||||
* @mpi_request: pointer to message frame
|
||||
|
@ -211,10 +202,5 @@ _debug_dump_config(void *mpi_request, int sz)
|
|||
}
|
||||
pr_info("\n");
|
||||
}
|
||||
#else
|
||||
#define _debug_dump_mf(mpi_request, sz)
|
||||
#define _debug_dump_reply(mpi_request, sz)
|
||||
#define _debug_dump_config(mpi_request, sz)
|
||||
#endif /* CONFIG_SCSI_MPT3SAS_LOGGING */
|
||||
|
||||
#endif /* MPT3SAS_DEBUG_H_INCLUDED */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -734,7 +734,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
|||
rphy->identify = mpt3sas_port->remote_identify;
|
||||
|
||||
if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
|
||||
sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
|
||||
sas_device = mpt3sas_get_sdev_by_addr(ioc,
|
||||
mpt3sas_port->remote_identify.sas_address);
|
||||
if (!sas_device) {
|
||||
dfailprintk(ioc, printk(MPT3SAS_FMT
|
||||
|
@ -750,8 +750,10 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
|||
ioc->name, __FILE__, __LINE__, __func__);
|
||||
}
|
||||
|
||||
if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE)
|
||||
if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
|
||||
sas_device->pend_sas_rphy_add = 0;
|
||||
sas_device_put(sas_device);
|
||||
}
|
||||
|
||||
if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
|
||||
dev_printk(KERN_INFO, &rphy->dev,
|
||||
|
@ -1324,15 +1326,17 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
|
|||
int rc;
|
||||
|
||||
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
||||
sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
|
||||
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
||||
rphy->identify.sas_address);
|
||||
if (sas_device) {
|
||||
*identifier = sas_device->enclosure_logical_id;
|
||||
rc = 0;
|
||||
sas_device_put(sas_device);
|
||||
} else {
|
||||
*identifier = 0;
|
||||
rc = -ENXIO;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1352,12 +1356,14 @@ _transport_get_bay_identifier(struct sas_rphy *rphy)
|
|||
int rc;
|
||||
|
||||
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
||||
sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
|
||||
sas_device = __mpt3sas_get_sdev_by_addr(ioc,
|
||||
rphy->identify.sas_address);
|
||||
if (sas_device)
|
||||
if (sas_device) {
|
||||
rc = sas_device->slot;
|
||||
else
|
||||
sas_device_put(sas_device);
|
||||
} else {
|
||||
rc = -ENXIO;
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* Scsi Host Layer for MPT (Message Passing Technology) based controllers
|
||||
*
|
||||
* Copyright (C) 2012-2014 LSI Corporation
|
||||
* Copyright (C) 2013-2015 Avago Technologies
|
||||
* (mailto: MPT-FusionLinux.pdl@avagotech.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
|
||||
* 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.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "mpt3sas_base.h"
|
||||
|
||||
/**
|
||||
* _warpdrive_disable_ddio - Disable direct I/O for all the volumes
|
||||
* @ioc: per adapter object
|
||||
*/
|
||||
static void
|
||||
_warpdrive_disable_ddio(struct MPT3SAS_ADAPTER *ioc)
|
||||
{
|
||||
Mpi2RaidVolPage1_t vol_pg1;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
struct _raid_device *raid_device;
|
||||
u16 handle;
|
||||
u16 ioc_status;
|
||||
unsigned long flags;
|
||||
|
||||
handle = 0xFFFF;
|
||||
while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
||||
&vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
||||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
||||
break;
|
||||
handle = le16_to_cpu(vol_pg1.DevHandle);
|
||||
spin_lock_irqsave(&ioc->raid_device_lock, flags);
|
||||
raid_device = mpt3sas_raid_device_find_by_handle(ioc, handle);
|
||||
if (raid_device)
|
||||
raid_device->direct_io_enabled = 0;
|
||||
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mpt3sas_get_num_volumes - Get number of volumes in the ioc
|
||||
* @ioc: per adapter object
|
||||
*/
|
||||
u8
|
||||
mpt3sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc)
|
||||
{
|
||||
Mpi2RaidVolPage1_t vol_pg1;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
u16 handle;
|
||||
u8 vol_cnt = 0;
|
||||
u16 ioc_status;
|
||||
|
||||
handle = 0xFFFF;
|
||||
while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
||||
&vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
||||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
||||
break;
|
||||
vol_cnt++;
|
||||
handle = le16_to_cpu(vol_pg1.DevHandle);
|
||||
}
|
||||
return vol_cnt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mpt3sas_init_warpdrive_properties - Set properties for warpdrive direct I/O.
|
||||
* @ioc: per adapter object
|
||||
* @raid_device: the raid_device object
|
||||
*/
|
||||
void
|
||||
mpt3sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc,
|
||||
struct _raid_device *raid_device)
|
||||
{
|
||||
Mpi2RaidVolPage0_t *vol_pg0;
|
||||
Mpi2RaidPhysDiskPage0_t pd_pg0;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
u16 sz;
|
||||
u8 num_pds, count;
|
||||
unsigned long stripe_sz, block_sz;
|
||||
u8 stripe_exp, block_exp;
|
||||
u64 dev_max_lba;
|
||||
|
||||
if (!ioc->is_warpdrive)
|
||||
return;
|
||||
|
||||
if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"globally as drives are exposed\n", ioc->name);
|
||||
return;
|
||||
}
|
||||
if (mpt3sas_get_num_volumes(ioc) > 1) {
|
||||
_warpdrive_disable_ddio(ioc);
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"globally as number of drives > 1\n", ioc->name);
|
||||
return;
|
||||
}
|
||||
if ((mpt3sas_config_get_number_pds(ioc, raid_device->handle,
|
||||
&num_pds)) || !num_pds) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"Failure in computing number of drives\n", ioc->name);
|
||||
return;
|
||||
}
|
||||
|
||||
sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
|
||||
sizeof(Mpi2RaidVol0PhysDisk_t));
|
||||
vol_pg0 = kzalloc(sz, GFP_KERNEL);
|
||||
if (!vol_pg0) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"Memory allocation failure for RVPG0\n", ioc->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
|
||||
MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"Failure in retrieving RVPG0\n", ioc->name);
|
||||
kfree(vol_pg0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* WARPDRIVE:If number of physical disks in a volume exceeds the max pds
|
||||
* assumed for WARPDRIVE, disable direct I/O
|
||||
*/
|
||||
if (num_pds > MPT_MAX_WARPDRIVE_PDS) {
|
||||
pr_warn(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"for the drive with handle(0x%04x): num_mem=%d, "
|
||||
"max_mem_allowed=%d\n", ioc->name, raid_device->handle,
|
||||
num_pds, MPT_MAX_WARPDRIVE_PDS);
|
||||
kfree(vol_pg0);
|
||||
return;
|
||||
}
|
||||
for (count = 0; count < num_pds; count++) {
|
||||
if (mpt3sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
|
||||
&pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
|
||||
vol_pg0->PhysDisk[count].PhysDiskNum) ||
|
||||
pd_pg0.DevHandle == MPT3SAS_INVALID_DEVICE_HANDLE) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is "
|
||||
"disabled for the drive with handle(0x%04x) member"
|
||||
"handle retrieval failed for member number=%d\n",
|
||||
ioc->name, raid_device->handle,
|
||||
vol_pg0->PhysDisk[count].PhysDiskNum);
|
||||
goto out_error;
|
||||
}
|
||||
/* Disable direct I/O if member drive lba exceeds 4 bytes */
|
||||
dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA);
|
||||
if (dev_max_lba >> 32) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is "
|
||||
"disabled for the drive with handle(0x%04x) member"
|
||||
" handle (0x%04x) unsupported max lba 0x%016llx\n",
|
||||
ioc->name, raid_device->handle,
|
||||
le16_to_cpu(pd_pg0.DevHandle),
|
||||
(unsigned long long)dev_max_lba);
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assumption for WD: Direct I/O is not supported if the volume is
|
||||
* not RAID0
|
||||
*/
|
||||
if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"for the drive with handle(0x%04x): type=%d, "
|
||||
"s_sz=%uK, blk_size=%u\n", ioc->name,
|
||||
raid_device->handle, raid_device->volume_type,
|
||||
(le32_to_cpu(vol_pg0->StripeSize) *
|
||||
le16_to_cpu(vol_pg0->BlockSize)) / 1024,
|
||||
le16_to_cpu(vol_pg0->BlockSize));
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
|
||||
stripe_exp = find_first_bit(&stripe_sz, 32);
|
||||
if (stripe_exp == 32) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"for the drive with handle(0x%04x) invalid stripe sz %uK\n",
|
||||
ioc->name, raid_device->handle,
|
||||
(le32_to_cpu(vol_pg0->StripeSize) *
|
||||
le16_to_cpu(vol_pg0->BlockSize)) / 1024);
|
||||
goto out_error;
|
||||
}
|
||||
raid_device->stripe_exponent = stripe_exp;
|
||||
block_sz = le16_to_cpu(vol_pg0->BlockSize);
|
||||
block_exp = find_first_bit(&block_sz, 16);
|
||||
if (block_exp == 16) {
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled "
|
||||
"for the drive with handle(0x%04x) invalid block sz %u\n",
|
||||
ioc->name, raid_device->handle,
|
||||
le16_to_cpu(vol_pg0->BlockSize));
|
||||
goto out_error;
|
||||
}
|
||||
raid_device->block_exponent = block_exp;
|
||||
raid_device->direct_io_enabled = 1;
|
||||
|
||||
pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is Enabled for the drive"
|
||||
" with handle(0x%04x)\n", ioc->name, raid_device->handle);
|
||||
/*
|
||||
* WARPDRIVE: Though the following fields are not used for direct IO,
|
||||
* stored for future purpose:
|
||||
*/
|
||||
raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
|
||||
raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
|
||||
raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);
|
||||
|
||||
|
||||
kfree(vol_pg0);
|
||||
return;
|
||||
|
||||
out_error:
|
||||
raid_device->direct_io_enabled = 0;
|
||||
for (count = 0; count < num_pds; count++)
|
||||
raid_device->pd_handle[count] = 0;
|
||||
kfree(vol_pg0);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpt3sas_scsi_direct_io_get - returns direct io flag
|
||||
* @ioc: per adapter object
|
||||
* @smid: system request message index
|
||||
*
|
||||
* Returns the smid stored scmd pointer.
|
||||
*/
|
||||
inline u8
|
||||
mpt3sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
|
||||
{
|
||||
return ioc->scsi_lookup[smid - 1].direct_io;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpt3sas_scsi_direct_io_set - sets direct io flag
|
||||
* @ioc: per adapter object
|
||||
* @smid: system request message index
|
||||
* @direct_io: Zero or non-zero value to set in the direct_io flag
|
||||
*
|
||||
* Returns Nothing.
|
||||
*/
|
||||
inline void
|
||||
mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
|
||||
{
|
||||
ioc->scsi_lookup[smid - 1].direct_io = direct_io;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpt3sas_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
|
||||
* @ioc: per adapter object
|
||||
* @scmd: pointer to scsi command object
|
||||
* @raid_device: pointer to raid device data structure
|
||||
* @mpi_request: pointer to the SCSI_IO reqest message frame
|
||||
* @smid: system request message index
|
||||
*
|
||||
* Returns nothing
|
||||
*/
|
||||
void
|
||||
mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
||||
struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
|
||||
u16 smid)
|
||||
{
|
||||
sector_t v_lba, p_lba, stripe_off, column, io_size;
|
||||
u32 stripe_sz, stripe_exp;
|
||||
u8 num_pds, cmd = scmd->cmnd[0];
|
||||
|
||||
if (cmd != READ_10 && cmd != WRITE_10 &&
|
||||
cmd != READ_16 && cmd != WRITE_16)
|
||||
return;
|
||||
|
||||
if (cmd == READ_10 || cmd == WRITE_10)
|
||||
v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]);
|
||||
else
|
||||
v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]);
|
||||
|
||||
io_size = scsi_bufflen(scmd) >> raid_device->block_exponent;
|
||||
|
||||
if (v_lba + io_size - 1 > raid_device->max_lba)
|
||||
return;
|
||||
|
||||
stripe_sz = raid_device->stripe_sz;
|
||||
stripe_exp = raid_device->stripe_exponent;
|
||||
stripe_off = v_lba & (stripe_sz - 1);
|
||||
|
||||
/* Return unless IO falls within a stripe */
|
||||
if (stripe_off + io_size > stripe_sz)
|
||||
return;
|
||||
|
||||
num_pds = raid_device->num_pds;
|
||||
p_lba = v_lba >> stripe_exp;
|
||||
column = sector_div(p_lba, num_pds);
|
||||
p_lba = (p_lba << stripe_exp) + stripe_off;
|
||||
mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]);
|
||||
|
||||
if (cmd == READ_10 || cmd == WRITE_10)
|
||||
put_unaligned_be32(lower_32_bits(p_lba),
|
||||
&mpi_request->CDB.CDB32[2]);
|
||||
else
|
||||
put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]);
|
||||
|
||||
mpt3sas_scsi_direct_io_set(ioc, smid, 1);
|
||||
}
|
|
@ -640,9 +640,9 @@ static void mvs_pci_remove(struct pci_dev *pdev)
|
|||
tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet);
|
||||
#endif
|
||||
|
||||
scsi_remove_host(mvi->shost);
|
||||
sas_unregister_ha(sha);
|
||||
sas_remove_host(mvi->shost);
|
||||
scsi_remove_host(mvi->shost);
|
||||
|
||||
MVS_CHIP_DISP->interrupt_disable(mvi);
|
||||
free_irq(mvi->pdev->irq, sha);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/io.h>
|
||||
#include <scsi/scsi.h>
|
||||
|
@ -858,8 +859,8 @@ static void mvumi_hs_build_page(struct mvumi_hba *mhba,
|
|||
struct mvumi_hs_page2 *hs_page2;
|
||||
struct mvumi_hs_page4 *hs_page4;
|
||||
struct mvumi_hs_page3 *hs_page3;
|
||||
struct timeval time;
|
||||
unsigned int local_time;
|
||||
u64 time;
|
||||
u64 local_time;
|
||||
|
||||
switch (hs_header->page_code) {
|
||||
case HS_PAGE_HOST_INFO:
|
||||
|
@ -877,9 +878,8 @@ static void mvumi_hs_build_page(struct mvumi_hba *mhba,
|
|||
hs_page2->slot_number = 0;
|
||||
hs_page2->intr_level = 0;
|
||||
hs_page2->intr_vector = 0;
|
||||
do_gettimeofday(&time);
|
||||
local_time = (unsigned int) (time.tv_sec -
|
||||
(sys_tz.tz_minuteswest * 60));
|
||||
time = ktime_get_real_seconds();
|
||||
local_time = (time - (sys_tz.tz_minuteswest * 60));
|
||||
hs_page2->seconds_since1970 = local_time;
|
||||
hs_header->checksum = mvumi_calculate_checksum(hs_header,
|
||||
hs_header->frame_length);
|
||||
|
|
|
@ -51,6 +51,8 @@ enum chip_flavors {
|
|||
chip_8076,
|
||||
chip_8077,
|
||||
chip_8006,
|
||||
chip_8070,
|
||||
chip_8072
|
||||
};
|
||||
|
||||
enum phy_speed {
|
||||
|
|
|
@ -58,6 +58,8 @@ static const struct pm8001_chip_info pm8001_chips[] = {
|
|||
[chip_8076] = {0, 16, &pm8001_80xx_dispatch,},
|
||||
[chip_8077] = {0, 16, &pm8001_80xx_dispatch,},
|
||||
[chip_8006] = {0, 16, &pm8001_80xx_dispatch,},
|
||||
[chip_8070] = {0, 8, &pm8001_80xx_dispatch,},
|
||||
[chip_8072] = {0, 16, &pm8001_80xx_dispatch,},
|
||||
};
|
||||
static int pm8001_id;
|
||||
|
||||
|
@ -479,7 +481,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
|
|||
|
||||
#ifdef PM8001_USE_TASKLET
|
||||
/* Tasklet for non msi-x interrupt handler */
|
||||
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||
if ((!pdev->msix_cap || !pci_msi_enabled())
|
||||
|| (pm8001_ha->chip_id == chip_8001))
|
||||
tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
|
||||
(unsigned long)&(pm8001_ha->irq_vector[0]));
|
||||
else
|
||||
|
@ -633,6 +636,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
|
|||
payload.minor_function = 0;
|
||||
payload.length = 128;
|
||||
}
|
||||
} else if ((pm8001_ha->chip_id == chip_8070 ||
|
||||
pm8001_ha->chip_id == chip_8072) &&
|
||||
pm8001_ha->pdev->subsystem_vendor == PCI_VENDOR_ID_ATTO) {
|
||||
payload.minor_function = 4;
|
||||
payload.length = 4096;
|
||||
} else {
|
||||
payload.minor_function = 1;
|
||||
payload.length = 4096;
|
||||
|
@ -659,6 +667,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
|
|||
else if (deviceid == 0x0042)
|
||||
pm8001_ha->sas_addr[j] =
|
||||
payload.func_specific[0x010 + i];
|
||||
} else if ((pm8001_ha->chip_id == chip_8070 ||
|
||||
pm8001_ha->chip_id == chip_8072) &&
|
||||
pm8001_ha->pdev->subsystem_vendor == PCI_VENDOR_ID_ATTO) {
|
||||
pm8001_ha->sas_addr[j] =
|
||||
payload.func_specific[0x010 + i];
|
||||
} else
|
||||
pm8001_ha->sas_addr[j] =
|
||||
payload.func_specific[0x804 + i];
|
||||
|
@ -719,6 +732,153 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct pm8001_mpi3_phy_pg_trx_config {
|
||||
u32 LaneLosCfg;
|
||||
u32 LanePgaCfg1;
|
||||
u32 LanePisoCfg1;
|
||||
u32 LanePisoCfg2;
|
||||
u32 LanePisoCfg3;
|
||||
u32 LanePisoCfg4;
|
||||
u32 LanePisoCfg5;
|
||||
u32 LanePisoCfg6;
|
||||
u32 LaneBctCtrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* pm8001_get_internal_phy_settings : Retrieves the internal PHY settings
|
||||
* @pm8001_ha : our adapter
|
||||
* @phycfg : PHY config page to populate
|
||||
*/
|
||||
static
|
||||
void pm8001_get_internal_phy_settings(struct pm8001_hba_info *pm8001_ha,
|
||||
struct pm8001_mpi3_phy_pg_trx_config *phycfg)
|
||||
{
|
||||
phycfg->LaneLosCfg = 0x00000132;
|
||||
phycfg->LanePgaCfg1 = 0x00203949;
|
||||
phycfg->LanePisoCfg1 = 0x000000FF;
|
||||
phycfg->LanePisoCfg2 = 0xFF000001;
|
||||
phycfg->LanePisoCfg3 = 0xE7011300;
|
||||
phycfg->LanePisoCfg4 = 0x631C40C0;
|
||||
phycfg->LanePisoCfg5 = 0xF8102036;
|
||||
phycfg->LanePisoCfg6 = 0xF74A1000;
|
||||
phycfg->LaneBctCtrl = 0x00FB33F8;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm8001_get_external_phy_settings : Retrieves the external PHY settings
|
||||
* @pm8001_ha : our adapter
|
||||
* @phycfg : PHY config page to populate
|
||||
*/
|
||||
static
|
||||
void pm8001_get_external_phy_settings(struct pm8001_hba_info *pm8001_ha,
|
||||
struct pm8001_mpi3_phy_pg_trx_config *phycfg)
|
||||
{
|
||||
phycfg->LaneLosCfg = 0x00000132;
|
||||
phycfg->LanePgaCfg1 = 0x00203949;
|
||||
phycfg->LanePisoCfg1 = 0x000000FF;
|
||||
phycfg->LanePisoCfg2 = 0xFF000001;
|
||||
phycfg->LanePisoCfg3 = 0xE7011300;
|
||||
phycfg->LanePisoCfg4 = 0x63349140;
|
||||
phycfg->LanePisoCfg5 = 0xF8102036;
|
||||
phycfg->LanePisoCfg6 = 0xF80D9300;
|
||||
phycfg->LaneBctCtrl = 0x00FB33F8;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm8001_get_phy_mask : Retrieves the mask that denotes if a PHY is int/ext
|
||||
* @pm8001_ha : our adapter
|
||||
* @phymask : The PHY mask
|
||||
*/
|
||||
static
|
||||
void pm8001_get_phy_mask(struct pm8001_hba_info *pm8001_ha, int *phymask)
|
||||
{
|
||||
switch (pm8001_ha->pdev->subsystem_device) {
|
||||
case 0x0070: /* H1280 - 8 external 0 internal */
|
||||
case 0x0072: /* H12F0 - 16 external 0 internal */
|
||||
*phymask = 0x0000;
|
||||
break;
|
||||
|
||||
case 0x0071: /* H1208 - 0 external 8 internal */
|
||||
case 0x0073: /* H120F - 0 external 16 internal */
|
||||
*phymask = 0xFFFF;
|
||||
break;
|
||||
|
||||
case 0x0080: /* H1244 - 4 external 4 internal */
|
||||
*phymask = 0x00F0;
|
||||
break;
|
||||
|
||||
case 0x0081: /* H1248 - 4 external 8 internal */
|
||||
*phymask = 0x0FF0;
|
||||
break;
|
||||
|
||||
case 0x0082: /* H1288 - 8 external 8 internal */
|
||||
*phymask = 0xFF00;
|
||||
break;
|
||||
|
||||
default:
|
||||
PM8001_INIT_DBG(pm8001_ha,
|
||||
pm8001_printk("Unknown subsystem device=0x%.04x",
|
||||
pm8001_ha->pdev->subsystem_device));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pm8001_set_phy_settings_ven_117c_12Gb : Configure ATTO 12Gb PHY settings
|
||||
* @pm8001_ha : our adapter
|
||||
*/
|
||||
static
|
||||
int pm8001_set_phy_settings_ven_117c_12G(struct pm8001_hba_info *pm8001_ha)
|
||||
{
|
||||
struct pm8001_mpi3_phy_pg_trx_config phycfg_int;
|
||||
struct pm8001_mpi3_phy_pg_trx_config phycfg_ext;
|
||||
int phymask = 0;
|
||||
int i = 0;
|
||||
|
||||
memset(&phycfg_int, 0, sizeof(phycfg_int));
|
||||
memset(&phycfg_ext, 0, sizeof(phycfg_ext));
|
||||
|
||||
pm8001_get_internal_phy_settings(pm8001_ha, &phycfg_int);
|
||||
pm8001_get_external_phy_settings(pm8001_ha, &phycfg_ext);
|
||||
pm8001_get_phy_mask(pm8001_ha, &phymask);
|
||||
|
||||
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
|
||||
if (phymask & (1 << i)) {/* Internal PHY */
|
||||
pm8001_set_phy_profile_single(pm8001_ha, i,
|
||||
sizeof(phycfg_int) / sizeof(u32),
|
||||
(u32 *)&phycfg_int);
|
||||
|
||||
} else { /* External PHY */
|
||||
pm8001_set_phy_profile_single(pm8001_ha, i,
|
||||
sizeof(phycfg_ext) / sizeof(u32),
|
||||
(u32 *)&phycfg_ext);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm8001_configure_phy_settings : Configures PHY settings based on vendor ID.
|
||||
* @pm8001_ha : our hba.
|
||||
*/
|
||||
static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha)
|
||||
{
|
||||
switch (pm8001_ha->pdev->subsystem_vendor) {
|
||||
case PCI_VENDOR_ID_ATTO:
|
||||
if (pm8001_ha->pdev->device == 0x0042) /* 6Gb */
|
||||
return 0;
|
||||
else
|
||||
return pm8001_set_phy_settings_ven_117c_12G(pm8001_ha);
|
||||
|
||||
case PCI_VENDOR_ID_ADAPTEC2:
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return pm8001_get_phy_settings_info(pm8001_ha);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PM8001_USE_MSIX
|
||||
/**
|
||||
* pm8001_setup_msix - enable MSI-X interrupt
|
||||
|
@ -791,7 +951,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
|
|||
pdev = pm8001_ha->pdev;
|
||||
|
||||
#ifdef PM8001_USE_MSIX
|
||||
if (pdev->msix_cap)
|
||||
if (pdev->msix_cap && pci_msi_enabled())
|
||||
return pm8001_setup_msix(pm8001_ha);
|
||||
else {
|
||||
PM8001_INIT_DBG(pm8001_ha,
|
||||
|
@ -802,6 +962,8 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
|
|||
|
||||
intx:
|
||||
/* initialize the INT-X interrupt */
|
||||
pm8001_ha->irq_vector[0].irq_id = 0;
|
||||
pm8001_ha->irq_vector[0].drv_inst = pm8001_ha;
|
||||
rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED,
|
||||
DRV_NAME, SHOST_TO_SAS_HA(pm8001_ha->shost));
|
||||
return rc;
|
||||
|
@ -901,12 +1063,9 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
pm8001_init_sas_add(pm8001_ha);
|
||||
/* phy setting support for motherboard controller */
|
||||
if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 &&
|
||||
pdev->subsystem_vendor != 0) {
|
||||
rc = pm8001_get_phy_settings_info(pm8001_ha);
|
||||
if (rc)
|
||||
goto err_out_shost;
|
||||
}
|
||||
if (pm8001_configure_phy_settings(pm8001_ha))
|
||||
goto err_out_shost;
|
||||
|
||||
pm8001_post_sas_ha_init(shost, chip);
|
||||
rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
|
||||
if (rc)
|
||||
|
@ -936,10 +1095,10 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
|
|||
struct pm8001_hba_info *pm8001_ha;
|
||||
int i, j;
|
||||
pm8001_ha = sha->lldd_ha;
|
||||
scsi_remove_host(pm8001_ha->shost);
|
||||
sas_unregister_ha(sha);
|
||||
sas_remove_host(pm8001_ha->shost);
|
||||
list_del(&pm8001_ha->list);
|
||||
scsi_remove_host(pm8001_ha->shost);
|
||||
PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);
|
||||
PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
|
||||
|
||||
|
@ -955,7 +1114,8 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
|
|||
#endif
|
||||
#ifdef PM8001_USE_TASKLET
|
||||
/* For non-msix and msix interrupts */
|
||||
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||
if ((!pdev->msix_cap || !pci_msi_enabled()) ||
|
||||
(pm8001_ha->chip_id == chip_8001))
|
||||
tasklet_kill(&pm8001_ha->tasklet[0]);
|
||||
else
|
||||
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
|
||||
|
@ -1004,7 +1164,8 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
#endif
|
||||
#ifdef PM8001_USE_TASKLET
|
||||
/* For non-msix and msix interrupts */
|
||||
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||
if ((!pdev->msix_cap || !pci_msi_enabled()) ||
|
||||
(pm8001_ha->chip_id == chip_8001))
|
||||
tasklet_kill(&pm8001_ha->tasklet[0]);
|
||||
else
|
||||
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
|
||||
|
@ -1073,7 +1234,8 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
|
|||
goto err_out_disable;
|
||||
#ifdef PM8001_USE_TASKLET
|
||||
/* Tasklet for non msi-x interrupt handler */
|
||||
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||
if ((!pdev->msix_cap || !pci_msi_enabled()) ||
|
||||
(pm8001_ha->chip_id == chip_8001))
|
||||
tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
|
||||
(unsigned long)&(pm8001_ha->irq_vector[0]));
|
||||
else
|
||||
|
@ -1086,6 +1248,19 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
|
|||
for (i = 1; i < pm8001_ha->number_of_intr; i++)
|
||||
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
|
||||
}
|
||||
|
||||
/* Chip documentation for the 8070 and 8072 SPCv */
|
||||
/* states that a 500ms minimum delay is required */
|
||||
/* before issuing commands. Otherwise, the firmare */
|
||||
/* will enter an unrecoverable state. */
|
||||
|
||||
if (pm8001_ha->chip_id == chip_8070 ||
|
||||
pm8001_ha->chip_id == chip_8072) {
|
||||
mdelay(500);
|
||||
}
|
||||
|
||||
/* Spin up the PHYs */
|
||||
|
||||
pm8001_ha->flags = PM8001F_RUN_TIME;
|
||||
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
|
||||
pm8001_ha->phy[i].enable_completion = &completion;
|
||||
|
@ -1164,6 +1339,20 @@ static struct pci_device_id pm8001_pci_table[] = {
|
|||
PCI_VENDOR_ID_ADAPTEC2, 0x0808, 0, 0, chip_8077 },
|
||||
{ PCI_VENDOR_ID_ADAPTEC2, 0x8074,
|
||||
PCI_VENDOR_ID_ADAPTEC2, 0x0404, 0, 0, chip_8074 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8070,
|
||||
PCI_VENDOR_ID_ATTO, 0x0070, 0, 0, chip_8070 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8070,
|
||||
PCI_VENDOR_ID_ATTO, 0x0071, 0, 0, chip_8070 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8072,
|
||||
PCI_VENDOR_ID_ATTO, 0x0072, 0, 0, chip_8072 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8072,
|
||||
PCI_VENDOR_ID_ATTO, 0x0073, 0, 0, chip_8072 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8070,
|
||||
PCI_VENDOR_ID_ATTO, 0x0080, 0, 0, chip_8070 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8072,
|
||||
PCI_VENDOR_ID_ATTO, 0x0081, 0, 0, chip_8072 },
|
||||
{ PCI_VENDOR_ID_ATTO, 0x8072,
|
||||
PCI_VENDOR_ID_ATTO, 0x0082, 0, 0, chip_8072 },
|
||||
{} /* terminate list */
|
||||
};
|
||||
|
||||
|
@ -1219,7 +1408,7 @@ MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>");
|
|||
MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>");
|
||||
MODULE_AUTHOR("Nikith Ganigarakoppal <Nikith.Ganigarakoppal@pmcs.com>");
|
||||
MODULE_DESCRIPTION(
|
||||
"PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077 "
|
||||
"PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077/8070/8072 "
|
||||
"SAS/SATA controller driver");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -106,7 +106,9 @@ do { \
|
|||
#define DEV_IS_EXPANDER(type) ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE))
|
||||
#define IS_SPCV_12G(dev) ((dev->device == 0X8074) \
|
||||
|| (dev->device == 0X8076) \
|
||||
|| (dev->device == 0X8077))
|
||||
|| (dev->device == 0X8077) \
|
||||
|| (dev->device == 0X8070) \
|
||||
|| (dev->device == 0X8072))
|
||||
|
||||
#define PM8001_NAME_LENGTH 32/* generic length of strings */
|
||||
extern struct list_head hba_list;
|
||||
|
@ -708,6 +710,8 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);
|
|||
int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
|
||||
void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
|
||||
u32 length, u8 *buf);
|
||||
void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
|
||||
u32 phy, u32 length, u32 *buf);
|
||||
int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
|
||||
ssize_t pm80xx_get_fatal_dump(struct device *cdev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
|
|
@ -1267,6 +1267,8 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)
|
|||
/* check iButton feature support for motherboard controller */
|
||||
if (pm8001_ha->pdev->subsystem_vendor !=
|
||||
PCI_VENDOR_ID_ADAPTEC2 &&
|
||||
pm8001_ha->pdev->subsystem_vendor !=
|
||||
PCI_VENDOR_ID_ATTO &&
|
||||
pm8001_ha->pdev->subsystem_vendor != 0) {
|
||||
ibutton0 = pm8001_cr32(pm8001_ha, 0,
|
||||
MSGU_HOST_SCRATCH_PAD_6);
|
||||
|
@ -4576,6 +4578,38 @@ void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
|
|||
}
|
||||
PM8001_INIT_DBG(pm8001_ha, pm8001_printk("phy settings completed\n"));
|
||||
}
|
||||
|
||||
void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
|
||||
u32 phy, u32 length, u32 *buf)
|
||||
{
|
||||
u32 tag, opc;
|
||||
int rc, i;
|
||||
struct set_phy_profile_req payload;
|
||||
struct inbound_queue_table *circularQ;
|
||||
|
||||
memset(&payload, 0, sizeof(payload));
|
||||
|
||||
rc = pm8001_tag_alloc(pm8001_ha, &tag);
|
||||
if (rc)
|
||||
PM8001_INIT_DBG(pm8001_ha, pm8001_printk("Invalid tag"));
|
||||
|
||||
circularQ = &pm8001_ha->inbnd_q_tbl[0];
|
||||
opc = OPC_INB_SET_PHY_PROFILE;
|
||||
|
||||
payload.tag = cpu_to_le32(tag);
|
||||
payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
|
||||
| (phy & 0xFF));
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
payload.reserved[i] = cpu_to_le32(*(buf + i));
|
||||
|
||||
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
|
||||
if (rc)
|
||||
pm8001_tag_free(pm8001_ha, tag);
|
||||
|
||||
PM8001_INIT_DBG(pm8001_ha,
|
||||
pm8001_printk("PHY %d settings applied", phy));
|
||||
}
|
||||
const struct pm8001_dispatch pm8001_80xx_dispatch = {
|
||||
.name = "pmc80xx",
|
||||
.chip_init = pm80xx_chip_init,
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <asm/processor.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
|
@ -5562,11 +5563,9 @@ static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
|
|||
__be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
|
||||
struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
|
||||
|
||||
struct timeval tv;
|
||||
__le64 timestamp;
|
||||
|
||||
do_gettimeofday(&tv);
|
||||
timestamp = tv.tv_sec * 1000;
|
||||
timestamp = ktime_get_real_seconds() * 1000;
|
||||
|
||||
pinstance->timestamp_data->timestamp[0] = (__u8)(timestamp);
|
||||
pinstance->timestamp_data->timestamp[1] = (__u8)((timestamp) >> 8);
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
* Default timeout
|
||||
*/
|
||||
#define SCSI_TIMEOUT (2*HZ)
|
||||
#define SCSI_REPORT_LUNS_TIMEOUT (30*HZ)
|
||||
|
||||
/*
|
||||
* Prefix values for the SCSI id's (stored in sysfs name field)
|
||||
|
@ -1382,7 +1383,7 @@ retry:
|
|||
|
||||
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
|
||||
lun_data, length, &sshdr,
|
||||
SCSI_TIMEOUT + 4 * HZ, 3, NULL);
|
||||
SCSI_REPORT_LUNS_TIMEOUT, 3, NULL);
|
||||
|
||||
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
|
||||
"scsi scan: REPORT LUNS"
|
||||
|
@ -1711,8 +1712,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
|
|||
return NULL;
|
||||
|
||||
if (shost->async_scan) {
|
||||
shost_printk(KERN_INFO, shost, "%s called twice\n", __func__);
|
||||
dump_stack();
|
||||
shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -773,6 +773,29 @@ static struct bin_attribute dev_attr_vpd_##_page = { \
|
|||
sdev_vpd_pg_attr(pg83);
|
||||
sdev_vpd_pg_attr(pg80);
|
||||
|
||||
static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
|
||||
if (!sdev->inquiry)
|
||||
return -EINVAL;
|
||||
|
||||
return memory_read_from_buffer(buf, count, &off, sdev->inquiry,
|
||||
sdev->inquiry_len);
|
||||
}
|
||||
|
||||
static struct bin_attribute dev_attr_inquiry = {
|
||||
.attr = {
|
||||
.name = "inquiry",
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
.size = 0,
|
||||
.read = show_inquiry,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
@ -957,6 +980,7 @@ static struct attribute *scsi_sdev_attrs[] = {
|
|||
static struct bin_attribute *scsi_sdev_bin_attrs[] = {
|
||||
&dev_attr_vpd_pg83,
|
||||
&dev_attr_vpd_pg80,
|
||||
&dev_attr_inquiry,
|
||||
NULL
|
||||
};
|
||||
static struct attribute_group scsi_sdev_attr_group = {
|
||||
|
|
|
@ -204,6 +204,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
|
|||
buffer_data[2] &= ~0x05;
|
||||
buffer_data[2] |= wce << 2 | rcd;
|
||||
sp = buffer_data[0] & 0x80 ? 1 : 0;
|
||||
buffer_data[0] &= ~0x80;
|
||||
|
||||
if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT,
|
||||
SD_MAX_RETRIES, &data, &sshdr)) {
|
||||
|
|
|
@ -787,8 +787,14 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
|
|||
return k; /* probably out of space --> ENOMEM */
|
||||
}
|
||||
if (atomic_read(&sdp->detaching)) {
|
||||
if (srp->bio)
|
||||
if (srp->bio) {
|
||||
if (srp->rq->cmd != srp->rq->__cmd)
|
||||
kfree(srp->rq->cmd);
|
||||
|
||||
blk_end_request_all(srp->rq, -EIO);
|
||||
srp->rq = NULL;
|
||||
}
|
||||
|
||||
sg_finish_rem_req(srp);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ config SCSI_UFSHCD_PLATFORM
|
|||
If unsure, say N.
|
||||
|
||||
config SCSI_UFS_QCOM
|
||||
bool "QCOM specific hooks to UFS controller platform driver"
|
||||
tristate "QCOM specific hooks to UFS controller platform driver"
|
||||
depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
|
||||
select PHY_QCOM_UFS
|
||||
help
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -35,8 +35,8 @@
|
|||
|
||||
#define UFS_QCOM_LIMIT_NUM_LANES_RX 2
|
||||
#define UFS_QCOM_LIMIT_NUM_LANES_TX 2
|
||||
#define UFS_QCOM_LIMIT_HSGEAR_RX UFS_HS_G2
|
||||
#define UFS_QCOM_LIMIT_HSGEAR_TX UFS_HS_G2
|
||||
#define UFS_QCOM_LIMIT_HSGEAR_RX UFS_HS_G3
|
||||
#define UFS_QCOM_LIMIT_HSGEAR_TX UFS_HS_G3
|
||||
#define UFS_QCOM_LIMIT_PWMGEAR_RX UFS_PWM_G4
|
||||
#define UFS_QCOM_LIMIT_PWMGEAR_TX UFS_PWM_G4
|
||||
#define UFS_QCOM_LIMIT_RX_PWR_PWM SLOW_MODE
|
||||
|
@ -58,6 +58,21 @@ enum {
|
|||
REG_UFS_CFG2 = 0xE0,
|
||||
REG_UFS_HW_VERSION = 0xE4,
|
||||
|
||||
UFS_TEST_BUS = 0xE8,
|
||||
UFS_TEST_BUS_CTRL_0 = 0xEC,
|
||||
UFS_TEST_BUS_CTRL_1 = 0xF0,
|
||||
UFS_TEST_BUS_CTRL_2 = 0xF4,
|
||||
UFS_UNIPRO_CFG = 0xF8,
|
||||
|
||||
/*
|
||||
* QCOM UFS host controller vendor specific registers
|
||||
* added in HW Version 3.0.0
|
||||
*/
|
||||
UFS_AH8_CFG = 0xFC,
|
||||
};
|
||||
|
||||
/* QCOM UFS host controller vendor specific debug registers */
|
||||
enum {
|
||||
UFS_DBG_RD_REG_UAWM = 0x100,
|
||||
UFS_DBG_RD_REG_UARM = 0x200,
|
||||
UFS_DBG_RD_REG_TXUC = 0x300,
|
||||
|
@ -73,6 +88,14 @@ enum {
|
|||
UFS_UFS_DBG_RD_EDTL_RAM = 0x1900,
|
||||
};
|
||||
|
||||
#define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x) (0x000 + x)
|
||||
#define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x) (0x400 + x)
|
||||
|
||||
/* bit definitions for REG_UFS_CFG1 register */
|
||||
#define QUNIPRO_SEL UFS_BIT(0)
|
||||
#define TEST_BUS_EN BIT(18)
|
||||
#define TEST_BUS_SEL GENMASK(22, 19)
|
||||
|
||||
/* bit definitions for REG_UFS_CFG2 register */
|
||||
#define UAWM_HW_CGC_EN (1 << 0)
|
||||
#define UARM_HW_CGC_EN (1 << 1)
|
||||
|
@ -83,6 +106,9 @@ enum {
|
|||
#define TMRLUT_HW_CGC_EN (1 << 6)
|
||||
#define OCSC_HW_CGC_EN (1 << 7)
|
||||
|
||||
/* bit definition for UFS_UFS_TEST_BUS_CTRL_n */
|
||||
#define TEST_BUS_SUB_SEL_MASK 0x1F /* All XXX_SEL fields are 5 bits wide */
|
||||
|
||||
#define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\
|
||||
TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\
|
||||
DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\
|
||||
|
@ -106,6 +132,21 @@ enum ufs_qcom_phy_init_type {
|
|||
UFS_PHY_INIT_CFG_RESTORE,
|
||||
};
|
||||
|
||||
/* QCOM UFS debug print bit mask */
|
||||
#define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0)
|
||||
#define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1)
|
||||
#define UFS_QCOM_DBG_PRINT_TEST_BUS_EN BIT(2)
|
||||
|
||||
#define UFS_QCOM_DBG_PRINT_ALL \
|
||||
(UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_ICE_REGS_EN | \
|
||||
UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
|
||||
|
||||
/* QUniPro Vendor specific attributes */
|
||||
#define DME_VS_CORE_CLK_CTRL 0xD002
|
||||
/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */
|
||||
#define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8)
|
||||
#define DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK 0xFF
|
||||
|
||||
static inline void
|
||||
ufs_qcom_get_controller_revision(struct ufs_hba *hba,
|
||||
u8 *major, u16 *minor, u16 *step)
|
||||
|
@ -157,8 +198,13 @@ struct ufs_hw_version {
|
|||
u16 minor;
|
||||
u8 major;
|
||||
};
|
||||
struct ufs_qcom_host {
|
||||
|
||||
struct ufs_qcom_testbus {
|
||||
u8 select_major;
|
||||
u8 select_minor;
|
||||
};
|
||||
|
||||
struct ufs_qcom_host {
|
||||
/*
|
||||
* Set this capability if host controller supports the QUniPro mode
|
||||
* and if driver wants the Host controller to operate in QUniPro mode.
|
||||
|
@ -166,6 +212,12 @@ struct ufs_qcom_host {
|
|||
* controller supports the QUniPro mode.
|
||||
*/
|
||||
#define UFS_QCOM_CAP_QUNIPRO UFS_BIT(0)
|
||||
|
||||
/*
|
||||
* Set this capability if host controller can retain the secure
|
||||
* configuration even after UFS controller core power collapse.
|
||||
*/
|
||||
#define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE UFS_BIT(1)
|
||||
u32 caps;
|
||||
|
||||
struct phy *generic_phy;
|
||||
|
@ -178,13 +230,23 @@ struct ufs_qcom_host {
|
|||
struct clk *tx_l1_sync_clk;
|
||||
bool is_lane_clks_enabled;
|
||||
|
||||
void __iomem *dev_ref_clk_ctrl_mmio;
|
||||
bool is_dev_ref_clk_enabled;
|
||||
struct ufs_hw_version hw_ver;
|
||||
|
||||
u32 dev_ref_clk_en_mask;
|
||||
|
||||
/* Bitmask for enabling debug prints */
|
||||
u32 dbg_print_en;
|
||||
struct ufs_qcom_testbus testbus;
|
||||
};
|
||||
|
||||
#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba)
|
||||
#define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba)
|
||||
#define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba)
|
||||
|
||||
int ufs_qcom_testbus_config(struct ufs_qcom_host *host);
|
||||
|
||||
static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host)
|
||||
{
|
||||
if (host->caps & UFS_QCOM_CAP_QUNIPRO)
|
||||
|
|
|
@ -38,20 +38,7 @@
|
|||
#include <linux/of.h>
|
||||
|
||||
#include "ufshcd.h"
|
||||
|
||||
static const struct of_device_id ufs_of_match[];
|
||||
static struct ufs_hba_variant_ops *get_variant_ops(struct device *dev)
|
||||
{
|
||||
if (dev->of_node) {
|
||||
const struct of_device_id *match;
|
||||
|
||||
match = of_match_node(ufs_of_match, dev->of_node);
|
||||
if (match)
|
||||
return (struct ufs_hba_variant_ops *)match->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#include "ufshcd-pltfrm.h"
|
||||
|
||||
static int ufshcd_parse_clock_info(struct ufs_hba *hba)
|
||||
{
|
||||
|
@ -245,10 +232,11 @@ out:
|
|||
* Returns 0 if successful
|
||||
* Returns non-zero otherwise
|
||||
*/
|
||||
static int ufshcd_pltfrm_suspend(struct device *dev)
|
||||
int ufshcd_pltfrm_suspend(struct device *dev)
|
||||
{
|
||||
return ufshcd_system_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_suspend);
|
||||
|
||||
/**
|
||||
* ufshcd_pltfrm_resume - resume power management function
|
||||
|
@ -257,43 +245,47 @@ static int ufshcd_pltfrm_suspend(struct device *dev)
|
|||
* Returns 0 if successful
|
||||
* Returns non-zero otherwise
|
||||
*/
|
||||
static int ufshcd_pltfrm_resume(struct device *dev)
|
||||
int ufshcd_pltfrm_resume(struct device *dev)
|
||||
{
|
||||
return ufshcd_system_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_resume);
|
||||
|
||||
static int ufshcd_pltfrm_runtime_suspend(struct device *dev)
|
||||
int ufshcd_pltfrm_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return ufshcd_runtime_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
static int ufshcd_pltfrm_runtime_resume(struct device *dev)
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_suspend);
|
||||
|
||||
int ufshcd_pltfrm_runtime_resume(struct device *dev)
|
||||
{
|
||||
return ufshcd_runtime_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
static int ufshcd_pltfrm_runtime_idle(struct device *dev)
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_resume);
|
||||
|
||||
int ufshcd_pltfrm_runtime_idle(struct device *dev)
|
||||
{
|
||||
return ufshcd_runtime_idle(dev_get_drvdata(dev));
|
||||
}
|
||||
#else /* !CONFIG_PM */
|
||||
#define ufshcd_pltfrm_suspend NULL
|
||||
#define ufshcd_pltfrm_resume NULL
|
||||
#define ufshcd_pltfrm_runtime_suspend NULL
|
||||
#define ufshcd_pltfrm_runtime_resume NULL
|
||||
#define ufshcd_pltfrm_runtime_idle NULL
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_idle);
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
|
||||
void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown);
|
||||
|
||||
/**
|
||||
* ufshcd_pltfrm_probe - probe routine of the driver
|
||||
* ufshcd_pltfrm_init - probe routine of the driver
|
||||
* @pdev: pointer to Platform device handle
|
||||
* @vops: pointer to variant ops
|
||||
*
|
||||
* Returns 0 on success, non-zero value on failure
|
||||
*/
|
||||
static int ufshcd_pltfrm_probe(struct platform_device *pdev)
|
||||
int ufshcd_pltfrm_init(struct platform_device *pdev,
|
||||
struct ufs_hba_variant_ops *vops)
|
||||
{
|
||||
struct ufs_hba *hba;
|
||||
void __iomem *mmio_base;
|
||||
|
@ -321,19 +313,19 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
hba->vops = get_variant_ops(&pdev->dev);
|
||||
hba->vops = vops;
|
||||
|
||||
err = ufshcd_parse_clock_info(hba);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "%s: clock parse failed %d\n",
|
||||
__func__, err);
|
||||
goto out;
|
||||
goto dealloc_host;
|
||||
}
|
||||
err = ufshcd_parse_regulator_info(hba);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "%s: regulator init failed %d\n",
|
||||
__func__, err);
|
||||
goto out;
|
||||
goto dealloc_host;
|
||||
}
|
||||
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
|
@ -352,50 +344,12 @@ static int ufshcd_pltfrm_probe(struct platform_device *pdev)
|
|||
out_disable_rpm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
dealloc_host:
|
||||
ufshcd_dealloc_host(hba);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_pltfrm_remove - remove platform driver routine
|
||||
* @pdev: pointer to platform device handle
|
||||
*
|
||||
* Returns 0 on success, non-zero value on failure
|
||||
*/
|
||||
static int ufshcd_pltfrm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ufs_hba *hba = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_get_sync(&(pdev)->dev);
|
||||
ufshcd_remove(hba);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id ufs_of_match[] = {
|
||||
{ .compatible = "jedec,ufs-1.1"},
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops ufshcd_dev_pm_ops = {
|
||||
.suspend = ufshcd_pltfrm_suspend,
|
||||
.resume = ufshcd_pltfrm_resume,
|
||||
.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
|
||||
.runtime_resume = ufshcd_pltfrm_runtime_resume,
|
||||
.runtime_idle = ufshcd_pltfrm_runtime_idle,
|
||||
};
|
||||
|
||||
static struct platform_driver ufshcd_pltfrm_driver = {
|
||||
.probe = ufshcd_pltfrm_probe,
|
||||
.remove = ufshcd_pltfrm_remove,
|
||||
.shutdown = ufshcd_pltfrm_shutdown,
|
||||
.driver = {
|
||||
.name = "ufshcd",
|
||||
.pm = &ufshcd_dev_pm_ops,
|
||||
.of_match_table = ufs_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(ufshcd_pltfrm_driver);
|
||||
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);
|
||||
|
||||
MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
|
||||
MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 UFSHCD_PLTFRM_H_
|
||||
#define UFSHCD_PLTFRM_H_
|
||||
|
||||
#include "ufshcd.h"
|
||||
|
||||
int ufshcd_pltfrm_init(struct platform_device *pdev,
|
||||
struct ufs_hba_variant_ops *vops);
|
||||
void ufshcd_pltfrm_shutdown(struct platform_device *pdev);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
int ufshcd_pltfrm_suspend(struct device *dev);
|
||||
int ufshcd_pltfrm_resume(struct device *dev);
|
||||
int ufshcd_pltfrm_runtime_suspend(struct device *dev);
|
||||
int ufshcd_pltfrm_runtime_resume(struct device *dev);
|
||||
int ufshcd_pltfrm_runtime_idle(struct device *dev);
|
||||
|
||||
#else /* !CONFIG_PM */
|
||||
|
||||
#define ufshcd_pltfrm_suspend NULL
|
||||
#define ufshcd_pltfrm_resume NULL
|
||||
#define ufshcd_pltfrm_runtime_suspend NULL
|
||||
#define ufshcd_pltfrm_runtime_resume NULL
|
||||
#define ufshcd_pltfrm_runtime_idle NULL
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#endif /* UFSHCD_PLTFRM_H_ */
|
|
@ -271,10 +271,8 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
|
|||
*/
|
||||
static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) {
|
||||
if (hba->vops && hba->vops->get_ufs_hci_version)
|
||||
return hba->vops->get_ufs_hci_version(hba);
|
||||
}
|
||||
if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION)
|
||||
return ufshcd_vops_get_ufs_hci_version(hba);
|
||||
|
||||
return ufshcd_readl(hba, REG_UFS_VERSION);
|
||||
}
|
||||
|
@ -627,6 +625,7 @@ start:
|
|||
out:
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_hold);
|
||||
|
||||
static void ufshcd_gate_work(struct work_struct *work)
|
||||
{
|
||||
|
@ -714,6 +713,7 @@ void ufshcd_release(struct ufs_hba *hba)
|
|||
__ufshcd_release(hba);
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_release);
|
||||
|
||||
static ssize_t ufshcd_clkgate_delay_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
|
@ -2473,9 +2473,8 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba,
|
|||
dev_err(hba->dev,
|
||||
"%s: power mode change failed %d\n", __func__, ret);
|
||||
} else {
|
||||
if (hba->vops && hba->vops->pwr_change_notify)
|
||||
hba->vops->pwr_change_notify(hba,
|
||||
POST_CHANGE, NULL, pwr_mode);
|
||||
ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, NULL,
|
||||
pwr_mode);
|
||||
|
||||
memcpy(&hba->pwr_info, pwr_mode,
|
||||
sizeof(struct ufs_pa_layer_attr));
|
||||
|
@ -2495,10 +2494,10 @@ static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
|
|||
struct ufs_pa_layer_attr final_params = { 0 };
|
||||
int ret;
|
||||
|
||||
if (hba->vops && hba->vops->pwr_change_notify)
|
||||
hba->vops->pwr_change_notify(hba,
|
||||
PRE_CHANGE, desired_pwr_mode, &final_params);
|
||||
else
|
||||
ret = ufshcd_vops_pwr_change_notify(hba, PRE_CHANGE,
|
||||
desired_pwr_mode, &final_params);
|
||||
|
||||
if (ret)
|
||||
memcpy(&final_params, desired_pwr_mode, sizeof(final_params));
|
||||
|
||||
ret = ufshcd_change_power_mode(hba, &final_params);
|
||||
|
@ -2647,8 +2646,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
|
|||
/* UniPro link is disabled at this point */
|
||||
ufshcd_set_link_off(hba);
|
||||
|
||||
if (hba->vops && hba->vops->hce_enable_notify)
|
||||
hba->vops->hce_enable_notify(hba, PRE_CHANGE);
|
||||
ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE);
|
||||
|
||||
/* start controller initialization sequence */
|
||||
ufshcd_hba_start(hba);
|
||||
|
@ -2681,8 +2679,7 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
|
|||
/* enable UIC related interrupts */
|
||||
ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
|
||||
|
||||
if (hba->vops && hba->vops->hce_enable_notify)
|
||||
hba->vops->hce_enable_notify(hba, POST_CHANGE);
|
||||
ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2735,8 +2732,7 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
|
|||
int retries = DME_LINKSTARTUP_RETRIES;
|
||||
|
||||
do {
|
||||
if (hba->vops && hba->vops->link_startup_notify)
|
||||
hba->vops->link_startup_notify(hba, PRE_CHANGE);
|
||||
ufshcd_vops_link_startup_notify(hba, PRE_CHANGE);
|
||||
|
||||
ret = ufshcd_dme_link_startup(hba);
|
||||
|
||||
|
@ -2767,11 +2763,9 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
|
|||
}
|
||||
|
||||
/* Include any host controller configuration via UIC commands */
|
||||
if (hba->vops && hba->vops->link_startup_notify) {
|
||||
ret = hba->vops->link_startup_notify(hba, POST_CHANGE);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
ret = ufshcd_vops_link_startup_notify(hba, POST_CHANGE);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = ufshcd_make_hba_operational(hba);
|
||||
out:
|
||||
|
@ -4577,8 +4571,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
|
|||
}
|
||||
}
|
||||
|
||||
if (hba->vops && hba->vops->setup_clocks)
|
||||
ret = hba->vops->setup_clocks(hba, on);
|
||||
ret = ufshcd_vops_setup_clocks(hba, on);
|
||||
out:
|
||||
if (ret) {
|
||||
list_for_each_entry(clki, head, list) {
|
||||
|
@ -4644,27 +4637,22 @@ static int ufshcd_variant_hba_init(struct ufs_hba *hba)
|
|||
if (!hba->vops)
|
||||
goto out;
|
||||
|
||||
if (hba->vops->init) {
|
||||
err = hba->vops->init(hba);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
err = ufshcd_vops_init(hba);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (hba->vops->setup_regulators) {
|
||||
err = hba->vops->setup_regulators(hba, true);
|
||||
if (err)
|
||||
goto out_exit;
|
||||
}
|
||||
err = ufshcd_vops_setup_regulators(hba, true);
|
||||
if (err)
|
||||
goto out_exit;
|
||||
|
||||
goto out;
|
||||
|
||||
out_exit:
|
||||
if (hba->vops->exit)
|
||||
hba->vops->exit(hba);
|
||||
ufshcd_vops_exit(hba);
|
||||
out:
|
||||
if (err)
|
||||
dev_err(hba->dev, "%s: variant %s init failed err %d\n",
|
||||
__func__, hba->vops ? hba->vops->name : "", err);
|
||||
__func__, ufshcd_get_var_name(hba), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -4673,14 +4661,11 @@ static void ufshcd_variant_hba_exit(struct ufs_hba *hba)
|
|||
if (!hba->vops)
|
||||
return;
|
||||
|
||||
if (hba->vops->setup_clocks)
|
||||
hba->vops->setup_clocks(hba, false);
|
||||
ufshcd_vops_setup_clocks(hba, false);
|
||||
|
||||
if (hba->vops->setup_regulators)
|
||||
hba->vops->setup_regulators(hba, false);
|
||||
ufshcd_vops_setup_regulators(hba, false);
|
||||
|
||||
if (hba->vops->exit)
|
||||
hba->vops->exit(hba);
|
||||
ufshcd_vops_exit(hba);
|
||||
}
|
||||
|
||||
static int ufshcd_hba_init(struct ufs_hba *hba)
|
||||
|
@ -5057,17 +5042,13 @@ disable_clks:
|
|||
* vendor specific host controller register space call them before the
|
||||
* host clocks are ON.
|
||||
*/
|
||||
if (hba->vops && hba->vops->suspend) {
|
||||
ret = hba->vops->suspend(hba, pm_op);
|
||||
if (ret)
|
||||
goto set_link_active;
|
||||
}
|
||||
ret = ufshcd_vops_suspend(hba, pm_op);
|
||||
if (ret)
|
||||
goto set_link_active;
|
||||
|
||||
if (hba->vops && hba->vops->setup_clocks) {
|
||||
ret = hba->vops->setup_clocks(hba, false);
|
||||
if (ret)
|
||||
goto vops_resume;
|
||||
}
|
||||
ret = ufshcd_vops_setup_clocks(hba, false);
|
||||
if (ret)
|
||||
goto vops_resume;
|
||||
|
||||
if (!ufshcd_is_link_active(hba))
|
||||
ufshcd_setup_clocks(hba, false);
|
||||
|
@ -5078,7 +5059,7 @@ disable_clks:
|
|||
hba->clk_gating.state = CLKS_OFF;
|
||||
/*
|
||||
* Disable the host irq as host controller as there won't be any
|
||||
* host controller trasanction expected till resume.
|
||||
* host controller transaction expected till resume.
|
||||
*/
|
||||
ufshcd_disable_irq(hba);
|
||||
/* Put the host controller in low power mode if possible */
|
||||
|
@ -5086,8 +5067,7 @@ disable_clks:
|
|||
goto out;
|
||||
|
||||
vops_resume:
|
||||
if (hba->vops && hba->vops->resume)
|
||||
hba->vops->resume(hba, pm_op);
|
||||
ufshcd_vops_resume(hba, pm_op);
|
||||
set_link_active:
|
||||
ufshcd_vreg_set_hpm(hba);
|
||||
if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba))
|
||||
|
@ -5143,11 +5123,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
|
|||
* vendor specific host controller register space call them when the
|
||||
* host clocks are ON.
|
||||
*/
|
||||
if (hba->vops && hba->vops->resume) {
|
||||
ret = hba->vops->resume(hba, pm_op);
|
||||
if (ret)
|
||||
goto disable_vreg;
|
||||
}
|
||||
ret = ufshcd_vops_resume(hba, pm_op);
|
||||
if (ret)
|
||||
goto disable_vreg;
|
||||
|
||||
if (ufshcd_is_link_hibern8(hba)) {
|
||||
ret = ufshcd_uic_hibern8_exit(hba);
|
||||
|
@ -5188,8 +5166,7 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
|
|||
set_old_link_state:
|
||||
ufshcd_link_state_transition(hba, old_link_state, 0);
|
||||
vendor_suspend:
|
||||
if (hba->vops && hba->vops->suspend)
|
||||
hba->vops->suspend(hba, pm_op);
|
||||
ufshcd_vops_suspend(hba, pm_op);
|
||||
disable_vreg:
|
||||
ufshcd_vreg_set_lpm(hba);
|
||||
disable_irq_and_vops_clks:
|
||||
|
@ -5371,6 +5348,16 @@ void ufshcd_remove(struct ufs_hba *hba)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_remove);
|
||||
|
||||
/**
|
||||
* ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA)
|
||||
* @hba: pointer to Host Bus Adapter (HBA)
|
||||
*/
|
||||
void ufshcd_dealloc_host(struct ufs_hba *hba)
|
||||
{
|
||||
scsi_host_put(hba->host);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);
|
||||
|
||||
/**
|
||||
* ufshcd_set_dma_mask - Set dma mask based on the controller
|
||||
* addressing capability
|
||||
|
@ -5432,6 +5419,10 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
|
|||
if (!head || list_empty(head))
|
||||
goto out;
|
||||
|
||||
ret = ufshcd_vops_clk_scale_notify(hba, scale_up, PRE_CHANGE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_for_each_entry(clki, head, list) {
|
||||
if (!IS_ERR_OR_NULL(clki->clk)) {
|
||||
if (scale_up && clki->max_freq) {
|
||||
|
@ -5462,8 +5453,9 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up)
|
|||
dev_dbg(hba->dev, "%s: clk: %s, rate: %lu\n", __func__,
|
||||
clki->name, clk_get_rate(clki->clk));
|
||||
}
|
||||
if (hba->vops->clk_scale_notify)
|
||||
hba->vops->clk_scale_notify(hba);
|
||||
|
||||
ret = ufshcd_vops_clk_scale_notify(hba, scale_up, POST_CHANGE);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -223,8 +223,10 @@ struct ufs_clk_info {
|
|||
bool enabled;
|
||||
};
|
||||
|
||||
#define PRE_CHANGE 0
|
||||
#define POST_CHANGE 1
|
||||
enum ufs_notify_change_status {
|
||||
PRE_CHANGE,
|
||||
POST_CHANGE,
|
||||
};
|
||||
|
||||
struct ufs_pa_layer_attr {
|
||||
u32 gear_rx;
|
||||
|
@ -259,22 +261,28 @@ struct ufs_pwr_mode_info {
|
|||
* to be set.
|
||||
* @suspend: called during host controller PM callback
|
||||
* @resume: called during host controller PM callback
|
||||
* @dbg_register_dump: used to dump controller debug information
|
||||
*/
|
||||
struct ufs_hba_variant_ops {
|
||||
const char *name;
|
||||
int (*init)(struct ufs_hba *);
|
||||
void (*exit)(struct ufs_hba *);
|
||||
u32 (*get_ufs_hci_version)(struct ufs_hba *);
|
||||
void (*clk_scale_notify)(struct ufs_hba *);
|
||||
int (*setup_clocks)(struct ufs_hba *, bool);
|
||||
int (*clk_scale_notify)(struct ufs_hba *, bool,
|
||||
enum ufs_notify_change_status);
|
||||
int (*setup_clocks)(struct ufs_hba *, bool);
|
||||
int (*setup_regulators)(struct ufs_hba *, bool);
|
||||
int (*hce_enable_notify)(struct ufs_hba *, bool);
|
||||
int (*link_startup_notify)(struct ufs_hba *, bool);
|
||||
int (*hce_enable_notify)(struct ufs_hba *,
|
||||
enum ufs_notify_change_status);
|
||||
int (*link_startup_notify)(struct ufs_hba *,
|
||||
enum ufs_notify_change_status);
|
||||
int (*pwr_change_notify)(struct ufs_hba *,
|
||||
bool, struct ufs_pa_layer_attr *,
|
||||
enum ufs_notify_change_status status,
|
||||
struct ufs_pa_layer_attr *,
|
||||
struct ufs_pa_layer_attr *);
|
||||
int (*suspend)(struct ufs_hba *, enum ufs_pm_op);
|
||||
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
|
||||
void (*dbg_register_dump)(struct ufs_hba *hba);
|
||||
};
|
||||
|
||||
/* clock gating state */
|
||||
|
@ -576,6 +584,7 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg)
|
|||
}
|
||||
|
||||
int ufshcd_alloc_host(struct device *, struct ufs_hba **);
|
||||
void ufshcd_dealloc_host(struct ufs_hba *);
|
||||
int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int);
|
||||
void ufshcd_remove(struct ufs_hba *);
|
||||
|
||||
|
@ -594,6 +603,27 @@ static inline void check_upiu_size(void)
|
|||
GENERAL_UPIU_REQUEST_SIZE + QUERY_DESC_MAX_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_set_variant - set variant specific data to the hba
|
||||
* @hba - per adapter instance
|
||||
* @variant - pointer to variant specific data
|
||||
*/
|
||||
static inline void ufshcd_set_variant(struct ufs_hba *hba, void *variant)
|
||||
{
|
||||
BUG_ON(!hba);
|
||||
hba->priv = variant;
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_get_variant - get variant specific data from the hba
|
||||
* @hba - per adapter instance
|
||||
*/
|
||||
static inline void *ufshcd_get_variant(struct ufs_hba *hba)
|
||||
{
|
||||
BUG_ON(!hba);
|
||||
return hba->priv;
|
||||
}
|
||||
|
||||
extern int ufshcd_runtime_suspend(struct ufs_hba *hba);
|
||||
extern int ufshcd_runtime_resume(struct ufs_hba *hba);
|
||||
extern int ufshcd_runtime_idle(struct ufs_hba *hba);
|
||||
|
@ -653,4 +683,109 @@ static inline int ufshcd_dme_peer_get(struct ufs_hba *hba,
|
|||
|
||||
int ufshcd_hold(struct ufs_hba *hba, bool async);
|
||||
void ufshcd_release(struct ufs_hba *hba);
|
||||
|
||||
/* Wrapper functions for safely calling variant operations */
|
||||
static inline const char *ufshcd_get_var_name(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->vops)
|
||||
return hba->vops->name;
|
||||
return "";
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_init(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->vops && hba->vops->init)
|
||||
return hba->vops->init(hba);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ufshcd_vops_exit(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->vops && hba->vops->exit)
|
||||
return hba->vops->exit(hba);
|
||||
}
|
||||
|
||||
static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->vops && hba->vops->get_ufs_hci_version)
|
||||
return hba->vops->get_ufs_hci_version(hba);
|
||||
|
||||
return ufshcd_readl(hba, REG_UFS_VERSION);
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba,
|
||||
bool up, enum ufs_notify_change_status status)
|
||||
{
|
||||
if (hba->vops && hba->vops->clk_scale_notify)
|
||||
return hba->vops->clk_scale_notify(hba, up, status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on)
|
||||
{
|
||||
if (hba->vops && hba->vops->setup_clocks)
|
||||
return hba->vops->setup_clocks(hba, on);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_setup_regulators(struct ufs_hba *hba, bool status)
|
||||
{
|
||||
if (hba->vops && hba->vops->setup_regulators)
|
||||
return hba->vops->setup_regulators(hba, status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_hce_enable_notify(struct ufs_hba *hba,
|
||||
bool status)
|
||||
{
|
||||
if (hba->vops && hba->vops->hce_enable_notify)
|
||||
return hba->vops->hce_enable_notify(hba, status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static inline int ufshcd_vops_link_startup_notify(struct ufs_hba *hba,
|
||||
bool status)
|
||||
{
|
||||
if (hba->vops && hba->vops->link_startup_notify)
|
||||
return hba->vops->link_startup_notify(hba, status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba,
|
||||
bool status,
|
||||
struct ufs_pa_layer_attr *dev_max_params,
|
||||
struct ufs_pa_layer_attr *dev_req_params)
|
||||
{
|
||||
if (hba->vops && hba->vops->pwr_change_notify)
|
||||
return hba->vops->pwr_change_notify(hba, status,
|
||||
dev_max_params, dev_req_params);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
|
||||
{
|
||||
if (hba->vops && hba->vops->suspend)
|
||||
return hba->vops->suspend(hba, op);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_resume(struct ufs_hba *hba, enum ufs_pm_op op)
|
||||
{
|
||||
if (hba->vops && hba->vops->resume)
|
||||
return hba->vops->resume(hba, op);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->vops && hba->vops->dbg_register_dump)
|
||||
hba->vops->dbg_register_dump(hba);
|
||||
}
|
||||
|
||||
#endif /* End of Header */
|
||||
|
|
Загрузка…
Ссылка в новой задаче