Directly write to SATA interface to perform simple read and write operation on a storage device.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <scsi/sg.h>
#include <scsi/scsi.h>
main()
{
int fd;
unsigned char buffer[512];
fd=open("/dev/sda", O_RDWR );
ReadSector(fd, 0, 1, buffer);
WriteSector(fd, 0, 1, buffer);
}
// return 0 on fail
// return 1 on success
int ReadSector(int fd, int sector, int nsec, unsigned char *pbuffer)
{
int res;
int t_length;
sg_io_hdr_t io_hdr;
unsigned char sense_b[SG_MAX_SENSE];
unsigned char rdCmdBlk6[6];
t_length = 512; // 512 bytes transferred per sec
// Prepare SCSI READ (6) command
rdCmdBlk6[0] = READ_6; // COMMAND
rdCmdBlk6[1] = (sector & 0xFF0000 ) >> 16; // LBA
rdCmdBlk6[2] = (sector & 0xff00) >> 8; // LBA
rdCmdBlk6[3] = sector & 0xff; // LBA
rdCmdBlk6[4] = nsec;
rdCmdBlk6[5] = 0x00;
// Prepare the sg_io_hdr_t structure
memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
io_hdr.interface_id = 'S'; // Always set to 'S' for sg driver
io_hdr.cmd_len = sizeof(rdCmdBlk6); // Size of SCSI command
io_hdr.mx_sb_len = sizeof(sense_b); // Max sense buffer size(for error)
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; // Data transfer direction(no data)
io_hdr.dxfer_len = nsec*t_length; // Data transfer length(512)
io_hdr.dxferp = pbuffer; // Data transfer buffer(none)
io_hdr.cmdp = rdCmdBlk6; // SCSI command buffer
io_hdr.sbp = sense_b; // Sense buffer
io_hdr.timeout = 5000; // Timeout(5s)
// Sends the command to device
if ((res = ioctl(fd, SG_IO, &io_hdr)) < 0) {
return 0;
}
// Error processing
if ( ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) || // check info
(io_hdr.masked_status != 0x00) || // check status(0 if ioctl success)
(io_hdr.msg_status != 0x00) || // check message status
(io_hdr.host_status != 0x00) || // check host status
(io_hdr.driver_status != 0x00) ) // check driver status
{
return 0;
} else {
return 1;
}
}
int WriteSector(int fd, int sector, int nsec, unsigned char *pbuffer)
{
int res;
int t_length;
sg_io_hdr_t io_hdr;
unsigned char sense_b[SG_MAX_SENSE];
unsigned char rdCmdBlk6[6] ;
t_length = 512; // 512 bytes transferred per sec
// Prepare SCSI WRITE (6) command
rdCmdBlk6[0] = WRITE_6; // COMMAND
rdCmdBlk6[1] = (sector & 0xFF0000 ) >> 16; // LBA
rdCmdBlk6[2] = (sector & 0xff00) >> 8; // LBA
rdCmdBlk6[3] = sector & 0xff; // LBA
rdCmdBlk6[4] = nsec;
rdCmdBlk6[5] = 0x00;
// Prepare the sg_io_hdr_t structure
memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
io_hdr.interface_id = 'S'; // Always set to 'S' for sg driver
io_hdr.cmd_len = sizeof(rdCmdBlk6); // Size of SCSI command
io_hdr.mx_sb_len = sizeof(sense_b); // Max sense buffer size(for error)
io_hdr.dxfer_direction = SG_DXFER_TO_DEV; // Data transfer direction(no data)
io_hdr.dxfer_len = nsec*t_length; // Data transfer length(512)
io_hdr.dxferp = pbuffer; // Data transfer buffer(none)
io_hdr.cmdp = rdCmdBlk6; // SCSI command buffer
io_hdr.sbp = sense_b; // Sense buffer
io_hdr.timeout = 5000; // Timeout(5s)
// Sends the command to device
if ((res = ioctl(fd, SG_IO, &io_hdr)) < 0) {
return 0;
}
// Error processing
if ( ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) || // check info
(io_hdr.masked_status != 0x00) || // check status(0 if ioctl success)
(io_hdr.msg_status != 0x00) || // check message status
(io_hdr.host_status != 0x00) || // check host status
(io_hdr.driver_status != 0x00) ) // check driver status
{
return 0;
} else {
return 1;
}
}
No comments:
Post a Comment