Deleted Added
full compact
camcontrol.c (241737) camcontrol.c (249115)
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 241737 2012-10-19 14:49:42Z ed $");
30__FBSDID("$FreeBSD: head/sbin/camcontrol/camcontrol.c 249115 2013-04-04 23:19:51Z smh $");
31
32#include <sys/ioctl.h>
33#include <sys/stdint.h>
34#include <sys/types.h>
35#include <sys/endian.h>
36#include <sys/sbuf.h>
37
38#include <stdio.h>

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

82 CAM_CMD_IDLE = 0x00000014,
83 CAM_CMD_STANDBY = 0x00000015,
84 CAM_CMD_SLEEP = 0x00000016,
85 CAM_CMD_SMP_CMD = 0x00000017,
86 CAM_CMD_SMP_RG = 0x00000018,
87 CAM_CMD_SMP_PC = 0x00000019,
88 CAM_CMD_SMP_PHYLIST = 0x0000001a,
89 CAM_CMD_SMP_MANINFO = 0x0000001b,
31
32#include <sys/ioctl.h>
33#include <sys/stdint.h>
34#include <sys/types.h>
35#include <sys/endian.h>
36#include <sys/sbuf.h>
37
38#include <stdio.h>

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

82 CAM_CMD_IDLE = 0x00000014,
83 CAM_CMD_STANDBY = 0x00000015,
84 CAM_CMD_SLEEP = 0x00000016,
85 CAM_CMD_SMP_CMD = 0x00000017,
86 CAM_CMD_SMP_RG = 0x00000018,
87 CAM_CMD_SMP_PC = 0x00000019,
88 CAM_CMD_SMP_PHYLIST = 0x0000001a,
89 CAM_CMD_SMP_MANINFO = 0x0000001b,
90 CAM_CMD_DOWNLOAD_FW = 0x0000001c
90 CAM_CMD_DOWNLOAD_FW = 0x0000001c,
91 CAM_CMD_SECURITY = 0x0000001d
91} cam_cmdmask;
92
93typedef enum {
94 CAM_ARG_NONE = 0x00000000,
95 CAM_ARG_VERBOSE = 0x00000001,
96 CAM_ARG_DEVICE = 0x00000002,
97 CAM_ARG_BUS = 0x00000004,
98 CAM_ARG_TARGET = 0x00000008,

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

135
136#ifndef MINIMALISTIC
137static const char scsicmd_opts[] = "a:c:dfi:o:r";
138static const char readdefect_opts[] = "f:GP";
139static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
140static const char smprg_opts[] = "l";
141static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
142static const char smpphylist_opts[] = "lq";
92} cam_cmdmask;
93
94typedef enum {
95 CAM_ARG_NONE = 0x00000000,
96 CAM_ARG_VERBOSE = 0x00000001,
97 CAM_ARG_DEVICE = 0x00000002,
98 CAM_ARG_BUS = 0x00000004,
99 CAM_ARG_TARGET = 0x00000008,

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

136
137#ifndef MINIMALISTIC
138static const char scsicmd_opts[] = "a:c:dfi:o:r";
139static const char readdefect_opts[] = "f:GP";
140static const char negotiate_opts[] = "acD:M:O:qR:T:UW:";
141static const char smprg_opts[] = "l";
142static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:";
143static const char smpphylist_opts[] = "lq";
144static char pwd_opt;
143#endif
144
145static struct camcontrol_opts option_table[] = {
146#ifndef MINIMALISTIC
147 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
148 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
149 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
150 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},

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

178 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
179 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
180 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
181 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
182 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
183 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
184 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
185 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
145#endif
146
147static struct camcontrol_opts option_table[] = {
148#ifndef MINIMALISTIC
149 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
150 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
151 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
152 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},

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

180 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
181 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
182 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
183 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
184 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
185 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
186 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
187 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"},
188 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"},
186#endif /* MINIMALISTIC */
187 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
188 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
189 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
190 {NULL, 0, 0, NULL}
191};
192
193typedef enum {

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

269 int timeout, int argc, char **argv, char *combinedopt);
270static int scsiformat(struct cam_device *device, int argc, char **argv,
271 char *combinedopt, int retry_count, int timeout);
272static int scsireportluns(struct cam_device *device, int argc, char **argv,
273 char *combinedopt, int retry_count, int timeout);
274static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
275 char *combinedopt, int retry_count, int timeout);
276static int atapm(struct cam_device *device, int argc, char **argv,
189#endif /* MINIMALISTIC */
190 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
191 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
192 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
193 {NULL, 0, 0, NULL}
194};
195
196typedef enum {

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

272 int timeout, int argc, char **argv, char *combinedopt);
273static int scsiformat(struct cam_device *device, int argc, char **argv,
274 char *combinedopt, int retry_count, int timeout);
275static int scsireportluns(struct cam_device *device, int argc, char **argv,
276 char *combinedopt, int retry_count, int timeout);
277static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
278 char *combinedopt, int retry_count, int timeout);
279static int atapm(struct cam_device *device, int argc, char **argv,
277 char *combinedopt, int retry_count, int timeout);
280 char *combinedopt, int retry_count, int timeout);
281static int atasecurity(struct cam_device *device, int retry_count, int timeout,
282 int argc, char **argv, char *combinedopt);
283
278#endif /* MINIMALISTIC */
279#ifndef min
280#define min(a,b) (((a)<(b))?(a):(b))
281#endif
282#ifndef max
283#define max(a,b) (((a)>(b))?(a):(b))
284#endif
285

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

1323 } else
1324 printf("\n");
1325 printf("unload %s %s\n",
1326 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1327 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1328 printf("free-fall %s %s\n",
1329 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1330 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
284#endif /* MINIMALISTIC */
285#ifndef min
286#define min(a,b) (((a)<(b))?(a):(b))
287#endif
288#ifndef max
289#define max(a,b) (((a)>(b))?(a):(b))
290#endif
291

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

1329 } else
1330 printf("\n");
1331 printf("unload %s %s\n",
1332 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no",
1333 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no");
1334 printf("free-fall %s %s\n",
1335 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no",
1336 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no");
1331 printf("data set management (TRIM) %s\n",
1332 parm->support_dsm & ATA_SUPPORT_DSM_TRIM ? "yes" : "no");
1337 printf("Data Set Management (DSM/TRIM) ");
1338 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) {
1339 printf("yes\n");
1340 printf("DSM - max 512byte blocks ");
1341 if (parm->max_dsm_blocks == 0x00)
1342 printf("yes not specified\n");
1343 else
1344 printf("yes %d\n",
1345 parm->max_dsm_blocks);
1346
1347 printf("DSM - deterministic read ");
1348 if (parm->support3 & ATA_SUPPORT_DRAT) {
1349 if (parm->support3 & ATA_SUPPORT_RZAT)
1350 printf("yes zeroed\n");
1351 else
1352 printf("yes any value\n");
1353 } else {
1354 printf("no\n");
1355 }
1356 } else {
1357 printf("no\n");
1358 }
1333}
1334
1335static int
1359}
1360
1361static int
1336ataidentify(struct cam_device *device, int retry_count, int timeout)
1362scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet)
1337{
1363{
1338 union ccb *ccb;
1339 struct ata_params *ident_buf;
1340 struct ccb_getdev cgd;
1341 u_int i, error = 0;
1342 int16_t *ptr;
1364 struct ata_pass_16 *ata_pass_16;
1365 struct ata_cmd ata_cmd;
1343
1366
1344 if (get_cgd(device, &cgd) != 0) {
1345 warnx("couldn't get CGD");
1346 return(1);
1347 }
1348 ccb = cam_getccb(device);
1367 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes;
1368 ata_cmd.command = ata_pass_16->command;
1369 ata_cmd.control = ata_pass_16->control;
1370 ata_cmd.features = ata_pass_16->features;
1349
1371
1350 if (ccb == NULL) {
1351 warnx("couldn't allocate CCB");
1352 return(1);
1372 if (arglist & CAM_ARG_VERBOSE) {
1373 warnx("sending ATA %s via pass_16 with timeout of %u msecs",
1374 ata_op_string(&ata_cmd),
1375 ccb->csio.ccb_h.timeout);
1353 }
1354
1376 }
1377
1355 /* cam_getccb cleans up the header, caller has to zero the payload */
1356 bzero(&(&ccb->ccb_h)[1],
1357 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
1378 /* Disable freezing the device queue */
1379 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1358
1380
1359 ptr = (uint16_t *)malloc(sizeof(struct ata_params));
1381 if (arglist & CAM_ARG_ERR_RECOVER)
1382 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1360
1383
1361 if (ptr == NULL) {
1362 cam_freeccb(ccb);
1363 warnx("can't malloc memory for identify\n");
1364 return(1);
1384 if (cam_send_ccb(device, ccb) < 0) {
1385 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1386 warn("error sending ATA %s via pass_16",
1387 ata_op_string(&ata_cmd));
1388 }
1389
1390 if (arglist & CAM_ARG_VERBOSE) {
1391 cam_error_print(device, ccb, CAM_ESF_ALL,
1392 CAM_EPF_ALL, stderr);
1393 }
1394
1395 return (1);
1365 }
1396 }
1366 bzero(ptr, sizeof(struct ata_params));
1367
1397
1368 cam_fill_ataio(&ccb->ataio,
1369 retry_count,
1370 NULL,
1371 /*flags*/CAM_DIR_IN,
1372 MSG_SIMPLE_Q_TAG,
1373 /*data_ptr*/(u_int8_t *)ptr,
1374 /*dxfer_len*/sizeof(struct ata_params),
1375 timeout ? timeout : 30 * 1000);
1376 if (cgd.protocol == PROTO_ATA)
1377 ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
1378 else
1379 ata_28bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
1398 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) &&
1399 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1400 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1401 warnx("ATA %s via pass_16 failed",
1402 ata_op_string(&ata_cmd));
1403 }
1404 if (arglist & CAM_ARG_VERBOSE) {
1405 cam_error_print(device, ccb, CAM_ESF_ALL,
1406 CAM_EPF_ALL, stderr);
1407 }
1380
1408
1409 return (1);
1410 }
1411
1412 return (0);
1413}
1414
1415
1416static int
1417ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet)
1418{
1419 if (arglist & CAM_ARG_VERBOSE) {
1420 warnx("sending ATA %s with timeout of %u msecs",
1421 ata_op_string(&(ccb->ataio.cmd)),
1422 ccb->ataio.ccb_h.timeout);
1423 }
1424
1381 /* Disable freezing the device queue */
1382 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1383
1384 if (arglist & CAM_ARG_ERR_RECOVER)
1385 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1386
1387 if (cam_send_ccb(device, ccb) < 0) {
1425 /* Disable freezing the device queue */
1426 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
1427
1428 if (arglist & CAM_ARG_ERR_RECOVER)
1429 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
1430
1431 if (cam_send_ccb(device, ccb) < 0) {
1388 perror("error sending ATA identify");
1432 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1433 warn("error sending ATA %s",
1434 ata_op_string(&(ccb->ataio.cmd)));
1435 }
1389
1390 if (arglist & CAM_ARG_VERBOSE) {
1391 cam_error_print(device, ccb, CAM_ESF_ALL,
1392 CAM_EPF_ALL, stderr);
1393 }
1394
1436
1437 if (arglist & CAM_ARG_VERBOSE) {
1438 cam_error_print(device, ccb, CAM_ESF_ALL,
1439 CAM_EPF_ALL, stderr);
1440 }
1441
1395 free(ptr);
1396 cam_freeccb(ccb);
1397 return(1);
1442 return (1);
1398 }
1399
1400 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1443 }
1444
1445 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1401 error = 1;
1446 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) {
1447 warnx("ATA %s failed: %d",
1448 ata_op_string(&(ccb->ataio.cmd)), quiet);
1449 }
1402
1403 if (arglist & CAM_ARG_VERBOSE) {
1404 cam_error_print(device, ccb, CAM_ESF_ALL,
1405 CAM_EPF_ALL, stderr);
1406 }
1450
1451 if (arglist & CAM_ARG_VERBOSE) {
1452 cam_error_print(device, ccb, CAM_ESF_ALL,
1453 CAM_EPF_ALL, stderr);
1454 }
1455
1456 return (1);
1407 }
1408
1457 }
1458
1409 cam_freeccb(ccb);
1459 return (0);
1460}
1410
1461
1462static int
1463ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries,
1464 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags,
1465 u_int8_t tag_action, u_int8_t command, u_int8_t features,
1466 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr,
1467 u_int16_t dxfer_len, int timeout, int quiet)
1468{
1469 if (data_ptr != NULL) {
1470 ata_flags |= AP_FLAG_BYT_BLOK_BYTES |
1471 AP_FLAG_TLEN_SECT_CNT;
1472 if (flags & CAM_DIR_OUT)
1473 ata_flags |= AP_FLAG_TDIR_TO_DEV;
1474 else
1475 ata_flags |= AP_FLAG_TDIR_FROM_DEV;
1476 } else {
1477 ata_flags |= AP_FLAG_TLEN_NO_DATA;
1478 }
1479
1480 bzero(&(&ccb->ccb_h)[1],
1481 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1482
1483 scsi_ata_pass_16(&ccb->csio,
1484 retries,
1485 NULL,
1486 flags,
1487 tag_action,
1488 protocol,
1489 ata_flags,
1490 features,
1491 sector_count,
1492 lba,
1493 command,
1494 /*control*/0,
1495 data_ptr,
1496 dxfer_len,
1497 /*sense_len*/SSD_FULL_SIZE,
1498 timeout);
1499
1500 return scsi_cam_pass_16_send(device, ccb, quiet);
1501}
1502
1503static int
1504ata_try_pass_16(struct cam_device *device)
1505{
1506 struct ccb_pathinq cpi;
1507
1508 if (get_cpi(device, &cpi) != 0) {
1509 warnx("couldn't get CPI");
1510 return (-1);
1511 }
1512
1513 if (cpi.protocol == PROTO_SCSI) {
1514 /* possibly compatible with pass_16 */
1515 return (1);
1516 }
1517
1518 /* likely not compatible with pass_16 */
1519 return (0);
1520}
1521
1522static int
1523ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries,
1524 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action,
1525 u_int8_t command, u_int8_t features, u_int32_t lba,
1526 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len,
1527 int timeout, int quiet)
1528{
1529
1530
1531 switch (ata_try_pass_16(device)) {
1532 case -1:
1533 return (1);
1534 case 1:
1535 /* Try using SCSI Passthrough */
1536 return ata_do_pass_16(device, ccb, retries, flags, protocol,
1537 0, tag_action, command, features, lba,
1538 sector_count, data_ptr, dxfer_len,
1539 timeout, quiet);
1540 }
1541
1542 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) -
1543 sizeof(struct ccb_hdr));
1544 cam_fill_ataio(&ccb->ataio,
1545 retries,
1546 NULL,
1547 flags,
1548 tag_action,
1549 data_ptr,
1550 dxfer_len,
1551 timeout);
1552
1553 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count);
1554 return ata_cam_send(device, ccb, quiet);
1555}
1556
1557static void
1558dump_data(uint16_t *ptr, uint32_t len)
1559{
1560 u_int i;
1561
1562 for (i = 0; i < len / 2; i++) {
1563 if ((i % 8) == 0)
1564 printf(" %3d: ", i);
1565 printf("%04hx ", ptr[i]);
1566 if ((i % 8) == 7)
1567 printf("\n");
1568 }
1569 if ((i % 8) != 7)
1570 printf("\n");
1571}
1572
1573static int
1574ata_do_identify(struct cam_device *device, int retry_count, int timeout,
1575 union ccb *ccb, struct ata_params** ident_bufp)
1576{
1577 struct ata_params *ident_buf;
1578 struct ccb_pathinq cpi;
1579 struct ccb_getdev cgd;
1580 u_int i, error;
1581 int16_t *ptr;
1582 u_int8_t command, retry_command;
1583
1584 if (get_cpi(device, &cpi) != 0) {
1585 warnx("couldn't get CPI");
1586 return (-1);
1587 }
1588
1589 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */
1590 if (cpi.protocol == PROTO_ATA) {
1591 if (get_cgd(device, &cgd) != 0) {
1592 warnx("couldn't get CGD");
1593 return (-1);
1594 }
1595
1596 command = (cgd.protocol == PROTO_ATA) ?
1597 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY;
1598 retry_command = 0;
1599 } else {
1600 /* We don't know which for sure so try both */
1601 command = ATA_ATA_IDENTIFY;
1602 retry_command = ATA_ATAPI_IDENTIFY;
1603 }
1604
1605 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params));
1606 if (ptr == NULL) {
1607 warnx("can't calloc memory for identify\n");
1608 return (1);
1609 }
1610
1611 error = ata_do_28bit_cmd(device,
1612 ccb,
1613 /*retries*/retry_count,
1614 /*flags*/CAM_DIR_IN,
1615 /*protocol*/AP_PROTO_PIO_IN,
1616 /*tag_action*/MSG_SIMPLE_Q_TAG,
1617 /*command*/command,
1618 /*features*/0,
1619 /*lba*/0,
1620 /*sector_count*/(u_int8_t)sizeof(struct ata_params),
1621 /*data_ptr*/(u_int8_t *)ptr,
1622 /*dxfer_len*/sizeof(struct ata_params),
1623 /*timeout*/timeout ? timeout : 30 * 1000,
1624 /*quiet*/1);
1625
1411 if (error != 0) {
1626 if (error != 0) {
1412 free(ptr);
1413 return(error);
1627 if (retry_command == 0) {
1628 free(ptr);
1629 return (1);
1630 }
1631 error = ata_do_28bit_cmd(device,
1632 ccb,
1633 /*retries*/retry_count,
1634 /*flags*/CAM_DIR_IN,
1635 /*protocol*/AP_PROTO_PIO_IN,
1636 /*tag_action*/MSG_SIMPLE_Q_TAG,
1637 /*command*/retry_command,
1638 /*features*/0,
1639 /*lba*/0,
1640 /*sector_count*/(u_int8_t)
1641 sizeof(struct ata_params),
1642 /*data_ptr*/(u_int8_t *)ptr,
1643 /*dxfer_len*/sizeof(struct ata_params),
1644 /*timeout*/timeout ? timeout : 30 * 1000,
1645 /*quiet*/0);
1646
1647 if (error != 0) {
1648 free(ptr);
1649 return (1);
1650 }
1414 }
1415
1651 }
1652
1416 for (i = 0; i < sizeof(struct ata_params) / 2; i++)
1653 error = 1;
1654 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1417 ptr[i] = le16toh(ptr[i]);
1655 ptr[i] = le16toh(ptr[i]);
1656 if (ptr[i] != 0)
1657 error = 0;
1658 }
1659
1418 if (arglist & CAM_ARG_VERBOSE) {
1419 fprintf(stdout, "%s%d: Raw identify data:\n",
1420 device->device_name, device->dev_unit_num);
1660 if (arglist & CAM_ARG_VERBOSE) {
1661 fprintf(stdout, "%s%d: Raw identify data:\n",
1662 device->device_name, device->dev_unit_num);
1421 for (i = 0; i < sizeof(struct ata_params) / 2; i++) {
1422 if ((i % 8) == 0)
1423 fprintf(stdout, " %3d: ", i);
1424 fprintf(stdout, "%04x ", (uint16_t)ptr[i]);
1425 if ((i % 8) == 7)
1426 fprintf(stdout, "\n");
1427 }
1663 dump_data(ptr, sizeof(struct ata_params));
1428 }
1664 }
1665
1666 /* check for invalid (all zero) response */
1667 if (error != 0) {
1668 warnx("Invalid identify response detected");
1669 free(ptr);
1670 return (error);
1671 }
1672
1429 ident_buf = (struct ata_params *)ptr;
1430 if (strncmp(ident_buf->model, "FX", 2) &&
1431 strncmp(ident_buf->model, "NEC", 3) &&
1432 strncmp(ident_buf->model, "Pioneer", 7) &&
1433 strncmp(ident_buf->model, "SHARP", 5)) {
1434 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1435 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1436 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));

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

1441 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1442 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1443 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1444 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1445 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1446 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1447 sizeof(ident_buf->media_serial));
1448
1673 ident_buf = (struct ata_params *)ptr;
1674 if (strncmp(ident_buf->model, "FX", 2) &&
1675 strncmp(ident_buf->model, "NEC", 3) &&
1676 strncmp(ident_buf->model, "Pioneer", 7) &&
1677 strncmp(ident_buf->model, "SHARP", 5)) {
1678 ata_bswap(ident_buf->model, sizeof(ident_buf->model));
1679 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
1680 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));

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

1685 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
1686 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
1687 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
1688 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
1689 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial));
1690 ata_bpack(ident_buf->media_serial, ident_buf->media_serial,
1691 sizeof(ident_buf->media_serial));
1692
1449 fprintf(stdout, "%s%d: ", device->device_name,
1450 device->dev_unit_num);
1693 *ident_bufp = ident_buf;
1694
1695 return (0);
1696}
1697
1698
1699static int
1700ataidentify(struct cam_device *device, int retry_count, int timeout)
1701{
1702 union ccb *ccb;
1703 struct ata_params *ident_buf;
1704
1705 if ((ccb = cam_getccb(device)) == NULL) {
1706 warnx("couldn't allocate CCB");
1707 return (1);
1708 }
1709
1710 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) {
1711 cam_freeccb(ccb);
1712 return (1);
1713 }
1714
1715 printf("%s%d: ", device->device_name, device->dev_unit_num);
1451 ata_print_ident(ident_buf);
1452 camxferrate(device);
1453 atacapprint(ident_buf);
1454
1455 free(ident_buf);
1716 ata_print_ident(ident_buf);
1717 camxferrate(device);
1718 atacapprint(ident_buf);
1719
1720 free(ident_buf);
1721 cam_freeccb(ccb);
1456
1722
1457 return(0);
1723 return (0);
1458}
1459#endif /* MINIMALISTIC */
1460
1724}
1725#endif /* MINIMALISTIC */
1726
1727
1728#ifndef MINIMALISTIC
1729enum {
1730 ATA_SECURITY_ACTION_PRINT,
1731 ATA_SECURITY_ACTION_FREEZE,
1732 ATA_SECURITY_ACTION_UNLOCK,
1733 ATA_SECURITY_ACTION_DISABLE,
1734 ATA_SECURITY_ACTION_ERASE,
1735 ATA_SECURITY_ACTION_ERASE_ENHANCED,
1736 ATA_SECURITY_ACTION_SET_PASSWORD
1737} atasecurity_action;
1738
1739static void
1740atasecurity_print_time(u_int16_t tw)
1741{
1742
1743 if (tw == 0)
1744 printf("unspecified");
1745 else if (tw >= 255)
1746 printf("> 508 min");
1747 else
1748 printf("%i min", 2 * tw);
1749}
1750
1751static u_int32_t
1752atasecurity_erase_timeout_msecs(u_int16_t timeout)
1753{
1754
1755 if (timeout == 0)
1756 return 2 * 3600 * 1000; /* default: two hours */
1757 else if (timeout > 255)
1758 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */
1759
1760 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */
1761}
1762
1763
1764static void
1765atasecurity_notify(u_int8_t command, struct ata_security_password *pwd)
1766{
1767 struct ata_cmd cmd;
1768
1769 bzero(&cmd, sizeof(cmd));
1770 cmd.command = command;
1771 printf("Issuing %s", ata_op_string(&cmd));
1772
1773 if (pwd != NULL) {
1774 char pass[sizeof(pwd->password)+1];
1775
1776 /* pwd->password may not be null terminated */
1777 pass[sizeof(pwd->password)] = '\0';
1778 strncpy(pass, pwd->password, sizeof(pwd->password));
1779 printf(" password='%s', user='%s'",
1780 pass,
1781 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
1782 "master" : "user");
1783
1784 if (command == ATA_SECURITY_SET_PASSWORD) {
1785 printf(", mode='%s'",
1786 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
1787 "maximum" : "high");
1788 }
1789 }
1790
1791 printf("\n");
1792}
1793
1794static int
1795atasecurity_freeze(struct cam_device *device, union ccb *ccb,
1796 int retry_count, u_int32_t timeout, int quiet)
1797{
1798
1799 if (quiet == 0)
1800 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
1801
1802 return ata_do_28bit_cmd(device,
1803 ccb,
1804 retry_count,
1805 /*flags*/CAM_DIR_NONE,
1806 /*protocol*/AP_PROTO_NON_DATA,
1807 /*tag_action*/MSG_SIMPLE_Q_TAG,
1808 /*command*/ATA_SECURITY_FREEZE_LOCK,
1809 /*features*/0,
1810 /*lba*/0,
1811 /*sector_count*/0,
1812 /*data_ptr*/NULL,
1813 /*dxfer_len*/0,
1814 /*timeout*/timeout,
1815 /*quiet*/0);
1816}
1817
1818static int
1819atasecurity_unlock(struct cam_device *device, union ccb *ccb,
1820 int retry_count, u_int32_t timeout,
1821 struct ata_security_password *pwd, int quiet)
1822{
1823
1824 if (quiet == 0)
1825 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
1826
1827 return ata_do_28bit_cmd(device,
1828 ccb,
1829 retry_count,
1830 /*flags*/CAM_DIR_OUT,
1831 /*protocol*/AP_PROTO_PIO_OUT,
1832 /*tag_action*/MSG_SIMPLE_Q_TAG,
1833 /*command*/ATA_SECURITY_UNLOCK,
1834 /*features*/0,
1835 /*lba*/0,
1836 /*sector_count*/0,
1837 /*data_ptr*/(u_int8_t *)pwd,
1838 /*dxfer_len*/sizeof(*pwd),
1839 /*timeout*/timeout,
1840 /*quiet*/0);
1841}
1842
1843static int
1844atasecurity_disable(struct cam_device *device, union ccb *ccb,
1845 int retry_count, u_int32_t timeout,
1846 struct ata_security_password *pwd, int quiet)
1847{
1848
1849 if (quiet == 0)
1850 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
1851 return ata_do_28bit_cmd(device,
1852 ccb,
1853 retry_count,
1854 /*flags*/CAM_DIR_OUT,
1855 /*protocol*/AP_PROTO_PIO_OUT,
1856 /*tag_action*/MSG_SIMPLE_Q_TAG,
1857 /*command*/ATA_SECURITY_DISABLE_PASSWORD,
1858 /*features*/0,
1859 /*lba*/0,
1860 /*sector_count*/0,
1861 /*data_ptr*/(u_int8_t *)pwd,
1862 /*dxfer_len*/sizeof(*pwd),
1863 /*timeout*/timeout,
1864 /*quiet*/0);
1865}
1866
1867
1868static int
1869atasecurity_erase_confirm(struct cam_device *device,
1870 struct ata_params* ident_buf)
1871{
1872
1873 printf("\nYou are about to ERASE ALL DATA from the following"
1874 " device:\n%s%d,%s%d: ", device->device_name,
1875 device->dev_unit_num, device->given_dev_name,
1876 device->given_unit_number);
1877 ata_print_ident(ident_buf);
1878
1879 for(;;) {
1880 char str[50];
1881 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
1882
1883 if (fgets(str, sizeof(str), stdin) != NULL) {
1884 if (strncasecmp(str, "yes", 3) == 0) {
1885 return (1);
1886 } else if (strncasecmp(str, "no", 2) == 0) {
1887 return (0);
1888 } else {
1889 printf("Please answer \"yes\" or "
1890 "\"no\"\n");
1891 }
1892 }
1893 }
1894
1895 /* NOTREACHED */
1896 return (0);
1897}
1898
1899static int
1900atasecurity_erase(struct cam_device *device, union ccb *ccb,
1901 int retry_count, u_int32_t timeout,
1902 u_int32_t erase_timeout,
1903 struct ata_security_password *pwd, int quiet)
1904{
1905 int error;
1906
1907 if (quiet == 0)
1908 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
1909
1910 error = ata_do_28bit_cmd(device,
1911 ccb,
1912 retry_count,
1913 /*flags*/CAM_DIR_NONE,
1914 /*protocol*/AP_PROTO_NON_DATA,
1915 /*tag_action*/MSG_SIMPLE_Q_TAG,
1916 /*command*/ATA_SECURITY_ERASE_PREPARE,
1917 /*features*/0,
1918 /*lba*/0,
1919 /*sector_count*/0,
1920 /*data_ptr*/NULL,
1921 /*dxfer_len*/0,
1922 /*timeout*/timeout,
1923 /*quiet*/0);
1924
1925 if (error != 0)
1926 return error;
1927
1928 if (quiet == 0)
1929 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
1930
1931 error = ata_do_28bit_cmd(device,
1932 ccb,
1933 retry_count,
1934 /*flags*/CAM_DIR_OUT,
1935 /*protocol*/AP_PROTO_PIO_OUT,
1936 /*tag_action*/MSG_SIMPLE_Q_TAG,
1937 /*command*/ATA_SECURITY_ERASE_UNIT,
1938 /*features*/0,
1939 /*lba*/0,
1940 /*sector_count*/0,
1941 /*data_ptr*/(u_int8_t *)pwd,
1942 /*dxfer_len*/sizeof(*pwd),
1943 /*timeout*/erase_timeout,
1944 /*quiet*/0);
1945
1946 if (error == 0 && quiet == 0)
1947 printf("\nErase Complete\n");
1948
1949 return error;
1950}
1951
1952static int
1953atasecurity_set_password(struct cam_device *device, union ccb *ccb,
1954 int retry_count, u_int32_t timeout,
1955 struct ata_security_password *pwd, int quiet)
1956{
1957
1958 if (quiet == 0)
1959 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
1960
1961 return ata_do_28bit_cmd(device,
1962 ccb,
1963 retry_count,
1964 /*flags*/CAM_DIR_OUT,
1965 /*protocol*/AP_PROTO_PIO_OUT,
1966 /*tag_action*/MSG_SIMPLE_Q_TAG,
1967 /*command*/ATA_SECURITY_SET_PASSWORD,
1968 /*features*/0,
1969 /*lba*/0,
1970 /*sector_count*/0,
1971 /*data_ptr*/(u_int8_t *)pwd,
1972 /*dxfer_len*/sizeof(*pwd),
1973 /*timeout*/timeout,
1974 /*quiet*/0);
1975}
1976
1977static void
1978atasecurity_print(struct ata_params *parm)
1979{
1980
1981 printf("\nSecurity Option Value\n");
1982 if (arglist & CAM_ARG_VERBOSE) {
1983 printf("status %04x\n",
1984 parm->security_status);
1985 }
1986 printf("supported %s\n",
1987 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
1988 if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
1989 return;
1990 printf("enabled %s\n",
1991 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
1992 printf("drive locked %s\n",
1993 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
1994 printf("security config frozen %s\n",
1995 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
1996 printf("count expired %s\n",
1997 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
1998 printf("security level %s\n",
1999 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2000 printf("enhanced erase supported %s\n",
2001 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2002 printf("erase time ");
2003 atasecurity_print_time(parm->erase_time);
2004 printf("\n");
2005 printf("enhanced erase time ");
2006 atasecurity_print_time(parm->enhanced_erase_time);
2007 printf("\n");
2008 printf("master password rev %04x%s\n",
2009 parm->master_passwd_revision,
2010 parm->master_passwd_revision == 0x0000 ||
2011 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : "");
2012}
2013
1461/*
2014/*
2015 * Validates and copies the password in optarg to the passed buffer.
2016 * If the password in optarg is the same length as the buffer then
2017 * the data will still be copied but no null termination will occur.
2018 */
2019static int
2020ata_getpwd(u_int8_t *passwd, int max, char opt)
2021{
2022 int len;
2023
2024 len = strlen(optarg);
2025 if (len > max) {
2026 warnx("-%c password is too long", opt);
2027 return (1);
2028 } else if (len == 0) {
2029 warnx("-%c password is missing", opt);
2030 return (1);
2031 } else if (optarg[0] == '-'){
2032 warnx("-%c password starts with '-' (generic arg?)", opt);
2033 return (1);
2034 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2035 warnx("-%c password conflicts with existing password from -%c",
2036 opt, pwd_opt);
2037 return (1);
2038 }
2039
2040 /* Callers pass in a buffer which does NOT need to be terminated */
2041 strncpy(passwd, optarg, max);
2042 pwd_opt = opt;
2043
2044 return (0);
2045}
2046
2047static int
2048atasecurity(struct cam_device *device, int retry_count, int timeout,
2049 int argc, char **argv, char *combinedopt)
2050{
2051 union ccb *ccb;
2052 struct ata_params *ident_buf;
2053 int error, confirm, quiet, c, action, actions, setpwd;
2054 int security_enabled, erase_timeout, pwdsize;
2055 struct ata_security_password pwd;
2056
2057 actions = 0;
2058 setpwd = 0;
2059 erase_timeout = 0;
2060 confirm = 0;
2061 quiet = 0;
2062
2063 memset(&pwd, 0, sizeof(pwd));
2064
2065 /* default action is to print security information */
2066 action = ATA_SECURITY_ACTION_PRINT;
2067
2068 /* user is master by default as its safer that way */
2069 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2070 pwdsize = sizeof(pwd.password);
2071
2072 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2073 switch(c){
2074 case 'f':
2075 action = ATA_SECURITY_ACTION_FREEZE;
2076 actions++;
2077 break;
2078
2079 case 'U':
2080 if (strcasecmp(optarg, "user") == 0) {
2081 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
2082 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
2083 } else if (strcasecmp(optarg, "master") != 0) {
2084 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
2085 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
2086 } else {
2087 warnx("-U argument '%s' is invalid (must be "
2088 "'user' or 'master')", optarg);
2089 return (1);
2090 }
2091 break;
2092
2093 case 'l':
2094 if (strcasecmp(optarg, "high") == 0) {
2095 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
2096 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
2097 } else if (strcasecmp(optarg, "maximum") == 0) {
2098 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
2099 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
2100 } else {
2101 warnx("-l argument '%s' is unknown (must be "
2102 "'high' or 'maximum')", optarg);
2103 return (1);
2104 }
2105 break;
2106
2107 case 'k':
2108 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2109 return (1);
2110 action = ATA_SECURITY_ACTION_UNLOCK;
2111 actions++;
2112 break;
2113
2114 case 'd':
2115 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2116 return (1);
2117 action = ATA_SECURITY_ACTION_DISABLE;
2118 actions++;
2119 break;
2120
2121 case 'e':
2122 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2123 return (1);
2124 action = ATA_SECURITY_ACTION_ERASE;
2125 actions++;
2126 break;
2127
2128 case 'h':
2129 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2130 return (1);
2131 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
2132 action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
2133 actions++;
2134 break;
2135
2136 case 's':
2137 if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2138 return (1);
2139 setpwd = 1;
2140 if (action == ATA_SECURITY_ACTION_PRINT)
2141 action = ATA_SECURITY_ACTION_SET_PASSWORD;
2142 /*
2143 * Don't increment action as this can be combined
2144 * with other actions.
2145 */
2146 break;
2147
2148 case 'y':
2149 confirm++;
2150 break;
2151
2152 case 'q':
2153 quiet++;
2154 break;
2155
2156 case 'T':
2157 erase_timeout = atoi(optarg) * 1000;
2158 break;
2159 }
2160 }
2161
2162 if (actions > 1) {
2163 warnx("too many security actions specified");
2164 return (1);
2165 }
2166
2167 if ((ccb = cam_getccb(device)) == NULL) {
2168 warnx("couldn't allocate CCB");
2169 return (1);
2170 }
2171
2172 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2173 if (error != 0) {
2174 cam_freeccb(ccb);
2175 return (1);
2176 }
2177
2178 if (quiet == 0) {
2179 printf("%s%d: ", device->device_name, device->dev_unit_num);
2180 ata_print_ident(ident_buf);
2181 camxferrate(device);
2182 }
2183
2184 if (action == ATA_SECURITY_ACTION_PRINT) {
2185 atasecurity_print(ident_buf);
2186 free(ident_buf);
2187 cam_freeccb(ccb);
2188 return (0);
2189 }
2190
2191 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
2192 warnx("Security not supported");
2193 free(ident_buf);
2194 cam_freeccb(ccb);
2195 return (1);
2196 }
2197
2198 /* default timeout 15 seconds the same as linux hdparm */
2199 timeout = timeout ? timeout : 15 * 1000;
2200
2201 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
2202
2203 /* first set the password if requested */
2204 if (setpwd == 1) {
2205 /* confirm we can erase before setting the password if erasing */
2206 if (confirm == 0 &&
2207 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
2208 action == ATA_SECURITY_ACTION_ERASE) &&
2209 atasecurity_erase_confirm(device, ident_buf) == 0) {
2210 cam_freeccb(ccb);
2211 free(ident_buf);
2212 return (error);
2213 }
2214
2215 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
2216 pwd.revision = ident_buf->master_passwd_revision;
2217 if (pwd.revision != 0 && pwd.revision != 0xfff &&
2218 --pwd.revision == 0) {
2219 pwd.revision = 0xfffe;
2220 }
2221 }
2222 error = atasecurity_set_password(device, ccb, retry_count,
2223 timeout, &pwd, quiet);
2224 if (error != 0) {
2225 cam_freeccb(ccb);
2226 free(ident_buf);
2227 return (error);
2228 }
2229 security_enabled = 1;
2230 }
2231
2232 switch(action) {
2233 case ATA_SECURITY_ACTION_FREEZE:
2234 error = atasecurity_freeze(device, ccb, retry_count,
2235 timeout, quiet);
2236 break;
2237
2238 case ATA_SECURITY_ACTION_UNLOCK:
2239 if (security_enabled) {
2240 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2241 error = atasecurity_unlock(device, ccb,
2242 retry_count, timeout, &pwd, quiet);
2243 } else {
2244 warnx("Can't unlock, drive is not locked");
2245 error = 1;
2246 }
2247 } else {
2248 warnx("Can't unlock, security is disabled");
2249 error = 1;
2250 }
2251 break;
2252
2253 case ATA_SECURITY_ACTION_DISABLE:
2254 if (security_enabled) {
2255 /* First unlock the drive if its locked */
2256 if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
2257 error = atasecurity_unlock(device, ccb,
2258 retry_count,
2259 timeout,
2260 &pwd,
2261 quiet);
2262 }
2263
2264 if (error == 0) {
2265 error = atasecurity_disable(device,
2266 ccb,
2267 retry_count,
2268 timeout,
2269 &pwd,
2270 quiet);
2271 }
2272 } else {
2273 warnx("Can't disable security (already disabled)");
2274 error = 1;
2275 }
2276 break;
2277
2278 case ATA_SECURITY_ACTION_ERASE:
2279 if (security_enabled) {
2280 if (erase_timeout == 0) {
2281 erase_timeout = atasecurity_erase_timeout_msecs(
2282 ident_buf->erase_time);
2283 }
2284
2285 error = atasecurity_erase(device, ccb, retry_count,
2286 timeout, erase_timeout, &pwd,
2287 quiet);
2288 } else {
2289 warnx("Can't secure erase (security is disabled)");
2290 error = 1;
2291 }
2292 break;
2293
2294 case ATA_SECURITY_ACTION_ERASE_ENHANCED:
2295 if (security_enabled) {
2296 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
2297 if (erase_timeout == 0) {
2298 erase_timeout =
2299 atasecurity_erase_timeout_msecs(
2300 ident_buf->enhanced_erase_time);
2301 }
2302
2303 error = atasecurity_erase(device, ccb,
2304 retry_count, timeout,
2305 erase_timeout, &pwd,
2306 quiet);
2307 } else {
2308 warnx("Enhanced erase is not supported");
2309 error = 1;
2310 }
2311 } else {
2312 warnx("Can't secure erase (enhanced), "
2313 "(security is disabled)");
2314 error = 1;
2315 }
2316 break;
2317 }
2318
2319 cam_freeccb(ccb);
2320 free(ident_buf);
2321
2322 return (error);
2323}
2324#endif /* MINIMALISTIC */
2325
2326/*
1462 * Parse out a bus, or a bus, target and lun in the following
1463 * format:
1464 * bus
1465 * bus:target
1466 * bus:target:lun
1467 *
1468 * Returns the number of parsed components, or 0.
1469 */

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

