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:
commit
febdfbd213
68 changed files with 5848 additions and 31761 deletions
58
Documentation/devicetree/bindings/ufs/ufs-qcom.txt
Normal file
58
Documentation/devicetree/bindings/ufs/ufs-qcom.txt
Normal file
|
|
@ -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
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue