Deleted Added
full compact
camcontrol.c (42647) camcontrol.c (46581)
1/*
1/*
2 * Copyright (c) 1997, 1998 Kenneth D. Merry
2 * Copyright (c) 1997, 1998, 1999 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
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

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

20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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 *
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
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

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

20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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 * $Id: camcontrol.c,v 1.8 1998/12/20 20:32:34 mjacob Exp $
28 * $Id: camcontrol.c,v 1.9 1999/01/14 05:56:30 gibbs Exp $
29 */
30
31#include <sys/ioctl.h>
32#include <sys/types.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>

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

60 CAM_ARG_RESCAN = 0x00000005,
61 CAM_ARG_READ_DEFECTS = 0x00000006,
62 CAM_ARG_MODE_PAGE = 0x00000007,
63 CAM_ARG_SCSI_CMD = 0x00000008,
64 CAM_ARG_DEVTREE = 0x00000009,
65 CAM_ARG_USAGE = 0x0000000a,
66 CAM_ARG_DEBUG = 0x0000000b,
67 CAM_ARG_RESET = 0x0000000c,
29 */
30
31#include <sys/ioctl.h>
32#include <sys/types.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>

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

60 CAM_ARG_RESCAN = 0x00000005,
61 CAM_ARG_READ_DEFECTS = 0x00000006,
62 CAM_ARG_MODE_PAGE = 0x00000007,
63 CAM_ARG_SCSI_CMD = 0x00000008,
64 CAM_ARG_DEVTREE = 0x00000009,
65 CAM_ARG_USAGE = 0x0000000a,
66 CAM_ARG_DEBUG = 0x0000000b,
67 CAM_ARG_RESET = 0x0000000c,
68 CAM_ARG_FORMAT = 0x0000000d,
69 CAM_ARG_TAG = 0x0000000e,
70 CAM_ARG_RATE = 0x0000000f,
68 CAM_ARG_OPT_MASK = 0x0000000f,
69 CAM_ARG_VERBOSE = 0x00000010,
70 CAM_ARG_DEVICE = 0x00000020,
71 CAM_ARG_BUS = 0x00000040,
72 CAM_ARG_TARGET = 0x00000080,
73 CAM_ARG_LUN = 0x00000100,
74 CAM_ARG_EJECT = 0x00000200,
75 CAM_ARG_UNIT = 0x00000400,

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

103 cam_argmask argnum;
104 const char *subopt;
105};
106
107extern int optreset;
108
109static const char scsicmd_opts[] = "c:i:o:";
110static const char readdefect_opts[] = "f:GP";
71 CAM_ARG_OPT_MASK = 0x0000000f,
72 CAM_ARG_VERBOSE = 0x00000010,
73 CAM_ARG_DEVICE = 0x00000020,
74 CAM_ARG_BUS = 0x00000040,
75 CAM_ARG_TARGET = 0x00000080,
76 CAM_ARG_LUN = 0x00000100,
77 CAM_ARG_EJECT = 0x00000200,
78 CAM_ARG_UNIT = 0x00000400,

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

106 cam_argmask argnum;
107 const char *subopt;
108};
109
110extern int optreset;
111
112static const char scsicmd_opts[] = "c:i:o:";
113static const char readdefect_opts[] = "f:GP";
114static const char negotiate_opts[] = "acD:O:qR:T:UW:";
111
112struct camcontrol_opts option_table[] = {
113 {"tur", CAM_ARG_TUR, NULL},
114 {"inquiry", CAM_ARG_INQUIRY, "DSR"},
115 {"start", CAM_ARG_STARTSTOP | CAM_ARG_START_UNIT, NULL},
116 {"stop", CAM_ARG_STARTSTOP, NULL},
117 {"eject", CAM_ARG_STARTSTOP | CAM_ARG_EJECT, NULL},
118 {"rescan", CAM_ARG_RESCAN, NULL},
119 {"reset", CAM_ARG_RESET, NULL},
120 {"cmd", CAM_ARG_SCSI_CMD, scsicmd_opts},
121 {"command", CAM_ARG_SCSI_CMD, scsicmd_opts},
122 {"defects", CAM_ARG_READ_DEFECTS, readdefect_opts},
123 {"defectlist", CAM_ARG_READ_DEFECTS, readdefect_opts},
124 {"devlist", CAM_ARG_DEVTREE, NULL},
125 {"periphlist", CAM_ARG_DEVLIST, NULL},
126 {"modepage", CAM_ARG_MODE_PAGE, "dem:P:"},
115
116struct camcontrol_opts option_table[] = {
117 {"tur", CAM_ARG_TUR, NULL},
118 {"inquiry", CAM_ARG_INQUIRY, "DSR"},
119 {"start", CAM_ARG_STARTSTOP | CAM_ARG_START_UNIT, NULL},
120 {"stop", CAM_ARG_STARTSTOP, NULL},
121 {"eject", CAM_ARG_STARTSTOP | CAM_ARG_EJECT, NULL},
122 {"rescan", CAM_ARG_RESCAN, NULL},
123 {"reset", CAM_ARG_RESET, NULL},
124 {"cmd", CAM_ARG_SCSI_CMD, scsicmd_opts},
125 {"command", CAM_ARG_SCSI_CMD, scsicmd_opts},
126 {"defects", CAM_ARG_READ_DEFECTS, readdefect_opts},
127 {"defectlist", CAM_ARG_READ_DEFECTS, readdefect_opts},
128 {"devlist", CAM_ARG_DEVTREE, NULL},
129 {"periphlist", CAM_ARG_DEVLIST, NULL},
130 {"modepage", CAM_ARG_MODE_PAGE, "dem:P:"},
131 {"tags", CAM_ARG_TAG, "N:q"},
132 {"negotiate", CAM_ARG_RATE, negotiate_opts},
133 {"rate", CAM_ARG_RATE, negotiate_opts},
127 {"debug", CAM_ARG_DEBUG, "ITSc"},
128 {"help", CAM_ARG_USAGE, NULL},
129 {"-?", CAM_ARG_USAGE, NULL},
130 {"-h", CAM_ARG_USAGE, NULL},
131 {NULL, 0, NULL}
132};
133
134typedef enum {

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

139
140cam_argmask arglist;
141
142
143camcontrol_optret getoption(char *arg, cam_argmask *argnum, char **subopt);
144static int getdevlist(struct cam_device *device);
145static int getdevtree(void);
146static int testunitready(struct cam_device *device, int retry_count,
134 {"debug", CAM_ARG_DEBUG, "ITSc"},
135 {"help", CAM_ARG_USAGE, NULL},
136 {"-?", CAM_ARG_USAGE, NULL},
137 {"-h", CAM_ARG_USAGE, NULL},
138 {NULL, 0, NULL}
139};
140
141typedef enum {

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

146
147cam_argmask arglist;
148
149
150camcontrol_optret getoption(char *arg, cam_argmask *argnum, char **subopt);
151static int getdevlist(struct cam_device *device);
152static int getdevtree(void);
153static int testunitready(struct cam_device *device, int retry_count,
147 int timeout);
154 int timeout, int quiet);
148static int scsistart(struct cam_device *device, int startstop, int loadeject,
149 int retry_count, int timeout);
150static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
151 char *combinedopt, int retry_count, int timeout);
152static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
153static int scsiserial(struct cam_device *device, int retry_count, int timeout);
154static int scsixferrate(struct cam_device *device);
155static int dorescan_or_reset(int argc, char **argv, int rescan);
156static int rescan_or_reset_bus(int bus, int rescan);
157static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
158static int readdefects(struct cam_device *device, int argc, char **argv,
159 char *combinedopt, int retry_count, int timeout);
160static void modepage(struct cam_device *device, int argc, char **argv,
161 char *combinedopt, int retry_count, int timeout);
162static int scsicmd(struct cam_device *device, int argc, char **argv,
163 char *combinedopt, int retry_count, int timeout);
155static int scsistart(struct cam_device *device, int startstop, int loadeject,
156 int retry_count, int timeout);
157static int scsidoinquiry(struct cam_device *device, int argc, char **argv,
158 char *combinedopt, int retry_count, int timeout);
159static int scsiinquiry(struct cam_device *device, int retry_count, int timeout);
160static int scsiserial(struct cam_device *device, int retry_count, int timeout);
161static int scsixferrate(struct cam_device *device);
162static int dorescan_or_reset(int argc, char **argv, int rescan);
163static int rescan_or_reset_bus(int bus, int rescan);
164static int scanlun_or_reset_dev(int bus, int target, int lun, int scan);
165static int readdefects(struct cam_device *device, int argc, char **argv,
166 char *combinedopt, int retry_count, int timeout);
167static void modepage(struct cam_device *device, int argc, char **argv,
168 char *combinedopt, int retry_count, int timeout);
169static int scsicmd(struct cam_device *device, int argc, char **argv,
170 char *combinedopt, int retry_count, int timeout);
171static int tagcontrol(struct cam_device *device, int argc, char **argv,
172 char *combinedopt);
173static void cts_print(struct cam_device *device,
174 struct ccb_trans_settings *cts);
175static void cpi_print(struct ccb_pathinq *cpi);
176static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi);
177static int get_print_cts(struct cam_device *device, int user_settings,
178 int quiet, struct ccb_trans_settings *cts);
179static int ratecontrol(struct cam_device *device, int retry_count,
180 int timeout, int argc, char **argv, char *combinedopt);
164
165camcontrol_optret
166getoption(char *arg, cam_argmask *argnum, char **subopt)
167{
168 struct camcontrol_opts *opts;
169 int num_matches = 0;
170
171 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);

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

