Deleted Added
full compact
fwcontrol.c (146442) fwcontrol.c (163712)
1/*
2 * Copyright (C) 2002
3 * Hidetoshi Shimokawa. 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

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

28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <sys/cdefs.h>
1/*
2 * Copyright (C) 2002
3 * Hidetoshi Shimokawa. 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

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

28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/usr.sbin/fwcontrol/fwcontrol.c 146442 2005-05-20 12:50:47Z charnier $");
36__FBSDID("$FreeBSD: head/usr.sbin/fwcontrol/fwcontrol.c 163712 2006-10-26 22:33:38Z imp $");
37
38#include <sys/param.h>
39#include <sys/malloc.h>
40#include <sys/types.h>
41#include <sys/sysctl.h>
42#include <sys/socket.h>
43#include <sys/ioctl.h>
44#include <sys/errno.h>
45#include <sys/eui64.h>
46#include <dev/firewire/firewire.h>
47#include <dev/firewire/iec13213.h>
48#include <dev/firewire/fwphyreg.h>
37
38#include <sys/param.h>
39#include <sys/malloc.h>
40#include <sys/types.h>
41#include <sys/sysctl.h>
42#include <sys/socket.h>
43#include <sys/ioctl.h>
44#include <sys/errno.h>
45#include <sys/eui64.h>
46#include <dev/firewire/firewire.h>
47#include <dev/firewire/iec13213.h>
48#include <dev/firewire/fwphyreg.h>
49#include <dev/firewire/iec68113.h>
49
50#include <netinet/in.h>
51#include <fcntl.h>
52#include <stdio.h>
53#include <err.h>
54#include <stdlib.h>
55#include <string.h>
50
51#include <netinet/in.h>
52#include <fcntl.h>
53#include <stdio.h>
54#include <err.h>
55#include <stdlib.h>
56#include <string.h>
57#include <sysexits.h>
56#include <unistd.h>
58#include <unistd.h>
59#include "fwmethods.h"
57
60
58extern int dvrecv(int, char *, char, int);
59extern int dvsend(int, char *, char, int);
61static void sysctl_set_int(const char *, int);
60
62
61int sysctl_set_int(const char *, int);
62
63static void
64usage(void)
65{
66 fprintf(stderr,
67 "fwcontrol [-u bus_num] [-rt] [-g gap_count] [-o node] "
68 "[-b pri_req] [-c node] [-d node] [-l file] "
69 "[-R file] [-S file] [-m target]\n"
70 "\t-u: specify bus number\n"
71 "\t-g: broadcast gap_count by phy_config packet\n"
72 "\t-o: send link-on packet to the node\n"
73 "\t-s: write RESET_START register on the node\n"
74 "\t-b: set PRIORITY_BUDGET register on all supported nodes\n"
75 "\t-c: read configuration ROM\n"
76 "\t-r: bus reset\n"
77 "\t-t: read topology map\n"
78 "\t-d: hex dump of configuration ROM\n"
79 "\t-l: load and parse hex dump file of configuration ROM\n"
63static void
64usage(void)
65{
66 fprintf(stderr,
67 "fwcontrol [-u bus_num] [-rt] [-g gap_count] [-o node] "
68 "[-b pri_req] [-c node] [-d node] [-l file] "
69 "[-R file] [-S file] [-m target]\n"
70 "\t-u: specify bus number\n"
71 "\t-g: broadcast gap_count by phy_config packet\n"
72 "\t-o: send link-on packet to the node\n"
73 "\t-s: write RESET_START register on the node\n"
74 "\t-b: set PRIORITY_BUDGET register on all supported nodes\n"
75 "\t-c: read configuration ROM\n"
76 "\t-r: bus reset\n"
77 "\t-t: read topology map\n"
78 "\t-d: hex dump of configuration ROM\n"
79 "\t-l: load and parse hex dump file of configuration ROM\n"
80 "\t-R: Receive DV stream\n"
80 "\t-R: Receive DV or MPEG TS stream\n"
81 "\t-S: Send DV stream\n"
82 "\t-m: set fwmem target\n");
81 "\t-S: Send DV stream\n"
82 "\t-m: set fwmem target\n");
83 exit(0);
83 exit(EX_USAGE);
84}
85
86static void
87fweui2eui64(const struct fw_eui64 *fweui, struct eui64 *eui)
88{
89 *(u_int32_t*)&(eui->octet[0]) = htonl(fweui->hi);
90 *(u_int32_t*)&(eui->octet[4]) = htonl(fweui->lo);
91}

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

271 asyreq->pkt.mode.wreqq.data = htonl(0x1);
272
273 if (ioctl(fd, FW_ASYREQ, asyreq) < 0)
274 err(1, "ioctl");
275 free(asyreq);
276}
277
278static void
84}
85
86static void
87fweui2eui64(const struct fw_eui64 *fweui, struct eui64 *eui)
88{
89 *(u_int32_t*)&(eui->octet[0]) = htonl(fweui->hi);
90 *(u_int32_t*)&(eui->octet[4]) = htonl(fweui->lo);
91}

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

271 asyreq->pkt.mode.wreqq.data = htonl(0x1);
272
273 if (ioctl(fd, FW_ASYREQ, asyreq) < 0)
274 err(1, "ioctl");
275 free(asyreq);
276}
277
278static void
279set_pri_req(int fd, int pri_req)
279set_pri_req(int fd, u_int32_t pri_req)
280{
281 struct fw_devlstreq *data;
282 struct fw_devinfo *devinfo;
283 struct eui64 eui;
284 char addr[EUI64_SIZ];
285 u_int32_t max, reg, old;
286 int i;
287
288 data = get_dev(fd);
289#define BUGET_REG 0xf0000218
290 for (i = 0; i < data->info_len; i++) {
291 devinfo = &data->dev[i];
292 if (!devinfo->status)
293 continue;
294 reg = read_write_quad(fd, devinfo->eui, BUGET_REG, 1, 0);
295 fweui2eui64(&devinfo->eui, &eui);
296 eui64_ntoa(&eui, addr, sizeof(addr));
297 printf("%d %s, %08x",
298 devinfo->dst, addr, reg);
280{
281 struct fw_devlstreq *data;
282 struct fw_devinfo *devinfo;
283 struct eui64 eui;
284 char addr[EUI64_SIZ];
285 u_int32_t max, reg, old;
286 int i;
287
288 data = get_dev(fd);
289#define BUGET_REG 0xf0000218
290 for (i = 0; i < data->info_len; i++) {
291 devinfo = &data->dev[i];
292 if (!devinfo->status)
293 continue;
294 reg = read_write_quad(fd, devinfo->eui, BUGET_REG, 1, 0);
295 fweui2eui64(&devinfo->eui, &eui);
296 eui64_ntoa(&eui, addr, sizeof(addr));
297 printf("%d %s, %08x",
298 devinfo->dst, addr, reg);
299 if (reg > 0 && pri_req >= 0) {
299 if (reg > 0) {
300 old = (reg & 0x3f);
301 max = (reg & 0x3f00) >> 8;
302 if (pri_req > max)
303 pri_req = max;
304 printf(" 0x%x -> 0x%x\n", old, pri_req);
305 read_write_quad(fd, devinfo->eui, BUGET_REG, 0, pri_req);
306 } else {
307 printf("\n");
308 }
309 }
310 free((void *)data);
311}
312
313static void
300 old = (reg & 0x3f);
301 max = (reg & 0x3f00) >> 8;
302 if (pri_req > max)
303 pri_req = max;
304 printf(" 0x%x -> 0x%x\n", old, pri_req);
305 read_write_quad(fd, devinfo->eui, BUGET_REG, 0, pri_req);
306 } else {
307 printf("\n");
308 }
309 }
310 free((void *)data);
311}
312
313static void
314parse_bus_info_block(u_int32_t *p, int info_len)
314parse_bus_info_block(u_int32_t *p)
315{
316 char addr[EUI64_SIZ];
317 struct bus_info *bi;
318 struct eui64 eui;
319
320 bi = (struct bus_info *)p;
321 fweui2eui64(&bi->eui64, &eui);
322 eui64_ntoa(&eui, addr, sizeof(addr));

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

387 }
388 printf("info_len=%d crc_len=%d crc=0x%04x",
389 hdr->info_len, hdr->crc_len, hdr->crc);
390 crc = crom_crc(crom_buf+1, hdr->crc_len);
391 if (crc == hdr->crc)
392 printf("(OK)\n");
393 else
394 printf("(NG)\n");
315{
316 char addr[EUI64_SIZ];
317 struct bus_info *bi;
318 struct eui64 eui;
319
320 bi = (struct bus_info *)p;
321 fweui2eui64(&bi->eui64, &eui);
322 eui64_ntoa(&eui, addr, sizeof(addr));

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

387 }
388 printf("info_len=%d crc_len=%d crc=0x%04x",
389 hdr->info_len, hdr->crc_len, hdr->crc);
390 crc = crom_crc(crom_buf+1, hdr->crc_len);
391 if (crc == hdr->crc)
392 printf("(OK)\n");
393 else
394 printf("(NG)\n");
395 parse_bus_info_block(crom_buf+1, hdr->info_len);
395 parse_bus_info_block(crom_buf+1);
396
397 crom_init_context(&cc, crom_buf);
398 dir = cc.stack[0].dir;
399 if (!dir) {
400 printf("no root directory - giving up\n");
401 return;
402 }
403 printf("root_directory: len=0x%04x(%d) crc=0x%04x",

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

598 break;
599 }
600 if (*fd < 0)
601 err(1, "open");
602
603 }
604}
605
396
397 crom_init_context(&cc, crom_buf);
398 dir = cc.stack[0].dir;
399 if (!dir) {
400 printf("no root directory - giving up\n");
401 return;
402 }
403 printf("root_directory: len=0x%04x(%d) crc=0x%04x",

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

598 break;
599 }
600 if (*fd < 0)
601 err(1, "open");
602
603 }
604}
605
606int
606static void
607sysctl_set_int(const char *name, int val)
608{
609 if (sysctlbyname(name, NULL, NULL, &val, sizeof(int)) < 0)
610 err(1, "sysctl %s failed.", name);
611}
612
607sysctl_set_int(const char *name, int val)
608{
609 if (sysctlbyname(name, NULL, NULL, &val, sizeof(int)) < 0)
610 err(1, "sysctl %s failed.", name);
611}
612
613static fwmethod *
614detect_recv_fn(int fd, char ich)
615{
616 char *buf;
617 struct fw_isochreq isoreq;
618 struct fw_isobufreq bufreq;
619 int len;
620 u_int32_t *ptr;
621 struct ciphdr *ciph;
622 fwmethod *retfn;
623
624 bufreq.rx.nchunk = 8;
625 bufreq.rx.npacket = 16;
626 bufreq.rx.psize = 1024;
627 bufreq.tx.nchunk = 0;
628 bufreq.tx.npacket = 0;
629 bufreq.tx.psize = 0;
630
631 if (ioctl(fd, FW_SSTBUF, &bufreq) < 0)
632 err(1, "ioctl FW_SSTBUF");
633
634 isoreq.ch = ich & 0x3f;
635 isoreq.tag = (ich >> 6) & 3;
636
637 if (ioctl(fd, FW_SRSTREAM, &isoreq) < 0)
638 err(1, "ioctl FW_SRSTREAM");
639
640 buf = (char *)malloc(1024*16);
641 len = read(fd, buf, 1024*16);
642 ptr = (u_int32_t *) buf;
643 ciph = (struct ciphdr *)(ptr + 1);
644
645 switch(ciph->fmt) {
646 case CIP_FMT_DVCR:
647 fprintf(stderr, "Detected DV format on input.\n");
648 retfn = dvrecv;
649 break;
650 case CIP_FMT_MPEG:
651 fprintf(stderr, "Detected MPEG TS format on input.\n");
652 retfn = mpegtsrecv;
653 break;
654 default:
655 errx(1, "Unsupported format for receiving: fmt=0x%x", ciph->fmt);
656 }
657 free(buf);
658 return retfn;
659}
660
613int
614main(int argc, char **argv)
615{
616 u_int32_t crom_buf[1024/4];
617 char devbase[1024] = "/dev/fw0";
661int
662main(int argc, char **argv)
663{
664 u_int32_t crom_buf[1024/4];
665 char devbase[1024] = "/dev/fw0";
618 int fd, tmp, ch, len=1024;
666 int fd, ch, len=1024;
667 long tmp;
619 struct fw_eui64 eui;
620 struct eui64 target;
668 struct fw_eui64 eui;
669 struct eui64 target;
670 fwmethod *recvfn = NULL;
621
622 fd = -1;
623
624 if (argc < 2) {
625 open_dev(&fd, devbase);
626 list_dev(fd);
627 }
628
671
672 fd = -1;
673
674 if (argc < 2) {
675 open_dev(&fd, devbase);
676 list_dev(fd);
677 }
678
629 while ((ch = getopt(argc, argv, "g:m:o:s:b:prtc:d:l:u:R:S:")) != -1)
679 while ((ch = getopt(argc, argv, "M:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1)
630 switch(ch) {
631 case 'b':
632 tmp = strtol(optarg, NULL, 0);
680 switch(ch) {
681 case 'b':
682 tmp = strtol(optarg, NULL, 0);
683 if (tmp < 0 || tmp > (long)0xffffffff)
684 errx(EX_USAGE, "invalid number: %s", optarg);
633 open_dev(&fd, devbase);
634 set_pri_req(fd, tmp);
635 break;
636 case 'c':
637 open_dev(&fd, devbase);
638 tmp = str2node(fd, optarg);
639 get_crom(fd, tmp, crom_buf, len);
640 show_crom(crom_buf);

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

652 break;
653 case 'l':
654 load_crom(optarg, crom_buf);
655 show_crom(crom_buf);
656 break;
657 case 'm':
658 if (eui64_hostton(optarg, &target) != 0 &&
659 eui64_aton(optarg, &target) != 0)
685 open_dev(&fd, devbase);
686 set_pri_req(fd, tmp);
687 break;
688 case 'c':
689 open_dev(&fd, devbase);
690 tmp = str2node(fd, optarg);
691 get_crom(fd, tmp, crom_buf, len);
692 show_crom(crom_buf);

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

704 break;
705 case 'l':
706 load_crom(optarg, crom_buf);
707 show_crom(crom_buf);
708 break;
709 case 'm':
710 if (eui64_hostton(optarg, &target) != 0 &&
711 eui64_aton(optarg, &target) != 0)
660 errx(1, "invalid target: %s", optarg);
712 errx(EX_USAGE, "invalid target: %s", optarg);
661 eui.hi = ntohl(*(u_int32_t*)&(target.octet[0]));
662 eui.lo = ntohl(*(u_int32_t*)&(target.octet[4]));
663 sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi);
664 sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo);
665 break;
666 case 'o':
667 open_dev(&fd, devbase);
668 tmp = str2node(fd, optarg);

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

683 reset_start(fd, tmp);
684 break;
685 case 't':
686 open_dev(&fd, devbase);
687 show_topology_map(fd);
688 break;
689 case 'u':
690 tmp = strtol(optarg, NULL, 0);
713 eui.hi = ntohl(*(u_int32_t*)&(target.octet[0]));
714 eui.lo = ntohl(*(u_int32_t*)&(target.octet[4]));
715 sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi);
716 sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo);
717 break;
718 case 'o':
719 open_dev(&fd, devbase);
720 tmp = str2node(fd, optarg);

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

735 reset_start(fd, tmp);
736 break;
737 case 't':
738 open_dev(&fd, devbase);
739 show_topology_map(fd);
740 break;
741 case 'u':
742 tmp = strtol(optarg, NULL, 0);
691 snprintf(devbase, sizeof(devbase), "/dev/fw%d", tmp);
743 snprintf(devbase, sizeof(devbase), "/dev/fw%ld", tmp);
692 if (fd > 0) {
693 close(fd);
694 fd = -1;
695 }
696 if (argc == optind) {
697 open_dev(&fd, devbase);
698 list_dev(fd);
699 }
700 break;
701#define TAG (1<<6)
702#define CHANNEL 63
744 if (fd > 0) {
745 close(fd);
746 fd = -1;
747 }
748 if (argc == optind) {
749 open_dev(&fd, devbase);
750 list_dev(fd);
751 }
752 break;
753#define TAG (1<<6)
754#define CHANNEL 63
755 case 'M':
756 switch (optarg[0]) {
757 case 'm':
758 recvfn = mpegtsrecv;
759 break;
760 case 'd':
761 recvfn = dvrecv;
762 break;
763 default:
764 errx(EX_USAGE, "unrecognized method: %s",
765 optarg);
766 }
767 break;
703 case 'R':
704 open_dev(&fd, devbase);
768 case 'R':
769 open_dev(&fd, devbase);
705 dvrecv(fd, optarg, TAG | CHANNEL, -1);
770 if (recvfn == NULL) /* guess... */
771 recvfn = detect_recv_fn(fd, TAG | CHANNEL);
772 close(fd);
773 fd = -1;
774 open_dev(&fd, devbase);
775 (*recvfn)(fd, optarg, TAG | CHANNEL, -1);
706 break;
707 case 'S':
708 open_dev(&fd, devbase);
709 dvsend(fd, optarg, TAG | CHANNEL, -1);
710 break;
711 default:
712 usage();
713 }
714 return 0;
715}
776 break;
777 case 'S':
778 open_dev(&fd, devbase);
779 dvsend(fd, optarg, TAG | CHANNEL, -1);
780 break;
781 default:
782 usage();
783 }
784 return 0;
785}