Esempio n. 1
0
NTSTATUS
LsuWriteBlocks(
	IN PLANSCSI_SESSION	LSS,
	IN PBYTE			Buffer,
	IN UINT64			LogicalBlockAddress,
	IN ULONG			TransferBlocks,
	IN ULONG			BlockBytes,
	IN ULONG			PduFlags
) {
	NTSTATUS		status;
	LANSCSI_PDUDESC	PduDesc;
	BYTE			PduResponse;

	LSS_INITIALIZE_PDUDESC(LSS, &PduDesc, IDE_COMMAND, WIN_WRITE, PduFlags, LogicalBlockAddress, TransferBlocks, TransferBlocks * BlockBytes, Buffer, NULL);
	status = LspRequest(
					LSS,
					&PduDesc,
					&PduResponse
				);

	if(!NT_SUCCESS(status)) {
		KDPrintM(DBG_OTHER_ERROR, 
			("Error: logicalBlockAddress = %I64x, transferBlocks = %x\n", 
			LogicalBlockAddress, TransferBlocks));

	} else if(PduResponse != LANSCSI_RESPONSE_SUCCESS) {
		KDPrintM(DBG_OTHER_ERROR, 
			("Error: logicalBlockAddress = %I64x, transferBlocks = %x PduResponse:%x\n", 
			LogicalBlockAddress, TransferBlocks, PduResponse));

		status = STATUS_REQUEST_NOT_ACCEPTED;
	}

	return status;
}
Esempio n. 2
0
NTSTATUS
LsuGetIdentify(
	PLANSCSI_SESSION	LSS,
	struct hd_driveid	*info
){
	NTSTATUS		status;
	LANSCSI_PDUDESC	PduDesc;
	BYTE			PduResponse;

	status = STATUS_SUCCESS;

	// identify.
	LSS_INITIALIZE_PDUDESC(LSS, &PduDesc, IDE_COMMAND, WIN_IDENTIFY, 0, 0, 1, sizeof(struct hd_driveid), info, NULL);
	status = LspRequest(LSS, &PduDesc, &PduResponse);
	if(!NT_SUCCESS(status) || PduResponse != LANSCSI_RESPONSE_SUCCESS) {
		KDPrintM(DBG_OTHER_ERROR, ("Identify Failed...\n"));
		return status;
	}

	return status;
}
Esempio n. 3
0
NTSTATUS
LsuConfigureIdeDisk(
	IN PLANSCSI_SESSION	LSS,
	IN UCHAR			UdmaRestrict,
	OUT PULONG			PduFlags,
	OUT PBOOLEAN		Dma,
	OUT PULONG			BlockBytes
){
	NTSTATUS			status;
	struct hd_driveid	info;
	ULONG				pduFlags;
	BOOLEAN				setDmaMode;
	ULONG				blockBytes;
	LANSCSI_PDUDESC		pduDesc;
	UCHAR				pduResponse;

	//
	//	Get identify
	//

	status = LsuGetIdentify(LSS, &info);
	if(!NT_SUCCESS(status)) {
		KDPrint(1, ("LsuGetIdentify(1) failed. NTSTATUS: %08lx.\n", status));
		return status;
	}

	//
	// IO mode: DMA/PIO Mode.
	//
	KDPrintM(DBG_OTHER_INFO, ("Major 0x%x, Minor 0x%x, Capa 0x%x\n",
							info.major_rev_num,
							info.minor_rev_num,
							info.capability));
	KDPrintM(DBG_OTHER_INFO, ("DMA 0x%x, U-DMA 0x%x\n",
							info.dma_mword,
							info.dma_ultra));

	//
	//	determine IO mode ( UltraDMA, DMA, and PIO ) according to hardware versions and disk capacity.
	//
	setDmaMode = FALSE;
	pduFlags = 0;
	blockBytes = 512;

	do {
		UCHAR	DmaFeature;
		UCHAR	DmaMode;

		DmaFeature = 0;
		DmaMode = 0;

		//
		// Ultra DMA if NDAS chip is 2.0 or higher.
		//
		/*
			We don't support UDMA for 2.0 rev 0 due to the bug.
			The bug : Written data using UDMA will be corrupted
		*/
		if (
			(info.dma_ultra & 0x00ff) &&
			(
				(LANSCSIIDE_VERSION_2_0 < LSS->HWVersion) ||
				((LANSCSIIDE_VERSION_2_0 == LSS->HWVersion) && (0 != LSS->HWRevision))
			))
		{
			// Find Fastest Mode.
			if(info.dma_ultra & 0x0001)
				DmaMode = 0;
			if(info.dma_ultra & 0x0002)
				DmaMode = 1;
			if(info.dma_ultra & 0x0004)
				DmaMode = 2;
			//	if Cable80, try higher Ultra Dma Mode.
#ifdef __DETECT_CABLE80__
			if(info.hw_config & 0x2000) {
#endif
				if(info.dma_ultra & 0x0008)
					DmaMode = 3;
				if(info.dma_ultra & 0x0010)
					DmaMode = 4;
				if(info.dma_ultra & 0x0020)
					DmaMode = 5;
				if(info.dma_ultra & 0x0040)
					DmaMode = 6;
				if(info.dma_ultra & 0x0080)
					DmaMode = 7;

				//
				// If the ndas device is version 2.0 revision 100Mbps,
				// Restrict UDMA to mode 2.
				//

				if (LSS->HWVersion == LANSCSIIDE_VERSION_2_0 && 
					LSS->HWRevision == LANSCSIIDE_VER20_REV_100M) {

					if(DmaMode > 2)
						DmaMode = 2;
				}

				//
				// Restrict UDMA mode when requested.
				//

				if(UdmaRestrict != 0xff) {
					if(DmaMode > UdmaRestrict) {
						DmaMode = UdmaRestrict;
						KDPrintM(DBG_LURN_INFO, ("UDMA restriction applied. UDMA=%d\n", (ULONG)DmaMode));
					}
				}

#ifdef __DETECT_CABLE80__
			}
#endif
			KDPrintM(DBG_OTHER_INFO, ("Ultra DMA %d detected.\n", (int)DmaMode));
			DmaFeature = DmaMode | 0x40;	// Ultra DMA mode.
			pduFlags |= PDUDESC_FLAG_DMA|PDUDESC_FLAG_UDMA;

			// Set Ultra DMA mode if needed
			if(!(info.dma_ultra & (0x0100 << DmaMode))) {
				setDmaMode = TRUE;
			}

		//
		//	detect DMA
		//	Lower 8 bits of dma_mword represent supported dma modes.
		//
		} else if(info.dma_mword & 0x00ff) {
			if(info.dma_mword & 0x0001)
				DmaMode = 0;
			if(info.dma_mword & 0x0002)
				DmaMode = 1;
			if(info.dma_mword & 0x0004)
				DmaMode = 2;

			KDPrintM(DBG_OTHER_INFO, ("DMA mode %d detected.\n", (int)DmaMode));
			DmaFeature = DmaMode | 0x20;
			pduFlags |= PDUDESC_FLAG_DMA;

			// Set DMA mode if needed
			if(!(info.dma_mword & (0x0100 << DmaMode))) {
				setDmaMode = TRUE;
			}

		}

		// Set DMA mode if needed.
		if(setDmaMode) {
			LSS_INITIALIZE_PDUDESC(LSS, &pduDesc, IDE_COMMAND, WIN_SETFEATURES, 0, 0, 0, 0, NULL, NULL);
			pduDesc.Feature = SETFEATURES_XFER;
			pduDesc.BlockCount = DmaFeature;
			status = LspRequest(LSS, &pduDesc, &pduResponse);
			if(!NT_SUCCESS(status)) {
				KDPrintM(DBG_OTHER_ERROR, ("Set Feature Failed...\n"));
				return status;
			}
			if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
				KDPrintM(DBG_OTHER_ERROR, ("SETFEATURES: PduResponse=%x\n", (ULONG)pduResponse));
				return STATUS_UNSUCCESSFUL;
			}

			// identify.
			status = LsuGetIdentify(LSS, &info);
			if(!NT_SUCCESS(status)) {
				KDPrint(1, ("LsuGetIdentify(2) failed. NTSTATUS: %08lx.\n", status));
				return status;
			}
			KDPrintM(DBG_OTHER_INFO, ("After Set Feature DMA 0x%x, U-DMA 0x%x\n",
							info.dma_mword,
							info.dma_ultra));
		}
		if(pduFlags & PDUDESC_FLAG_DMA) {
			break;
		}
		//
		//	PIO.
		//
		KDPrintM(DBG_OTHER_ERROR, ("NetDisk does not support DMA mode. Turn to PIO mode.\n"));
		pduFlags |= PDUDESC_FLAG_PIO;

	} while(0);


	//
	// Bytes of sector
	//

	blockBytes = AtaGetBytesPerBlock(&info);

	//
	// LBA support
	//

	if(!(info.capability & 0x02)) {
		pduFlags &= ~PDUDESC_FLAG_LBA;
		ASSERT(FALSE);
	} else {
		pduFlags |= PDUDESC_FLAG_LBA;
	}

	//
	// LBA48 support
	//

	if(info.command_set_2 & 0x0400 || info.cfs_enable_2 & 0x0400) {	// Support LBA48bit
		pduFlags |= PDUDESC_FLAG_LBA48;

		//
		//	If LBA48 is on, LBA is also on.
		//

		pduFlags |= PDUDESC_FLAG_LBA;
	}

	KDPrint(1, ("LBA support: LBA %d, LBA48 %d\n",
		(pduFlags & PDUDESC_FLAG_LBA) != 0,
		(pduFlags & PDUDESC_FLAG_LBA48) != 0
		));


	//
	//	Set return values
	//

	if(PduFlags) {
		*PduFlags = pduFlags;
	}
	if(Dma) {
		if(pduFlags & (PDUDESC_FLAG_DMA|PDUDESC_FLAG_UDMA)) {
			*Dma = TRUE;
		} else {
			*Dma = FALSE;
		}
	}
	if(BlockBytes) {
		*BlockBytes = blockBytes;
	}

	return status;
}
Esempio n. 4
0
//////////////////////////////////////////////////////////////////////////
//
//	IDE devices
//
NTSTATUS
LsuConfigureIdeDisk(
	PLANSCSI_SESSION	LSS,
	PULONG				PduFlags,
	PBOOLEAN			Dma
){
	NTSTATUS			status;
	struct hd_driveid	info;
	ULONG				pduFlags;
	BOOLEAN				setDmaMode;
	LANSCSI_PDUDESC		pduDesc;
	UCHAR				pduResponse;

	//
	//	Get identify
	//

	status = LsuGetIdentify(LSS, &info);
	if(!NT_SUCCESS(status)) {
		KDPrint(1, ("LsuGetIdentify(1) failed. NTSTATUS: %08lx.\n", status));
		return status;
	}

	//
	// IO mode: DMA/PIO Mode.
	//
	KDPrintM(DBG_OTHER_INFO, ("Major 0x%x, Minor 0x%x, Capa 0x%x\n",
							info.major_rev_num,
							info.minor_rev_num,
							info.capability));
	KDPrintM(DBG_OTHER_INFO, ("DMA 0x%x, U-DMA 0x%x\n",
							info.dma_mword,
							info.dma_ultra));

	//
	//	determine IO mode ( UltraDMA, DMA, and PIO ) according to hardware versions and disk capacity.
	//
	setDmaMode = FALSE;
	pduFlags = 0;

	do {
		UCHAR	DmaFeature;
		UCHAR	DmaMode;

		DmaFeature = 0;
		DmaMode = 0;

		//
		// Ultra DMA if NDAS chip is 2.0 or higher.
		//	Lower 8 bits of dma_ultra represent supported ultra dma modes.
		//
		if(LSS->HWVersion >= LANSCSIIDE_VERSION_2_0 && (info.dma_ultra & 0x00ff)) {
			// Find Fastest Mode.
			if(info.dma_ultra & 0x0001)
				DmaMode = 0;
			if(info.dma_ultra & 0x0002)
				DmaMode = 1;
			if(info.dma_ultra & 0x0004)
				DmaMode = 2;
			//	if Cable80, try higher Ultra Dma Mode.
#ifdef __DETECT_CABLE80__
			if(info.hw_config & 0x2000) {
#endif
				if(info.dma_ultra & 0x0008)
					DmaMode = 3;
				if (!(LSS->HWVersion == LANSCSIIDE_VERSION_2_0 && 
					(LSS->HWRevision == 0))) {
				  if(info.dma_ultra & 0x0010)
					  DmaMode = 4;
				  if(info.dma_ultra & 0x0020)
					  DmaMode = 5;
				  if(info.dma_ultra & 0x0040)
					  DmaMode = 6;
				  if(info.dma_ultra & 0x0080)
					  DmaMode = 7;
				}
#ifdef __DETECT_CABLE80__
			}
#endif

			// Limit UDMA mode 2 for 2.0G 100M test revision
			if (LSS->HWVersion == LANSCSIIDE_VERSION_2_0 && LSS->HWRevision == 0x01f) {
				if (DmaMode > 2)
					DmaMode = 2;
			}

			KDPrintM(DBG_OTHER_INFO, ("Ultra DMA %d detected.\n", (int)DmaMode));
			DmaFeature = DmaMode | 0x40;	// Ultra DMA mode.
			pduFlags |= PDUDESC_FLAG_DMA|PDUDESC_FLAG_UDMA;

			// Set Ultra DMA mode if needed
			if(!(info.dma_ultra & (0x0100 << DmaMode))) {
				setDmaMode = TRUE;
			}

		//
		//	detect DMA
		//	Lower 8 bits of dma_mword represent supported dma modes.
		//
		} else if(info.dma_mword & 0x00ff) {
			if(info.dma_mword & 0x0001)
				DmaMode = 0;
			if(info.dma_mword & 0x0002)
				DmaMode = 1;
			if(info.dma_mword & 0x0004)
				DmaMode = 2;

			KDPrintM(DBG_OTHER_INFO, ("DMA mode %d detected.\n", (int)DmaMode));
			DmaFeature = DmaMode | 0x20;
			pduFlags |= PDUDESC_FLAG_DMA;

			// Set DMA mode if needed
			if(!(info.dma_mword & (0x0100 << DmaMode))) {
				setDmaMode = TRUE;
			}

		}

		// Set DMA mode if needed.
		if(setDmaMode) {
			LSS_INITIALIZE_PDUDESC(LSS, &pduDesc, IDE_COMMAND, WIN_SETFEATURES, 0, 0, 0, NULL);
			pduDesc.Feature = SETFEATURES_XFER;
			pduDesc.Param8[0] = DmaFeature;
			status = LspRequest(LSS, &pduDesc, &pduResponse);
			if(!NT_SUCCESS(status)) {
				KDPrintM(DBG_OTHER_ERROR, ("Set Feature Failed...\n"));
				return status;
			}
			if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
				KDPrintM(DBG_OTHER_ERROR, ("SETFEATURES: PduResponse=%x\n", (ULONG)pduResponse));
				return STATUS_UNSUCCESSFUL;
			}

			// identify.
			status = LsuGetIdentify(LSS, &info);
			if(!NT_SUCCESS(status)) {
				KDPrint(1, ("LsuGetIdentify(2) failed. NTSTATUS: %08lx.\n", status));
				return status;
			}
			KDPrintM(DBG_OTHER_INFO, ("After Set Feature DMA 0x%x, U-DMA 0x%x\n",
							info.dma_mword,
							info.dma_ultra));
		}
		if(pduFlags & PDUDESC_FLAG_DMA) {
			break;
		}
		//
		//	PIO.
		//
		KDPrintM(DBG_OTHER_ERROR, ("NetDisk does not support DMA mode. Turn to PIO mode.\n"));
		pduFlags |= PDUDESC_FLAG_PIO;

	} while(0);


	//
	// LBA support
	//

	if(!(info.capability & 0x02)) {
		pduFlags &= ~PDUDESC_FLAG_LBA;
		ASSERT(FALSE);
	} else {
		pduFlags |= PDUDESC_FLAG_LBA;
	}

	//
	// LBA48 support
	//

	if(info.command_set_2 & 0x0400 || info.cfs_enable_2 & 0x0400) {	// Support LBA48bit
		pduFlags |= PDUDESC_FLAG_LBA48;

		//
		//	If LBA48 is on, LBA is also on.
		//

		pduFlags |= PDUDESC_FLAG_LBA;
	}

	KDPrint(1, ("LBA support: LBA %d, LBA48 %d\n",
		(pduFlags & PDUDESC_FLAG_LBA) != 0,
		(pduFlags & PDUDESC_FLAG_LBA48) != 0
		));


	//
	//	Set return values
	//

	if(PduFlags) {
		*PduFlags = pduFlags;
	}
	if(Dma) {
		if(pduFlags & (PDUDESC_FLAG_DMA|PDUDESC_FLAG_UDMA)) {
			*Dma = TRUE;
		} else {
			*Dma = FALSE;
		}
	}

	return status;
}