Deleted Added
full compact
camcontrol.c (274322) camcontrol.c (276835)
1/*
2 * Copyright (c) 1997-2007 Kenneth D. Merry
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1997-2007 Kenneth D. Merry
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sbin/camcontrol/camcontrol.c 274322 2014-11-09 18:13:08Z bryanv $");
30__FBSDID("$FreeBSD: head/sbin/camcontrol/camcontrol.c 276835 2015-01-08 16:58:40Z ken $");
31
32#include <sys/ioctl.h>
33#include <sys/stdint.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/endian.h>
37#include <sys/sbuf.h>
38

--- 123 unchanged lines hidden (view full) ---

162struct ata_set_max_pwd
163{
164 u_int16_t reserved1;
165 u_int8_t password[32];
166 u_int16_t reserved2[239];
167};
168
169static const char scsicmd_opts[] = "a:c:dfi:o:r";
31
32#include <sys/ioctl.h>
33#include <sys/stdint.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/endian.h>
37#include <sys/sbuf.h>
38

--- 123 unchanged lines hidden (view full) ---

162struct ata_set_max_pwd
163{
164 u_int16_t reserved1;
165 u_int8_t password[32];
166 u_int16_t reserved2[239];
167};
168
169static const char scsicmd_opts[] = "a:c:dfi:o:r";
170static const char readdefect_opts[] = "f:GP";
170static const char readdefect_opts[] = "f:GPqsS:X";
171static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
172static const char smprg_opts[] = "l";
173static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
174static const char smpphylist_opts[] = "lq";
175static char pwd_opt;
176#endif
177
178static struct camcontrol_opts option_table[] = {

--- 3185 unchanged lines hidden (view full) ---

3364 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3365 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3366 ccb.ccb_h.status & CAM_STATUS_MASK);
3367 return(1);
3368 }
3369}
3370
3371#ifndef MINIMALISTIC
171static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
172static const char smprg_opts[] = "l";
173static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
174static const char smpphylist_opts[] = "lq";
175static char pwd_opt;
176#endif
177
178static struct camcontrol_opts option_table[] = {

--- 3185 unchanged lines hidden (view full) ---

3364 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3365 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3366 ccb.ccb_h.status & CAM_STATUS_MASK);
3367 return(1);
3368 }
3369}
3370
3371#ifndef MINIMALISTIC
3372
3373static struct scsi_nv defect_list_type_map[] = {
3374 { "block", SRDD10_BLOCK_FORMAT },
3375 { "extbfi", SRDD10_EXT_BFI_FORMAT },
3376 { "extphys", SRDD10_EXT_PHYS_FORMAT },
3377 { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3378 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3379 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3380};
3381
3372static int
3373readdefects(struct cam_device *device, int argc, char **argv,
3374 char *combinedopt, int retry_count, int timeout)
3375{
3376 union ccb *ccb = NULL;
3382static int
3383readdefects(struct cam_device *device, int argc, char **argv,
3384 char *combinedopt, int retry_count, int timeout)
3385{
3386 union ccb *ccb = NULL;
3377 struct scsi_read_defect_data_10 *rdd_cdb;
3387 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3388 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3389 size_t hdr_size = 0, entry_size = 0;
3390 int use_12byte = 0;
3391 int hex_format = 0;
3378 u_int8_t *defect_list = NULL;
3392 u_int8_t *defect_list = NULL;
3379 u_int32_t max_dlist_length = SRDD10_MAX_LENGTH, dlist_length = 0;
3380 u_int32_t returned_length = 0;
3381 u_int32_t num_returned = 0;
3382 u_int8_t returned_format;
3393 u_int8_t list_format = 0;
3394 int list_type_set = 0;
3395 u_int32_t dlist_length = 0;
3396 u_int32_t returned_length = 0, valid_len = 0;
3397 u_int32_t num_returned = 0, num_valid = 0;
3398 u_int32_t max_possible_size = 0, hdr_max = 0;
3399 u_int32_t starting_offset = 0;
3400 u_int8_t returned_format, returned_type;
3383 unsigned int i;
3401 unsigned int i;
3402 int summary = 0, quiet = 0;
3384 int c, error = 0;
3403 int c, error = 0;
3385 int lists_specified;
3386 int get_length = 1;
3404 int lists_specified = 0;
3405 int get_length = 1, first_pass = 1;
3406 int mads = 0;
3387
3388 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3389 switch(c){
3390 case 'f':
3391 {
3407
3408 while ((c = getopt(argc, argv, combinedopt)) != -1) {
3409 switch(c){
3410 case 'f':
3411 {
3392 char *tstr;
3393 tstr = optarg;
3394 while (isspace(*tstr) && (*tstr != '\0'))
3395 tstr++;
3396 if (strcmp(tstr, "block") == 0)
3397 arglist |= CAM_ARG_FORMAT_BLOCK;
3398 else if (strcmp(tstr, "bfi") == 0)
3399 arglist |= CAM_ARG_FORMAT_BFI;
3400 else if (strcmp(tstr, "phys") == 0)
3401 arglist |= CAM_ARG_FORMAT_PHYS;
3402 else {
3412 scsi_nv_status status;
3413 int entry_num = 0;
3414
3415 status = scsi_get_nv(defect_list_type_map,
3416 sizeof(defect_list_type_map) /
3417 sizeof(defect_list_type_map[0]), optarg,
3418 &entry_num, SCSI_NV_FLAG_IG_CASE);
3419
3420 if (status == SCSI_NV_FOUND) {
3421 list_format = defect_list_type_map[
3422 entry_num].value;
3423 list_type_set = 1;
3424 } else {
3425 warnx("%s: %s %s option %s", __func__,
3426 (status == SCSI_NV_AMBIGUOUS) ?
3427 "ambiguous" : "invalid", "defect list type",
3428 optarg);
3403 error = 1;
3429 error = 1;
3404 warnx("invalid defect format %s", tstr);
3405 goto defect_bailout;
3406 }
3407 break;
3408 }
3409 case 'G':
3410 arglist |= CAM_ARG_GLIST;
3411 break;
3412 case 'P':
3413 arglist |= CAM_ARG_PLIST;
3414 break;
3430 goto defect_bailout;
3431 }
3432 break;
3433 }
3434 case 'G':
3435 arglist |= CAM_ARG_GLIST;
3436 break;
3437 case 'P':
3438 arglist |= CAM_ARG_PLIST;
3439 break;
3440 case 'q':
3441 quiet = 1;
3442 break;
3443 case 's':
3444 summary = 1;
3445 break;
3446 case 'S': {
3447 char *endptr;
3448
3449 starting_offset = strtoul(optarg, &endptr, 0);
3450 if (*endptr != '\0') {
3451 error = 1;
3452 warnx("invalid starting offset %s", optarg);
3453 goto defect_bailout;
3454 }
3455 break;
3456 }
3457 case 'X':
3458 hex_format = 1;
3459 break;
3415 default:
3416 break;
3417 }
3418 }
3419
3460 default:
3461 break;
3462 }
3463 }
3464
3420 ccb = cam_getccb(device);
3421
3422 /*
3423 * Eventually we should probably support the 12 byte READ DEFECT
3424 * DATA command. It supports a longer parameter list, which may be
3425 * necessary on newer drives with lots of defects. According to
3426 * the SBC-3 spec, drives are supposed to return an illegal request
3427 * if they have more defect data than will fit in 64K.
3428 */
3429 defect_list = malloc(max_dlist_length);
3430 if (defect_list == NULL) {
3431 warnx("can't malloc memory for defect list");
3465 if (list_type_set == 0) {
3432 error = 1;
3466 error = 1;
3467 warnx("no defect list format specified");
3433 goto defect_bailout;
3434 }
3435
3468 goto defect_bailout;
3469 }
3470
3471 if (arglist & CAM_ARG_PLIST) {
3472 list_format |= SRDD10_PLIST;
3473 lists_specified++;
3474 }
3475
3476 if (arglist & CAM_ARG_GLIST) {
3477 list_format |= SRDD10_GLIST;
3478 lists_specified++;
3479 }
3480
3436 /*
3481 /*
3482 * This implies a summary, and was the previous behavior.
3483 */
3484 if (lists_specified == 0)
3485 summary = 1;
3486
3487 ccb = cam_getccb(device);
3488
3489retry_12byte:
3490
3491 /*
3437 * We start off asking for just the header to determine how much
3438 * defect data is available. Some Hitachi drives return an error
3439 * if you ask for more data than the drive has. Once we know the
3440 * length, we retry the command with the returned length.
3441 */
3492 * We start off asking for just the header to determine how much
3493 * defect data is available. Some Hitachi drives return an error
3494 * if you ask for more data than the drive has. Once we know the
3495 * length, we retry the command with the returned length.
3496 */
3442 dlist_length = sizeof(struct scsi_read_defect_data_hdr_10);
3497 if (use_12byte == 0)
3498 dlist_length = sizeof(*hdr10);
3499 else
3500 dlist_length = sizeof(*hdr12);
3443
3501
3444 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
3445
3446retry:
3502retry:
3503 if (defect_list != NULL) {
3504 free(defect_list);
3505 defect_list = NULL;
3506 }
3507 defect_list = malloc(dlist_length);
3508 if (defect_list == NULL) {
3509 warnx("can't malloc memory for defect list");
3510 error = 1;
3511 goto defect_bailout;
3512 }
3447
3513
3448 lists_specified = 0;
3514next_batch:
3515 bzero(defect_list, dlist_length);
3449
3450 /*
3451 * cam_getccb() zeros the CCB header only. So we need to zero the
3452 * payload portion of the ccb.
3453 */
3454 bzero(&(&ccb->ccb_h)[1],
3455 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3456
3516
3517 /*
3518 * cam_getccb() zeros the CCB header only. So we need to zero the
3519 * payload portion of the ccb.
3520 */
3521 bzero(&(&ccb->ccb_h)[1],
3522 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
3523
3457 cam_fill_csio(&ccb->csio,
3458 /*retries*/ retry_count,
3459 /*cbfcnp*/ NULL,
3460 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ?
3461 CAM_PASS_ERR_RECOVER : 0),
3462 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3463 /*data_ptr*/ defect_list,
3464 /*dxfer_len*/ dlist_length,
3465 /*sense_len*/ SSD_FULL_SIZE,
3466 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10),
3467 /*timeout*/ timeout ? timeout : 5000);
3524 scsi_read_defects(&ccb->csio,
3525 /*retries*/ retry_count,
3526 /*cbfcnp*/ NULL,
3527 /*tag_action*/ MSG_SIMPLE_Q_TAG,
3528 /*list_format*/ list_format,
3529 /*addr_desc_index*/ starting_offset,
3530 /*data_ptr*/ defect_list,
3531 /*dxfer_len*/ dlist_length,
3532 /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3533 /*sense_len*/ SSD_FULL_SIZE,
3534 /*timeout*/ timeout ? timeout : 5000);
3468
3535
3469 rdd_cdb->opcode = READ_DEFECT_DATA_10;
3470 if (arglist & CAM_ARG_FORMAT_BLOCK)
3471 rdd_cdb->format = SRDD10_BLOCK_FORMAT;
3472 else if (arglist & CAM_ARG_FORMAT_BFI)
3473 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT;
3474 else if (arglist & CAM_ARG_FORMAT_PHYS)
3475 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT;
3476 else {
3477 error = 1;
3478 warnx("no defect list format specified");
3479 goto defect_bailout;
3480 }
3481 if (arglist & CAM_ARG_PLIST) {
3482 rdd_cdb->format |= SRDD10_PLIST;
3483 lists_specified++;
3484 }
3485
3486 if (arglist & CAM_ARG_GLIST) {
3487 rdd_cdb->format |= SRDD10_GLIST;
3488 lists_specified++;
3489 }
3490
3491 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length);
3492
3493 /* Disable freezing the device queue */
3494 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3495
3496 if (cam_send_ccb(device, ccb) < 0) {
3497 perror("error reading defect list");
3498
3499 if (arglist & CAM_ARG_VERBOSE) {
3500 cam_error_print(device, ccb, CAM_ESF_ALL,
3501 CAM_EPF_ALL, stderr);
3502 }
3503
3504 error = 1;
3505 goto defect_bailout;
3506 }
3507
3536 /* Disable freezing the device queue */
3537 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3538
3539 if (cam_send_ccb(device, ccb) < 0) {
3540 perror("error reading defect list");
3541
3542 if (arglist & CAM_ARG_VERBOSE) {
3543 cam_error_print(device, ccb, CAM_ESF_ALL,
3544 CAM_EPF_ALL, stderr);
3545 }
3546
3547 error = 1;
3548 goto defect_bailout;
3549 }
3550
3508 returned_length = scsi_2btoul(((struct
3509 scsi_read_defect_data_hdr_10 *)defect_list)->length);
3551 valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3510
3552
3553 if (use_12byte == 0) {
3554 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3555 hdr_size = sizeof(*hdr10);
3556 hdr_max = SRDDH10_MAX_LENGTH;
3557
3558 if (valid_len >= hdr_size) {
3559 returned_length = scsi_2btoul(hdr10->length);
3560 returned_format = hdr10->format;
3561 } else {
3562 returned_length = 0;
3563 returned_format = 0;
3564 }
3565 } else {
3566 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
3567 hdr_size = sizeof(*hdr12);
3568 hdr_max = SRDDH12_MAX_LENGTH;
3569
3570 if (valid_len >= hdr_size) {
3571 returned_length = scsi_4btoul(hdr12->length);
3572 returned_format = hdr12->format;
3573 } else {
3574 returned_length = 0;
3575 returned_format = 0;
3576 }
3577 }
3578
3579 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
3580 switch (returned_type) {
3581 case SRDD10_BLOCK_FORMAT:
3582 entry_size = sizeof(struct scsi_defect_desc_block);
3583 break;
3584 case SRDD10_LONG_BLOCK_FORMAT:
3585 entry_size = sizeof(struct scsi_defect_desc_long_block);
3586 break;
3587 case SRDD10_EXT_PHYS_FORMAT:
3588 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3589 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
3590 break;
3591 case SRDD10_EXT_BFI_FORMAT:
3592 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3593 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
3594 break;
3595 default:
3596 warnx("Unknown defect format 0x%x\n", returned_type);
3597 error = 1;
3598 goto defect_bailout;
3599 break;
3600 }
3601
3602 max_possible_size = (hdr_max / entry_size) * entry_size;
3603 num_returned = returned_length / entry_size;
3604 num_valid = min(returned_length, valid_len - hdr_size);
3605 num_valid /= entry_size;
3606
3511 if (get_length != 0) {
3512 get_length = 0;
3513
3514 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3515 CAM_SCSI_STATUS_ERROR) {
3516 struct scsi_sense_data *sense;
3517 int error_code, sense_key, asc, ascq;
3518

--- 6 unchanged lines hidden (view full) ---

3525 * If the drive is reporting that it just doesn't
3526 * support the defect list format, go ahead and use
3527 * the length it reported. Otherwise, the length
3528 * may not be valid, so use the maximum.
3529 */
3530 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3531 && (asc == 0x1c) && (ascq == 0x00)
3532 && (returned_length > 0)) {
3607 if (get_length != 0) {
3608 get_length = 0;
3609
3610 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
3611 CAM_SCSI_STATUS_ERROR) {
3612 struct scsi_sense_data *sense;
3613 int error_code, sense_key, asc, ascq;
3614

--- 6 unchanged lines hidden (view full) ---

3621 * If the drive is reporting that it just doesn't
3622 * support the defect list format, go ahead and use
3623 * the length it reported. Otherwise, the length
3624 * may not be valid, so use the maximum.
3625 */
3626 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3627 && (asc == 0x1c) && (ascq == 0x00)
3628 && (returned_length > 0)) {
3533 dlist_length = returned_length +
3534 sizeof(struct scsi_read_defect_data_hdr_10);
3535 dlist_length = min(dlist_length,
3536 SRDD10_MAX_LENGTH);
3537 } else
3538 dlist_length = max_dlist_length;
3629 if ((use_12byte == 0)
3630 && (returned_length >= max_possible_size)) {
3631 get_length = 1;
3632 use_12byte = 1;
3633 goto retry_12byte;
3634 }
3635 dlist_length = returned_length + hdr_size;
3636 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3637 && (asc == 0x1f) && (ascq == 0x00)
3638 && (returned_length > 0)) {
3639 /* Partial defect list transfer */
3640 /*
3641 * Hitachi drives return this error
3642 * along with a partial defect list if they
3643 * have more defects than the 10 byte
3644 * command can support. Retry with the 12
3645 * byte command.
3646 */
3647 if (use_12byte == 0) {
3648 get_length = 1;
3649 use_12byte = 1;
3650 goto retry_12byte;
3651 }
3652 dlist_length = returned_length + hdr_size;
3653 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
3654 && (asc == 0x24) && (ascq == 0x00)) {
3655 /* Invalid field in CDB */
3656 /*
3657 * SBC-3 says that if the drive has more
3658 * defects than can be reported with the
3659 * 10 byte command, it should return this
3660 * error and no data. Retry with the 12
3661 * byte command.
3662 */
3663 if (use_12byte == 0) {
3664 get_length = 1;
3665 use_12byte = 1;
3666 goto retry_12byte;
3667 }
3668 dlist_length = returned_length + hdr_size;
3669 } else {
3670 /*
3671 * If we got a SCSI error and no valid length,
3672 * just use the 10 byte maximum. The 12
3673 * byte maximum is too large.
3674 */
3675 if (returned_length == 0)
3676 dlist_length = SRDD10_MAX_LENGTH;
3677 else {
3678 if ((use_12byte == 0)
3679 && (returned_length >=
3680 max_possible_size)) {
3681 get_length = 1;
3682 use_12byte = 1;
3683 goto retry_12byte;
3684 }
3685 dlist_length = returned_length +
3686 hdr_size;
3687 }
3688 }
3539 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3540 CAM_REQ_CMP){
3541 error = 1;
3542 warnx("Error reading defect header");
3543 if (arglist & CAM_ARG_VERBOSE)
3544 cam_error_print(device, ccb, CAM_ESF_ALL,
3545 CAM_EPF_ALL, stderr);
3546 goto defect_bailout;
3547 } else {
3689 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
3690 CAM_REQ_CMP){
3691 error = 1;
3692 warnx("Error reading defect header");
3693 if (arglist & CAM_ARG_VERBOSE)
3694 cam_error_print(device, ccb, CAM_ESF_ALL,
3695 CAM_EPF_ALL, stderr);
3696 goto defect_bailout;
3697 } else {
3548 dlist_length = returned_length +
3549 sizeof(struct scsi_read_defect_data_hdr_10);
3550 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3698 if ((use_12byte == 0)
3699 && (returned_length >= max_possible_size)) {
3700 get_length = 1;
3701 use_12byte = 1;
3702 goto retry_12byte;
3703 }
3704 dlist_length = returned_length + hdr_size;
3551 }
3705 }
3706 if (summary != 0) {
3707 fprintf(stdout, "%u", num_returned);
3708 if (quiet == 0) {
3709 fprintf(stdout, " defect%s",
3710 (num_returned != 1) ? "s" : "");
3711 }
3712 fprintf(stdout, "\n");
3552
3713
3714 goto defect_bailout;
3715 }
3716
3717 /*
3718 * We always limit the list length to the 10-byte maximum
3719 * length (0xffff). The reason is that some controllers
3720 * can't handle larger I/Os, and we can transfer the entire
3721 * 10 byte list in one shot. For drives that support the 12
3722 * byte read defects command, we'll step through the list
3723 * by specifying a starting offset. For drives that don't
3724 * support the 12 byte command's starting offset, we'll
3725 * just display the first 64K.
3726 */
3727 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
3728
3553 goto retry;
3554 }
3555
3729 goto retry;
3730 }
3731
3556 returned_format = ((struct scsi_read_defect_data_hdr_10 *)
3557 defect_list)->format;
3558
3559 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3560 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3561 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3562 struct scsi_sense_data *sense;
3563 int error_code, sense_key, asc, ascq;
3564
3565 sense = &ccb->csio.sense_data;
3566 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3567 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3568 &ascq, /*show_errors*/ 1);
3569
3570 /*
3571 * According to the SCSI spec, if the disk doesn't support
3572 * the requested format, it will generally return a sense
3573 * key of RECOVERED ERROR, and an additional sense code
3732
3733 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
3734 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
3735 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
3736 struct scsi_sense_data *sense;
3737 int error_code, sense_key, asc, ascq;
3738
3739 sense = &ccb->csio.sense_data;
3740 scsi_extract_sense_len(sense, ccb->csio.sense_len -
3741 ccb->csio.sense_resid, &error_code, &sense_key, &asc,
3742 &ascq, /*show_errors*/ 1);
3743
3744 /*
3745 * According to the SCSI spec, if the disk doesn't support
3746 * the requested format, it will generally return a sense
3747 * key of RECOVERED ERROR, and an additional sense code
3574 * of "DEFECT LIST NOT FOUND". So, we check for that, and
3575 * also check to make sure that the returned length is
3576 * greater than 0, and then print out whatever format the
3577 * disk gave us.
3748 * of "DEFECT LIST NOT FOUND". HGST drives also return
3749 * Primary/Grown defect list not found errors. So just
3750 * check for an ASC of 0x1c.
3578 */
3579 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3751 */
3752 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
3580 && (asc == 0x1c) && (ascq == 0x00)
3581 && (returned_length > 0)) {
3582 warnx("requested defect format not available");
3583 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) {
3584 case SRDD10_BLOCK_FORMAT:
3585 warnx("Device returned block format");
3586 break;
3587 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3588 warnx("Device returned bytes from index"
3589 " format");
3590 break;
3591 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3592 warnx("Device returned physical sector format");
3593 break;
3594 default:
3753 && (asc == 0x1c)) {
3754 const char *format_str;
3755
3756 format_str = scsi_nv_to_str(defect_list_type_map,
3757 sizeof(defect_list_type_map) /
3758 sizeof(defect_list_type_map[0]),
3759 list_format & SRDD10_DLIST_FORMAT_MASK);
3760 warnx("requested defect format %s not available",
3761 format_str ? format_str : "unknown");
3762
3763 format_str = scsi_nv_to_str(defect_list_type_map,
3764 sizeof(defect_list_type_map) /
3765 sizeof(defect_list_type_map[0]), returned_type);
3766 if (format_str != NULL) {
3767 warnx("Device returned %s format",
3768 format_str);
3769 } else {
3595 error = 1;
3596 warnx("Device returned unknown defect"
3770 error = 1;
3771 warnx("Device returned unknown defect"
3597 " data format %#x", returned_format);
3772 " data format %#x", returned_type);
3598 goto defect_bailout;
3773 goto defect_bailout;
3599 break; /* NOTREACHED */
3600 }
3601 } else {
3602 error = 1;
3603 warnx("Error returned from read defect data command");
3604 if (arglist & CAM_ARG_VERBOSE)
3605 cam_error_print(device, ccb, CAM_ESF_ALL,
3606 CAM_EPF_ALL, stderr);
3607 goto defect_bailout;
3608 }
3609 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3610 error = 1;
3611 warnx("Error returned from read defect data command");
3612 if (arglist & CAM_ARG_VERBOSE)
3613 cam_error_print(device, ccb, CAM_ESF_ALL,
3614 CAM_EPF_ALL, stderr);
3615 goto defect_bailout;
3616 }
3617
3774 }
3775 } else {
3776 error = 1;
3777 warnx("Error returned from read defect data command");
3778 if (arglist & CAM_ARG_VERBOSE)
3779 cam_error_print(device, ccb, CAM_ESF_ALL,
3780 CAM_EPF_ALL, stderr);
3781 goto defect_bailout;
3782 }
3783 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3784 error = 1;
3785 warnx("Error returned from read defect data command");
3786 if (arglist & CAM_ARG_VERBOSE)
3787 cam_error_print(device, ccb, CAM_ESF_ALL,
3788 CAM_EPF_ALL, stderr);
3789 goto defect_bailout;
3790 }
3791
3792 if (first_pass != 0) {
3793 fprintf(stderr, "Got %d defect", num_returned);
3794
3795 if ((lists_specified == 0) || (num_returned == 0)) {
3796 fprintf(stderr, "s.\n");
3797 goto defect_bailout;
3798 } else if (num_returned == 1)
3799 fprintf(stderr, ":\n");
3800 else
3801 fprintf(stderr, "s:\n");
3802
3803 first_pass = 0;
3804 }
3805
3618 /*
3619 * XXX KDM I should probably clean up the printout format for the
3620 * disk defects.
3621 */
3806 /*
3807 * XXX KDM I should probably clean up the printout format for the
3808 * disk defects.
3809 */
3622 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){
3623 case SRDDH10_PHYSICAL_SECTOR_FORMAT:
3624 {
3625 struct scsi_defect_desc_phys_sector *dlist;
3810 switch (returned_type) {
3811 case SRDD10_PHYSICAL_SECTOR_FORMAT:
3812 case SRDD10_EXT_PHYS_FORMAT:
3813 {
3814 struct scsi_defect_desc_phys_sector *dlist;
3626
3815
3627 dlist = (struct scsi_defect_desc_phys_sector *)
3628 (defect_list +
3629 sizeof(struct scsi_read_defect_data_hdr_10));
3816 dlist = (struct scsi_defect_desc_phys_sector *)
3817 (defect_list + hdr_size);
3630
3818
3631 num_returned = returned_length /
3632 sizeof(struct scsi_defect_desc_phys_sector);
3819 for (i = 0; i < num_valid; i++) {
3820 uint32_t sector;
3633
3821
3634 fprintf(stderr, "Got %d defect", num_returned);
3635
3636 if ((lists_specified == 0) || (num_returned == 0)) {
3637 fprintf(stderr, "s.\n");
3638 break;
3639 } else if (num_returned == 1)
3640 fprintf(stderr, ":\n");
3822 sector = scsi_4btoul(dlist[i].sector);
3823 if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
3824 mads = (sector & SDD_EXT_PHYS_MADS) ?
3825 0 : 1;
3826 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
3827 }
3828 if (hex_format == 0)
3829 fprintf(stdout, "%d:%d:%d%s",
3830 scsi_3btoul(dlist[i].cylinder),
3831 dlist[i].head,
3832 scsi_4btoul(dlist[i].sector),
3833 mads ? " - " : "\n");
3641 else
3834 else
3642 fprintf(stderr, "s:\n");
3643
3644 for (i = 0; i < num_returned; i++) {
3645 fprintf(stdout, "%d:%d:%d\n",
3835 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3646 scsi_3btoul(dlist[i].cylinder),
3647 dlist[i].head,
3836 scsi_3btoul(dlist[i].cylinder),
3837 dlist[i].head,
3648 scsi_4btoul(dlist[i].sector));
3649 }
3650 break;
3838 scsi_4btoul(dlist[i].sector),
3839 mads ? " - " : "\n");
3840 mads = 0;
3651 }
3841 }
3652 case SRDDH10_BYTES_FROM_INDEX_FORMAT:
3653 {
3654 struct scsi_defect_desc_bytes_from_index *dlist;
3842 if (num_valid < num_returned) {
3843 starting_offset += num_valid;
3844 goto next_batch;
3845 }
3846 break;
3847 }
3848 case SRDD10_BYTES_FROM_INDEX_FORMAT:
3849 case SRDD10_EXT_BFI_FORMAT:
3850 {
3851 struct scsi_defect_desc_bytes_from_index *dlist;
3655
3852
3656 dlist = (struct scsi_defect_desc_bytes_from_index *)
3657 (defect_list +
3658 sizeof(struct scsi_read_defect_data_hdr_10));
3853 dlist = (struct scsi_defect_desc_bytes_from_index *)
3854 (defect_list + hdr_size);
3659
3855
3660 num_returned = returned_length /
3661 sizeof(struct scsi_defect_desc_bytes_from_index);
3856 for (i = 0; i < num_valid; i++) {
3857 uint32_t bfi;
3662
3858
3663 fprintf(stderr, "Got %d defect", num_returned);
3664
3665 if ((lists_specified == 0) || (num_returned == 0)) {
3666 fprintf(stderr, "s.\n");
3667 break;
3668 } else if (num_returned == 1)
3669 fprintf(stderr, ":\n");
3859 bfi = scsi_4btoul(dlist[i].bytes_from_index);
3860 if (returned_type == SRDD10_EXT_BFI_FORMAT) {
3861 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
3862 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
3863 }
3864 if (hex_format == 0)
3865 fprintf(stdout, "%d:%d:%d%s",
3866 scsi_3btoul(dlist[i].cylinder),
3867 dlist[i].head,
3868 scsi_4btoul(dlist[i].bytes_from_index),
3869 mads ? " - " : "\n");
3670 else
3870 else
3671 fprintf(stderr, "s:\n");
3672
3673 for (i = 0; i < num_returned; i++) {
3674 fprintf(stdout, "%d:%d:%d\n",
3871 fprintf(stdout, "0x%x:0x%x:0x%x%s",
3675 scsi_3btoul(dlist[i].cylinder),
3676 dlist[i].head,
3872 scsi_3btoul(dlist[i].cylinder),
3873 dlist[i].head,
3677 scsi_4btoul(dlist[i].bytes_from_index));
3678 }
3679 break;
3874 scsi_4btoul(dlist[i].bytes_from_index),
3875 mads ? " - " : "\n");
3876
3877 mads = 0;
3680 }
3878 }
3681 case SRDDH10_BLOCK_FORMAT:
3682 {
3683 struct scsi_defect_desc_block *dlist;
3879 if (num_valid < num_returned) {
3880 starting_offset += num_valid;
3881 goto next_batch;
3882 }
3883 break;
3884 }
3885 case SRDDH10_BLOCK_FORMAT:
3886 {
3887 struct scsi_defect_desc_block *dlist;
3684
3888
3685 dlist = (struct scsi_defect_desc_block *)(defect_list +
3686 sizeof(struct scsi_read_defect_data_hdr_10));
3889 dlist = (struct scsi_defect_desc_block *)
3890 (defect_list + hdr_size);
3687
3891
3688 num_returned = returned_length /
3689 sizeof(struct scsi_defect_desc_block);
3892 for (i = 0; i < num_valid; i++) {
3893 if (hex_format == 0)
3894 fprintf(stdout, "%u\n",
3895 scsi_4btoul(dlist[i].address));
3896 else
3897 fprintf(stdout, "0x%x\n",
3898 scsi_4btoul(dlist[i].address));
3899 }
3690
3900
3691 fprintf(stderr, "Got %d defect", num_returned);
3901 if (num_valid < num_returned) {
3902 starting_offset += num_valid;
3903 goto next_batch;
3904 }
3692
3905
3693 if ((lists_specified == 0) || (num_returned == 0)) {
3694 fprintf(stderr, "s.\n");
3695 break;
3696 } else if (num_returned == 1)
3697 fprintf(stderr, ":\n");
3906 break;
3907 }
3908 case SRDD10_LONG_BLOCK_FORMAT:
3909 {
3910 struct scsi_defect_desc_long_block *dlist;
3911
3912 dlist = (struct scsi_defect_desc_long_block *)
3913 (defect_list + hdr_size);
3914
3915 for (i = 0; i < num_valid; i++) {
3916 if (hex_format == 0)
3917 fprintf(stdout, "%ju\n",
3918 (uintmax_t)scsi_8btou64(
3919 dlist[i].address));
3698 else
3920 else
3699 fprintf(stderr, "s:\n");
3921 fprintf(stdout, "0x%jx\n",
3922 (uintmax_t)scsi_8btou64(
3923 dlist[i].address));
3924 }
3700
3925
3701 for (i = 0; i < num_returned; i++)
3702 fprintf(stdout, "%u\n",
3703 scsi_4btoul(dlist[i].address));
3704 break;
3926 if (num_valid < num_returned) {
3927 starting_offset += num_valid;
3928 goto next_batch;
3705 }
3929 }
3706 default:
3707 fprintf(stderr, "Unknown defect format %d\n",
3708 returned_format & SRDDH10_DLIST_FORMAT_MASK);
3709 error = 1;
3710 break;
3930 break;
3711 }
3931 }
3932 default:
3933 fprintf(stderr, "Unknown defect format 0x%x\n",
3934 returned_type);
3935 error = 1;
3936 break;
3937 }
3712defect_bailout:
3713
3714 if (defect_list != NULL)
3715 free(defect_list);
3716
3717 if (ccb != NULL)
3718 cam_freeccb(ccb);
3719

