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} |