~gandelman-a/ubuntu/oneiric/scsitools/mergeproposal

« back to all changes in this revision

Viewing changes to sraw/srawread.c

  • Committer: Adam Gandelman
  • Date: 2011-05-20 17:58:41 UTC
  • mfrom: (6.2.4 debian)
  • Revision ID: adam.gandelman@canonical.com-20110520175841-74orsktetfakacqd
merged

Show diffs side-by-side

added added

removed removed

Lines of Context:
79
79
 *
80
80
 */
81
81
 
 
82
#define USE_READ_10
 
83
#undef  SET_FUA  /* "force unit access" for READ(10): don't read from cache but from media */
 
84
#define LESS_VERBOSE_OUTPUT
82
85
#define USE_GETTIMEOFDAY /* please, always! gettimeofday(2) is much more accurate */
83
 
#define USE_SG_IO
84
86
 
85
87
 
86
88
#include <stdio.h>
87
 
#include <string.h>
88
89
#include <unistd.h>
89
 
#include <errno.h>
90
 
#include <inttypes.h>
91
90
#include <sys/times.h>
92
91
#include <linux/hdreg.h>
93
 
#include <stdlib.h>
94
 
#include <sys/ioctl.h>
95
 
#ifdef USE_SG_IO
96
 
# include <scsi/sg.h>
97
 
#endif
98
92
 
99
 
FILE *infile = NULL;
100
 
unsigned char buffer[2*64*1024+8];
 
93
FILE *infile, *ptable;
 
94
unsigned char buffer[2*64*1024];
101
95
 
102
96
 
