/****************************************************************************** * * SkHandleResultPacket() - handte the FW resulta packet * * Description: * Retrieve the command result and handle the data * * Returns: * 0 on success, 1 on error */ void SkHandleResultPacket( SK_AC *pAC, /* Adapter context */ SK_U32 *pMsgBuff, /* Message buffer */ SK_U32 FrameLength) /* Message size */ { #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS FwCmdResult *FwCommandResult; SK_U16 CommandType; SK_U16 CommandLength; SK_U16 CommandResult; #endif /* * THIS ROUTINE MUST COPY THE CONTENT OF pMsgBuff TO ANOTHER LOCATION! * pMsgBuff WILL BE FREED AFTER THIS ROUTINE HAS FINISHED! */ if (pAC->FwBufferLen > 0) { /* Clear the old buffer */ kfree(pAC->pFwBuffer); } if ((pAC->pFwBuffer = (SK_U32 *) kmalloc(FrameLength, GFP_KERNEL)) != NULL ) { /* Copy the data into a new buffer */ pAC->FwBufferLen = FrameLength; memcpy(pAC->pFwBuffer, pMsgBuff, FrameLength); } else { printk("Alloc data ERROR\n"); return; } /* DEBUG CODE! */ #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS FwCommandResult = (FwCmdResult *) pAC->pFwBuffer; CommandType = FwCommandResult->Hdr.Cmd; CommandLength = FwCommandResult->Hdr.Len; CommandResult = FwCommandResult->Result; printk("%s: SkHandleResultPacket => CommandType: 0x%x\n", DRV_NAME, CommandType); printk("%s: SkHandleResultPacket => CommandLength: 0x%x\n", DRV_NAME, CommandLength); printk("%s: SkHandleResultPacket => CommandResult: 0x%x\n", DRV_NAME, CommandResult); /* Print output to see complete FW command result buffer */ PrintDataBuffer("SkHandleResultPacket => FIFO DATA", pMsgBuff, FrameLength); #endif }
/****************************************************************************** * * SkHandleMsgCmdResponsePacket() - handte the FW resulta packet * * Description: * Store the received msg cmd response for later retrieval * * Returns: * - (void) */ void SkHandleMsgCmdResponsePacket( SK_AC *pAC, /* Adapter context */ SK_U32 *pMsgBuff, /* Message buffer */ SK_U32 FrameLength) /* Message size */ { if (pMsgBuff && FrameLength) { #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS printk("%s-%s() FrameLength: 0x%x\n", DRV_NAME, __func__, FrameLength); PrintDataBuffer("FIFO DATA", pMsgBuff, FrameLength); #endif if (pAC->FwBufferLen > 0) { kfree(pAC->pFwBuffer); /* Clear the old buffer */ } if ((pAC->pFwBuffer = (SK_U32 *) kmalloc(FrameLength, GFP_KERNEL)) != NULL ) { /* Copy the data into a new buffer */ pAC->FwBufferLen = FrameLength; memcpy(pAC->pFwBuffer, pMsgBuff, FrameLength); } else { printk("%s-%s() Alloc data ERROR\n", DRV_NAME, __func__); } } }
/****************************************************************************** * * SkWriteRamBuf() - Handle a write request from the upper layer * * Description: * Handle a write request to the firmware * * BE AWARE: SK_IN/SK_OUT macros will swap the following 32bit * variables in RamReadAddr() and RamWriteAddr(): * * - LowDword * - HighDword * - RPointer * - WPointer * - DPointer * - CurrRamAddr * * Returns: * 0 on success, 1 on error */ SK_U8 SkWriteRamBuf( SK_AC *pAC, /* Adapter context */ SK_U32 *pMsgBuff, SK_U32 FrameLength, SK_U32 DatagramType) { SK_U32 LowDword = 0x0; SK_U32 HighDword = 0x0; SK_U32 RPointer = 0x0; SK_U32 WPointer = 0x0; SK_U32 Size = 0x0; SK_U32 DPointer = 0x0; SK_U32 CurrRamAddr = pAC->RamAddr; SK_U32 WPointerRamAddr; SK_U16 *pDataLow = (SK_U16 *) &LowDword; SK_U16 DatagramLength; /* Read the FIFO status */ (void) RamReadAddr(pAC, CurrRamAddr, &LowDword, &HighDword, pAC->RamSelect); /* FIFO not available => Return! */ if ((SK_U32) LowDword == 0) { printk("%s: SkWriteRamBuf => Fifo not available!\n", DRV_NAME); return 1; } #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS printk("SkWriteRamBuf => Fifo available: 0x%x\n", LowDword); #endif /* Set CurrRamAddr to beginning of FIFO write array! */ CurrRamAddr = HOST_WRITE_QWORD; /* Retrieve read pointer */ (void) RamReadAddr(pAC, CurrRamAddr, &DPointer, &RPointer, pAC->RamSelect); /* Retrieve write pointer */ CurrRamAddr++; (void) RamReadAddr(pAC, CurrRamAddr, &Size, &WPointer, pAC->RamSelect); WPointerRamAddr = CurrRamAddr; /* Convert pointer addresses to quadword addresses */ RPointer = (RPointer - HOST_ROM_ADDR)/8; WPointer = (WPointer - HOST_ROM_ADDR)/8; #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS printk("SkWriteRamBuf START => RPointer: 0x%x\n", RPointer); printk("SkWriteRamBuf START => WPointer: 0x%x\n", WPointer); #endif /* * Fill LowDword and HighDword with FIFO datagram information: * LowDword: Datagram and payload length, HighDword: Transaction ID */ DatagramLength = 8; DatagramLength += (FrameLength/8) * 8; if (FrameLength % 8) { DatagramLength += 8; } /* ENDIANESS */ #ifdef SK_LITTLE_ENDIAN pDataLow[0] = DatagramLength; pDataLow[1] = FrameLength; #else pDataLow[1] = DatagramLength; pDataLow[0] = FrameLength; #endif HighDword = DatagramType; /* Write FIFO datagram information into RAM */ (void) RamWriteAddr(pAC, WPointer, LowDword, HighDword, pAC->RamSelect); WPointer++; /* TEST */ #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS PrintDataBuffer("SkWriteRamBuf => FIFO DATA", (char *) pMsgBuff, FrameLength); #endif /* Write payload data into FIFO RAM */ WPointer = SkWriteData(pAC, pMsgBuff, WPointer, FrameLength); /* Set the write pointer address */ if (WPointer > HOST_WRITE_LAST_QWORD) { WPointer = HOST_WRITE_QWORD+2; } #ifdef VERBOSE_ASF_FIFO_DBUG_RPINTS printk("SkWriteRamBuf END => RPointer: 0x%x\n", RPointer); printk("SkWriteRamBuf END => WPointer: 0x%x\n", WPointer); #endif WPointer = (WPointer*8)+HOST_ROM_ADDR; (void) RamWriteAddr(pAC, WPointerRamAddr, Size, WPointer, pAC->RamSelect); return 0; } /* SkWriteRamBuf */
VOID __cdecl main( _In_ int argc, _In_z_ char *argv[] ) { BOOL status = 0; DWORD accessMode = 0, shareMode = 0; HANDLE fileHandle = NULL; ULONG alignmentMask = 0; // default == no alignment requirement UCHAR srbType = 0; // default == SRB_TYPE_SCSI_REQUEST_BLOCK PUCHAR dataBuffer = NULL; PUCHAR pUnAlignedBuffer = NULL; SCSI_PASS_THROUGH_WITH_BUFFERS sptwb; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; SCSI_PASS_THROUGH_WITH_BUFFERS_EX sptwb_ex; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX sptdwb_ex; CHAR string[NAME_COUNT]; ULONG length = 0, errorCode = 0, returned = 0, sectorSize = 512; if ((argc < 2) || (argc > 3)) { printf("Usage: %s <port-name> [-mode]\n", argv[0] ); printf("Examples:\n"); printf(" spti g: (open the disk class driver in SHARED READ/WRITE mode)\n"); printf(" spti Scsi2: (open the miniport driver for the 3rd host adapter)\n"); printf(" spti Tape0 w (open the tape class driver in SHARED WRITE mode)\n"); printf(" spti i: c (open the CD-ROM class driver in SHARED READ mode)\n"); return; } StringCbPrintf(string, sizeof(string), "\\\\.\\%s", argv[1]); shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // default accessMode = GENERIC_WRITE | GENERIC_READ; // default if (argc == 3) { switch(tolower(argv[2][0])) { case 'r': shareMode = FILE_SHARE_READ; break; case 'w': shareMode = FILE_SHARE_WRITE; break; case 'c': shareMode = FILE_SHARE_READ; sectorSize = 2048; break; default: printf("%s is an invalid mode.\n", argv[2]); puts("\tr = read"); puts("\tw = write"); puts("\tc = read CD (2048 byte sector mode)"); return; } } fileHandle = CreateFile(string, accessMode, shareMode, NULL, OPEN_EXISTING, 0, NULL); if (fileHandle == INVALID_HANDLE_VALUE) { errorCode = GetLastError(); printf("Error opening %s. Error: %d\n", string, errorCode); PrintError(errorCode); return; } // // Get the alignment requirements // status = QueryPropertyForDevice(fileHandle, &alignmentMask, &srbType); if (!status ) { errorCode = GetLastError(); printf("Error getting device and/or adapter properties; " "error was %d\n", errorCode); PrintError(errorCode); CloseHandle(fileHandle); return; } printf("\n" " ***** Detected Alignment Mask *****\n" " ***** was %08x *****\n\n\n", alignmentMask); // // Send SCSI Pass Through // puts(" ***** MODE SENSE -- return all pages *****"); puts(" ***** with SenseInfo buffer *****\n"); if(srbType == 1) { ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX)); sptwb_ex.spt.Version = 0; sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX); sptwb_ex.spt.ScsiStatus = 0; sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8); sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb_ex.spt.DataOutTransferLength = 0; sptwb_ex.spt.DataInTransferLength = 192; sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN; sptwb_ex.spt.TimeOutValue = 2; sptwb_ex.spt.StorAddressOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress); sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8; sptwb_ex.StorAddress.Port = 0; sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH; sptwb_ex.StorAddress.Path = 0; sptwb_ex.StorAddress.Target = 1; sptwb_ex.StorAddress.Lun = 0; sptwb_ex.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf); sptwb_ex.spt.DataOutBufferOffset = 0; sptwb_ex.spt.DataInBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf); sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb_ex.spt.Cdb[2] = MODE_SENSE_RETURN_ALL; sptwb_ex.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) + sptwb_ex.spt.DataInTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_EX, &sptwb_ex, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX), &sptwb_ex, length, &returned, FALSE); PrintStatusResultsEx(status,returned,&sptwb_ex,length); } else { ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 192; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf); sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf); sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb.spt.Cdb[2] = MODE_SENSE_RETURN_ALL; sptwb.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) + sptwb.spt.DataTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE); PrintStatusResults(status,returned,&sptwb,length); } printf(" ***** MODE SENSE -- return all pages *****\n"); printf(" ***** without SenseInfo buffer *****\n\n"); if(srbType == 1) { ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX)); sptwb_ex.spt.Version = 0; sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX); sptwb_ex.spt.ScsiStatus = 0; sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8); sptwb_ex.spt.SenseInfoLength = 0; sptwb_ex.spt.DataOutTransferLength = 0; sptwb_ex.spt.DataInTransferLength = 192; sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN; sptwb_ex.spt.TimeOutValue = 2; sptwb_ex.spt.StorAddressOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress); sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8; sptwb_ex.StorAddress.Port = 0; sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH; sptwb_ex.StorAddress.Path = 0; sptwb_ex.StorAddress.Target = 1; sptwb_ex.StorAddress.Lun = 0; sptwb_ex.spt.SenseInfoOffset = 0; sptwb_ex.spt.DataOutBufferOffset = 0; sptwb_ex.spt.DataInBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf); sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb_ex.spt.Cdb[2] = MODE_SENSE_RETURN_ALL; sptwb_ex.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) + sptwb_ex.spt.DataInTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_EX, &sptwb_ex, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX), &sptwb_ex, length, &returned, FALSE); PrintStatusResultsEx(status,returned,&sptwb_ex,length); } else { ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = 0; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 192; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf); sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb.spt.Cdb[2] = MODE_SENSE_RETURN_ALL; sptwb.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) + sptwb.spt.DataTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE); PrintStatusResults(status,returned,&sptwb,length); } printf(" ***** TEST UNIT READY *****\n"); printf(" ***** DataInBufferLength = 0 *****\n\n"); if(srbType == 1) { ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX)); sptwb_ex.spt.Version = 0; sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX); sptwb_ex.spt.ScsiStatus = 0; sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8); sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb_ex.spt.DataOutTransferLength = 0; sptwb_ex.spt.DataInTransferLength = 0; sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN; sptwb_ex.spt.TimeOutValue = 2; sptwb_ex.spt.StorAddressOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress); sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8; sptwb_ex.StorAddress.Port = 0; sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH; sptwb_ex.StorAddress.Path = 0; sptwb_ex.StorAddress.Target = 1; sptwb_ex.StorAddress.Lun = 0; sptwb_ex.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf); sptwb_ex.spt.DataOutBufferOffset = 0; sptwb_ex.spt.DataInBufferOffset = 0; sptwb_ex.spt.Cdb[0] = SCSIOP_TEST_UNIT_READY; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf); status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_EX, &sptwb_ex, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX), &sptwb_ex, length, &returned, FALSE); PrintStatusResultsEx(status,returned,&sptwb_ex,length); } else { ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 0; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = 0; sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf); sptwb.spt.Cdb[0] = SCSIOP_TEST_UNIT_READY; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf); status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE); PrintStatusResults(status,returned,&sptwb,length); } // // Do a mode sense with a bad data buffer offset. This will fail. // printf(" ***** MODE SENSE -- return all pages *****\n"); printf(" ***** bad DataBufferOffset -- should fail *****\n\n"); if(srbType == 1) { ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX)); sptwb_ex.spt.Version = 0; sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX); sptwb_ex.spt.ScsiStatus = 0; sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8); sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb_ex.spt.DataOutTransferLength = 0; sptwb_ex.spt.DataInTransferLength = 192; sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN; sptwb_ex.spt.TimeOutValue = 2; sptwb_ex.spt.StorAddressOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress); sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8; sptwb_ex.StorAddress.Port = 0; sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH; sptwb_ex.StorAddress.Path = 0; sptwb_ex.StorAddress.Target = 1; sptwb_ex.StorAddress.Lun = 0; sptwb_ex.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf); sptwb_ex.spt.DataOutBufferOffset = 0; sptwb_ex.spt.DataInBufferOffset = 0; sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb_ex.spt.Cdb[2] = MODE_SENSE_RETURN_ALL; sptwb_ex.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) + sptwb_ex.spt.DataInTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_EX, &sptwb_ex, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX), &sptwb_ex, length, &returned, FALSE); PrintStatusResultsEx(status,returned,&sptwb_ex,length); } else { ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = 0; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 192; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = 0; sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf); sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb.spt.Cdb[2] = MODE_SENSE_RETURN_ALL; sptwb.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) + sptwb.spt.DataTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE); PrintStatusResults(status,returned,&sptwb,length); } // // Get caching mode sense page. // printf(" ***** MODE SENSE *****\n"); printf(" ***** return caching mode sense page *****\n\n"); if(srbType == 1) { ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX)); sptwb_ex.spt.Version = 0; sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX); sptwb_ex.spt.ScsiStatus = 0; sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8); sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb_ex.spt.DataOutTransferLength = 0; sptwb_ex.spt.DataInTransferLength = 192; sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN; sptwb_ex.spt.TimeOutValue = 2; sptwb_ex.spt.StorAddressOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress); sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8; sptwb_ex.StorAddress.Port = 0; sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH; sptwb_ex.StorAddress.Path = 0; sptwb_ex.StorAddress.Target = 1; sptwb_ex.StorAddress.Lun = 0; sptwb_ex.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf); sptwb_ex.spt.DataOutBufferOffset = 0; sptwb_ex.spt.DataInBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf); sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb_ex.spt.Cdb[1] = 0x08; // target shall not return any block descriptors sptwb_ex.spt.Cdb[2] = MODE_PAGE_CACHING; sptwb_ex.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) + sptwb_ex.spt.DataInTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_EX, &sptwb_ex, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX), &sptwb_ex, length, &returned, FALSE); PrintStatusResultsEx(status,returned,&sptwb_ex,length); } else { ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)); sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = CDB6GENERIC_LENGTH; sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH; sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN; sptwb.spt.DataTransferLength = 192; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf); sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf); sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE; sptwb.spt.Cdb[1] = 0x08; // target shall not return any block descriptors sptwb.spt.Cdb[2] = MODE_PAGE_CACHING; sptwb.spt.Cdb[4] = 192; length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) + sptwb.spt.DataTransferLength; status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH, &sptwb, sizeof(SCSI_PASS_THROUGH), &sptwb, length, &returned, FALSE); PrintStatusResults(status,returned,&sptwb,length); } printf(" ***** WRITE DATA BUFFER operation *****\n"); dataBuffer = AllocateAlignedBuffer(sectorSize,alignmentMask, &pUnAlignedBuffer); FillMemory(dataBuffer,sectorSize/2,'N'); FillMemory(dataBuffer + sectorSize/2,sectorSize/2,'T'); if(srbType == 1) { ZeroMemory(&sptdwb_ex,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX)); sptdwb_ex.sptd.Version = 0; sptdwb_ex.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT_EX); sptdwb_ex.sptd.ScsiStatus = 0; sptdwb_ex.sptd.CdbLength = CDB10GENERIC_LENGTH; sptdwb_ex.sptd.StorAddressLength = sizeof(STOR_ADDR_BTL8); sptdwb_ex.sptd.SenseInfoLength = SPT_SENSE_LENGTH; sptdwb_ex.sptd.DataOutTransferLength = sectorSize; sptdwb_ex.sptd.DataInTransferLength = 0; sptdwb_ex.sptd.DataDirection = SCSI_IOCTL_DATA_OUT; sptdwb_ex.sptd.TimeOutValue = 2; sptdwb_ex.sptd.StorAddressOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX,StorAddress); sptdwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8; sptdwb_ex.StorAddress.Port = 0; sptdwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH; sptdwb_ex.StorAddress.Path = 0; sptdwb_ex.StorAddress.Target = 1; sptdwb_ex.StorAddress.Lun = 0; sptdwb_ex.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX,ucSenseBuf); sptdwb_ex.sptd.DataOutBuffer = dataBuffer; sptdwb_ex.sptd.DataInBuffer = NULL; sptdwb_ex.sptd.Cdb[0] = SCSIOP_WRITE_DATA_BUFF; sptdwb_ex.sptd.Cdb[1] = 2; // Data mode sptdwb_ex.sptd.Cdb[7] = (UCHAR)(sectorSize >> 8); // Parameter List length sptdwb_ex.sptd.Cdb[8] = 0; length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX); status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT_EX, &sptdwb_ex, length, &sptdwb_ex, length, &returned, FALSE); PrintStatusResultsEx(status,returned, (PSCSI_PASS_THROUGH_WITH_BUFFERS_EX)&sptdwb_ex,length); if ((sptdwb_ex.sptd.ScsiStatus == 0) && (status != 0)) { PrintDataBuffer(dataBuffer,sptdwb_ex.sptd.DataOutTransferLength); } }