SCSI Read (10) and Write (10) with the SCSI Generic Interface
In SCSI, the units of the LBA and the transfer length are in blocks, sometimes called sectors. This is almost always 512 bytes. So, you can't read or write just 32 bytes. At a minimum, you'll have to do 512 bytes == one block. This one point is most of what you need to fix.
Your transfer length is zero in your scsi_write implementation, so it's not actually going to write any data.
You should use different buffers for the CDB and the write/read data. I suspect that confusion about these buffers is leading your implementation to write past the end of one of your statically-allocated arrays and over your ReadBuffer. Run it under valgrind and see what shows up.
And lastly, a lot could go wrong in whatever is in handle_scsi_cmd. It can be tricky to set up the data transfer... in particular, make sure you're straight on which way the data is going in the I/O header's dxfer_direction: SG_DXFER_TO_DEV for write, SG_DXFER_FROM_DEV for read.
Check out this example of how to do a read(16). This is more along the lines of what you're trying to accomplish.
https://github.com/hreinecke/sg3_utils/blob/master/examples/sg_simple16.c
SCSI generic write() thread safe?
Read and write should be by definition safe but:
1) Reading and writing, does it happen on the same file descriptor. If not, the open file table in your system can have multiple offsets, resulting in data read and write in an inconsistent way.
2) If you have a block of data that has to be written to your disk, do you use write in a for loop? This is not safe, because other read or write operations can be started between two write calls. Have a look at readv and writev to atomically write big data blocks.
COMPARE AND WRITE on umapped block?
When a block is unmapped it is equal to all zeroes. You should perform all your commands that read or compare data with this block as it was just zeroes.
Meaning of the PMI bit in the SCSI READ CAPACITY command
This is actually out in SBC-3 too now, as of revision 28 (January, 2011) You can see the change here: (sign up required) http://www.t10.org/cgi-bin/ac.pl?t=d&f=11-010r0.pdf . So, you're talking SBC-2 compatibility.
Anyway, I don't think you'll ever see these fields set in practice. But, for the sake of completeness, you may wish to incorporate some additional error handling.
- Fail the request if PMI is zero, but the initiator specified an LBA.
- Fail the request if the LBA specified in the CDB is greater than the last LBA of your disk.
Presuming your implementation always knows what the capacity of your disk is, then there should never be a "substantial vendor specific delay". You can read the standard, then, as "return information on the last logical block after that specified in the LOGICAL BLOCK ADDRESS field". This should simply be the last LBA of your disk.
To answer your questions directly: when PMI is set, and an LBA is specified, you should report the last LBA on your disk, subject to the above error handling. And, you only need to look at the LBA field to do the error handling.
For SCSI, was there a change to the definition of ADDITIONAL LENGTH?
It is just worded in a more general way:
"If the information being transferred to the Data-In Buffer includes fields containing counts of the number of bytes in some or all of the data, then the contents of these fields shall not
be altered to reflect the truncation"
Get Device max links speed with scsi cmd
According to SPL-4, you many use SMP DISCOVER
function or SCSI MODE SENSE
page 19h Protocol Specific Port
, subpage 01h Phy Control And Discover
.
For link speed, you should use NEGOTIATED LOGICAL LINK RATE
. The max link speed are HARDWARE MAXIMUM PHYSICAL LINK RATE
(physical limitation) and PROGRAMMED MAXIMUM PHYSICAL LINK RATE
(configured by PHY CONTROL
function)
This is the example of using SMP DISCOVER
way:
[fge@el7 ~]$ sudo smp_discover /dev/bsg/expander-0\:0
phy 0:T:attached:[500015535990a300:00 t(SATA)] 3 Gbps
phy 1:T:attached:[500015535990a301:00 t(SATA)] 3 Gbps
phy 2:T:attached:[500015535990a302:00 t(SATA)] 1.5 Gbps
phy 3:T:attached:[500015535990a303:00 t(SATA)] 3 Gbps
phy 4:T:attached:[500015535990a304:00 t(SATA)] 3 Gbps
phy 5:T:attached:[500015535990a305:00 t(SATA)] 3 Gbps
phy 6:T:attached:[500015535990a306:00 t(SATA)] 3 Gbps
phy 7:T:attached:[500015535990a307:00 t(SATA)] 3 Gbps
phy 8:T:attached:[500015535990a308:00 t(SATA)] 3 Gbps
phy 9:T:attached:[500015535990a309:00 t(SATA)] 3 Gbps
phy 10:T:attached:[500015535990a30a:00 t(SATA)] 3 Gbps
phy 11:T:attached:[500015535990a30b:00 t(SATA)] 3 Gbps
phy 12:T:attached:[500015535990a30c:00 t(SATA)] 3 Gbps
phy 13:T:attached:[500015535990a30d:00 t(SATA)] 3 Gbps
phy 14:T:attached:[50014ee5aaab876f:01 t(SSP)] 3 Gbps
phy 15:T:attached:[500015535990a30f:00 t(SATA)] 3 Gbps
phy 16:S:attached:[5d4ae520995f8200:03 i(SSP+STP+SMP)] 3 Gbps
phy 20:T:attached:[500015535956633f:16 exp i(SMP) t(SMP)] 3 Gbps
phy 21:T:attached:[500015535956633f:17 exp i(SMP) t(SMP)] 3 Gbps
phy 22:T:attached:[500015535956633f:18 exp i(SMP) t(SMP)] 3 Gbps
phy 23:T:attached:[500015535956633f:19 exp i(SMP) t(SMP)] 3 Gbps
phy 24:D:attached:[500015535990a33e:24 V i(SSP) t(SSP)] 3 Gbps
send SCSI commands using C#
You have a few options
1- Use p/invoke (platform invoke) interoperability. Using this you can do one of two things. Either use p/invoke to call the Win32 api from .NET, alternatively you can write a C dll that exports a simplified interface to control the device and then interop to this dll.
2- You could use managed C++, and create a library that you can call from C#.
3- You could wrap your C code as a COM object and use COM interop from C#.
Since you presumably have some working C code, I think the easiest would be to create a DLL that exports a easy to invoke interface and then use P/Invoke to call that from C#
Related Topics
How to Add an Icon to The Bash Prompt
Command to Measure Tlb Misses on Linux
Linux Append Console Output to a Logfile
Checking If a Binary Compiled with "-Static"
Difference Between Dts and Acpi
How to Remember Multiple Tabs' Session in Terminal? (Alike Ff Session Manager)
Checking Shared Libraries for Non Default Loaders
Execute a Script After Every Git Push
How to Measure Mispredictions for a Single Branch on Linux
Are Mlock()-Ed Pages Static, or Can They Be Moved in Physical Ram
How to Touch a File and Mkdir If Needed in One Line
Can't Access Publicly Exposed Docker Container Port from External Machine, Only from Localhost
Bash - How to Print Multi Line Strings (With '\N') Using Printf
Embedded Linux - Mechanism for Deploying Firmware Updates
Check for Iommu Support on Linux