245
246static int
247getdevtree(void)
248{
249 union ccb ccb;
250 int bufsize, i, fd;
251 int need_close = 0;
252 int error = 0;
181
182camcontrol_optret
183getoption(char *arg, cam_argmask *argnum, char **subopt)
184{
185 struct camcontrol_opts *opts;
186 int num_matches = 0;
187
188 for (opts = option_table; (opts != NULL) && (opts->optname != NULL);

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

262
263static int
264getdevtree(void)
265{
266 union ccb ccb;
267 int bufsize, i, fd;
268 int need_close = 0;
269 int error = 0;
270 int skip_device = 0;
253
254 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
255 warn("couldn't open %s", XPT_DEVICE);
256 return(1);
257 }
258
271
272 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
273 warn("couldn't open %s", XPT_DEVICE);
274 return(1);
275 }
276
259 bzero(&(&ccb.ccb_h)[1], sizeof(struct ccb_dev_match));
277 bzero(&(&ccb.ccb_h)[1],
278 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr));
260
261 ccb.ccb_h.func_code = XPT_DEV_MATCH;
262 bufsize = sizeof(struct dev_match_result) * 100;
263 ccb.cdm.match_buf_len = bufsize;
264 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
265 ccb.cdm.num_matches = 0;
266
267 /*

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

321 case DEV_MATCH_DEVICE: {
322 struct device_match_result *dev_result;
323 char vendor[16], product[48], revision[16];
324 char tmpstr[256];
325
326 dev_result =
327 &ccb.cdm.matches[i].result.device_result;
328
279
280 ccb.ccb_h.func_code = XPT_DEV_MATCH;
281 bufsize = sizeof(struct dev_match_result) * 100;
282 ccb.cdm.match_buf_len = bufsize;
283 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
284 ccb.cdm.num_matches = 0;
285
286 /*

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

340 case DEV_MATCH_DEVICE: {
341 struct device_match_result *dev_result;
342 char vendor[16], product[48], revision[16];
343 char tmpstr[256];
344
345 dev_result =
346 &ccb.cdm.matches[i].result.device_result;
347
348 if ((dev_result->flags
349 & DEV_RESULT_UNCONFIGURED)
350 && ((arglist & CAM_ARG_VERBOSE) == 0)) {
351 skip_device = 1;
352 break;
353 } else
354 skip_device = 0;
355
329 cam_strvis(vendor, dev_result->inq_data.vendor,
330 sizeof(dev_result->inq_data.vendor),
331 sizeof(vendor));
332 cam_strvis(product,
333 dev_result->inq_data.product,
334 sizeof(dev_result->inq_data.product),
335 sizeof(product));
336 cam_strvis(revision,

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

356 break;
357 }
358 case DEV_MATCH_PERIPH: {
359 struct periph_match_result *periph_result;
360
361 periph_result =
362 &ccb.cdm.matches[i].result.periph_result;
363
356 cam_strvis(vendor, dev_result->inq_data.vendor,
357 sizeof(dev_result->inq_data.vendor),
358 sizeof(vendor));
359 cam_strvis(product,
360 dev_result->inq_data.product,
361 sizeof(dev_result->inq_data.product),
362 sizeof(product));
363 cam_strvis(revision,

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

383 break;
384 }
385 case DEV_MATCH_PERIPH: {
386 struct periph_match_result *periph_result;
387
388 periph_result =
389 &ccb.cdm.matches[i].result.periph_result;
390
391 if (skip_device != 0)
392 break;
393
364 if (need_close > 1)
365 fprintf(stdout, ",");
366
367 fprintf(stdout, "%s%d",
368 periph_result->periph_name,
369 periph_result->unit_number);
370
371 need_close++;

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

384 fprintf(stdout, ")\n");
385
386 close(fd);
387
388 return(error);
389}
390
391static int
394 if (need_close > 1)
395 fprintf(stdout, ",");
396
397 fprintf(stdout, "%s%d",
398 periph_result->periph_name,
399 periph_result->unit_number);
400
401 need_close++;

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

414 fprintf(stdout, ")\n");
415
416 close(fd);
417
418 return(error);
419}
420
421static int
392testunitready(struct cam_device *device, int retry_count, int timeout)
422testunitready(struct cam_device *device, int retry_count, int timeout,
423 int quiet)
393{
394 int error = 0;
395 union ccb *ccb;
396
397 ccb = cam_getccb(device);
398
399 scsi_test_unit_ready(&ccb->csio,
400 /* retries */ retry_count,

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

405
406 /* Disable freezing the device queue */
407 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
408
409 if (arglist & CAM_ARG_ERR_RECOVER)
410 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
411
412 if (cam_send_ccb(device, ccb) < 0) {
424{
425 int error = 0;
426 union ccb *ccb;
427
428 ccb = cam_getccb(device);
429
430 scsi_test_unit_ready(&ccb->csio,
431 /* retries */ retry_count,

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

436
437 /* Disable freezing the device queue */
438 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
439
440 if (arglist & CAM_ARG_ERR_RECOVER)
441 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
442
443 if (cam_send_ccb(device, ccb) < 0) {
413 perror("error sending test unit ready");
444 if (quiet == 0)
445 perror("error sending test unit ready");
414
415 if (arglist & CAM_ARG_VERBOSE) {
416 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
417 CAM_SCSI_STATUS_ERROR)
418 scsi_sense_print(device, &ccb->csio, stderr);
419 else
420 fprintf(stderr, "CAM status is %#x\n",
421 ccb->ccb_h.status);
422 }
423
424 cam_freeccb(ccb);
425 return(1);
426 }
427
446
447 if (arglist & CAM_ARG_VERBOSE) {
448 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
449 CAM_SCSI_STATUS_ERROR)
450 scsi_sense_print(device, &ccb->csio, stderr);
451 else
452 fprintf(stderr, "CAM status is %#x\n",
453 ccb->ccb_h.status);
454 }
455
456 cam_freeccb(ccb);
457 return(1);
458 }
459
428 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
429 fprintf(stdout, "Unit is ready\n");
430 else {
431 fprintf(stdout, "Unit is not ready\n");
460 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
461 if (quiet == 0)
462 fprintf(stdout, "Unit is ready\n");
463 } else {
464 if (quiet == 0)
465 fprintf(stdout, "Unit is not ready\n");
432 error = 1;
433
434 if (arglist & CAM_ARG_VERBOSE) {
435 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
436 CAM_SCSI_STATUS_ERROR)
437 scsi_sense_print(device, &ccb->csio, stderr);
438 else
439 fprintf(stderr, "CAM status is %#x\n",

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

590 ccb = cam_getccb(device);
591
592 if (ccb == NULL) {
593 warnx("couldn't allocate CCB");
594 return(1);
595 }
596
597 /* cam_getccb cleans up the header, caller has to zero the payload */
466 error = 1;
467
468 if (arglist & CAM_ARG_VERBOSE) {
469 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
470 CAM_SCSI_STATUS_ERROR)
471 scsi_sense_print(device, &ccb->csio, stderr);
472 else
473 fprintf(stderr, "CAM status is %#x\n",

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

624 ccb = cam_getccb(device);
625
626 if (ccb == NULL) {
627 warnx("couldn't allocate CCB");
628 return(1);
629 }
630
631 /* cam_getccb cleans up the header, caller has to zero the payload */
598 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
632 bzero(&(&ccb->ccb_h)[1],
633 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
599
600 inq_buf = (struct scsi_inquiry_data *)malloc(
601 sizeof(struct scsi_inquiry_data));
602
603 if (inq_buf == NULL) {
604 cam_freeccb(ccb);
605 warnx("can't malloc memory for inquiry\n");
606 return(1);

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

655
656 cam_freeccb(ccb);
657
658 if (error != 0) {
659 free(inq_buf);
660 return(error);
661 }
662
634
635 inq_buf = (struct scsi_inquiry_data *)malloc(
636 sizeof(struct scsi_inquiry_data));
637
638 if (inq_buf == NULL) {
639 cam_freeccb(ccb);
640 warnx("can't malloc memory for inquiry\n");
641 return(1);

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

690
691 cam_freeccb(ccb);
692
693 if (error != 0) {
694 free(inq_buf);
695 return(error);
696 }
697
698 fprintf(stdout, "%s%d: ", device->device_name,
699 device->dev_unit_num);
663 scsi_print_inquiry(inq_buf);
664
665 free(inq_buf);
666
700 scsi_print_inquiry(inq_buf);
701
702 free(inq_buf);
703
667 if (arglist & CAM_ARG_GET_SERIAL)
668 fprintf(stdout, "Serial Number ");
669
670 return(0);
671}
672
673static int
674scsiserial(struct cam_device *device, int retry_count, int timeout)
675{
676 union ccb *ccb;
677 struct scsi_vpd_unit_serial_number *serial_buf;
678 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
679 int error = 0;
680
681 ccb = cam_getccb(device);
682
683 if (ccb == NULL) {
684 warnx("couldn't allocate CCB");
685 return(1);
686 }
687
688 /* cam_getccb cleans up the header, caller has to zero the payload */
704 return(0);
705}
706
707static int
708scsiserial(struct cam_device *device, int retry_count, int timeout)
709{
710 union ccb *ccb;
711 struct scsi_vpd_unit_serial_number *serial_buf;
712 char serial_num[SVPD_SERIAL_NUM_SIZE + 1];
713 int error = 0;
714
715 ccb = cam_getccb(device);
716
717 if (ccb == NULL) {
718 warnx("couldn't allocate CCB");
719 return(1);
720 }
721
722 /* cam_getccb cleans up the header, caller has to zero the payload */
689 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
723 bzero(&(&ccb->ccb_h)[1],
724 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
690
691 serial_buf = (struct scsi_vpd_unit_serial_number *)
692 malloc(sizeof(*serial_buf));
693
694 if (serial_buf == NULL) {
695 cam_freeccb(ccb);
696 warnx("can't malloc memory for serial number");
697 return(1);

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

749 if (error != 0) {
750 free(serial_buf);
751 return(error);
752 }
753
754 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
755 serial_num[serial_buf->length] = '\0';
756
725
726 serial_buf = (struct scsi_vpd_unit_serial_number *)
727 malloc(sizeof(*serial_buf));
728
729 if (serial_buf == NULL) {
730 cam_freeccb(ccb);
731 warnx("can't malloc memory for serial number");
732 return(1);

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

784 if (error != 0) {
785 free(serial_buf);
786 return(error);
787 }
788
789 bcopy(serial_buf->serial_num, serial_num, serial_buf->length);
790 serial_num[serial_buf->length] = '\0';
791
757 if (((arglist & CAM_ARG_GET_STDINQ) == 0)
758 && (arglist & CAM_ARG_GET_XFERRATE))
759 fprintf(stdout, "Serial Number ");
792 if ((arglist & CAM_ARG_GET_STDINQ)
793 || (arglist & CAM_ARG_GET_XFERRATE))
794 fprintf(stdout, "%s%d: Serial Number ",
795 device->device_name, device->dev_unit_num);
760
761 fprintf(stdout, "%.60s\n", serial_num);
762
763 free(serial_buf);
764
765 return(0);
766}
767
768static int
769scsixferrate(struct cam_device *device)
770{
771 u_int32_t freq;
772 u_int32_t speed;
796
797 fprintf(stdout, "%.60s\n", serial_num);
798
799 free(serial_buf);
800
801 return(0);
802}
803
804static int
805scsixferrate(struct cam_device *device)
806{
807 u_int32_t freq;
808 u_int32_t speed;
809 union ccb *ccb;
810 u_int mb;
811 int retval = 0;
773
812
774 if (device->sync_period != 0)
775 freq = scsi_calc_syncsrate(device->sync_period);
776 else
813 ccb = cam_getccb(device);
814
815 if (ccb == NULL) {
816 warnx("couldn't allocate CCB");
817 return(1);
818 }
819
820 bzero(&(&ccb->ccb_h)[1],
821 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
822
823 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
824 ccb->cts.flags = CCB_TRANS_CURRENT_SETTINGS;
825
826 if (((retval = cam_send_ccb(device, ccb)) < 0)
827 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
828 char *error_string = "error getting transfer settings";
829
830 if (retval < 0)
831 warn(error_string);
832 else
833 warnx(error_string);
834
835 /*
836 * If there is an error, it won't be a SCSI error since
837 * this isn't a SCSI CCB.
838 */
839 if (arglist & CAM_ARG_VERBOSE)
840 fprintf(stderr, "CAM status is %#x\n",
841 ccb->ccb_h.status);
842
843 retval = 1;
844
845 goto xferrate_bailout;
846
847 }
848
849 if (((ccb->cts.valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
850 && (ccb->cts.sync_offset != 0)) {
851 freq = scsi_calc_syncsrate(ccb->cts.sync_period);
852 speed = freq;
853 } else {
854 struct ccb_pathinq cpi;
855
856 retval = get_cpi(device, &cpi);
857
858 if (retval != 0)
859 goto xferrate_bailout;
860
861 speed = cpi.base_transfer_speed;
777 freq = 0;
862 freq = 0;
863 }
778
864
779 speed = freq;
780 speed *= (0x01 << device->bus_width);
781 fprintf(stdout, "%d.%dMB/s transfers ", speed / 1000, speed % 1000);
865 fprintf(stdout, "%s%d: ", device->device_name,
866 device->dev_unit_num);
782
867
783 if (device->sync_period != 0)
784 fprintf(stdout, "(%d.%dMHz, offset %d", freq / 1000,
785 freq % 1000, device->sync_offset);
868 if ((ccb->cts.valid & CCB_TRANS_BUS_WIDTH_VALID) != 0)
869 speed *= (0x01 << device->bus_width);
786
870
787 if (device->bus_width != 0) {
788 if (device->sync_period == 0)
789 fprintf(stdout, "(");
790 else
791 fprintf(stdout, ", ");
792 fprintf(stdout, "%dbit)", 8 * (0x01 << device->bus_width));
793 } else if (device->sync_period != 0)
794 fprintf(stdout, ")");
795
871 mb = speed / 1000;
872
873 if (mb > 0)
874 fprintf(stdout, "%d.%03dMB/s transfers ",
875 mb, speed % 1000);
876 else
877 fprintf(stdout, "%dKB/s transfers ",
878 (speed % 1000) * 1000);
879
880 if (((ccb->cts.valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
881 && (ccb->cts.sync_offset != 0))
882 fprintf(stdout, "(%d.%03dMHz, offset %d", freq / 1000,
883 freq % 1000, ccb->cts.sync_offset);
884
885 if (((ccb->cts.valid & CCB_TRANS_BUS_WIDTH_VALID) != 0)
886 && (ccb->cts.bus_width > 0)) {
887 if (((ccb->cts.valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
888 && (ccb->cts.sync_offset != 0)) {
889 fprintf(stdout, ", ");
890 } else {
891 fprintf(stdout, " (");
892 }
893 fprintf(stdout, "%dbit)", 8 * (0x01 << ccb->cts.bus_width));
894 } else if (((ccb->cts.valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
895 && (ccb->cts.sync_offset != 0)) {
896 fprintf(stdout, ")");
897 }
898
796 if (device->inq_data.flags & SID_CmdQue)
797 fprintf(stdout, ", Tagged Queueing Enabled");
798
799 fprintf(stdout, "\n");
800
899 if (device->inq_data.flags & SID_CmdQue)
900 fprintf(stdout, ", Tagged Queueing Enabled");
901
902 fprintf(stdout, "\n");
903
801 return(0);
904xferrate_bailout:
905
906 cam_freeccb(ccb);
907
908 return(retval);
802}
803
804static int
805dorescan_or_reset(int argc, char **argv, int rescan)
806{
807 static const char *must =
808 "you must specify a bus, or a bus:target:lun to %s";
809 int error = 0;

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

1025 defect_list = malloc(dlist_length);
1026
1027 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1028
1029 /*
1030 * cam_getccb() zeros the CCB header only. So we need to zero the
1031 * payload portion of the ccb.
1032 */
909}
910
911static int
912dorescan_or_reset(int argc, char **argv, int rescan)
913{
914 static const char *must =
915 "you must specify a bus, or a bus:target:lun to %s";
916 int error = 0;

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

1132 defect_list = malloc(dlist_length);
1133
1134 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes;
1135
1136 /*
1137 * cam_getccb() zeros the CCB header only. So we need to zero the
1138 * payload portion of the ccb.
1139 */
1033 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
1140 bzero(&(&ccb->ccb_h)[1],
1141 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1034
1035 cam_fill_csio(&ccb->csio,
1036 /*retries*/ retry_count,
1037 /*cbfcnp*/ NULL,
1038 /*flags*/ CAM_DIR_IN | (arglist & CAM_ARG_ERR_RECOVER) ?
1039 CAM_PASS_ERR_RECOVER : 0,
1040 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1041 /*data_ptr*/ defect_list,

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

1265 union ccb *ccb;
1266 int retval;
1267
1268 ccb = cam_getccb(device);
1269
1270 if (ccb == NULL)
1271 errx(1, "mode_sense: couldn't allocate CCB");
1272
1142
1143 cam_fill_csio(&ccb->csio,
1144 /*retries*/ retry_count,
1145 /*cbfcnp*/ NULL,
1146 /*flags*/ CAM_DIR_IN | (arglist & CAM_ARG_ERR_RECOVER) ?
1147 CAM_PASS_ERR_RECOVER : 0,
1148 /*tag_action*/ MSG_SIMPLE_Q_TAG,
1149 /*data_ptr*/ defect_list,

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

1373 union ccb *ccb;
1374 int retval;
1375
1376 ccb = cam_getccb(device);
1377
1378 if (ccb == NULL)
1379 errx(1, "mode_sense: couldn't allocate CCB");
1380
1273 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
1381 bzero(&(&ccb->ccb_h)[1],
1382 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1274
1275 scsi_mode_sense(&ccb->csio,
1276 /* retries */ retry_count,
1277 /* cbfcnp */ NULL,
1278 /* tag_action */ MSG_SIMPLE_Q_TAG,
1279 /* dbd */ dbd,
1280 /* page_code */ page_control << 6,
1281 /* page */ mode_page,

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

1318 union ccb *ccb;
1319 int retval;
1320
1321 ccb = cam_getccb(device);
1322
1323 if (ccb == NULL)
1324 errx(1, "mode_select: couldn't allocate CCB");
1325
1383
1384 scsi_mode_sense(&ccb->csio,
1385 /* retries */ retry_count,
1386 /* cbfcnp */ NULL,
1387 /* tag_action */ MSG_SIMPLE_Q_TAG,
1388 /* dbd */ dbd,
1389 /* page_code */ page_control << 6,
1390 /* page */ mode_page,

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

1427 union ccb *ccb;
1428 int retval;
1429
1430 ccb = cam_getccb(device);
1431
1432 if (ccb == NULL)
1433 errx(1, "mode_select: couldn't allocate CCB");
1434
1326 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
1435 bzero(&(&ccb->ccb_h)[1],
1436 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1327
1328 scsi_mode_select(&ccb->csio,
1329 /* retries */ retry_count,
1330 /* cbfcnp */ NULL,
1331 /* tag_action */ MSG_SIMPLE_Q_TAG,
1332 /* scsi_page_fmt */ 1,
1333 /* save_pages */ save_pages,
1334 /* param_buf */ data,

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

1421
1422 ccb = cam_getccb(device);
1423
1424 if (ccb == NULL) {
1425 warnx("scsicmd: error allocating ccb");
1426 return(1);
1427 }
1428
1437
1438 scsi_mode_select(&ccb->csio,
1439 /* retries */ retry_count,
1440 /* cbfcnp */ NULL,
1441 /* tag_action */ MSG_SIMPLE_Q_TAG,
1442 /* scsi_page_fmt */ 1,
1443 /* save_pages */ save_pages,
1444 /* param_buf */ data,

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

1531
1532 ccb = cam_getccb(device);
1533
1534 if (ccb == NULL) {
1535 warnx("scsicmd: error allocating ccb");
1536 return(1);
1537 }
1538
1429 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
1539 bzero(&(&ccb->ccb_h)[1],
1540 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1430
1431 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1432 switch(c) {
1433 case 'c':
1434 tstr = optarg;
1435 while (isspace(*tstr) && (*tstr != '\0'))
1436 tstr++;
1437 hook.argc = argc - optind;

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

1779 }
1780 }
1781 close(fd);
1782 }
1783
1784 return(error);
1785}
1786
1541
1542 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1543 switch(c) {
1544 case 'c':
1545 tstr = optarg;
1546 while (isspace(*tstr) && (*tstr != '\0'))
1547 tstr++;
1548 hook.argc = argc - optind;

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

1890 }
1891 }
1892 close(fd);
1893 }
1894
1895 return(error);
1896}
1897
1898static int
1899tagcontrol(struct cam_device *device, int argc, char **argv,
1900 char *combinedopt)
1901{
1902 int c;
1903 union ccb *ccb;
1904 int numtags = -1;
1905 int retval = 0;
1906 int quiet = 0;
1907 char pathstr[1024];
1908
1909 ccb = cam_getccb(device);
1910
1911 if (ccb == NULL) {
1912 warnx("tagcontrol: error allocating ccb");
1913 return(1);
1914 }
1915
1916 while ((c = getopt(argc, argv, combinedopt)) != -1) {
1917 switch(c) {
1918 case 'N':
1919 numtags = strtol(optarg, NULL, 0);
1920 if (numtags < 0) {
1921 warnx("tag count %d is < 0", numtags);
1922 retval = 1;
1923 goto tagcontrol_bailout;
1924 }
1925 break;
1926 case 'q':
1927 quiet++;
1928 break;
1929 default:
1930 break;
1931 }
1932 }
1933
1934 cam_path_string(device, pathstr, sizeof(pathstr));
1935
1936 if (numtags >= 0) {
1937 bzero(&(&ccb->ccb_h)[1],
1938 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
1939 ccb->ccb_h.func_code = XPT_REL_SIMQ;
1940 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
1941 ccb->crs.openings = numtags;
1942
1943
1944 if (cam_send_ccb(device, ccb) < 0) {
1945 perror("error sending XPT_REL_SIMQ CCB");
1946 retval = 1;
1947 goto tagcontrol_bailout;
1948 }
1949
1950 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1951 warnx("XPT_REL_SIMQ CCB failed, status %#x",
1952 ccb->ccb_h.status);
1953 retval = 1;
1954 goto tagcontrol_bailout;
1955 }
1956
1957
1958 if (quiet == 0)
1959 fprintf(stdout, "%stagged openings now %d\n",
1960 pathstr, ccb->crs.openings);
1961 }
1962
1963 bzero(&(&ccb->ccb_h)[1],
1964 sizeof(struct ccb_getdev) - sizeof(struct ccb_hdr));
1965
1966 ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1967
1968 if (cam_send_ccb(device, ccb) < 0) {
1969 perror("error sending XPT_GDEV_TYPE CCB");
1970 retval = 1;
1971 goto tagcontrol_bailout;
1972 }
1973
1974 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1975 warnx("XPT_GDEV_TYPE CCB failed, status %#x",
1976 ccb->ccb_h.status);
1977 retval = 1;
1978 goto tagcontrol_bailout;
1979 }
1980
1981 if (arglist & CAM_ARG_VERBOSE) {
1982 fprintf(stdout, "%s", pathstr);
1983 fprintf(stdout, "dev_openings %d\n", ccb->cgd.dev_openings);
1984 fprintf(stdout, "%s", pathstr);
1985 fprintf(stdout, "dev_active %d\n", ccb->cgd.dev_active);
1986 fprintf(stdout, "%s", pathstr);
1987 fprintf(stdout, "devq_openings %d\n", ccb->cgd.devq_openings);
1988 fprintf(stdout, "%s", pathstr);
1989 fprintf(stdout, "devq_queued %d\n", ccb->cgd.devq_queued);
1990 fprintf(stdout, "%s", pathstr);
1991 fprintf(stdout, "held %d\n", ccb->cgd.held);
1992 fprintf(stdout, "%s", pathstr);
1993 fprintf(stdout, "mintags %d\n", ccb->cgd.mintags);
1994 fprintf(stdout, "%s", pathstr);
1995 fprintf(stdout, "maxtags %d\n", ccb->cgd.maxtags);
1996 } else {
1997 if (quiet == 0) {
1998 fprintf(stdout, "%s", pathstr);
1999 fprintf(stdout, "device openings: ");
2000 }
2001 fprintf(stdout, "%d\n", ccb->cgd.dev_openings +
2002 ccb->cgd.dev_active);
2003 }
2004
2005tagcontrol_bailout:
2006
2007 cam_freeccb(ccb);
2008 return(retval);
2009}
2010
2011static void
2012cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
2013{
2014 char pathstr[1024];
2015
2016 cam_path_string(device, pathstr, sizeof(pathstr));
2017
2018 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
2019
2020 fprintf(stdout, "%ssync parameter: %d\n", pathstr,
2021 cts->sync_period);
2022
2023 if (cts->sync_offset != 0) {
2024 u_int freq;
2025 u_int speed;
2026
2027 freq = scsi_calc_syncsrate(cts->sync_period);
2028 fprintf(stdout, "%sfrequencey: %d.%03dMHz\n", pathstr,
2029 freq / 1000, freq % 1000);
2030 }
2031 }
2032
2033 if (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID)
2034 fprintf(stdout, "%soffset: %d\n", pathstr, cts->sync_offset);
2035
2036 if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID)
2037 fprintf(stdout, "%sbus width: %d bits\n", pathstr,
2038 (0x01 << cts->bus_width) * 8);
2039
2040 if (cts->valid & CCB_TRANS_DISC_VALID)
2041 fprintf(stdout, "%sdisconnection is %s\n", pathstr,
2042 (cts->flags & CCB_TRANS_DISC_ENB) ? "enabled" :
2043 "disabled");
2044
2045 if (cts->valid & CCB_TRANS_TQ_VALID)
2046 fprintf(stdout, "%stagged queueing is %s\n", pathstr,
2047 (cts->flags & CCB_TRANS_TAG_ENB) ? "enabled" :
2048 "disabled");
2049
2050}
2051
2052/*
2053 * Get a path inquiry CCB for the specified device.
2054 */
2055static int
2056get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
2057{
2058 union ccb *ccb;
2059 int retval = 0;
2060
2061 ccb = cam_getccb(device);
2062
2063 if (ccb == NULL) {
2064 warnx("get_cpi: couldn't allocate CCB");
2065 return(1);
2066 }
2067
2068 bzero(&(&ccb->ccb_h)[1],
2069 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2070
2071 ccb->ccb_h.func_code = XPT_PATH_INQ;
2072
2073 if (cam_send_ccb(device, ccb) < 0) {
2074 warn("get_cpi: error sending Path Inquiry CCB");
2075
2076 if (arglist & CAM_ARG_VERBOSE)
2077 fprintf(stderr, "CAM status is %#x\n",
2078 ccb->ccb_h.status);
2079
2080 retval = 1;
2081
2082 goto get_cpi_bailout;
2083 }
2084
2085 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2086
2087 if (arglist & CAM_ARG_VERBOSE)
2088 fprintf(stderr, "get_cpi: CAM status is %#x\n",
2089 ccb->ccb_h.status);
2090
2091 retval = 1;
2092
2093 goto get_cpi_bailout;
2094 }
2095
2096 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
2097
2098get_cpi_bailout:
2099
2100 cam_freeccb(ccb);
2101
2102 return(retval);
2103}
2104
2105static void
2106cpi_print(struct ccb_pathinq *cpi)
2107{
2108 char adapter_str[1024];
2109 int i;
2110
2111 snprintf(adapter_str, sizeof(adapter_str),
2112 "%s%d:", cpi->dev_name, cpi->unit_number);
2113
2114 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
2115 cpi->version_num);
2116
2117 for (i = 1; i < 0xff; i = i << 1) {
2118 char *str;
2119
2120 if ((i & cpi->hba_inquiry) == 0)
2121 continue;
2122
2123 fprintf(stdout, "%s supports ", adapter_str);
2124
2125 switch(i) {
2126 case PI_MDP_ABLE:
2127 str = "MDP message";
2128 break;
2129 case PI_WIDE_32:
2130 str = "32 bit wide SCSI";
2131 break;
2132 case PI_WIDE_16:
2133 str = "16 bit wide SCSI";
2134 break;
2135 case PI_SDTR_ABLE:
2136 str = "SDTR message";
2137 break;
2138 case PI_LINKED_CDB:
2139 str = "linked CDBs";
2140 break;
2141 case PI_TAG_ABLE:
2142 str = "tag queue messages";
2143 break;
2144 case PI_SOFT_RST:
2145 str = "soft reset alternative";
2146 break;
2147 }
2148 fprintf(stdout, "%s\n", str);
2149 }
2150
2151 for (i = 1; i < 0xff; i = i << 1) {
2152 char *str;
2153
2154 if ((i & cpi->hba_misc) == 0)
2155 continue;
2156
2157 fprintf(stdout, "%s ", adapter_str);
2158
2159 switch(i) {
2160 case PIM_SCANHILO:
2161 str = "bus scans from high ID to low ID";
2162 break;
2163 case PIM_NOREMOVE:
2164 str = "removable devices not included in scan";
2165 break;
2166 case PIM_NOINITIATOR:
2167 str = "initiator role not supported";
2168 break;
2169 case PIM_NOBUSRESET:
2170 str = "user has disabled initial BUS RESET or"
2171 " controller is in target/mixed mode";
2172 break;
2173 }
2174 fprintf(stdout, "%s\n", str);
2175 }
2176
2177 for (i = 1; i < 0xff; i = i << 1) {
2178 char *str;
2179
2180 if ((i & cpi->target_sprt) == 0)
2181 continue;
2182
2183 fprintf(stdout, "%s supports ", adapter_str);
2184 switch(i) {
2185 case PIT_PROCESSOR:
2186 str = "target mode processor mode";
2187 break;
2188 case PIT_PHASE:
2189 str = "target mode phase cog. mode";
2190 break;
2191 case PIT_DISCONNECT:
2192 str = "disconnects in target mode";
2193 break;
2194 case PIT_TERM_IO:
2195 str = "terminate I/O message in target mode";
2196 break;
2197 case PIT_GRP_6:
2198 str = "group 6 commands in target mode";
2199 break;
2200 case PIT_GRP_7:
2201 str = "group 7 commands in target mode";
2202 break;
2203 }
2204
2205 fprintf(stdout, "%s\n", str);
2206 }
2207 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
2208 cpi->hba_eng_cnt);
2209 fprintf(stdout, "%s maxium target: %d\n", adapter_str,
2210 cpi->max_target);
2211 fprintf(stdout, "%s maxium LUN: %d\n", adapter_str,
2212 cpi->max_lun);
2213 fprintf(stdout, "%s highest path ID in subsystem: %d\n",
2214 adapter_str, cpi->hpath_id);
2215 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
2216 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
2217 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
2218 fprintf(stdout, "%s base transfer speed: ", adapter_str);
2219 if (cpi->base_transfer_speed > 1000)
2220 fprintf(stdout, "%d.%03dMB/sec\n",
2221 cpi->base_transfer_speed / 1000,
2222 cpi->base_transfer_speed % 1000);
2223 else
2224 fprintf(stdout, "%dKB/sec\n",
2225 (cpi->base_transfer_speed % 1000) * 1000);
2226}
2227
2228static int
2229get_print_cts(struct cam_device *device, int user_settings, int quiet,
2230 struct ccb_trans_settings *cts)
2231{
2232 int retval;
2233 union ccb *ccb;
2234
2235 retval = 0;
2236 ccb = cam_getccb(device);
2237
2238 if (ccb == NULL) {
2239 warnx("get_print_cts: error allocating ccb");
2240 return(1);
2241 }
2242
2243 bzero(&(&ccb->ccb_h)[1],
2244 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
2245
2246 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
2247
2248 if (user_settings == 0)
2249 ccb->cts.flags = CCB_TRANS_CURRENT_SETTINGS;
2250 else
2251 ccb->cts.flags = CCB_TRANS_USER_SETTINGS;
2252
2253 if (cam_send_ccb(device, ccb) < 0) {
2254 perror("error sending XPT_GET_TRAN_SETTINGS CCB");
2255 retval = 1;
2256 goto get_print_cts_bailout;
2257 }
2258
2259 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2260 warnx("XPT_GET_TRANS_SETTINGS CCB failed, status %#x",
2261 ccb->ccb_h.status);
2262 retval = 1;
2263 goto get_print_cts_bailout;
2264 }
2265
2266 if (quiet == 0)
2267 cts_print(device, &ccb->cts);
2268
2269 if (cts != NULL)
2270 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
2271
2272get_print_cts_bailout:
2273
2274 cam_freeccb(ccb);
2275
2276 return(retval);
2277}
2278
2279static int
2280ratecontrol(struct cam_device *device, int retry_count, int timeout,
2281 int argc, char **argv, char *combinedopt)
2282{
2283 int c;
2284 union ccb *ccb;
2285 int user_settings = 0;
2286 int retval = 0;
2287 int disc_enable = -1, tag_enable = -1;
2288 int offset = -1;
2289 double syncrate = -1;
2290 int bus_width = -1;
2291 int quiet = 0;
2292 int change_settings = 0, send_tur = 0;
2293 struct ccb_pathinq cpi;
2294
2295 ccb = cam_getccb(device);
2296
2297 if (ccb == NULL) {
2298 warnx("ratecontrol: error allocating ccb");
2299 return(1);
2300 }
2301
2302 while ((c = getopt(argc, argv, combinedopt)) != -1) {
2303 switch(c){
2304 case 'a':
2305 send_tur = 1;
2306 break;
2307 case 'c':
2308 user_settings = 0;
2309 break;
2310 case 'D':
2311 if (strncasecmp(optarg, "enable", 6) == 0)
2312 disc_enable = 1;
2313 else if (strncasecmp(optarg, "disable", 7) == 0)
2314 disc_enable = 0;
2315 else {
2316 warnx("-D argument \"%s\" is unknown", optarg);
2317 retval = 1;
2318 goto ratecontrol_bailout;
2319 }
2320 change_settings = 1;
2321 break;
2322 case 'O':
2323 offset = strtol(optarg, NULL, 0);
2324 if (offset < 0) {
2325 warnx("offset value %d is < 0", offset);
2326 retval = 1;
2327 goto ratecontrol_bailout;
2328 }
2329 change_settings = 1;
2330 break;
2331 case 'q':
2332 quiet++;
2333 break;
2334 case 'R':
2335 syncrate = atof(optarg);
2336
2337 if (syncrate < 0) {
2338 warnx("sync rate %f is < 0", syncrate);
2339 retval = 1;
2340 goto ratecontrol_bailout;
2341 }
2342 change_settings = 1;
2343 break;
2344 case 'T':
2345 if (strncasecmp(optarg, "enable", 6) == 0)
2346 tag_enable = 1;
2347 else if (strncasecmp(optarg, "disable", 7) == 0)
2348 tag_enable = 0;
2349 else {
2350 warnx("-T argument \"%s\" is unknown", optarg);
2351 retval = 1;
2352 goto ratecontrol_bailout;
2353 }
2354 change_settings = 1;
2355 break;
2356 case 'U':
2357 user_settings = 1;
2358 break;
2359 case 'W':
2360 bus_width = strtol(optarg, NULL, 0);
2361 if (bus_width < 0) {
2362 warnx("bus width %d is < 0", bus_width);
2363 retval = 1;
2364 goto ratecontrol_bailout;
2365 }
2366 change_settings = 1;
2367 break;
2368 default:
2369 break;
2370 }
2371 }
2372
2373 bzero(&(&ccb->ccb_h)[1],
2374 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr));
2375
2376 /*
2377 * Grab path inquiry information, so we can determine whether
2378 * or not the initiator is capable of the things that the user
2379 * requests.
2380 */
2381 ccb->ccb_h.func_code = XPT_PATH_INQ;
2382
2383 if (cam_send_ccb(device, ccb) < 0) {
2384 perror("error sending XPT_PATH_INQ CCB");
2385 retval = 1;
2386 goto ratecontrol_bailout;
2387 }
2388
2389 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2390 warnx("XPT_PATH_INQ CCB failed, status %#x",
2391 ccb->ccb_h.status);
2392 retval = 1;
2393 goto ratecontrol_bailout;
2394 }
2395
2396 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq));
2397
2398 bzero(&(&ccb->ccb_h)[1],
2399 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr));
2400
2401 if (quiet == 0)
2402 fprintf(stdout, "Current Parameters:\n");
2403
2404 retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
2405
2406 if (retval != 0)
2407 goto ratecontrol_bailout;
2408
2409 if (arglist & CAM_ARG_VERBOSE)
2410 cpi_print(&cpi);
2411
2412 if (change_settings) {
2413 if (disc_enable != -1) {
2414 ccb->cts.valid |= CCB_TRANS_DISC_VALID;
2415 if (disc_enable == 0)
2416 ccb->cts.flags &= ~CCB_TRANS_DISC_ENB;
2417 else
2418 ccb->cts.flags |= CCB_TRANS_DISC_ENB;
2419 } else
2420 ccb->cts.valid &= ~CCB_TRANS_DISC_VALID;
2421
2422 if (tag_enable != -1) {
2423 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
2424 warnx("HBA does not support tagged queueing, "
2425 "so you cannot modify tag settings");
2426 retval = 1;
2427 goto ratecontrol_bailout;
2428 }
2429
2430 ccb->cts.valid |= CCB_TRANS_TQ_VALID;
2431
2432 if (tag_enable == 0)
2433 ccb->cts.flags &= ~CCB_TRANS_TAG_ENB;
2434 else
2435 ccb->cts.flags |= CCB_TRANS_TAG_ENB;
2436 } else
2437 ccb->cts.valid &= ~CCB_TRANS_TQ_VALID;
2438
2439 if (offset != -1) {
2440 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
2441 warnx("HBA at %s%d is not cable of changing "
2442 "offset", cpi.dev_name,
2443 cpi.unit_number);
2444 retval = 1;
2445 goto ratecontrol_bailout;
2446 }
2447 ccb->cts.valid |= CCB_TRANS_SYNC_OFFSET_VALID;
2448 ccb->cts.sync_offset = offset;
2449 } else
2450 ccb->cts.valid &= ~CCB_TRANS_SYNC_OFFSET_VALID;
2451
2452 if (syncrate != -1) {
2453 int num_syncrates;
2454 int prelim_sync_period;
2455 int period_factor_set = 0;
2456 u_int freq;
2457 int i;
2458
2459 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
2460 warnx("HBA at %s%d is not cable of changing "
2461 "transfer rates", cpi.dev_name,
2462 cpi.unit_number);
2463 retval = 1;
2464 goto ratecontrol_bailout;
2465 }
2466
2467 ccb->cts.valid |= CCB_TRANS_SYNC_RATE_VALID;
2468
2469 /*
2470 * The sync rate the user gives us is in MHz.
2471 * We need to translate it into KHz for this
2472 * calculation.
2473 */
2474 syncrate *= 1000;
2475
2476 /*
2477 * Next, we calculate a "preliminary" sync period
2478 * in tenths of a nanosecond.
2479 */
2480 if (syncrate == 0)
2481 prelim_sync_period = 0;
2482 else
2483 prelim_sync_period = 10000000 / syncrate;
2484
2485 ccb->cts.sync_period =
2486 scsi_calc_syncparam(prelim_sync_period);
2487
2488 freq = scsi_calc_syncsrate(ccb->cts.sync_period);
2489 } else
2490 ccb->cts.valid &= ~CCB_TRANS_SYNC_RATE_VALID;
2491
2492 /*
2493 * The bus_width argument goes like this:
2494 * 0 == 8 bit
2495 * 1 == 16 bit
2496 * 2 == 32 bit
2497 * Therefore, if you shift the number of bits given on the
2498 * command line right by 4, you should get the correct
2499 * number.
2500 */
2501 if (bus_width != -1) {
2502
2503 /*
2504 * We might as well validate things here with a
2505 * decipherable error message, rather than what
2506 * will probably be an indecipherable error message
2507 * by the time it gets back to us.
2508 */
2509 if ((bus_width == 16)
2510 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
2511 warnx("HBA does not support 16 bit bus width");
2512 retval = 1;
2513 goto ratecontrol_bailout;
2514 } else if ((bus_width == 32)
2515 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
2516 warnx("HBA does not support 32 bit bus width");
2517 retval = 1;
2518 goto ratecontrol_bailout;
2519 } else if (bus_width != 8) {
2520 warnx("Invalid bus width %d", bus_width);
2521 retval = 1;
2522 goto ratecontrol_bailout;
2523 }
2524
2525 ccb->cts.valid |= CCB_TRANS_BUS_WIDTH_VALID;
2526 ccb->cts.bus_width = bus_width >> 4;
2527 } else
2528 ccb->cts.valid &= ~CCB_TRANS_BUS_WIDTH_VALID;
2529
2530 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
2531
2532 if (cam_send_ccb(device, ccb) < 0) {
2533 perror("error sending XPT_SET_TRAN_SETTINGS CCB");
2534 retval = 1;
2535 goto ratecontrol_bailout;
2536 }
2537
2538 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2539 warnx("XPT_SET_TRANS_SETTINGS CCB failed, status %#x",
2540 ccb->ccb_h.status);
2541 retval = 1;
2542 goto ratecontrol_bailout;
2543 }
2544 }
2545
2546 if (send_tur) {
2547 retval = testunitready(device, retry_count, timeout,
2548 (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
2549
2550 /*
2551 * If the TUR didn't succeed, just bail.
2552 */
2553 if (retval != 0) {
2554 if (quiet == 0)
2555 fprintf(stderr, "Test Unit Ready failed\n");
2556 goto ratecontrol_bailout;
2557 }
2558
2559 /*
2560 * If the user wants things quiet, there's no sense in
2561 * getting the transfer settings, if we're not going
2562 * to print them.
2563 */
2564 if (quiet != 0)
2565 goto ratecontrol_bailout;
2566
2567 fprintf(stdout, "New Parameters:\n");
2568 retval = get_print_cts(device, user_settings, 0, NULL);
2569 }
2570
2571ratecontrol_bailout:
2572
2573 cam_freeccb(ccb);
2574 return(retval);
2575}
2576
1787void
1788usage(void)
1789{
1790 fprintf(stderr,
1791"usage: camcontrol <command> [ generic args ] [ command args ]\n"
1792" camcontrol devlist [-v]\n"
1793" camcontrol periphlist [-n dev_name] [-u unit]\n"
1794" camcontrol tur [generic args]\n"
1795" camcontrol inquiry [generic args] [-D] [-S] [-R]\n"
1796" camcontrol start [generic args]\n"
1797" camcontrol stop [generic args]\n"
1798" camcontrol eject [generic args]\n"
1799" camcontrol rescan <bus[:target:lun]>\n"
1800" camcontrol reset <bus[:target:lun]>\n"
1801" camcontrol defects [generic args] <-f format> [-P][-G]\n"
1802" camcontrol modepage [generic args] <-m page> [-P pagectl][-e][-d]\n"
1803" camcontrol cmd [generic args] <-c cmd [args]> \n"
1804" [-i len fmt|-o len fmt [args]]\n"
1805" camcontrol debug [-I][-T][-S][-c] <all|bus[:target[:lun]]|off>\n"
2577void
2578usage(void)
2579{
2580 fprintf(stderr,
2581"usage: camcontrol <command> [ generic args ] [ command args ]\n"
2582" camcontrol devlist [-v]\n"
2583" camcontrol periphlist [-n dev_name] [-u unit]\n"
2584" camcontrol tur [generic args]\n"
2585" camcontrol inquiry [generic args] [-D] [-S] [-R]\n"
2586" camcontrol start [generic args]\n"
2587" camcontrol stop [generic args]\n"
2588" camcontrol eject [generic args]\n"
2589" camcontrol rescan <bus[:target:lun]>\n"
2590" camcontrol reset <bus[:target:lun]>\n"
2591" camcontrol defects [generic args] <-f format> [-P][-G]\n"
2592" camcontrol modepage [generic args] <-m page> [-P pagectl][-e][-d]\n"
2593" camcontrol cmd [generic args] <-c cmd [args]> \n"
2594" [-i len fmt|-o len fmt [args]]\n"
2595" camcontrol debug [-I][-T][-S][-c] <all|bus[:target[:lun]]|off>\n"
2596" camcontrol tags [generic args] [-N tags] [-q] [-v]\n"
2597" camcontrol negotiate [generic args] [-a][-c][-D <enable|disable>]\n"
2598" [-O offset][-q][-R syncrate][-v]\n"
2599" [-T <enable|disable>][-U][-W bus_width]\n"
1806"Specify one of the following options:\n"
1807"devlist list all CAM devices\n"
1808"periphlist list all CAM peripheral drivers attached to a device\n"
1809"tur send a test unit ready to the named device\n"
1810"inquiry send a SCSI inquiry command to the named device\n"
1811"start send a Start Unit command to the device\n"
1812"stop send a Stop Unit command to the device\n"
1813"eject send a Stop Unit command to the device with the eject bit set\n"
1814"rescan rescan the given bus, or bus:target:lun\n"
1815"reset reset the given bus, or bus:target:lun\n"
1816"defects read the defect list of the specified device\n"
1817"modepage display or edit (-e) the given mode page\n"
1818"cmd send the given scsi command, may need -i or -o as well\n"
1819"debug turn debugging on/off for a bus, target, or lun, or all devices\n"
2600"Specify one of the following options:\n"
2601"devlist list all CAM devices\n"
2602"periphlist list all CAM peripheral drivers attached to a device\n"
2603"tur send a test unit ready to the named device\n"
2604"inquiry send a SCSI inquiry command to the named device\n"
2605"start send a Start Unit command to the device\n"
2606"stop send a Stop Unit command to the device\n"
2607"eject send a Stop Unit command to the device with the eject bit set\n"
2608"rescan rescan the given bus, or bus:target:lun\n"
2609"reset reset the given bus, or bus:target:lun\n"
2610"defects read the defect list of the specified device\n"
2611"modepage display or edit (-e) the given mode page\n"
2612"cmd send the given scsi command, may need -i or -o as well\n"
2613"debug turn debugging on/off for a bus, target, or lun, or all devices\n"
2614"tags report or set the number of transaction slots for a device\n"
2615"negotiate report or set device negotiation parameters\n"
1820"Generic arguments:\n"
1821"-v be verbose, print out sense information\n"
1822"-t timeout command timeout in seconds, overrides default timeout\n"
1823"-n dev_name specify device name (default is %s)\n"
1824"-u unit specify unit number (default is %d)\n"
1825"-E have the kernel attempt to perform SCSI error recovery\n"
1826"-C count specify the SCSI command retry count (needs -E to work)\n"
1827"modepage arguments:\n"
2616"Generic arguments:\n"
2617"-v be verbose, print out sense information\n"
2618"-t timeout command timeout in seconds, overrides default timeout\n"
2619"-n dev_name specify device name (default is %s)\n"
2620"-u unit specify unit number (default is %d)\n"
2621"-E have the kernel attempt to perform SCSI error recovery\n"
2622"-C count specify the SCSI command retry count (needs -E to work)\n"
2623"modepage arguments:\n"
2624"-m page specify the mode page to view or edit\n"
1828"-e edit the specified mode page\n"
2625"-e edit the specified mode page\n"
1829"-B disable block descriptors for mode sense\n"
2626"-d disable block descriptors for mode sense\n"
1830"-P pgctl page control field 0-3\n"
1831"defects arguments:\n"
1832"-f format specify defect list format (block, bfi or phys)\n"
1833"-G get the grown defect list\n"
1834"-P get the permanant defect list\n"
1835"inquiry arguments:\n"
1836"-D get the standard inquiry data\n"
1837"-S get the serial number\n"
1838"-R get the transfer rate, etc.\n"
1839"cmd arguments:\n"
1840"-c cdb [args] specify the SCSI CDB\n"
1841"-i len fmt specify input data and input data format\n"
1842"-o len fmt [args] specify output data and output data fmt\n"
1843"debug arguments:\n"
1844"-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
1845"-T CAM_DEBUG_TRACE -- routine flow tracking\n"
1846"-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
2627"-P pgctl page control field 0-3\n"
2628"defects arguments:\n"
2629"-f format specify defect list format (block, bfi or phys)\n"
2630"-G get the grown defect list\n"
2631"-P get the permanant defect list\n"
2632"inquiry arguments:\n"
2633"-D get the standard inquiry data\n"
2634"-S get the serial number\n"
2635"-R get the transfer rate, etc.\n"
2636"cmd arguments:\n"
2637"-c cdb [args] specify the SCSI CDB\n"
2638"-i len fmt specify input data and input data format\n"
2639"-o len fmt [args] specify output data and output data fmt\n"
2640"debug arguments:\n"
2641"-I CAM_DEBUG_INFO -- scsi commands, errors, data\n"
2642"-T CAM_DEBUG_TRACE -- routine flow tracking\n"
2643"-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
1847"-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n",
2644"-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
2645"tags arguments:\n"
2646"-N tags specify the number of tags to use for this device\n"
2647"-q be quiet, don't report the number of tags\n"
2648"-v report a number of tag-related parameters\n"
2649"negotiate arguments:\n"
2650"-a send a test unit ready after negotiation\n"
2651"-c report/set current negotiation settings\n"
2652"-D <arg> \"enable\" or \"disable\" disconnection\n"
2653"-O offset set command delay offset\n"
2654"-q be quiet, don't report anything\n"
2655"-R syncrate synchronization rate in MHz\n"
2656"-T <arg> \"enable\" or \"disable\" tagged queueing\n"
2657"-U report/set user negotiation settings\n"
2658"-W bus_width set the bus width in bits (8, 16 or 32)\n"
2659"-v also print a Path Inquiry CCB for the controller\n",
1848DEFAULT_DEVICE, DEFAULT_UNIT);
1849}
1850
1851int
1852main(int argc, char **argv)
1853{
1854 int c;
1855 char *device = NULL;

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

2020 switch(arglist & CAM_ARG_OPT_MASK) {
2021 case CAM_ARG_DEVLIST:
2022 error = getdevlist(cam_dev);
2023 break;
2024 case CAM_ARG_DEVTREE:
2025 error = getdevtree();
2026 break;
2027 case CAM_ARG_TUR:
2660DEFAULT_DEVICE, DEFAULT_UNIT);
2661}
2662
2663int
2664main(int argc, char **argv)
2665{
2666 int c;
2667 char *device = NULL;

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

2832 switch(arglist & CAM_ARG_OPT_MASK) {
2833 case CAM_ARG_DEVLIST:
2834 error = getdevlist(cam_dev);
2835 break;
2836 case CAM_ARG_DEVTREE:
2837 error = getdevtree();
2838 break;
2839 case CAM_ARG_TUR:
2028 error = testunitready(cam_dev, retry_count, timeout);
2840 error = testunitready(cam_dev, retry_count, timeout, 0);
2029 break;
2030 case CAM_ARG_INQUIRY:
2031 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
2032 retry_count, timeout);
2033 break;
2034 case CAM_ARG_STARTSTOP:
2035 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
2036 arglist & CAM_ARG_EJECT, retry_count,

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

2052 break;
2053 case CAM_ARG_SCSI_CMD:
2054 error = scsicmd(cam_dev, argc, argv, combinedopt,
2055 retry_count, timeout);
2056 break;
2057 case CAM_ARG_DEBUG:
2058 error = camdebug(argc, argv, combinedopt);
2059 break;
2841 break;
2842 case CAM_ARG_INQUIRY:
2843 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
2844 retry_count, timeout);
2845 break;
2846 case CAM_ARG_STARTSTOP:
2847 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
2848 arglist & CAM_ARG_EJECT, retry_count,

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

2864 break;
2865 case CAM_ARG_SCSI_CMD:
2866 error = scsicmd(cam_dev, argc, argv, combinedopt,
2867 retry_count, timeout);
2868 break;
2869 case CAM_ARG_DEBUG:
2870 error = camdebug(argc, argv, combinedopt);
2871 break;
2872 case CAM_ARG_TAG:
2873 error = tagcontrol(cam_dev, argc, argv, combinedopt);
2874 break;
2875 case CAM_ARG_RATE:
2876 error = ratecontrol(cam_dev, retry_count, timeout,
2877 argc, argv, combinedopt);
2878 break;
2060 default:
2061 usage();
2062 error = 1;
2063 break;
2064 }
2065
2066 if (cam_dev != NULL)
2067 cam_close_device(cam_dev);
2068
2069 exit(error);
2070}
2879 default:
2880 usage();
2881 error = 1;
2882 break;
2883 }
2884
2885 if (cam_dev != NULL)
2886 cam_close_device(cam_dev);
2887
2888 exit(error);
2889}