103
97
int read_size=32768;
127
121
int main( int argc, char *argv[] )
128
122
{
129
123
  int b,bstart=0,bstep=1;
130
 
  int c=1,verbose=0;
131
124
  int status, i;
132
125
  unsigned char *cmd;
133
 
  unsigned int capacity, sectorsize;
 
126
  int capacity, sectorsize;
134
127
  int this_count, block;
135
128
  int rate;
136
129
  double starttime, endtime;
137
 
  int read_len = 10;                    /* length of read command */
138
 
  int fua = 0;                          /* "force unit access" for READ(10): don't read from cache but from media */
139
 
#ifdef USE_SG_IO
140
 
  sg_io_hdr_t sgbuf;
141
 
  int legacy_ioctl=0;
142
 
#endif
143
 
 
144
 
  while (argc>c && argv[c][0] == '-') {
145
 
    for(i=1; i < strlen(argv[c]); i++)
146
 
      switch (argv[c][i]) {
147
 
        case 'v': verbose = 1; break;
148
 
#ifdef USE_SG_IO
149
 
        case 'i': legacy_ioctl = 1; break;
150
 
#endif
151
 
        case 'f': fua = 1; break;
152
 
        case '6': read_len = 6; break;
153
 
        default: goto error;
154
 
      }
155
 
    c++;
156
 
  }
157
 
  if (argc>c) {
158
 
    infile = fopen( argv[c], "r" );
159
 
    if (!infile) {
160
 
      perror(argv[c]);
161
 
      return 2;
162
 
    }
163
 
  }
164
 
  if (argc>c+1) bstart = atoi(argv[c+1]);
165
 
  if (argc>c+2) bstep  = atoi(argv[c+2]);
166
 
 
167
 
  if (infile == NULL || argc==1 || argc>c+3) {
168
 
error:
169
 
    printf("usage: sraw [-v]%s scsi-device [ bstart [ bstep ] ]\n",
170
 
#ifdef USE_SG_IO
171
 
            "[-i]"
172
 
#else
173
 
            ""
174
 
#endif
175
 
            );
176
 
    return 1;
177
 
  }
178
 
 
179
 
  memset(buffer, 0, sizeof(buffer));
180
 
 
 
130
 
 
131
  if (argc==1) { 
 
132
    printf("usage: srawread scsi-device [ bstart [ bstop ] ]\n");
 
133
    exit(0);
 
134
  }
 
135
 
 
136
  infile = fopen( argv[1], "r" );
 
137
  if(!infile) exit(0);
 
138
 
 
139
  if (argc>2) bstart = atoi(argv[2]);
 
140
  if (argc>3) bstep  = atoi(argv[2]);
 
141
 
 
142
  for (i=0; i<10*1024; i++)
 
143
  {
 
144
    buffer[i] = 0;
 
145
  }
 
146
  
181
147
  *( (int *)  buffer )          = 0;    /* length of input data */
182
148
  *( ((int *) buffer) + 1 )     = read_size;    /* length of output buffer */
183
149
 
184
 
  cmd = (unsigned char *) ( ((int *) buffer) + 2 );
 
150
  cmd = (char *) ( ((int *) buffer) + 2 );
185
151
  
186
 
  cmd[0] = 0x25;                        /* READ CAPICTY (10 bytes)*/
187
 
  cmd[1] = 0x00;                        /* b7-5: lun=0, b4-1: reserved, b0: reladdr=0 */
188
 
  /* cmd[2..5] = 0x00;                     logical block address = 0 */
189
 
  /* cmd[6..8] = 0x00;                     (reserved), cmd[8].b0=PMI(0) */
190
 
  /* cmd[9] = 0x00;                        control */
 
152
  cmd[0] = 0x25;                        /* INQUIRY */
 
153
  cmd[1] = 0x00;                        /* lun=0, evpd=0 */
 
154
  cmd[2] = 0x00;                        /* page code = 0 */
 
155
  cmd[3] = 0x00;                        /* (reserved) */
 
156
  cmd[4] = 0x00;                        /* allocation length */
 
157
  cmd[5] = 0x00;                        /* control */
191
158
 
192
 
#ifdef USE_SG_IO
193
 
  if (! legacy_ioctl) {
194
 
    memset(&sgbuf, 0, sizeof(sgbuf));
195
 
    sgbuf.interface_id = 'S';           /* SCSI Generic Interface */
196
 
    sgbuf.dxfer_direction = SG_DXFER_FROM_DEV;
197
 
    sgbuf.cmd_len = 10;
198
 
    sgbuf.cmdp = cmd;
199
 
    sgbuf.dxfer_len = 8;                /* send back 8 bytes of data (capacity, sectorsize) */
200
 
    sgbuf.dxferp = cmd;
201
 
    sgbuf.timeout = 2000;
202
 
    status = ioctl( fileno(infile), SG_IO, &sgbuf );
203
 
  }
204
 
  else
205
 
#endif
206
159
  status = ioctl( fileno(infile), 1 /* SCSI_IOCTL_SEND_COMMAND */, buffer );
207
 
  if (status < 0) {
208
 
    perror("ioctl");
209
 
    return 3;
210
 
  }
 
160
 
211
161
  capacity = (buffer[8] << 24) | (buffer[9] << 16)  | (buffer[10] << 8) | buffer[11];
212
162
  sectorsize = (buffer[12] << 24) | (buffer[13] << 16)  | (buffer[14] << 8) | buffer[15];
213
 
  if (verbose)
214
 
    printf("Size %llu bytes, sectorsize %u\n", ((uint64_t)capacity) * sectorsize, sectorsize);
 
163
  printf("Size %d  sectorsize %d\n", capacity * (sectorsize >> 9), sectorsize);
 
164
 
215
165
 
216
166
  do{
217
 
/*
218
167
          for (i=0; i<10*1024; i++)
219
168
          {
220
169
                  buffer[i] = 0;
221
170
          }
222
 
*/
 
171
          
223
172
          block = 0;
224
173
          this_count = read_size / sectorsize;
225
174
          starttime = time_so_far();
227
176
                  *( (int *)  buffer )          = 0;    /* length of input data */
228
177
                  *( ((int *) buffer) + 1 )     = read_size;    /* length of output buffer */
229
178
                  
230
 
                  cmd = (unsigned char *) ( ((int *) buffer) + 2 );
 
179
                  cmd = (char *) ( ((int *) buffer) + 2 );
231
180
                  
232
181
                  b = bstart + bstep * block;
233
 
                  if (read_len == 10) {
234
 
                    cmd[0] = 0x28;                      /* read_10 */
235
 
                    cmd[1] = 0x00;
236
 
                    if (fua)
237
 
                      cmd[1] |= 0x08;
238
 
                    cmd[2] = (b >> 24) & 0xff;
239
 
                    cmd[3] = (b >> 16) & 0xff;
240
 
                    cmd[4] = (b >>  8) & 0xff;
241
 
                    cmd[5] =  b        & 0xff;
242
 
                    cmd[6] = 0;
243
 
                    cmd[7] = (this_count >> 8) & 0xff; /* transfer length */
244
 
                    cmd[8] =  this_count       & 0xff;
245
 
                    cmd[9] = 0x00; /* control */
246
 
                  }
247
 
                  else {
248
 
                    cmd[0] = 0x08;                      /* read_6 */
249
 
                    cmd[1] = (b >> 16) & 0x1f;
250
 
                    cmd[2] = (b >> 8) & 0xff;
251
 
                    cmd[3] = b & 0xff;
252
 
                    cmd[4] = this_count;
253
 
                    cmd[5] = 0x00;
254
 
                  }
255
 
#ifdef USE_SG_IO
256
 
                  if (! legacy_ioctl) {
257
 
                    memset(&sgbuf, 0, sizeof(sgbuf));
258
 
                    sgbuf.interface_id = 'S';           /* SCSI Generic Interface */
259
 
                    sgbuf.dxfer_direction = SG_DXFER_FROM_DEV;
260
 
                    sgbuf.cmd_len = read_len;
261
 
                    sgbuf.cmdp = cmd;
262
 
                    sgbuf.dxfer_len = read_size;
263
 
                    sgbuf.dxferp = cmd;
264
 
                    sgbuf.timeout = 2000;
265
 
                    status = ioctl( fileno(infile), SG_IO, &sgbuf );
266
 
                  }
267
 
                  else
268
 
#endif
 
182
#ifdef USE_READ_10
 
183
                  cmd[0] = 0x28;                        /* read_10 */
 
184
                  cmd[1] = 0x00;
 
185
#ifdef SET_FUA
 
186
                  cmd[1] |= 0x08;
 
187
#endif /* SET_FUA */
 
188
                  cmd[2] = (b >> 24) & 0xff;
 
189
                  cmd[3] = (b >> 16) & 0xff;
 
190
                  cmd[4] = (b >>  8) & 0xff;
 
191
                  cmd[5] =  b        & 0xff;
 
192
                  cmd[6] = 0;
 
193
                  cmd[7] = (this_count >> 8) & 0xff; /* transfer length */
 
194
                  cmd[8] =  this_count       & 0xff;
 
195
                  cmd[9] = 0x00; /* control */
 
196
#else /* USE_READ_10 */
 
197
                  cmd[0] = 0x08;                        /* read_6 */
 
198
                  cmd[1] = (b >> 16) & 0x1f;
 
199
                  cmd[2] = (b >> 8) & 0xff;
 
200
                  cmd[3] = b & 0xff;
 
201
                  cmd[4] = this_count;
 
202
                  cmd[5] = 0x00;
 
203
#endif /* USE_READ_10 */
 
204
                  
269
205
                  status = ioctl( fileno(infile), 3 /* SCSI_IOCTL_BENCHMARK_COMMAND */, buffer );
270
 
                  if (status < 0) {
271
 
                    if (verbose)
272
 
                      printf("ioctl: %s\n", strerror(errno));
273
 
                    else
274
 
                      printf("(%d) ", status);
275
 
                  }
 
206
                  if(status) fprintf(stderr,"%x ", status);
276
207
                  block += this_count;
277
208
          } while(block < (10000 / (sectorsize >> 9)));
278
209
          endtime = time_so_far() - starttime;
279
210
          rate = (block * sectorsize) / endtime;
280
 
          if (!verbose)
281
 
            printf("%6d   %10.4f  %6d    %8d \n",
282
 
                 read_size, endtime, block, rate);
283
 
          else
284
 
            printf("Blocksize %d, time elapsed %1.4f seconds, %d blocks.  Throughput = %d bytes/sec\n",
285
 
                 read_size, endtime, block, rate);
 
211
#ifdef LESS_VERBOSE_OUTPUT
 
212
          printf("%6d   %10.4f  %6d    %8d \n",
 
213
                 read_size, endtime, block, rate);
 
214
#else /* LESS_VERBOSE_OUTPUT */
 
215
          printf("Blocksize %d, time elapsed %1.4f seconds, %d blocks.  Throughput = %d bytes/sec\n",
 
216
                 read_size, endtime, block, rate);
 
217
#endif /* LESS_VERBOSE_OUTPUT */
286
218
 
287
219
          read_size += 4096;
288
220
  } while(read_size <= 2*64*1024);