summaryrefslogtreecommitdiff
path: root/utils/imxtools/scsitools/scsitool.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/imxtools/scsitools/scsitool.c')
-rw-r--r--utils/imxtools/scsitools/scsitool.c402
1 files changed, 394 insertions, 8 deletions
diff --git a/utils/imxtools/scsitools/scsitool.c b/utils/imxtools/scsitools/scsitool.c
index c534667f05..8ef2774f32 100644
--- a/utils/imxtools/scsitools/scsitool.c
+++ b/utils/imxtools/scsitools/scsitool.c
@@ -76,6 +76,21 @@ void *buffer_alloc(int sz)
76} 76}
77#endif 77#endif
78 78
79static uint16_t fix_endian16be(uint16_t w)
80{
81 return w << 8 | w >> 8;
82}
83
84static uint32_t fix_endian32be(uint32_t w)
85{
86 return __builtin_bswap32(w);
87}
88
89static uint64_t fix_endian64be(uint64_t w)
90{
91 return __builtin_bswap64(w);
92}
93
79static void print_hex(void *_buffer, int buffer_size) 94static void print_hex(void *_buffer, int buffer_size)
80{ 95{
81 uint8_t *buffer = _buffer; 96 uint8_t *buffer = _buffer;
@@ -158,7 +173,7 @@ int do_scsi(uint8_t *cdb, int cdb_size, unsigned flags, void *sense, int *sense_
158 173
159int do_sense_analysis(int status, uint8_t *sense, int sense_size) 174int do_sense_analysis(int status, uint8_t *sense, int sense_size)
160{ 175{
161 if(status != GOOD || g_debug) 176 if(status != GOOD && g_debug)
162 { 177 {
163 cprintf_field("Status:", " "); fflush(stdout); 178 cprintf_field("Status:", " "); fflush(stdout);
164 sg_print_scsi_status(status); 179 sg_print_scsi_status(status);
@@ -200,11 +215,11 @@ int stmp_inquiry(uint8_t *dev_type, char vendor[9], char product[17])
200 215
201static int stmp_get_protocol_version(struct scsi_stmp_protocol_version_t *ver) 216static int stmp_get_protocol_version(struct scsi_stmp_protocol_version_t *ver)
202{ 217{
203 uint8_t cdb[10]; 218 uint8_t cdb[16];
204 memset(cdb, 0, sizeof(cdb)); 219 memset(cdb, 0, sizeof(cdb));
205 cdb[0] = SCSI_STMP_READ; 220 cdb[0] = SCSI_STMP_READ;
206 cdb[1] = SCSI_STMP_CMD_GET_PROTOCOL_VERSION; 221 cdb[1] = SCSI_STMP_CMD_GET_PROTOCOL_VERSION;
207 222
208 uint8_t sense[32]; 223 uint8_t sense[32];
209 int sense_size = sizeof(sense); 224 int sense_size = sizeof(sense);
210 225
@@ -220,6 +235,115 @@ static int stmp_get_protocol_version(struct scsi_stmp_protocol_version_t *ver)
220 return 0; 235 return 0;
221} 236}
222 237
238static int stmp_get_chip_major_rev_id(struct scsi_stmp_chip_major_rev_id_t *ver)
239{
240 uint8_t cdb[16];
241 memset(cdb, 0, sizeof(cdb));
242 cdb[0] = SCSI_STMP_READ;
243 cdb[1] = SCSI_STMP_CMD_GET_CHIP_MAJOR_REV_ID;
244
245 uint8_t sense[32];
246 int sense_size = sizeof(sense);
247
248 int buf_sz = sizeof(struct scsi_stmp_chip_major_rev_id_t);
249 int ret = do_scsi(cdb, sizeof(cdb), DO_READ, sense, &sense_size, ver, &buf_sz);
250 if(ret < 0)
251 return ret;
252 ret = do_sense_analysis(ret, sense, sense_size);
253 if(ret)
254 return ret;
255 if(buf_sz != sizeof(struct scsi_stmp_chip_major_rev_id_t))
256 return -1;
257 ver->rev = fix_endian16be(ver->rev);
258 return 0;
259}
260
261static int stmp_get_rom_rev_id(struct scsi_stmp_rom_rev_id_t *ver)
262{
263 uint8_t cdb[16];
264 memset(cdb, 0, sizeof(cdb));
265 cdb[0] = SCSI_STMP_READ;
266 cdb[1] = SCSI_STMP_CMD_GET_ROM_REV_ID;
267
268 uint8_t sense[32];
269 int sense_size = sizeof(sense);
270
271 int buf_sz = sizeof(struct scsi_stmp_rom_rev_id_t);
272 int ret = do_scsi(cdb, sizeof(cdb), DO_READ, sense, &sense_size, ver, &buf_sz);
273 if(ret < 0)
274 return ret;
275 ret = do_sense_analysis(ret, sense, sense_size);
276 if(ret)
277 return ret;
278 if(buf_sz != sizeof(struct scsi_stmp_rom_rev_id_t))
279 return -1;
280 ver->rev = fix_endian16be(ver->rev);
281 return 0;
282}
283
284static int stmp_get_logical_media_info(uint8_t info, void *data, int *len)
285{
286 uint8_t cdb[16];
287 memset(cdb, 0, sizeof(cdb));
288 cdb[0] = SCSI_STMP_READ;
289 cdb[1] = SCSI_STMP_CMD_GET_LOGICAL_MEDIA_INFO;
290 cdb[2] = info;
291
292 uint8_t sense[32];
293 int sense_size = sizeof(sense);
294
295 int ret = do_scsi(cdb, sizeof(cdb), DO_READ, sense, &sense_size, data, len);
296 if(ret < 0)
297 return ret;
298 return do_sense_analysis(ret, sense, sense_size);
299}
300
301static int stmp_get_logical_table(struct scsi_stmp_logical_table_t *table, int entry_count)
302{
303 uint8_t cdb[16];
304 memset(cdb, 0, sizeof(cdb));
305 cdb[0] = SCSI_STMP_READ;
306 cdb[1] = SCSI_STMP_CMD_GET_LOGICAL_TABLE;
307 cdb[2] = entry_count;
308
309 uint8_t sense[32];
310 int sense_size = sizeof(sense);
311
312 int buf_sz = sizeof(struct scsi_stmp_logical_table_t) +
313 entry_count * sizeof(struct scsi_stmp_logical_table_entry_t);
314 int ret = do_scsi(cdb, sizeof(cdb), DO_READ, sense, &sense_size, table, &buf_sz);
315 if(ret < 0)
316 return ret;
317 ret = do_sense_analysis(ret, sense, sense_size);
318 if(ret)
319 return ret;
320 if((buf_sz - sizeof(struct scsi_stmp_logical_table_t)) % sizeof(struct scsi_stmp_logical_table_entry_t))
321 return -1;
322 table->count = fix_endian16be(table->count);
323 struct scsi_stmp_logical_table_entry_t *entry = (void *)(table + 1);
324 for(int i = 0; i < entry_count; i++)
325 entry[i].size = fix_endian64be(entry[i].size);
326 return 0;
327}
328
329static int stmp_get_logical_drive_info(uint8_t drive, uint8_t info, void *data, int *len)
330{
331 uint8_t cdb[16];
332 memset(cdb, 0, sizeof(cdb));
333 cdb[0] = SCSI_STMP_READ;
334 cdb[1] = SCSI_STMP_CMD_GET_LOGICAL_DRIVE_INFO;
335 cdb[2] = drive;
336 cdb[3] = info;
337
338 uint8_t sense[32];
339 int sense_size = sizeof(sense);
340
341 int ret = do_scsi(cdb, sizeof(cdb), DO_READ, sense, &sense_size, data, len);
342 if(ret < 0)
343 return ret;
344 return do_sense_analysis(ret, sense, sense_size);
345}
346
223static int do_work(void) 347static int do_work(void)
224{ 348{
225 cprintf(BLUE, "Information\n"); 349 cprintf(BLUE, "Information\n");
@@ -229,16 +353,278 @@ static int do_work(void)
229 char product[17]; 353 char product[17];
230 int ret = stmp_inquiry(&dev_type, vendor, product); 354 int ret = stmp_inquiry(&dev_type, vendor, product);
231 if(ret) 355 if(ret)
232 errorf("Cannot get inquiry data: %d\n", ret); 356 {
233 cprintf_field(" Vendor: ", "%s\n", vendor); 357 cprintf(GREY, "Cannot get inquiry data: %d\n", ret);
234 cprintf_field(" Product: ", "%s\n", product); 358 }
359 else
360 {
361 cprintf_field(" Vendor: ", "%s\n", vendor);
362 cprintf_field(" Product: ", "%s\n", product);
363 }
235 364
236 struct scsi_stmp_protocol_version_t ver; 365 struct scsi_stmp_protocol_version_t ver;
237 ret = stmp_get_protocol_version(&ver); 366 ret = stmp_get_protocol_version(&ver);
238 if(ret) 367 if(ret)
239 errorf("Cannot get protocol version: %d\n", ret); 368 cprintf(GREY, "Cannot get protocol version: %d\n", ret);
369 else
370 cprintf_field(" Protocol: ", "%x.%x\n", ver.major, ver.minor);
371
372 do
373 {
374 union
375 {
376 uint8_t u8;
377 uint16_t u16;
378 uint32_t u32;
379 uint64_t u64;
380 uint8_t buf[52];
381 }u;
382
383 int len = 2;
384 ret = stmp_get_logical_media_info(0, &u.u16, &len);
385 if(!ret && len == 2)
386 {
387 u.u16 = fix_endian16be(u.u16);
388 cprintf_field(" Logical Media Info (0): ", "%#x\n", u.u16);
389 }
390
391 len = 4;
392 ret = stmp_get_logical_media_info(6, &u.u32, &len);
393 if(!ret && len == 4)
394 {
395 u.u32 = fix_endian32be(u.u32);
396 cprintf_field(" Logical Media Info (6): ", "%#x\n", u.u32);
397 }
398
399 len = 1;
400 ret = stmp_get_logical_media_info(5, &u.u8, &len);
401 if(!ret && len == 1)
402 cprintf_field(" Logical Media Info (5): ", "%#x\n", u.u8);
403
404 len = 8;
405 ret = stmp_get_logical_media_info(1, &u.u64, &len);
406 if(!ret && len == 8)
407 {
408 u.u64 = fix_endian64be(u.u64);
409 cprintf_field(" Logical Media Info (1): ", "%#llx\n", u.u64);
410 }
411
412 len = 4;
413 ret = stmp_get_logical_media_info(7, &u.u32, &len);
414 if(!ret && len == 4)
415 {
416 u.u32 = fix_endian32be(u.u32);
417 cprintf_field(" Logical Media Info (7): ", "%#x\n", u.u32);
418 }
419
420 len = 52;
421 ret = stmp_get_logical_media_info(8, &u.buf, &len);
422 if(!ret && len != 0)
423 {
424 cprintf(GREEN, " Logical Media Info (8):");
425 /*
426 for(int i = 0; i < len; i++)
427 cprintf(YELLOW, " %02x", u.buf[i]);
428 printf("\n");
429 */
430 print_hex(u.buf, len);
431 }
432
433 len = 1;
434 ret = stmp_get_logical_media_info(9, &u.u8, &len);
435 if(!ret && len == 1)
436 cprintf_field(" Logical Media Info (9): ", "%#x\n", u.u8);
437
438 len = 4;
439 ret = stmp_get_logical_media_info(12, &u.u32, &len);
440 if(!ret && len == 4)
441 {
442 u.u32 = fix_endian32be(u.u32);
443 cprintf_field(" Logical Media Info (12): ", "%#x\n", u.u32);
444 }
445
446 len = 8;
447 ret = stmp_get_logical_media_info(13, &u.u64, &len);
448 if(!ret && len == 8)
449 {
450 u.u64 = fix_endian64be(u.u64);
451 cprintf_field(" Logical Media Info (13): ", "%#llx\n", u.u64);
452 }
453
454 len = 4;
455 ret = stmp_get_logical_media_info(11, &u.u32, &len);
456 if(!ret && len == 4)
457 {
458 u.u32 = fix_endian32be(u.u32);
459 cprintf_field(" Logical Media Info (11): ", "%#x\n", u.u32);
460 }
461
462 len = 4;
463 ret = stmp_get_logical_media_info(14, &u.u32, &len);
464 if(!ret && len == 4)
465 {
466 u.u32 = fix_endian32be(u.u32);
467 cprintf_field(" Logical Media Info (14): ", "%#x\n", u.u32);
468 }
469 }while(0);
470
471 struct scsi_stmp_chip_major_rev_id_t chip_rev;
472 ret = stmp_get_chip_major_rev_id(&chip_rev);
473 if(ret)
474 cprintf(GREY, "Cannot get chip major revision id: %d\n", ret);
475 else
476 cprintf_field(" Chip Major Rev ID: ", "%x\n", chip_rev.rev);
240 477
241 cprintf_field(" Protocol: ", "%x.%x\n", ver.major, ver.minor); 478 struct scsi_stmp_rom_rev_id_t rom_rev;
479 ret = stmp_get_rom_rev_id(&rom_rev);
480 if(ret)
481 cprintf(GREY, "Cannot get rom revision id: %d\n", ret);
482 else
483 cprintf_field(" ROM Rev ID: ", "%x\n", rom_rev.rev);
484
485 struct
486 {
487 struct scsi_stmp_logical_table_t header;
488 struct scsi_stmp_logical_table_entry_t entry[20];
489 }table;
490
491 ret = stmp_get_logical_table(&table.header, sizeof(table.entry) / sizeof(table.entry[0]));
492 if(ret)
493 cprintf(GREY, "Cannot get logical table: %d\n", ret);
494 else
495 {
496 cprintf_field(" Logical Table: ", "%d entries\n", table.header.count);
497 for(int i = 0; i < table.header.count; i++)
498 {
499 cprintf_field2(" Drive No: ", "%2x", table.entry[i].drive_no);
500 cprintf_field2(" Type: ", "%2x", table.entry[i].type);
501 cprintf_field2(" Tag: ", "%2x", table.entry[i].tag);
502 unsigned long long size = table.entry[i].size;
503 int order = 0;
504 while(size >= 1024)
505 {
506 size /= 1024;
507 order++;
508 }
509 static const char *suffix[] = {"B", "KiB", "MiB", "GiB", "TiB"};
510 cprintf_field2(" Size: ", "%llu %s", size, suffix[order]);
511 cprintf(OFF, "\n");
512 }
513
514 for(int i = 0; i < table.header.count; i++)
515 {
516 union
517 {
518 uint8_t u8;
519 uint16_t u16;
520 uint32_t u32;
521 uint64_t u64;
522 uint8_t buf[52];
523 }u;
524 uint8_t drive = table.entry[i].drive_no;
525 cprintf_field(" Drive ", "%02x\n", drive);
526
527 int len = 4;
528 ret = stmp_get_logical_drive_info(drive, 0, &u.u32, &len);
529 if(!ret && len == 4)
530 {
531 u.u32 = fix_endian32be(u.u32);
532 cprintf_field(" Info 0: ", "%#x\n", u.u32);
533 }
534
535 len = 4;
536 ret = stmp_get_logical_drive_info(drive, 1, &u.u32, &len);
537 if(!ret && len == 4)
538 {
539 u.u32 = fix_endian32be(u.u32);
540 cprintf_field(" Info 1: ", "%#x\n", u.u32);
541 }
542
543 len = 8;
544 ret = stmp_get_logical_drive_info(drive, 2, &u.u64, &len);
545 if(!ret && len == 8)
546 {
547 u.u64 = fix_endian64be(u.u64);
548 cprintf_field(" Info 2: ", "%#llx\n", u.u64);
549 }
550
551 len = 4;
552 ret = stmp_get_logical_drive_info(drive, 3, &u.u32, &len);
553 if(!ret && len == 4)
554 {
555 u.u32 = fix_endian32be(u.u32);
556 cprintf_field(" Info 3: ", "%#x\n", u.u32);
557 }
558
559 len = 8;
560 ret = stmp_get_logical_drive_info(drive, 4, &u.u64, &len);
561 if(!ret && len == 8)
562 {
563 u.u64 = fix_endian64be(u.u64);
564 cprintf_field(" Info 4: ", "%#llx\n", u.u64);
565 }
566
567 len = 4;
568 ret = stmp_get_logical_drive_info(drive, 5, &u.u32, &len);
569 if(!ret && len == 4)
570 {
571 u.u32 = fix_endian32be(u.u32);
572 cprintf_field(" Info 5: ", "%#x\n", u.u32);
573 }
574
575 len = 1;
576 ret = stmp_get_logical_drive_info(drive, 6, &u.u8, &len);
577 if(!ret && len == 1)
578 {
579 cprintf_field(" Info 6: ", "%#x\n", u.u8);
580 }
581
582 len = 52;
583 ret = stmp_get_logical_drive_info(drive, 7, &u.buf, &len);
584 if(!ret && len != 0)
585 {
586 cprintf(GREEN, " Info 7:");
587 for(int i = 0; i < len; i++)
588 cprintf(YELLOW, " %02x", u.buf[i]);
589 printf("\n");
590 }
591
592 len = 52;
593 ret = stmp_get_logical_drive_info(drive, 8, &u.buf, &len);
594 if(!ret && len != 0)
595 {
596 cprintf(GREEN, " Info 8:");
597 for(int i = 0; i < len; i++)
598 cprintf(YELLOW, " %02x", u.buf[i]);
599 printf("\n");
600 }
601
602 len = 1;
603 ret = stmp_get_logical_drive_info(drive, 9, &u.u8, &len);
604 if(!ret && len == 1)
605 {
606 cprintf_field(" Info 9: ", "%#x\n", u.u8);
607 }
608
609 len = 2;
610 ret = stmp_get_logical_drive_info(drive, 10, &u.u16, &len);
611 if(!ret && len == 2)
612 {
613 u.u16 = fix_endian16be(u.u16);
614 cprintf_field(" Info 10: ", "%#x\n", u.u16);
615 }
616
617 len = 52;
618 ret = stmp_get_logical_drive_info(drive, 11, &u.buf, &len);
619 if(!ret && len != 0)
620 {
621 cprintf(GREEN, " Info 11:");
622 for(int i = 0; i < len; i++)
623 cprintf(YELLOW, " %02x", u.buf[i]);
624 printf("\n");
625 }
626 }
627 }
242 628
243 return 0; 629 return 0;
244} 630}