From owner-freebsd-firewire@FreeBSD.ORG Mon Jun 30 11:06:56 2008 Return-Path: Delivered-To: freebsd-firewire@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 33D9910656F4 for ; Mon, 30 Jun 2008 11:06:56 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 079768FC1D for ; Mon, 30 Jun 2008 11:06:56 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m5UB6tJh095723 for ; Mon, 30 Jun 2008 11:06:55 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m5UB6tuo095719 for freebsd-firewire@FreeBSD.org; Mon, 30 Jun 2008 11:06:55 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 30 Jun 2008 11:06:55 GMT Message-Id: <200806301106.m5UB6tuo095719@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-firewire@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-firewire@FreeBSD.org X-BeenThere: freebsd-firewire@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Firewire support in FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Jun 2008 11:06:56 -0000 Current FreeBSD problem reports Critical problems Serious problems S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/74238 firewire [firewire] fw_rcv: unknown response; firewire ad-hoc w 1 problem total. Non-critical problems S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/113785 firewire [firewire] dropouts when playing DV on firewire 1 problem total. From owner-freebsd-firewire@FreeBSD.ORG Mon Jun 30 22:13:01 2008 Return-Path: Delivered-To: freebsd-firewire@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 091C9106566C; Mon, 30 Jun 2008 22:13:01 +0000 (UTC) (envelope-from sbruno@miralink.com) Received: from plato.miralink.com (mail.miralink.com [70.103.185.20]) by mx1.freebsd.org (Postfix) with ESMTP id CB3998FC1E; Mon, 30 Jun 2008 22:13:00 +0000 (UTC) (envelope-from sbruno@miralink.com) Received: from localhost (localhost.localdomain [127.0.0.1]) by plato.miralink.com (Postfix) with ESMTP id BB7841A91B8; Mon, 30 Jun 2008 15:12:02 -0700 (PDT) X-Virus-Scanned: amavisd-new at X-Spam-Flag: NO X-Spam-Score: -4.399 X-Spam-Level: X-Spam-Status: No, score=-4.399 tagged_above=-10 required=6.6 tests=[ALL_TRUSTED=-1.8, AWL=0.000, BAYES_00=-2.599] Received: from plato.miralink.com ([127.0.0.1]) by localhost (plato.miralink.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id H08KAxDHlyjl; Mon, 30 Jun 2008 15:12:02 -0700 (PDT) Received: from [10.47.1.30] (vpn.office.miralink.com [10.0.0.5]) by plato.miralink.com (Postfix) with ESMTP id 90AF01A91A7; Mon, 30 Jun 2008 15:12:01 -0700 (PDT) Message-ID: <48695A6A.1030701@miralink.com> Date: Mon, 30 Jun 2008 15:12:58 -0700 From: Sean Bruno User-Agent: Thunderbird 2.0.0.14 (X11/20080501) MIME-Version: 1.0 To: freebsd-firewire@freebsd.org, Hidetoshi Shimokawa References: <486680D5.9070106@miralink.com> <48668196.6080602@miralink.com> In-Reply-To: <48668196.6080602@miralink.com> Content-Type: multipart/mixed; boundary="------------000801080501060205070102" Cc: Subject: This is where I'm going with fwcontrol X-BeenThere: freebsd-firewire@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Firewire support in FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Jun 2008 22:13:01 -0000 This is a multi-part message in MIME format. --------------000801080501060205070102 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Take a look at what I'm doing with fwcontrol if you have time. I'm modifying it such that it can find nodes on different "buses" or cards and allowing it to parse all arguments before execution begins. It's in the primitive stages right now and I'd really like to know what you think. Here is a current diff against RELENG_7 which seems to be the same as -CURRENT. Sean --------------000801080501060205070102 Content-Type: text/x-patch; name="fwcontrol.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fwcontrol.diff" Only in RELENG_7/src/usr.sbin/fwcontrol/: .fwcontrol.c.swp diff -u reference_RELENG_7/src/usr.sbin/fwcontrol/fwcontrol.c RELENG_7/src/usr.sbin/fwcontrol/fwcontrol.c --- reference_RELENG_7/src/usr.sbin/fwcontrol/fwcontrol.c 2008-05-01 23:15:58.000000000 -0700 +++ RELENG_7/src/usr.sbin/fwcontrol/fwcontrol.c 2008-06-30 09:05:21.000000000 -0700 @@ -81,6 +81,7 @@ "\t-l: load and parse hex dump file of configuration ROM\n" "\t-R: Receive DV or MPEG TS stream\n" "\t-S: Send DV stream\n" + "\t-p: Display current PHY register settings\n" "\t-m: set fwmem target\n"); exit(EX_USAGE); } @@ -590,22 +591,20 @@ ); } -static void +static int open_dev(int *fd, char *devbase) { char name[256]; int i; if (*fd < 0) { - for (i = 0; i < 4; i++) { - snprintf(name, sizeof(name), "%s.%d", devbase, i); - if ((*fd = open(name, O_RDWR)) >= 0) - break; - } + snprintf(name, sizeof(name), "%s.%d", devbase, i); + *fd = open(name, O_RDWR); if (*fd < 0) - err(1, "open"); + return(-1); } + return(0); } static void @@ -666,57 +665,107 @@ int main(int argc, char **argv) { +#define MAX_BOARDS 10 u_int32_t crom_buf[1024/4]; - char devbase[1024] = "/dev/fw0"; - int fd, ch, len=1024; + u_int32_t crom_buf_hex[1024/4]; + char devbase[64]; + const char *device_string = "/dev/fw"; + int fd = -1, ch, len=1024; + int dev_counter = 0; + int num_boards = 0; + int current_board = 0; + int open_needed = 0; long tmp; struct fw_eui64 eui; struct eui64 target; fwmethod *recvfn = NULL; - - fd = -1; - - if (argc < 2) { - open_dev(&fd, devbase); - list_dev(fd); - } - - while ((ch = getopt(argc, argv, "M:f:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1) +/* + * Holders for which functions + * to iterate through + */ + int priority_budget = 0; + int display_crom = 0; + char *crom_string = NULL; + char *crom_string_hex = NULL; + int display_crom_hex = 0; + int display_bus = MAX_BOARDS; + int adjust_gap_count = 0; + int reset_gap_count = 0; + int load_crom_from_file = 0; + int set_fwmem_target = 0; + long dump_phy_reg = 0; + int dump_topology = 0; + int send_link_on = 0; + int send_bus_reset = 0; + int send_reset_start = 0; + int recv_data = 0; + int send_data = 0; + + if (argc < 2) + open_needed = 1; + /* + * Parse all command line options, then execute requested operations. + */ + while ((ch = getopt(argc, argv, "M:f:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1) { switch(ch) { case 'b': - tmp = strtol(optarg, NULL, 0); - if (tmp < 0 || tmp > (long)0xffffffff) + priority_budget = strtol(optarg, NULL, 0); + if (priority_budget < 0 || priority_budget > (long)0xffffffff) errx(EX_USAGE, "invalid number: %s", optarg); - open_dev(&fd, devbase); - set_pri_req(fd, tmp); + open_needed = 1; + display_bus = -1; +# if 0 + open_dev(&fd, devbase); + set_pri_req(fd, tmp); +#endif break; case 'c': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - get_crom(fd, tmp, crom_buf, len); - show_crom(crom_buf); + crom_string = malloc(strlen(optarg)+1); + strcpy(crom_string, optarg); + display_crom = 1; + open_needed = 1; + display_bus = -1; break; case 'd': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - get_crom(fd, tmp, crom_buf, len); - dump_crom(crom_buf); + crom_string_hex = malloc(strlen(optarg)+1); + strcpy(crom_string_hex, optarg); + display_crom_hex = 1; + open_needed = 1; + display_bus = -1; break; case 'f': + adjust_gap_count = 1; + open_needed = 1; + display_bus = -1; +#if 0 tmp = strtol(optarg, NULL, 0); open_dev(&fd, devbase); send_phy_config(fd, tmp, -1); +#endif break; case 'g': + reset_gap_count = 1; + open_needed = 1; + display_bus = -1; +#if 0 tmp = strtol(optarg, NULL, 0); open_dev(&fd, devbase); send_phy_config(fd, -1, tmp); +#endif break; case 'l': + load_crom_from_file = 1; + open_needed = 1; + display_bus = -1; +#if 0 load_crom(optarg, crom_buf); show_crom(crom_buf); +#endif break; case 'm': + set_fwmem_target = 1; + display_bus = -1; +#if 0 if (eui64_hostton(optarg, &target) != 0 && eui64_aton(optarg, &target) != 0) errx(EX_USAGE, "invalid target: %s", optarg); @@ -724,41 +773,49 @@ eui.lo = ntohl(*(u_int32_t*)&(target.octet[4])); sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi); sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo); +#endif break; case 'o': + send_link_on = 1; + open_needed = 1; + display_bus = -1; +#if 0 open_dev(&fd, devbase); tmp = str2node(fd, optarg); send_link_on(fd, tmp); +#endif break; case 'p': - open_dev(&fd, devbase); - dump_phy_registers(fd); + dump_phy_reg = 1; + open_needed = 1; + display_bus = -1; break; case 'r': - open_dev(&fd, devbase); - if(ioctl(fd, FW_IBUSRST, &tmp) < 0) - err(1, "ioctl"); + send_bus_reset = 1; + open_needed = 1; + display_bus = -1; break; case 's': + send_reset_start = str2node(fd, optarg); + open_needed = 1; + display_bus = -1; +#if 0 open_dev(&fd, devbase); - tmp = str2node(fd, optarg); reset_start(fd, tmp); +#endif break; case 't': + dump_topology = 1; + open_needed = 1; + display_bus = -1; +#if 0 open_dev(&fd, devbase); show_topology_map(fd); +#endif break; case 'u': - tmp = strtol(optarg, NULL, 0); - snprintf(devbase, sizeof(devbase), "/dev/fw%ld", tmp); - if (fd > 0) { - close(fd); - fd = -1; - } - if (argc == optind) { - open_dev(&fd, devbase); - list_dev(fd); - } + display_bus = strtol(optarg, NULL, 0); + open_needed = 1; break; #define TAG (1<<6) #define CHANNEL 63 @@ -774,8 +831,13 @@ errx(EX_USAGE, "unrecognized method: %s", optarg); } + display_bus = -1; break; case 'R': + recv_data = 1; + open_needed = 1; + display_bus = -1; +#if 0 open_dev(&fd, devbase); if (recvfn == NULL) /* guess... */ recvfn = detect_recv_fn(fd, TAG | CHANNEL); @@ -783,13 +845,126 @@ fd = -1; open_dev(&fd, devbase); (*recvfn)(fd, optarg, TAG | CHANNEL, -1); +#endif break; case 'S': + send_data = 1; + open_needed = 1; + display_bus = -1; +#if 0 open_dev(&fd, devbase); dvsend(fd, optarg, TAG | CHANNEL, -1); +#endif break; default: usage(); + return 0; } + } + /* + * Iterate over the boards and display the + * node configuration if no other arguments + * are passed, eg "sudo fwcontrol" + * + * If any arguments are passed, assume board + * 0 for compatiblity reasons. + + * If command is set and this card is the bus + * we wish to execute the command for, then do it. + * + */ + for (current_board = 0; current_board < MAX_BOARDS; current_board++) { + if(open_needed){ + snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board); + if (open_dev(&fd, devbase) < 0) + return(EIO); + } + if (current_board == display_bus || + display_bus == MAX_BOARDS) { + list_dev(fd); + } + /* + * dump_phy_reg "-p" + */ + if (dump_phy_reg) { + if (display_bus == -1) { + if (current_board == 0) { /* This mimics the old behavior */ + dump_phy_registers(fd); + } else { + errx(EX_USAGE, "Displaying PHY registers requires -u \n"); + usage(); + } + } else if (current_board == display_bus) + dump_phy_registers(fd); + } + + /* + * send a BUS_RESET Event "-r" + */ + if (send_bus_reset) { + if (display_bus == -1) { + if (current_board == 0) { /* This mimics the old behavior */ + if(ioctl(fd, FW_IBUSRST, &tmp) < 0) + err(1, "ioctl"); + } else { + errx(EX_USAGE, "Sending a BUS Reset requires -u \n"); + usage(); + } + } else if (current_board == display_bus) { + if(ioctl(fd, FW_IBUSRST, &tmp) < 0) + err(1, "ioctl"); + } + } + /* + * Print out the CROM for this node "-c" + */ + if (display_crom) { + if (display_bus == -1) { + if (current_board == 0) { /* This mimics the old behavior */ + tmp = str2node(fd, crom_string); + get_crom(fd, tmp, crom_buf, len); + show_crom(crom_buf); + free(crom_string); + } else { + if(crom_string != NULL) + free(crom_string); + errx(EX_USAGE, "Displaying the CROM for a node requires -u \n"); + usage(); + } + } else if (current_board == display_bus) { + tmp = str2node(fd, crom_string); + get_crom(fd, tmp, crom_buf, len); + show_crom(crom_buf); + free(crom_string); + } + } + /* + * Hex Dump the CROM for this node "-d" + */ + if (display_crom_hex) { + if (display_bus == -1) { + if (current_board == 0) { /* This mimics the old behavior */ + tmp = str2node(fd, crom_string_hex); + get_crom(fd, tmp, crom_buf, len); + dump_crom(crom_buf); + free(crom_string_hex); + } else { + if(crom_string != NULL) + free(crom_string); + errx(EX_USAGE, "Dumping the CROM for a node requires -u \n"); + usage(); + } + } else if (current_board == display_bus) { + tmp = str2node(fd, crom_string_hex); + get_crom(fd, tmp, crom_buf, len); + dump_crom(crom_buf); + free(crom_string_hex); + } + } + if (fd > 0) { + close(fd); + fd = -1; + } + } return 0; } --------------000801080501060205070102-- From owner-freebsd-firewire@FreeBSD.ORG Wed Jul 2 00:26:29 2008 Return-Path: Delivered-To: freebsd-firewire@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9C6E5106564A; Wed, 2 Jul 2008 00:26:29 +0000 (UTC) (envelope-from sbruno@miralink.com) Received: from plato.miralink.com (mail.miralink.com [70.103.185.20]) by mx1.freebsd.org (Postfix) with ESMTP id 63B578FC0A; Wed, 2 Jul 2008 00:26:29 +0000 (UTC) (envelope-from sbruno@miralink.com) Received: from localhost (localhost.localdomain [127.0.0.1]) by plato.miralink.com (Postfix) with ESMTP id 5ACD71A9272; Tue, 1 Jul 2008 17:25:17 -0700 (PDT) X-Virus-Scanned: amavisd-new at X-Spam-Flag: NO X-Spam-Score: -4.399 X-Spam-Level: X-Spam-Status: No, score=-4.399 tagged_above=-10 required=6.6 tests=[ALL_TRUSTED=-1.8, AWL=0.000, BAYES_00=-2.599] Received: from plato.miralink.com ([127.0.0.1]) by localhost (plato.miralink.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oA905Gi3CTgQ; Tue, 1 Jul 2008 17:25:16 -0700 (PDT) Received: from iago.office.miralink.com (iago.office.miralink.com [10.0.0.40]) by plato.miralink.com (Postfix) with ESMTP id 7B5791A9240; Tue, 1 Jul 2008 17:25:16 -0700 (PDT) Message-ID: <486ACB33.50204@miralink.com> Date: Tue, 01 Jul 2008 17:26:27 -0700 From: Sean Bruno User-Agent: Thunderbird 2.0.0.14 (X11/20080501) MIME-Version: 1.0 To: freebsd-firewire@freebsd.org, Hidetoshi Shimokawa References: <486680D5.9070106@miralink.com> <48668196.6080602@miralink.com> <48695A6A.1030701@miralink.com> In-Reply-To: <48695A6A.1030701@miralink.com> Content-Type: multipart/mixed; boundary="------------000909010602070306070603" Cc: Subject: Re: This is where I'm going with fwcontrol X-BeenThere: freebsd-firewire@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Firewire support in FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Jul 2008 00:26:29 -0000 This is a multi-part message in MIME format. --------------000909010602070306070603 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Sean Bruno wrote: > Take a look at what I'm doing with fwcontrol if you have time. > > I'm modifying it such that it can find nodes on different "buses" or > cards and allowing it to parse all arguments before execution begins. > It's in the primitive stages right now and I'd really like to know > what you think. > > Here is a current diff against RELENG_7 which seems to be the same as > -CURRENT. > > Sean > ------------------------------------------------------------------------ > > _______________________________________________ > freebsd-firewire@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-firewire > To unsubscribe, send any mail to "freebsd-firewire-unsubscribe@freebsd.org" Here is today's version of fwcontrol. SUMMARY: -- cleanup a couple of memory leaks missing free's -- add "-p" to the usage display -- rework main() while loop to not act on arguments. Store those arguments so that multiple arguments can be passed on the command line. example: sudo fwcontrol -u 1 -r -o -- Allow code to use "-u" to denote a different /dev/fwX device other thatn /dev/fw0. This allows commands like a bus reset to act on a second firewire bus/card. -- Maintain backwards compatibility when "-u" is not used to mean that the command is to use /dev/fw0 -- Minor break to compatiblity. If fwcontrol is run with no arguments and there is more that one /dev/fwX device, it will iterate across all devices. Old behavior was to simply display the first device. I'd like some review of the code from anyone who has the time. I think that this is worth while to merge into -CURRENT and possibly back into 7.0 and 6.3 as I spent some considerable time on emulating the old behavior. I cannot test the -S/R/M arguments as I do not have a firewire video camera and would love to know if I've broken anything! :) -- Sean Bruno MiraLink Corporation 6015 NE 80th Ave, Ste 100 Portland, OR 97218 Phone 503-621-5143 Fax 503-621-5199 --------------000909010602070306070603 Content-Type: text/x-patch; name="fwcontrol.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fwcontrol.c.diff" Index: fwcontrol.c =================================================================== --- fwcontrol.c (revision 5540) +++ fwcontrol.c (working copy) @@ -81,6 +81,7 @@ "\t-l: load and parse hex dump file of configuration ROM\n" "\t-R: Receive DV or MPEG TS stream\n" "\t-S: Send DV stream\n" + "\t-p: Display current PHY register settings\n" "\t-m: set fwmem target\n"); exit(EX_USAGE); } @@ -92,18 +93,14 @@ *(u_int32_t*)&(eui->octet[4]) = htonl(fweui->lo); } -static struct fw_devlstreq * -get_dev(int fd) +static void +get_dev(int fd, struct fw_devlstreq *data) { - struct fw_devlstreq *data; - - data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); if (data == NULL) err(1, "malloc"); if( ioctl(fd, FW_GDEVLST, data) < 0) { err(1, "ioctl"); } - return data; } static int @@ -130,17 +127,23 @@ if (eui64_hostton(nodestr, &eui) != 0 && eui64_aton(nodestr, &eui) != 0) return (-1); - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + get_dev(fd,data); for (i = 0; i < data->info_len; i++) { fweui2eui64(&data->dev[i].eui, &tmpeui); if (memcmp(&eui, &tmpeui, sizeof(struct eui64)) == 0) { node = data->dev[i].dst; + if (data != NULL) + free(data); goto gotnode; } } - if (i >= data->info_len) + if (i >= data->info_len) { + if (data != NULL) + free(data); return (-1); + } gotnode: if (node < 0 || node > 63) @@ -158,7 +161,8 @@ char addr[EUI64_SIZ], hostname[40]; int i; - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + get_dev(fd, data); printf("%d devices (info_len=%d)\n", data->n, data->info_len); printf("node EUI64 status hostname\n"); for (i = 0; i < data->info_len; i++) { @@ -242,7 +246,7 @@ } static void -send_link_on(int fd, int node) +link_on(int fd, int node) { struct fw_asyreq *asyreq; @@ -290,7 +294,8 @@ u_int32_t max, reg, old; int i; - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + get_dev(fd, data); #define BUGET_REG 0xf0000218 for (i = 0; i < data->info_len; i++) { devinfo = &data->dev[i]; @@ -344,7 +349,8 @@ int i, error; struct fw_devlstreq *data; - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + get_dev(fd, data); for (i = 0; i < data->info_len; i++) { if (data->dev[i].dst == node && data->dev[i].eui.lo != 0) @@ -590,22 +596,16 @@ ); } -static void -open_dev(int *fd, char *devbase) +static int +open_dev(int *fd, char *devname) { - char name[256]; - int i; - if (*fd < 0) { - for (i = 0; i < 4; i++) { - snprintf(name, sizeof(name), "%s.%d", devbase, i); - if ((*fd = open(name, O_RDWR)) >= 0) - break; - } + *fd = open(devname, O_RDWR); if (*fd < 0) - err(1, "open"); + return(-1); } + return(0); } static void @@ -666,99 +666,147 @@ int main(int argc, char **argv) { +#define MAX_BOARDS 10 u_int32_t crom_buf[1024/4]; - char devbase[1024] = "/dev/fw0"; - int fd, ch, len=1024; + u_int32_t crom_buf_hex[1024/4]; + char devbase[64]; + const char *device_string = "/dev/fw"; + int fd = -1, ch, len=1024; + int current_board = 0; + /* + * If !command_set, then -u will display the nodes for the board. + * This emulates the previous behavior when -u is passed by itself + */ + int command_set = 0; + int open_needed = 0; long tmp; struct fw_eui64 eui; struct eui64 target; fwmethod *recvfn = NULL; +/* + * Holders for which functions + * to iterate through + */ + int display_board_only = 0; + int priority_budget = 0; + int display_crom = 0; + char *crom_string = NULL; + char *crom_string_hex = NULL; + int display_crom_hex = 0; + int adjust_gap_count = 0; + int reset_gap_count = 0; + int load_crom_from_file = 0; + int set_fwmem_target = 0; + long dump_phy_reg = 0; + int dump_topology = 0; + long send_link_on = 0; + int send_bus_reset = 0; + long send_reset_start = 0; + char *recv_data = NULL; + char *send_data = NULL; - fd = -1; - if (argc < 2) { - open_dev(&fd, devbase); - list_dev(fd); + for (current_board = 0; current_board < MAX_BOARDS; current_board++) { + snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board); + if (open_dev(&fd, devbase) < 0) { + return(0); + } + list_dev(fd); + close(fd); + fd = -1; + } } - - while ((ch = getopt(argc, argv, "M:f:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1) + /* + * Parse all command line options, then execute requested operations. + */ + while ((ch = getopt(argc, argv, "M:f:g:m:o:s:b:prtc:d:l:u:R:S:")) != -1) { switch(ch) { case 'b': - tmp = strtol(optarg, NULL, 0); - if (tmp < 0 || tmp > (long)0xffffffff) + priority_budget = strtol(optarg, NULL, 0); + if (priority_budget < 0 || priority_budget > (long)0xffffffff) errx(EX_USAGE, "invalid number: %s", optarg); - open_dev(&fd, devbase); - set_pri_req(fd, tmp); + command_set = 1; + open_needed = 1; + display_board_only = 0; break; case 'c': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - get_crom(fd, tmp, crom_buf, len); - show_crom(crom_buf); + crom_string = malloc(strlen(optarg)+1); + strcpy(crom_string, optarg); + display_crom = 1; + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'd': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - get_crom(fd, tmp, crom_buf, len); - dump_crom(crom_buf); + crom_string_hex = malloc(strlen(optarg)+1); + strcpy(crom_string_hex, optarg); + display_crom_hex = 1; + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'f': - tmp = strtol(optarg, NULL, 0); - open_dev(&fd, devbase); - send_phy_config(fd, tmp, -1); + adjust_gap_count = strtol(optarg, NULL, 0); + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'g': - tmp = strtol(optarg, NULL, 0); - open_dev(&fd, devbase); - send_phy_config(fd, -1, tmp); + reset_gap_count = strtol(optarg, NULL, 0); + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'l': + load_crom_from_file = 1; load_crom(optarg, crom_buf); - show_crom(crom_buf); + command_set = 1; + display_board_only = 0; break; case 'm': - if (eui64_hostton(optarg, &target) != 0 && - eui64_aton(optarg, &target) != 0) + set_fwmem_target = 1; + open_needed = 0; + command_set = 1; + display_board_only = 0; + if (eui64_hostton(optarg, &target) != 0 && + eui64_aton(optarg, &target) != 0) errx(EX_USAGE, "invalid target: %s", optarg); - eui.hi = ntohl(*(u_int32_t*)&(target.octet[0])); - eui.lo = ntohl(*(u_int32_t*)&(target.octet[4])); - sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi); - sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo); break; case 'o': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - send_link_on(fd, tmp); + send_link_on = str2node(fd, optarg); + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'p': - open_dev(&fd, devbase); - dump_phy_registers(fd); + dump_phy_reg = 1; + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'r': - open_dev(&fd, devbase); - if(ioctl(fd, FW_IBUSRST, &tmp) < 0) - err(1, "ioctl"); + send_bus_reset = 1; + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 's': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - reset_start(fd, tmp); + send_reset_start = str2node(fd, optarg); + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 't': - open_dev(&fd, devbase); - show_topology_map(fd); + dump_topology = 1; + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'u': - tmp = strtol(optarg, NULL, 0); - snprintf(devbase, sizeof(devbase), "/dev/fw%ld", tmp); - if (fd > 0) { - close(fd); - fd = -1; - } - if (argc == optind) { - open_dev(&fd, devbase); - list_dev(fd); - } + if(!command_set) + display_board_only = 1; + current_board = strtol(optarg, NULL, 0); + open_needed = 1; break; #define TAG (1<<6) #define CHANNEL 63 @@ -774,22 +822,151 @@ errx(EX_USAGE, "unrecognized method: %s", optarg); } + command_set = 1; + display_board_only = 0; break; case 'R': - open_dev(&fd, devbase); - if (recvfn == NULL) /* guess... */ - recvfn = detect_recv_fn(fd, TAG | CHANNEL); - close(fd); - fd = -1; - open_dev(&fd, devbase); - (*recvfn)(fd, optarg, TAG | CHANNEL, -1); + recv_data = malloc(strlen(optarg)+1); + strcpy(recv_data, optarg); + open_needed = 1; + command_set = 1; + display_board_only = 0; break; case 'S': - open_dev(&fd, devbase); - dvsend(fd, optarg, TAG | CHANNEL, -1); + send_data = malloc(strlen(optarg)+1); + strcpy(send_data, optarg); + open_needed = 1; + display_board_only = 0; break; default: usage(); + return 0; } + } /* end while */ + + /* + * If -u is passed, execute + * command for that card only. + * + * If -u is not passed, execute + * command for card 0 only. + * + */ + if(open_needed){ + snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board); + if (open_dev(&fd, devbase) < 0) + return(EIO); + } + /* + * display the nodes on this board "-u" + * only + */ + if (display_board_only) + list_dev(fd); + + /* + * dump_phy_reg "-p" + */ + if (dump_phy_reg) + dump_phy_registers(fd); + + /* + * send a BUS_RESET Event "-r" + */ + if (send_bus_reset) { + if(ioctl(fd, FW_IBUSRST, &tmp) < 0) + err(1, "ioctl"); + } + /* + * Print out the CROM for this node "-c" + */ + if (display_crom) { + tmp = str2node(fd, crom_string); + get_crom(fd, tmp, crom_buf, len); + show_crom(crom_buf); + free(crom_string); + } + /* + * Hex Dump the CROM for this node "-d" + */ + if (display_crom_hex) { + tmp = str2node(fd, crom_string_hex); + get_crom(fd, tmp, crom_buf_hex, len); + dump_crom(crom_buf_hex); + free(crom_string_hex); + } + /* + * Set Priority Budget to value for this node "-b" + */ + if (priority_budget) + set_pri_req(fd, priority_budget); + + /* + * Adjust the gap count for this card/bus to value "-f" + */ + if (adjust_gap_count) + send_phy_config(fd, adjust_gap_count, -1); + + /* + * Reset the gap count for this card/bus "-g" + */ + if (reset_gap_count) + send_phy_config(fd, -1, tmp); + + /* + * Load a CROM from a file "-l" + */ + if (load_crom_from_file) + show_crom(crom_buf); + /* + * Set the fwmem target for a node to argument "-m" + */ + if (set_fwmem_target) { + eui.hi = ntohl(*(u_int32_t*)&(target.octet[0])); + eui.lo = ntohl(*(u_int32_t*)&(target.octet[4])); + sysctl_set_int("hw.firewire.fwmem.eui64_hi", eui.hi); + sysctl_set_int("hw.firewire.fwmem.eui64_lo", eui.lo); + } + + /* + * Send a link on to this board/bus "-o" + */ + if (send_link_on) + link_on(fd, send_link_on); + + /* + * Send a reset start to this board/bus "-s" + */ + if (send_reset_start) + reset_start(fd, send_reset_start); + + /* + * Dump the node topology for this board/bus "-t" + */ + if (dump_topology) + show_topology_map(fd); + + /* + * Recieve data file from node "-R" + */ + if (recv_data != NULL){ + if (recvfn == NULL) /* guess... */ + recvfn = detect_recv_fn(fd, TAG | CHANNEL); + (*recvfn)(fd, recv_data, TAG | CHANNEL, -1); + free(recv_data); + } + + /* + * Send data file to node "-S" + */ + if (send_data != NULL){ + dvsend(fd, send_data, TAG | CHANNEL, -1); + free(send_data); + } + + if (fd > 0) { + close(fd); + fd = -1; + } return 0; } --------------000909010602070306070603--