[nvmewin] ModeSense Translation Issue
Robles, Raymond C
raymond.c.robles at intel.com
Fri Mar 22 13:54:57 PDT 2013
Hi Dharani,
Since this issue is directly related to the OFA Windows NVMe driver, you can redirect your question to the OFA NVMe distribution mailing list at nvmewin at lists.openfabrics.org<mailto:nvmewin at lists.openfabrics.org>. The technical at nvmepress.org<mailto:technical at nvmepress.org> distribution list is for the NVMe working group.
This is the open source community that originally developed the driver (similar to kernel.org for the Linux NVMe driver). We welcome any suggestions for improvements, defect identification, or anything relating to the OFA Windows NVMe driver.
We also encourage companies to submit patches for existing issues in the driver. Here are links with information on how to join the distribution list and about our patch submission process.
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/nvmewin --> subscribing to mailing list
https://www.openfabrics.org/resources/developer-tools/nvme-windows-development.html --> process on submitting patches and other misc. info
Thanks,
Ray
From: Dharani Kotte [mailto:Dharani.Kotte at sandisk.com]
Sent: Friday, March 22, 2013 1:41 PM
To: technical at nvmexpress.org
Subject: ModeSense Translation Issue
The ModeSense Translation is directly using pSrb->DataBuf to prepare the modesense data which is wrong. Because we are supposed to prepare the modesensedata in the local buffer and copy it based on the "allocLength" from the cdb which we actually the size of the pSrb->DataBuf. This is basically corrupting the Application buffer.
This needs a major change all over the ModeSense Translation code.
Example:
VOID SntiCreateModeDataHeader(
PSCSI_REQUEST_BLOCK pSrb,
PMODE_PARAMETER_BLOCK *ppModeParamBlock,
PUINT16 pModeDataLength,
UINT16 blockDescLength,
BOOLEAN modeSense10
)
{
PMODE_PARAMETER_HEADER pModeHeader6 = NULL;
PMODE_PARAMETER_HEADER10 pModeHeader10 = NULL;
if (modeSense10 == FALSE) {
/* MODE SENSE 6 */
pModeHeader6 = (PMODE_PARAMETER_HEADER)(GET_DATA_BUFFER(pSrb)); // This needs to be something like "gModesenseLocalBuf[]"
/* Set necessary fields */
memset(pModeHeader6, 0, sizeof(MODE_PARAMETER_HEADER));
pModeHeader6->MediumType = DIRECT_ACCESS_DEVICE;
pModeHeader6->DeviceSpecificParameter = 0;
pModeHeader6->BlockDescriptorLength = (UCHAR)blockDescLength;
}
VOID SntiTranslateCachingModePageResponse(
PNVME_SRB_EXTENSION pSrbExt,
PNVME_LUN_EXTENSION pLunExt,
PNVMe_COMPLETION_QUEUE_ENTRY pCQEntry,
UINT16 allocLength,
UINT8 longLbaAccepted,
UINT8 disableBlockDesc,
BOOLEAN modeSense10
)
{
PMODE_PARAMETER_HEADER pModeHeader6 = NULL;
PMODE_PARAMETER_HEADER10 pModeHeader10 = NULL;
PMODE_PARAMETER_BLOCK pModeParamBlock = NULL;
PCACHING_MODE_PAGE pCachingModePage = NULL;
PSCSI_REQUEST_BLOCK pSrb = pSrbExt->pSrb;
UINT32 volatileWriteCache = 0;
UINT16 modeDataLength = 0;
UINT16 blockDescLength = 0;
/* The Volatile Write Cache info will be stored in DWORD 0 of the CQE */
volatileWriteCache = pCQEntry->DW0;
memset(pSrb->DataBuffer, 0, allocLength);
/* Determine which Mode Parameter Descriptor Block to use (8 or 16) */
if (longLbaAccepted == 0)
blockDescLength = SHORT_DESC_BLOCK;
else
blockDescLength = LONG_DESC_BLOCK;
/* Mode Page Header */
SntiCreateModeDataHeader(pSrb,
&pModeParamBlock,
&modeDataLength,
(disableBlockDesc ? 0 : blockDescLength),
modeSense10);
/* Check if block descriptors enabled, if not, then mode pages comes next */
if (disableBlockDesc == BLOCK_DESCRIPTORS_ENABLED) {
/* Mode Parameter Descriptor Block */
SntiCreateModeParameterDescBlock(pLunExt,
pModeParamBlock,
&modeDataLength);
/* Increment pointer to after block descriptor */
pModeParamBlock++;
}
/* Caching Mode Page */
pCachingModePage = (PCACHING_MODE_PAGE)pModeParamBlock;
modeDataLength += sizeof(CACHING_MODE_PAGE);
memset(pCachingModePage, 0, sizeof(CACHING_MODE_PAGE));
pCachingModePage->PageCode = MODE_PAGE_CACHING;
pCachingModePage->PageSavable = MODE_PAGE_PARAM_SAVEABLE_DISABLED;
pCachingModePage->PageLength = CACHING_MODE_PAGE_LENGTH;
pCachingModePage->WriteCacheEnable = volatileWriteCache &
VOLATILE_WRITE_CACHE_MASK;
/* Now go back and set the Mode Data Length in the header */
if (modeSense10 == FALSE) {
/* Get the correct header that starts at the buffer beginning */
pModeHeader6 = (PMODE_PARAMETER_HEADER)(/* GET_DATA_BUFFER(pSrb)*/ gModesenseLocalBuf); // Changes
pModeHeader6->ModeDataLength = (UCHAR)(modeDataLength - 1);
} else {
/* Get the correct header that starts at the buffer beginning */
pModeHeader10 = (PMODE_PARAMETER_HEADER10)( /* GET_DATA_BUFFER(pSrb)*/ gModesenseLocalBuf); // Changes
pModeHeader10->ModeDataLength[0] =
((modeDataLength - 2) & WORD_HIGH_BYTE_MASK) >> BYTE_SHIFT_1;
pModeHeader10->ModeDataLength[1] =
((modeDataLength - 2) & WORD_LOW_BYTE_MASK);
}
pSrb->DataTransferLength = min(modeDataLength, allocLength);
StorPortCopyMemory((PVOID)pSrb->DataBuffer, (PVOID) gModesenseLocalBuf, pSrb->DataTransferLength); // Changes
pSrbExt->pSrb->ScsiStatus = SCSISTAT_GOOD;
pSrbExt->pSrb->SrbStatus = SRB_STATUS_SUCCESS;
} /* SntiTranslateCachingModePageResponse */
Thanks,
Dharani.
________________________________
PLEASE NOTE: The information contained in this electronic mail message is intended only for the use of the designated recipient(s) named above. If the reader of this message is not the intended recipient, you are hereby notified that you have received this message in error and that any review, dissemination, distribution, or copying of this message is strictly prohibited. If you have received this communication in error, please notify the sender by telephone or e-mail (as shown above) immediately and destroy any and all copies of this message in your possession (whether hard copies or electronically stored copies).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/nvmewin/attachments/20130322/eb2727a4/attachment.html>
More information about the nvmewin
mailing list