none
StorportWriteRegisterUlong() function call RRS feed

  • Question

  • In my SAS storport miniport driver, I am trying to write a DMA address in the StorPortHwInitialize() funtion using the StorPortWriteRegisterUlong() function and my program encounters a kernel panic.


    For a little bit of background:

    In HwFindAdapter routine,

    1) I get buffer area for my device queues using StorPortGetUncachedExtension() call.

    2) Then,  get DMAAddresses for these queues using the call  DMAPhysAddress StorPortConvertPhysicalAddressToUlong(StorPortGetPhysicalAddress (......))

    3) Then in HwInitialize() routine I write to these DMAAddresses for the queues using StorPortWriteRegister() ?

    At this time, the kernel panics. So,

    Question 1) are the steps listed above correct?

    Question 2) Is there a requirement of IRQL at which we can use StorPortWrite() call safely?

    Question 3) In other words, is it safe to use StorPortWriteRegisteUlong() call in HwInitialize() function?

    Thanks for your help.

    Friday, March 16, 2018 1:00 AM

Answers

  • This is not correct, if the buffer is to be used for DMA you are better off using StorPortAllocateContiguousMemorySpecifyCacheNode() since that will provide contiguous physical memory, and the StorPortGetUncachedExtension() call does not.

    If your device supports 64-bit addresses then you should not be using StorPortConvertPhysicalAddressToUlong since you are truncated the upper 32-bits of the address, if it only supports 32-bit addresses for DMA then StorPortAllocateContiguousMemorySpecifyCacheNode can allow you to allocate memory it can access.  

    If the device has a 64-bit register for DMA address then use StorPortWriteRegisterUlong64()

    StorPortWriteXXX and StorPortReadXXX calls work at any IRQL.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, March 16, 2018 1:58 PM
  • In a storport do not use MmAllocatePagesForMdl(), Storport should use Storport calls only.   In the past there were even checks in the WHQL testing to see if the driver was using some of the non-storport calls.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    • Marked as answer by P Krish Friday, March 16, 2018 5:23 PM
    Friday, March 16, 2018 5:21 PM

All replies

  • This is not correct, if the buffer is to be used for DMA you are better off using StorPortAllocateContiguousMemorySpecifyCacheNode() since that will provide contiguous physical memory, and the StorPortGetUncachedExtension() call does not.

    If your device supports 64-bit addresses then you should not be using StorPortConvertPhysicalAddressToUlong since you are truncated the upper 32-bits of the address, if it only supports 32-bit addresses for DMA then StorPortAllocateContiguousMemorySpecifyCacheNode can allow you to allocate memory it can access.  

    If the device has a 64-bit register for DMA address then use StorPortWriteRegisterUlong64()

    StorPortWriteXXX and StorPortReadXXX calls work at any IRQL.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, March 16, 2018 1:58 PM
  • Thanks for your response.Really appreciate your help.

    As I am figuring out the write mechanisms to use, I am wondering what is a better use case for MmAllocatePagesForMdl?

    1) Where should I use StorPortAllocate....() routines and where should I use MmAllocatePagesForMdl?

    Thanks.

    Friday, March 16, 2018 5:17 PM
  • In a storport do not use MmAllocatePagesForMdl(), Storport should use Storport calls only.   In the past there were even checks in the WHQL testing to see if the driver was using some of the non-storport calls.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    • Marked as answer by P Krish Friday, March 16, 2018 5:23 PM
    Friday, March 16, 2018 5:21 PM
  • Thanks for your help and sincerely appreciate your response.
    Friday, March 16, 2018 5:24 PM
  • I have a related question.

    In one of the routines, I need to get the number of pages that span a particular size and assign physically contiguous memory for the those pages.

    So, I am getting the number of pages using the function call ADDRESS_AND_SIZE_TO_SPAN_PAGES and using this as input to the size parameter in the call StorPortAllocateContiguousMemorySpecufyCacheNode(). I have put the code snippet below.

     ioc->chain_depth = min(ioc->chain_depth, MAX_CHAIN_DEPTH);
       sz = ioc->chain_depth * sizeof(struct chain_tracker);
       ioc->chain_pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(ioc->chain_lookup, sz);
       status = StorPortAllocateContiguousMemorySpecifyCacheNode(ioc,
                                                                                     ioc->chain_pages,
                                                                                     minPhysicalAddress,
                                                                                     maxPhysicalAddress,
                                                                                     boundaryPhysicalAddress,
                                                                                     MmCached,
                                                                                     MM_ANY_NODE_OK,
                                                                                     (PVOID *)&(ioc->chain_lookup) )

    1) Is this the correct way to get the number of pages needed and assign physical memory?

    Appreciate your response as always.

    Friday, March 16, 2018 8:07 PM
  • Sorry, I believe what I have listed above is wrong because, I was trying to do a Windows equivalent of get_free_pages() Linux call. Now, I believe that ExAllocateExAllocatePoolWithTag() with PagedPool option should do the job since it is only virtual memory associated and not physical memory. Please let me know if what I understand now is correct? I am happy to provide any further information to clarify my issue.

    Thanks.

    Friday, March 16, 2018 8:26 PM
  • StorPortAllocateContiguousMemorySpecifyCacheNode is the equivalent of get_free_pages().   You do not want to use ExAllocateXXX for this they are not physically contiguous.

    If you are allocating more than one page, StorPortAllocateContiguousMemorySpecifyCacheNode will return a page aligned block of memory.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, March 16, 2018 8:43 PM
  • Thanks for clarifying. Then I will not calculate the number of pages using ADDRESS_AND_SIZE_TO_SPAN_PAGES. but instead use bytes returned by the sizeof() macro for the size parameter (parameter 2)of the StorPortAllocateContiguousMemorySpecifyCacheNode() directly.

    Appreciate your help.

    Friday, March 16, 2018 9:11 PM