From owner-freebsd-firewire@FreeBSD.ORG Fri Aug 29 21:18:12 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 DEF3C106566C for ; Fri, 29 Aug 2008 21:18:12 +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 AAD5D8FC0C for ; Fri, 29 Aug 2008 21:18:12 +0000 (UTC) (envelope-from sbruno@miralink.com) Received: from localhost (localhost.localdomain [127.0.0.1]) by plato.miralink.com (Postfix) with ESMTP id 20E3A1A91B6; Fri, 29 Aug 2008 14:08:26 -0700 (PDT) X-Virus-Scanned: amavisd-new at X-Spam-Flag: NO X-Spam-Score: -4.356 X-Spam-Level: X-Spam-Status: No, score=-4.356 tagged_above=-10 required=6.6 tests=[ALL_TRUSTED=-1.8, AWL=0.043, 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 HqAM-fqgoEja; Fri, 29 Aug 2008 14:08:25 -0700 (PDT) Received: from [10.0.0.40] (iago.office.miralink.com [10.0.0.40]) by plato.miralink.com (Postfix) with ESMTP id EC2191A91A0; Fri, 29 Aug 2008 14:08:24 -0700 (PDT) Message-ID: <48B86793.6080404@miralink.com> Date: Fri, 29 Aug 2008 14:18:11 -0700 From: Sean Bruno User-Agent: Thunderbird 2.0.0.16 (X11/20080723) MIME-Version: 1.0 To: freebsd-firewire@freebsd.org, Dieter Content-Type: multipart/mixed; boundary="------------020006060308070201060902" Cc: Subject: New and improved? patch 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: Fri, 29 Aug 2008 21:18:13 -0000 This is a multi-part message in MIME format. --------------020006060308070201060902 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Freshly updated with new found information on what the heck -f -g actually do! See how this behaves for you. -- Sean Bruno MiraLink Corporation 6015 NE 80th Ave, Ste 100 Portland, OR 97218 Phone 503-621-5143 Fax 503-621-5199 MSN: sbruno@miralink.com Google: seanwbruno@gmail.com Yahoo: sean_bruno@yahoo.com --------------020006060308070201060902 Content-Type: text/plain; name="fwcontrol.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fwcontrol.diff" Index: fwcontrol.8 =================================================================== --- fwcontrol.8 (revision 182455) +++ fwcontrol.8 (working copy) @@ -59,7 +59,7 @@ The following options are available: .Bl -tag -width indent .It Fl u Ar bus_num -Specify the FireWire bus number to be operated on. +Specify the FireWire bus number to be operated on. Default is bus 0. .It Fl r Initiate bus reset. .It Fl t @@ -81,11 +81,14 @@ .It Fl f Ar node Force specified .Ar node -to be the root node on the next bus reset. +to be the root node on the next bus reset by sending a PHY config packet. +Valid values are 0 - 63. .It Fl g Ar gap_count -Broadcast +Broadcast new .Ar gap_count -by phy_config packet. +by sending a PHY_config packet. +By default this value is 63 on all nodes. +Valid values are 0 - 63. .It Fl i Ar pri_req Set the .Dv PRIORITY_BUDGET Index: fwcontrol.c =================================================================== --- fwcontrol.c (revision 182455) +++ fwcontrol.c (working copy) @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include "fwmethods.h" static void sysctl_set_int(const char *, int); @@ -64,21 +66,22 @@ usage(void) { fprintf(stderr, - "fwcontrol [-u bus_num] [-rt] [-f node] [-g gap_count] " - "[-o node] " - "[-b pri_req] [-c node] [-d node] [-l file] " - "[-R file] [-S file] [-m target]\n" + "fwcontrol [-u bus_num] [-prt] [-c node] [-d node] [-o node] [-s node]\n" + "\t [-l file] [-g gap_count] [-f force_root ] [-b pri_req]\n" + "\t [-M mode] [-R filename] [-S filename] [-m EUI64 | hostname]\n" "\t-u: specify bus number\n" - "\t-f: broadcast force_root by phy_config packet\n" - "\t-g: broadcast gap_count by phy_config packet\n" - "\t-o: send link-on packet to the node\n" - "\t-s: write RESET_START register on the node\n" - "\t-b: set PRIORITY_BUDGET register on all supported nodes\n" - "\t-c: read configuration ROM\n" + "\t-p: Display current PHY register settings\n" "\t-r: bus reset\n" "\t-t: read topology map\n" + "\t-c: read configuration ROM\n" "\t-d: hex dump of configuration ROM\n" + "\t-o: send link-on packet to the node\n" + "\t-s: write RESET_START register on the node\n" "\t-l: load and parse hex dump file of configuration ROM\n" + "\t-g: broadcast gap_count by phy_config packet\n" + "\t-f: broadcast force_root by phy_config packet\n" + "\t-b: set PRIORITY_BUDGET register on all supported nodes\n" + "\t-M: specify dv or mpeg\n" "\t-R: Receive DV or MPEG TS stream\n" "\t-S: Send DV stream\n" "\t-m: set fwmem target\n"); @@ -92,18 +95,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"); + err(EX_SOFTWARE, "%s: data malloc", __func__); if( ioctl(fd, FW_GDEVLST, data) < 0) { - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); } - return data; } static int @@ -130,17 +129,25 @@ 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)); + if (data == NULL) + err(EX_SOFTWARE, "%s: data malloc", __func__); + 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 +165,10 @@ char addr[EUI64_SIZ], hostname[40]; int i; - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + if (data == NULL) + err(EX_SOFTWARE, "%s:data malloc", __func__); + 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++) { @@ -184,6 +194,8 @@ u_int32_t *qld, res; asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16); + if (asyreq == NULL) + err(EX_SOFTWARE, "%s:asyreq malloc", __func__); asyreq->req.len = 16; #if 0 asyreq->req.type = FWASREQNODE; @@ -206,7 +218,7 @@ asyreq->pkt.mode.wreqq.data = htonl(data); if (ioctl(fd, FW_ASYREQ, asyreq) < 0) { - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); } res = qld[3]; free(asyreq); @@ -216,37 +228,56 @@ return 0; } +/* + * Send a PHY Config Packet + * ieee 1394a-2005 4.3.4.3 + * + * Message ID Root ID R T Gap Count + * 00(2 bits) (6 bits) 1 1 (6 bits) + * + * if "R" is set, then Root ID will be the next + * root node upon the next bus reset. + * if "T" is set, then Gap Count will be the + * value that all nodes use for their Gap Count + * if "R" and "T" are not set, then this message + * is either ignored or interpreted as an extended + * PHY config Packet as per 1394a-2005 4.3.4.4 + */ static void send_phy_config(int fd, int root_node, int gap_count) { struct fw_asyreq *asyreq; asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12); + if (asyreq == NULL) + err(EX_SOFTWARE, "%s:asyreq malloc", __func__); asyreq->req.len = 12; asyreq->req.type = FWASREQNODE; asyreq->pkt.mode.ld[0] = 0; asyreq->pkt.mode.ld[1] = 0; asyreq->pkt.mode.common.tcode = FWTCODE_PHY; if (root_node >= 0) - asyreq->pkt.mode.ld[1] |= (root_node & 0x3f) << 24 | 1 << 23; + asyreq->pkt.mode.ld[1] |= ((root_node << 24) | (1 << 23)); if (gap_count >= 0) - asyreq->pkt.mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16; + asyreq->pkt.mode.ld[1] |= ((1 << 22) | (gap_count << 16)); asyreq->pkt.mode.ld[2] = ~asyreq->pkt.mode.ld[1]; printf("send phy_config root_node=%d gap_count=%d\n", root_node, gap_count); if (ioctl(fd, FW_ASYREQ, asyreq) < 0) - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); free(asyreq); } static void -send_link_on(int fd, int node) +link_on(int fd, int node) { struct fw_asyreq *asyreq; asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12); + if (asyreq == NULL) + err(EX_SOFTWARE, "%s:asyreq malloc", __func__); asyreq->req.len = 12; asyreq->req.type = FWASREQNODE; asyreq->pkt.mode.common.tcode = FWTCODE_PHY; @@ -254,7 +285,7 @@ asyreq->pkt.mode.ld[2] = ~asyreq->pkt.mode.ld[1]; if (ioctl(fd, FW_ASYREQ, asyreq) < 0) - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); free(asyreq); } @@ -264,6 +295,8 @@ struct fw_asyreq *asyreq; asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16); + if (asyreq == NULL) + err(EX_SOFTWARE, "%s:asyreq malloc", __func__); asyreq->req.len = 16; asyreq->req.type = FWASREQNODE; asyreq->pkt.mode.wreqq.dst = FWLOCALBUS | (node & 0x3f); @@ -276,7 +309,7 @@ asyreq->pkt.mode.wreqq.data = htonl(0x1); if (ioctl(fd, FW_ASYREQ, asyreq) < 0) - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); free(asyreq); } @@ -290,7 +323,10 @@ u_int32_t max, reg, old; int i; - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + if (data == NULL) + err(EX_SOFTWARE, "%s:data malloc", __func__); + get_dev(fd, data); #define BUGET_REG 0xf0000218 for (i = 0; i < data->info_len; i++) { devinfo = &data->dev[i]; @@ -344,7 +380,10 @@ int i, error; struct fw_devlstreq *data; - data = get_dev(fd); + data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); + if (data == NULL) + err(EX_SOFTWARE, "%s:data malloc", __func__); + get_dev(fd, data); for (i = 0; i < data->info_len; i++) { if (data->dev[i].dst == node && data->dev[i].eui.lo != 0) @@ -360,7 +399,7 @@ buf.ptr = crom_buf; bzero(crom_buf, len); if ((error = ioctl(fd, FW_GCROM, &buf)) < 0) { - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); } return error; @@ -469,9 +508,9 @@ static const char *speed[] = {"S100", "S200", "S400", "S800"}; tmap = malloc(sizeof(struct fw_topology_map)); if (tmap == NULL) - return; + err(EX_SOFTWARE, "%s:tmap malloc", __func__); if (ioctl(fd, FW_GTPMAP, tmap) < 0) { - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); } printf("crc_len: %d generation:%d node_count:%d sid_count:%d\n", tmap->crc_len, tmap->generation, @@ -512,7 +551,7 @@ for (i = 0; i < len; i++) { reg.addr = offset + i; if (ioctl(fd, FWOHCI_RDPHYREG, ®) < 0) - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); buf[i] = (u_int8_t) reg.data; printf("0x%02x ", reg.data); } @@ -527,7 +566,7 @@ reg.addr = 0x7; reg.data = ((page & 7) << 5) | (port & 0xf); if (ioctl(fd, FWOHCI_WRPHYREG, ®) < 0) - err(1, "ioctl"); + err(EX_IOERR, "%s: ioctl", __func__); read_phy_registers(fd, buf, 8, 8); } @@ -590,22 +629,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 @@ -625,25 +658,40 @@ u_int32_t *ptr; struct ciphdr *ciph; fwmethod *retfn; +#define RECV_NUM_PACKET 16 +#define RECV_PACKET_SZ 1024 bufreq.rx.nchunk = 8; - bufreq.rx.npacket = 16; - bufreq.rx.psize = 1024; + bufreq.rx.npacket = RECV_NUM_PACKET; + bufreq.rx.psize = RECV_PACKET_SZ; bufreq.tx.nchunk = 0; bufreq.tx.npacket = 0; bufreq.tx.psize = 0; if (ioctl(fd, FW_SSTBUF, &bufreq) < 0) - err(1, "ioctl FW_SSTBUF"); + err(EX_IOERR, "%s: ioctl FW_SSTBUF", __func__); isoreq.ch = ich & 0x3f; isoreq.tag = (ich >> 6) & 3; if (ioctl(fd, FW_SRSTREAM, &isoreq) < 0) - err(1, "ioctl FW_SRSTREAM"); + err(EX_IOERR, "%s: ioctl FW_SRSTREAM", __func__); - buf = (char *)malloc(1024*16); - len = read(fd, buf, 1024*16); + buf = (char *)malloc(RECV_NUM_PACKET * RECV_PACKET_SZ); + if (buf == NULL) + err(EX_SOFTWARE, "%s:buf malloc", __func__); + /* + * fwdev.c seems to return EIO on error and + * the return value of the last uiomove + * on success. For now, checking that the + * return is not less than zero should be + * sufficient. fwdev.c::fw_read() should + * return the total length read, not the value + * of the last uiomove(). + */ + len = read(fd, buf, RECV_NUM_PACKET * RECV_PACKET_SZ); + if (len < 0) + err(EX_IOERR, "%s: error reading from device\n", __func__); ptr = (u_int32_t *) buf; ciph = (struct ciphdr *)(ptr + 1); @@ -666,102 +714,168 @@ 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; + int32_t 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 + */ + bool command_set = false; + bool open_needed = false; long tmp; struct fw_eui64 eui; struct eui64 target; fwmethod *recvfn = NULL; +/* + * Holders for which functions + * to iterate through + */ + bool display_board_only = false; + bool display_crom = false; + bool send_bus_reset = false; + bool display_crom_hex = false; + bool load_crom_from_file = false; + bool set_fwmem_target = false; + bool dump_topology = false; + bool dump_phy_reg = false; - fd = -1; + int32_t priority_budget = -1; + int32_t set_root_node = -1; + int32_t set_gap_count = -1; + int32_t send_link_on = -1; + int32_t send_reset_start = -1; + char *crom_string = NULL; + char *crom_string_hex = NULL; + char *recv_data = NULL; + char *send_data = NULL; + 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) { + if (current_board == 0) { + usage(); + } + return(EIO); + } + 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) - errx(EX_USAGE, "invalid number: %s", optarg); - open_dev(&fd, devbase); - set_pri_req(fd, tmp); + priority_budget = strtol(optarg, NULL, 0); + if (priority_budget < 0 || priority_budget > INT32_MAX) + errx(EX_USAGE, "%s: invalid number: %s", __func__, optarg); + command_set = true; + open_needed = true; + display_board_only = false; 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); + if (crom_string == NULL) + err(EX_SOFTWARE, "%s:crom_string malloc", __func__); + if ( (strtol(crom_string, NULL, 0) < 0) || strtol(crom_string, NULL, 0) > MAX_BOARDS) + err(EX_USAGE, "%s:Invalid value for node", __func__); + strcpy(crom_string, optarg); + display_crom = 1; + open_needed = true; + command_set = true; + display_board_only = false; 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); + if (crom_string_hex == NULL) + err(EX_SOFTWARE, "%s:crom_string_hex malloc", __func__); + strcpy(crom_string_hex, optarg); + display_crom_hex = 1; + open_needed = true; + command_set = true; + display_board_only = false; break; case 'f': - tmp = strtol(optarg, NULL, 0); - open_dev(&fd, devbase); - send_phy_config(fd, tmp, -1); +#define MAX_PHY_CONFIG 0x3f + set_root_node = strtol(optarg, NULL, 0); + if ( (set_root_node < 0) || (set_root_node > MAX_PHY_CONFIG) ) + err(EX_USAGE, "%s:set_root_node out of range", __func__); + open_needed = true; + command_set = true; + display_board_only = false; break; case 'g': - tmp = strtol(optarg, NULL, 0); - open_dev(&fd, devbase); - send_phy_config(fd, -1, tmp); + set_gap_count = strtol(optarg, NULL, 0); + if ( (set_gap_count < 0) || (set_gap_count > MAX_PHY_CONFIG) ) + err(EX_USAGE, "%s:set_gap_count out of range", __func__); + open_needed = true; + command_set = true; + display_board_only = false; break; case 'l': + load_crom_from_file = 1; load_crom(optarg, crom_buf); - show_crom(crom_buf); + command_set = true; + display_board_only = false; break; case 'm': - 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); + set_fwmem_target = 1; + open_needed = 0; + command_set = true; + display_board_only = false; + if (eui64_hostton(optarg, &target) != 0 && + eui64_aton(optarg, &target) != 0) + err(EX_USAGE, "%s: invalid target: %s", __func__, optarg); break; case 'o': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - send_link_on(fd, tmp); + send_link_on = str2node(fd, optarg); + if ( (send_link_on < 0) || (send_link_on > INT32_MAX) ) + err(EX_USAGE, "%s: node out of range: %s\n",__func__, optarg); + open_needed = true; + command_set = true; + display_board_only = false; break; case 'p': - open_dev(&fd, devbase); - dump_phy_registers(fd); + dump_phy_reg = 1; + open_needed = true; + command_set = true; + display_board_only = false; break; case 'r': - open_dev(&fd, devbase); - if(ioctl(fd, FW_IBUSRST, &tmp) < 0) - err(1, "ioctl"); + send_bus_reset = 1; + open_needed = true; + command_set = true; + display_board_only = false; break; case 's': - open_dev(&fd, devbase); - tmp = str2node(fd, optarg); - reset_start(fd, tmp); + send_reset_start = str2node(fd, optarg); + if ( (send_reset_start < 0) || (send_reset_start > INT32_MAX) ) + err(EX_USAGE, "%s: node out of range: %s\n", __func__, optarg); + open_needed = true; + command_set = true; + display_board_only = false; break; case 't': - open_dev(&fd, devbase); - show_topology_map(fd); + dump_topology = 1; + open_needed = true; + command_set = true; + display_board_only = false; 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 = true; + current_board = strtol(optarg, NULL, 0); + open_needed = true; break; -#define TAG (1<<6) -#define CHANNEL 63 case 'M': switch (optarg[0]) { case 'm': @@ -774,22 +888,164 @@ errx(EX_USAGE, "unrecognized method: %s", optarg); } + command_set = true; + display_board_only = false; 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); + if (recv_data == NULL) + err(EX_SOFTWARE, "%s:recv_data malloc", __func__); + strcpy(recv_data, optarg); + open_needed = false; + command_set = true; + display_board_only = false; break; case 'S': - open_dev(&fd, devbase); - dvsend(fd, optarg, TAG | CHANNEL, -1); + send_data = malloc(strlen(optarg)+1); + if (send_data == NULL) + err(EX_SOFTWARE, "%s:send_data malloc", __func__); + strcpy(send_data, optarg); + open_needed = true; + command_set = true; + display_board_only = false; 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) { + errx(EX_IOERR, "%s: Error opening board #%d\n", __func__, current_board); + } + } + /* + * 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(EX_IOERR, "%s: ioctl", __func__); + } + /* + * 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 >= 0) + set_pri_req(fd, priority_budget); + + /* + * Explicitly set the root node of this bus to value "-f" + */ + if (set_root_node >= 0) + send_phy_config(fd, set_root_node, -1); + + /* + * Set the gap count for this card/bus "-g" + */ + if (set_gap_count >= 0) + send_phy_config(fd, -1, set_gap_count); + + /* + * 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 >= 0) + link_on(fd, send_link_on); + + /* + * Send a reset start to this board/bus "-s" + */ + if (send_reset_start >= 0) + 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" + */ +#define TAG (1<<6) +#define CHANNEL 63 + if (recv_data != NULL){ + if (recvfn == NULL) { /* guess... */ + recvfn = detect_recv_fn(fd, TAG | CHANNEL); + close(fd); + } + snprintf(devbase, sizeof(devbase), "%s%d", device_string, current_board); + if (open_dev(&fd, devbase) < 0) + errx(EX_IOERR, "%s: Error opening board #%d in recv_data\n", __func__, current_board); + (*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; } --------------020006060308070201060902--