Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1991-1998 Microsoft Corporation
  3. Module Name:
  4. io.c
  5. Abstract:
  6. Author:
  7. Neil Sandlin (neilsa) 26-Apr-99
  8. Environment:
  9. Kernel mode only.
  10. --*/
  11. #include "pch.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text(PAGE,MemCardIrpReadWrite)
  14. #pragma alloc_text(PAGE,MemCardReadWrite)
  15. #endif
  16. NTSTATUS
  17. MemCardIrpReadWrite(
  18. IN PDEVICE_OBJECT DeviceObject,
  19. IN PIRP Irp
  20. )
  21. /*++
  22. Routine Description:
  23. This routine handles read/write irps for the memory card. It validates
  24. parameters and calls MemCardReadWrite to do the real work.
  25. Arguments:
  26. DeviceObject - a pointer to the object that represents the device
  27. that I/O is to be done on.
  28. Irp - a pointer to the I/O Request Packet for this request.
  29. Return Value:
  30. STATUS_SUCCESS if the packet was successfully read or written; the
  31. appropriate error is propogated otherwise.
  32. --*/
  33. {
  34. NTSTATUS status = STATUS_SUCCESS;
  35. PMEMCARD_EXTENSION memcardExtension = DeviceObject->DeviceExtension;
  36. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  37. BOOLEAN writeOperation;
  38. //
  39. // If the device is not active (not started yet or removed) we will
  40. // just fail this request outright.
  41. //
  42. if ( memcardExtension->IsRemoved || !memcardExtension->IsStarted) {
  43. if ( memcardExtension->IsRemoved) {
  44. status = STATUS_DELETE_PENDING;
  45. } else {
  46. status = STATUS_UNSUCCESSFUL;
  47. }
  48. goto ReadWriteComplete;
  49. }
  50. if (((irpSp->Parameters.Read.ByteOffset.LowPart +
  51. irpSp->Parameters.Read.Length) > memcardExtension->ByteCapacity) ||
  52. (irpSp->Parameters.Read.ByteOffset.HighPart != 0)) {
  53. status = STATUS_INVALID_PARAMETER;
  54. goto ReadWriteComplete;
  55. }
  56. //
  57. // verify that user is really expecting some I/O operation to
  58. // occur.
  59. //
  60. if (!irpSp->Parameters.Read.Length) {
  61. //
  62. // Complete this zero length request with no boost.
  63. //
  64. Irp->IoStatus.Status = STATUS_SUCCESS;
  65. goto ReadWriteComplete;
  66. }
  67. if ((DeviceObject->Flags & DO_VERIFY_VOLUME) && !(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
  68. //
  69. // The disk changed, and we set this bit. Fail
  70. // all current IRPs for this device; when all are
  71. // returned, the file system will clear
  72. // DO_VERIFY_VOLUME.
  73. //
  74. status = STATUS_VERIFY_REQUIRED;
  75. goto ReadWriteComplete;
  76. }
  77. writeOperation = (irpSp->MajorFunction == IRP_MJ_WRITE) ? TRUE : FALSE;
  78. //
  79. // Do the operation
  80. //
  81. status = MemCardReadWrite(memcardExtension,
  82. irpSp->Parameters.Read.ByteOffset.LowPart,
  83. MmGetSystemAddressForMdl(Irp->MdlAddress),
  84. irpSp->Parameters.Read.Length,
  85. writeOperation);
  86. ReadWriteComplete:
  87. if (NT_SUCCESS(status)) {
  88. Irp->IoStatus.Information = irpSp->Parameters.Read.Length;
  89. } else {
  90. Irp->IoStatus.Information = 0;
  91. }
  92. Irp->IoStatus.Status = status;
  93. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  94. return status;
  95. }
  96. NTSTATUS
  97. MemCardReadWrite(
  98. IN PMEMCARD_EXTENSION memcardExtension,
  99. IN ULONG startOffset,
  100. IN PVOID UserBuffer,
  101. IN ULONG lengthToCopy,
  102. IN BOOLEAN writeOperation
  103. )
  104. /*++
  105. Routine Description:
  106. This routine is called to read/write data to/from the memory card.
  107. It breaks the request into pieces based on the size of our memory
  108. window.
  109. Arguments:
  110. DeviceObject - a pointer to the object that represents the device
  111. that I/O is to be done on.
  112. Irp - a pointer to the I/O Request Packet for this request.
  113. Return Value:
  114. STATUS_SUCCESS if the packet was successfully read or written; the
  115. appropriate error is propogated otherwise.
  116. --*/
  117. {
  118. NTSTATUS status = STATUS_SUCCESS;
  119. PCHAR userBuffer = UserBuffer;
  120. ULONG windowOffset;
  121. ULONG singleCopyLength;
  122. BOOLEAN bSuccess;
  123. ULONGLONG CardBase;
  124. if (writeOperation && (memcardExtension->PcmciaInterface.IsWriteProtected)(memcardExtension->UnderlyingPDO)) {
  125. return STATUS_MEDIA_WRITE_PROTECTED;
  126. }
  127. MemCardDump(MEMCARDRW,("MemCard: DO %.8x %s offset %.8x, buffer %.8x, len %x\n",
  128. memcardExtension->DeviceObject,
  129. writeOperation?"WRITE":"READ",
  130. startOffset, UserBuffer, lengthToCopy));
  131. // pcmcia controller is 4k page granular
  132. windowOffset = startOffset % 4096;
  133. CardBase = startOffset - windowOffset;
  134. while(lengthToCopy) {
  135. bSuccess = (memcardExtension->PcmciaInterface.ModifyMemoryWindow) (
  136. memcardExtension->UnderlyingPDO,
  137. memcardExtension->HostBase,
  138. CardBase,
  139. TRUE,
  140. memcardExtension->MemoryWindowSize,
  141. 0, 0, FALSE);
  142. if (!bSuccess) {
  143. status = STATUS_DEVICE_NOT_READY;
  144. break;
  145. }
  146. singleCopyLength = (lengthToCopy <= (memcardExtension->MemoryWindowSize - windowOffset)) ?
  147. lengthToCopy :
  148. (memcardExtension->MemoryWindowSize - windowOffset);
  149. MemCardDump(MEMCARDRW,("MemCard: COPY %.8x (devbase %.8x) %s buffer %.8x, len %x\n",
  150. memcardExtension->MemoryWindowBase+windowOffset,
  151. (ULONG)(CardBase+windowOffset),
  152. (writeOperation ? "<=" : "=>"),
  153. userBuffer,
  154. singleCopyLength));
  155. if (writeOperation) {
  156. MemCardMtdWrite(memcardExtension,
  157. userBuffer,
  158. memcardExtension->MemoryWindowBase+windowOffset,
  159. singleCopyLength);
  160. } else {
  161. MemCardMtdRead(memcardExtension,
  162. userBuffer,
  163. memcardExtension->MemoryWindowBase+windowOffset,
  164. singleCopyLength);
  165. }
  166. lengthToCopy -= singleCopyLength;
  167. userBuffer += singleCopyLength;
  168. CardBase += memcardExtension->MemoryWindowSize;
  169. windowOffset = 0;
  170. }
  171. return status;
  172. }