--- 4076 unchanged lines hidden (view full) ---

7796" camcontrol stop [dev_id][generic args]\n"
7797" camcontrol load [dev_id][generic args]\n"
7798" camcontrol eject [dev_id][generic args]\n"
7799#endif /* MINIMALISTIC */
7800" camcontrol rescan <all | bus[:target:lun]>\n"
7801" camcontrol reset <all | bus[:target:lun]>\n"
7802#ifndef MINIMALISTIC
7803" camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
3938defect_bailout:
3939
3940 if (defect_list != NULL)
3941 free(defect_list);
3942
3943 if (ccb != NULL)
3944 cam_freeccb(ccb);
3945

--- 4076 unchanged lines hidden (view full) ---

8022" camcontrol stop [dev_id][generic args]\n"
8023" camcontrol load [dev_id][generic args]\n"
8024" camcontrol eject [dev_id][generic args]\n"
8025#endif /* MINIMALISTIC */
8026" camcontrol rescan <all | bus[:target:lun]>\n"
8027" camcontrol reset <all | bus[:target:lun]>\n"
8028#ifndef MINIMALISTIC
8029" camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n"
8030" [-q][-s][-S offset][-X]\n"
7804" camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
7805" [-P pagectl][-e | -b][-d]\n"
7806" camcontrol cmd [dev_id][generic args]\n"
7807" <-a cmd [args] | -c cmd [args]>\n"
7808" [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
7809" camcontrol smpcmd [dev_id][generic args]\n"
7810" <-r len fmt [args]> <-R len fmt [args]>\n"
7811" camcontrol smprg [dev_id][generic args][-l]\n"

--- 575 unchanged lines hidden ---
8031" camcontrol modepage [dev_id][generic args] <-m page | -l>\n"
8032" [-P pagectl][-e | -b][-d]\n"
8033" camcontrol cmd [dev_id][generic args]\n"
8034" <-a cmd [args] | -c cmd [args]>\n"
8035" [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
8036" camcontrol smpcmd [dev_id][generic args]\n"
8037" <-r len fmt [args]> <-R len fmt [args]>\n"
8038" camcontrol smprg [dev_id][generic args][-l]\n"

--- 575 unchanged lines hidden ---