5828" [-D <enable|disable>][-M mode][-O offset]\n"
5829" [-q][-R syncrate][-v][-T <enable|disable>]\n"
5830" [-U][-W bus_width]\n"
5831" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
5832" camcontrol idle [dev_id][generic args][-t time]\n"
5833" camcontrol standby [dev_id][generic args][-t time]\n"
5834" camcontrol sleep [dev_id][generic args]\n"
5835" camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
2327 * Parse out a bus, or a bus, target and lun in the following
2328 * format:
2329 * bus
2330 * bus:target
2331 * bus:target:lun
2332 *
2333 * Returns the number of parsed components, or 0.
2334 */

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

6693" [-D <enable|disable>][-M mode][-O offset]\n"
6694" [-q][-R syncrate][-v][-T <enable|disable>]\n"
6695" [-U][-W bus_width]\n"
6696" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
6697" camcontrol idle [dev_id][generic args][-t time]\n"
6698" camcontrol standby [dev_id][generic args][-t time]\n"
6699" camcontrol sleep [dev_id][generic args]\n"
6700" camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n"
6701" camcontrol security [dev_id][generic args]\n"
6702" <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
6703" [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
6704" [-U <user|master>] [-y]\n"
5836#endif /* MINIMALISTIC */
5837" camcontrol help\n");
5838 if (!printlong)
5839 return;
5840#ifndef MINIMALISTIC
5841 fprintf(stdout,
5842"Specify one of the following options:\n"
5843"devlist list all CAM devices\n"

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

5864"debug turn debugging on/off for a bus, target, or lun, or all devices\n"
5865"tags report or set the number of transaction slots for a device\n"
5866"negotiate report or set device negotiation parameters\n"
5867"format send the SCSI FORMAT UNIT command to the named device\n"
5868"idle send the ATA IDLE command to the named device\n"
5869"standby send the ATA STANDBY command to the named device\n"
5870"sleep send the ATA SLEEP command to the named device\n"
5871"fwdownload program firmware of the named device with the given image"
6705#endif /* MINIMALISTIC */
6706" camcontrol help\n");
6707 if (!printlong)
6708 return;
6709#ifndef MINIMALISTIC
6710 fprintf(stdout,
6711"Specify one of the following options:\n"
6712"devlist list all CAM devices\n"

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

6733"debug turn debugging on/off for a bus, target, or lun, or all devices\n"
6734"tags report or set the number of transaction slots for a device\n"
6735"negotiate report or set device negotiation parameters\n"
6736"format send the SCSI FORMAT UNIT command to the named device\n"
6737"idle send the ATA IDLE command to the named device\n"
6738"standby send the ATA STANDBY command to the named device\n"
6739"sleep send the ATA SLEEP command to the named device\n"
6740"fwdownload program firmware of the named device with the given image"
6741"security report or send ATA security commands to the named device\n"
5872"help this message\n"
5873"Device Identifiers:\n"
5874"bus:target specify the bus and target, lun defaults to 0\n"
5875"bus:target:lun specify the bus, target and lun\n"
5876"deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
5877"Generic arguments:\n"
5878"-v be verbose, print out sense information\n"
5879"-t timeout command timeout in seconds, overrides default timeout\n"

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

5960"-w don't send immediate format command\n"
5961"-y don't ask any questions\n"
5962"idle/standby arguments:\n"
5963"-t <arg> number of seconds before respective state.\n"
5964"fwdownload arguments:\n"
5965"-f fw_image path to firmware image file\n"
5966"-y don't ask any questions\n"
5967"-s run in simulation mode\n"
6742"help this message\n"
6743"Device Identifiers:\n"
6744"bus:target specify the bus and target, lun defaults to 0\n"
6745"bus:target:lun specify the bus, target and lun\n"
6746"deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n"
6747"Generic arguments:\n"
6748"-v be verbose, print out sense information\n"
6749"-t timeout command timeout in seconds, overrides default timeout\n"

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

6830"-w don't send immediate format command\n"
6831"-y don't ask any questions\n"
6832"idle/standby arguments:\n"
6833"-t <arg> number of seconds before respective state.\n"
6834"fwdownload arguments:\n"
6835"-f fw_image path to firmware image file\n"
6836"-y don't ask any questions\n"
6837"-s run in simulation mode\n"
5968"-v print info for every firmware segment sent to device\n");
6838"-v print info for every firmware segment sent to device\n"
6839"security arguments:\n"
6840"-d pwd disable security using the given password for the selected\n"
6841" user\n"
6842"-e pwd erase the device using the given pwd for the selected user\n"
6843"-f freeze the security configuration of the specified device\n"
6844"-h pwd enhanced erase the device using the given pwd for the\n"
6845" selected user\n"
6846"-k pwd unlock the device using the given pwd for the selected\n"
6847" user\n"
6848"-l <high|maximum> specifies which security level to set: high or maximum\n"
6849"-q be quiet, do not print any status messages\n"
6850"-s pwd password the device (enable security) using the given\n"
6851" pwd for the selected user\n"
6852"-T timeout overrides the timeout (seconds) used for erase operation\n"
6853"-U <user|master> specifies which user to set: user or master\n"
6854"-y don't ask any questions\n"
6855);
5969#endif /* MINIMALISTIC */
5970}
5971
5972int
5973main(int argc, char **argv)
5974{
5975 int c;
5976 char *device = NULL;

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

6273 error = scsireadcapacity(cam_dev, argc, argv,
6274 combinedopt, retry_count,
6275 timeout);
6276 break;
6277 case CAM_CMD_IDLE:
6278 case CAM_CMD_STANDBY:
6279 case CAM_CMD_SLEEP:
6280 error = atapm(cam_dev, argc, argv,
6856#endif /* MINIMALISTIC */
6857}
6858
6859int
6860main(int argc, char **argv)
6861{
6862 int c;
6863 char *device = NULL;

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

7160 error = scsireadcapacity(cam_dev, argc, argv,
7161 combinedopt, retry_count,
7162 timeout);
7163 break;
7164 case CAM_CMD_IDLE:
7165 case CAM_CMD_STANDBY:
7166 case CAM_CMD_SLEEP:
7167 error = atapm(cam_dev, argc, argv,
6281 combinedopt, retry_count,
6282 timeout);
7168 combinedopt, retry_count, timeout);
6283 break;
7169 break;
7170 case CAM_CMD_SECURITY:
7171 error = atasecurity(cam_dev, retry_count, timeout,
7172 argc, argv, combinedopt);
7173 break;
6284 case CAM_CMD_DOWNLOAD_FW:
6285 error = fwdownload(cam_dev, argc, argv, combinedopt,
6286 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
6287 get_disk_type(cam_dev));
6288 break;
6289#endif /* MINIMALISTIC */
6290 case CAM_CMD_USAGE:
6291 usage(1);

--- 12 unchanged lines hidden ---
7174 case CAM_CMD_DOWNLOAD_FW:
7175 error = fwdownload(cam_dev, argc, argv, combinedopt,
7176 arglist & CAM_ARG_VERBOSE, retry_count, timeout,
7177 get_disk_type(cam_dev));
7178 break;
7179#endif /* MINIMALISTIC */
7180 case CAM_CMD_USAGE:
7181 usage(1);

--- 12 unchanged lines hidden ---