From: Martin K. Petersen Date: Fri, 23 Sep 2011 00:54:11 +0000 (-0400) Subject: mpt2sas: Do not check DIF for unwritten blocks X-Git-Tag: v2.6.39-400.9.0~887^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=72e4d3bc42de030f72627684ed19d3d584a1a062;p=users%2Fjedix%2Flinux-maple.git mpt2sas: Do not check DIF for unwritten blocks Blocks that have never been written contain all ones in the protection information. When reading, a target device will disable checking for any block whose application tag contains 0xFFFF. Some MPT adapters, however, enable checking for all blocks by default. This causes reads to previously unwritten sectors to fail. Tweak the relevant bit in the MPT configuration page that causes the HBA to disable PI checking when a received app tag contains 0xFFFF. Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 1da606cb24613..5b4bddbb2706b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -2024,6 +2024,21 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) if (ioc->ir_firmware) mpt2sas_config_get_manufacturing_pg10(ioc, &mpi_reply, &ioc->manu_pg10); + + /* + * Ensure correct T10 PI operation if vendor left EEDPTagMode + * flag unset in NVDATA. + */ + mpt2sas_config_get_manufacturing_pg11(ioc, &mpi_reply, &ioc->manu_pg11); + if (ioc->manu_pg11.EEDPTagMode == 0) { + printk(KERN_ERR "%s: overriding NVDATA EEDPTagMode setting\n", + ioc->name); + ioc->manu_pg11.EEDPTagMode &= ~0x3; + ioc->manu_pg11.EEDPTagMode |= 0x1; + mpt2sas_config_set_manufacturing_pg11(ioc, &mpi_reply, + &ioc->manu_pg11); + } + mpt2sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2); mpt2sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3); mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 451dc1ce22874..3ea69cf95ee59 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h @@ -280,6 +280,19 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_10 { #define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01) #define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02) +/* Miscellaneous options */ +typedef struct _MPI2_CONFIG_PAGE_MAN_11 { + MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ + U32 Reserved1; /* 04h */ + U8 Reserved2; /* 08h */ + U8 EEDPTagMode; /* 09h */ + U8 Reserved3; /* 0Ah */ + U8 Reserved4; /* 0Bh */ + U32 Reserved5[23]; /* 0Ch-60h*/ +} MPI2_CONFIG_PAGE_MAN_11, + MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_11, + Mpi2ManufacturingPage11_t, MPI2_POINTER pMpi2ManufacturingPage11_t; + struct MPT2SAS_DEVICE { struct MPT2SAS_TARGET *sas_target; @@ -649,6 +662,7 @@ struct mpt2sas_port_facts { * @pfacts: static port facts data * @manu_pg0: static manufacturing page 0 * @manu_pg10: static manufacturing page 10 + * @manu_pg11: static manufacturing page 11 * @bios_pg2: static bios page 2 * @bios_pg3: static bios page 3 * @ioc_pg8: static ioc page 8 @@ -909,6 +923,7 @@ struct MPT2SAS_ADAPTER { u8 diag_buffer_status[MPI2_DIAG_BUF_TYPE_COUNT]; u32 unique_id[MPI2_DIAG_BUF_TYPE_COUNT]; Mpi2ManufacturingPage10_t manu_pg10; + Mpi2ManufacturingPage11_t manu_pg11; u32 product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23]; u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; u32 ring_buffer_offset; @@ -1002,6 +1017,10 @@ int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page); int mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page); +int mpt2sas_config_get_manufacturing_pg11(struct MPT2SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage11_t *config_page); +int mpt2sas_config_set_manufacturing_pg11(struct MPT2SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage11_t *config_page); int mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page); int mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 6861244249a3e..39b360321f748 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -503,6 +503,78 @@ mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc, return r; } +/** + * mpt2sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 + * @ioc: per adapter object + * @mpi_reply: reply mf payload returned from firmware + * @config_page: contents of the config page + * Context: sleep. + * + * Returns 0 for success, non-zero for failure. + */ +int +mpt2sas_config_get_manufacturing_pg11(struct MPT2SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage11_t *config_page) +{ + Mpi2ConfigRequest_t mpi_request; + int r; + + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); + mpi_request.Function = MPI2_FUNCTION_CONFIG; + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; + mpi_request.Header.PageNumber = 11; + mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; + mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); + if (r) + goto out; + + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, + sizeof(*config_page)); + out: + return r; +} + +/** + * mpt2sas_config_set_manufacturing_pg11 - set manufacturing page 11 + * @ioc: per adapter object + * @mpi_reply: reply mf payload returned from firmware + * @config_page: contents of the config page + * Context: sleep. + * + * Returns 0 for success, non-zero for failure. + */ +int +mpt2sas_config_set_manufacturing_pg11(struct MPT2SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage11_t *config_page) +{ + Mpi2ConfigRequest_t mpi_request; + int r; + + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); + mpi_request.Function = MPI2_FUNCTION_CONFIG; + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; + mpi_request.Header.PageNumber = 11; + mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; + mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); + if (r) + goto out; + + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, + sizeof(*config_page)); + out: + return r; +} + /** * mpt2sas_config_get_bios_pg2 - obtain bios page 2 * @ioc: per adapter object