fwcontrol.c revision 117474
1108441Ssimokawa/* 2108441Ssimokawa * Copyright (C) 2002 3108441Ssimokawa * Hidetoshi Shimokawa. All rights reserved. 4108441Ssimokawa * 5108441Ssimokawa * Redistribution and use in source and binary forms, with or without 6108441Ssimokawa * modification, are permitted provided that the following conditions 7108441Ssimokawa * are met: 8108441Ssimokawa * 1. Redistributions of source code must retain the above copyright 9108441Ssimokawa * notice, this list of conditions and the following disclaimer. 10108441Ssimokawa * 2. Redistributions in binary form must reproduce the above copyright 11108441Ssimokawa * notice, this list of conditions and the following disclaimer in the 12108441Ssimokawa * documentation and/or other materials provided with the distribution. 13108441Ssimokawa * 3. All advertising materials mentioning features or use of this software 14108441Ssimokawa * must display the following acknowledgement: 15108441Ssimokawa * 16108441Ssimokawa * This product includes software developed by Hidetoshi Shimokawa. 17108441Ssimokawa * 18108441Ssimokawa * 4. Neither the name of the author nor the names of its contributors 19108441Ssimokawa * may be used to endorse or promote products derived from this software 20108441Ssimokawa * without specific prior written permission. 21108441Ssimokawa * 22108441Ssimokawa * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23108441Ssimokawa * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24108441Ssimokawa * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25108441Ssimokawa * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26108441Ssimokawa * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27108441Ssimokawa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28108441Ssimokawa * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29108441Ssimokawa * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30108441Ssimokawa * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31108441Ssimokawa * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32108441Ssimokawa * SUCH DAMAGE. 33108441Ssimokawa * 34108441Ssimokawa * $FreeBSD: head/usr.sbin/fwcontrol/fwcontrol.c 117474 2003-07-12 09:36:53Z simokawa $ 35108441Ssimokawa */ 36108441Ssimokawa 37108441Ssimokawa#include <sys/param.h> 38108441Ssimokawa#include <sys/malloc.h> 39108441Ssimokawa#include <sys/socket.h> 40108441Ssimokawa#include <sys/ioctl.h> 41108441Ssimokawa#include <sys/errno.h> 42108441Ssimokawa#include <dev/firewire/firewire.h> 43108441Ssimokawa#include <dev/firewire/iec13213.h> 44108441Ssimokawa 45108441Ssimokawa#include <netinet/in.h> 46108441Ssimokawa#include <fcntl.h> 47108441Ssimokawa#include <stdio.h> 48108441Ssimokawa#include <err.h> 49108441Ssimokawa#include <stdlib.h> 50108441Ssimokawa#include <string.h> 51108441Ssimokawa#include <unistd.h> 52108441Ssimokawa 53109737Ssimokawaextern int dvrecv(int, char *, char, int); 54109737Ssimokawaextern int dvsend(int, char *, char, int); 55109737Ssimokawa 56108657Ssimokawastatic void 57108441Ssimokawausage(void) 58108441Ssimokawa{ 59109787Ssimokawa fprintf(stderr, 60114217Ssimokawa "fwcontrol [-g gap_count] [-o node] [-b pri_req] [-c node]" 61114217Ssimokawa " [-r] [-t] [-d node] [-l file] [-R file] [-S file]\n" 62114217Ssimokawa "\t-g: broadcast gap_count by phy_config packet\n" 63114217Ssimokawa "\t-o: send link-on packet to the node\n" 64114217Ssimokawa "\t-s: write RESET_START register on the node\n" 65114217Ssimokawa "\t-b: set PRIORITY_BUDGET register on all supported nodes\n" 66114217Ssimokawa "\t-c: read configuration ROM\n" 67114217Ssimokawa "\t-r: bus reset\n" 68114217Ssimokawa "\t-t: read topology map\n" 69114217Ssimokawa "\t-d: hex dump of configuration ROM\n" 70114217Ssimokawa "\t-l: load and parse hex dump file of configuration ROM\n" 71114217Ssimokawa "\t-R: Receive DV stream\n" 72114217Ssimokawa "\t-S: Send DV stream\n"); 73108441Ssimokawa exit(0); 74108441Ssimokawa} 75108441Ssimokawa 76109814Ssimokawastatic struct fw_devlstreq * 77109814Ssimokawaget_dev(int fd) 78108441Ssimokawa{ 79109814Ssimokawa struct fw_devlstreq *data; 80109814Ssimokawa 81109814Ssimokawa data = (struct fw_devlstreq *)malloc(sizeof(struct fw_devlstreq)); 82109814Ssimokawa if (data == NULL) 83109814Ssimokawa err(1, "malloc"); 84108441Ssimokawa if( ioctl(fd, FW_GDEVLST, data) < 0) { 85108441Ssimokawa err(1, "ioctl"); 86108441Ssimokawa } 87109814Ssimokawa return data; 88108441Ssimokawa} 89108441Ssimokawa 90108657Ssimokawastatic void 91108441Ssimokawalist_dev(int fd) 92108441Ssimokawa{ 93109814Ssimokawa struct fw_devlstreq *data; 94109814Ssimokawa struct fw_devinfo *devinfo; 95108441Ssimokawa int i; 96108441Ssimokawa 97109814Ssimokawa data = get_dev(fd); 98109814Ssimokawa printf("%d devices (info_len=%d)\n", data->n, data->info_len); 99110578Ssimokawa printf("node EUI64 status\n"); 100109814Ssimokawa for (i = 0; i < data->info_len; i++) { 101109814Ssimokawa devinfo = &data->dev[i]; 102110578Ssimokawa printf("%4d %08x%08x %6d\n", 103110578Ssimokawa (devinfo->status || i == 0) ? devinfo->dst : -1, 104109814Ssimokawa devinfo->eui.hi, 105109814Ssimokawa devinfo->eui.lo, 106109814Ssimokawa devinfo->status 107108441Ssimokawa ); 108108441Ssimokawa } 109109814Ssimokawa free((void *)data); 110108441Ssimokawa} 111108441Ssimokawa 112108657Ssimokawastatic u_int32_t 113108441Ssimokawaread_write_quad(int fd, struct fw_eui64 eui, u_int32_t addr_lo, int read, u_int32_t data) 114108441Ssimokawa{ 115108441Ssimokawa struct fw_asyreq *asyreq; 116108441Ssimokawa u_int32_t *qld, res; 117108441Ssimokawa 118108441Ssimokawa asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16); 119108441Ssimokawa asyreq->req.len = 16; 120114217Ssimokawa#if 0 121114217Ssimokawa asyreq->req.type = FWASREQNODE; 122114217Ssimokawa asyreq->pkt.mode.rreqq.dst = FWLOCALBUS | node; 123114217Ssimokawa#else 124108441Ssimokawa asyreq->req.type = FWASREQEUI; 125108441Ssimokawa asyreq->req.dst.eui = eui; 126108441Ssimokawa#endif 127108441Ssimokawa asyreq->pkt.mode.rreqq.tlrt = 0; 128108441Ssimokawa if (read) 129108441Ssimokawa asyreq->pkt.mode.rreqq.tcode = FWTCODE_RREQQ; 130108441Ssimokawa else 131108441Ssimokawa asyreq->pkt.mode.rreqq.tcode = FWTCODE_WREQQ; 132108441Ssimokawa 133113584Ssimokawa asyreq->pkt.mode.rreqq.dest_hi = 0xffff; 134113584Ssimokawa asyreq->pkt.mode.rreqq.dest_lo = addr_lo; 135108441Ssimokawa 136108441Ssimokawa qld = (u_int32_t *)&asyreq->pkt; 137108441Ssimokawa if (!read) 138108441Ssimokawa asyreq->pkt.mode.wreqq.data = data; 139108441Ssimokawa 140108441Ssimokawa if (ioctl(fd, FW_ASYREQ, asyreq) < 0) { 141108441Ssimokawa err(1, "ioctl"); 142108441Ssimokawa } 143108441Ssimokawa res = qld[3]; 144108441Ssimokawa free(asyreq); 145108441Ssimokawa if (read) 146108441Ssimokawa return ntohl(res); 147108441Ssimokawa else 148108441Ssimokawa return 0; 149108441Ssimokawa} 150108657Ssimokawa 151108657Ssimokawastatic void 152108441Ssimokawasend_phy_config(int fd, int root_node, int gap_count) 153108441Ssimokawa{ 154108441Ssimokawa struct fw_asyreq *asyreq; 155108441Ssimokawa 156108441Ssimokawa asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12); 157108441Ssimokawa asyreq->req.len = 12; 158108441Ssimokawa asyreq->req.type = FWASREQNODE; 159108441Ssimokawa asyreq->pkt.mode.ld[0] = 0; 160108441Ssimokawa asyreq->pkt.mode.ld[1] = 0; 161108441Ssimokawa asyreq->pkt.mode.common.tcode = FWTCODE_PHY; 162108441Ssimokawa if (root_node >= 0) 163113584Ssimokawa asyreq->pkt.mode.ld[1] |= (root_node & 0x3f) << 24 | 1 << 23; 164108441Ssimokawa if (gap_count >= 0) 165113584Ssimokawa asyreq->pkt.mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16; 166108441Ssimokawa asyreq->pkt.mode.ld[2] = ~asyreq->pkt.mode.ld[1]; 167108441Ssimokawa 168108441Ssimokawa printf("send phy_config root_node=%d gap_count=%d\n", 169108441Ssimokawa root_node, gap_count); 170108441Ssimokawa 171114274Ssimokawa if (ioctl(fd, FW_ASYREQ, asyreq) < 0) 172108441Ssimokawa err(1, "ioctl"); 173114274Ssimokawa free(asyreq); 174108441Ssimokawa} 175108441Ssimokawa 176108657Ssimokawastatic void 177114217Ssimokawasend_link_on(int fd, int node) 178114217Ssimokawa{ 179114217Ssimokawa struct fw_asyreq *asyreq; 180114217Ssimokawa 181114217Ssimokawa asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12); 182114217Ssimokawa asyreq->req.len = 12; 183114217Ssimokawa asyreq->req.type = FWASREQNODE; 184114217Ssimokawa asyreq->pkt.mode.common.tcode = FWTCODE_PHY; 185114217Ssimokawa asyreq->pkt.mode.ld[1] |= (1 << 30) | ((node & 0x3f) << 24); 186114217Ssimokawa asyreq->pkt.mode.ld[2] = ~asyreq->pkt.mode.ld[1]; 187114217Ssimokawa 188114274Ssimokawa if (ioctl(fd, FW_ASYREQ, asyreq) < 0) 189114217Ssimokawa err(1, "ioctl"); 190114274Ssimokawa free(asyreq); 191114217Ssimokawa} 192114217Ssimokawa 193114217Ssimokawastatic void 194114217Ssimokawareset_start(int fd, int node) 195114217Ssimokawa{ 196114217Ssimokawa struct fw_asyreq *asyreq; 197114217Ssimokawa 198114217Ssimokawa asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16); 199114217Ssimokawa asyreq->req.len = 16; 200114217Ssimokawa asyreq->req.type = FWASREQNODE; 201114217Ssimokawa asyreq->pkt.mode.wreqq.dst = FWLOCALBUS | (node & 0x3f); 202114217Ssimokawa asyreq->pkt.mode.wreqq.tlrt = 0; 203114217Ssimokawa asyreq->pkt.mode.wreqq.tcode = FWTCODE_WREQQ; 204114217Ssimokawa 205114217Ssimokawa asyreq->pkt.mode.wreqq.dest_hi = 0xffff; 206114217Ssimokawa asyreq->pkt.mode.wreqq.dest_lo = 0xf0000000 | RESET_START; 207114217Ssimokawa 208114217Ssimokawa asyreq->pkt.mode.wreqq.data = htonl(0x1); 209114217Ssimokawa 210114274Ssimokawa if (ioctl(fd, FW_ASYREQ, asyreq) < 0) 211114217Ssimokawa err(1, "ioctl"); 212114274Ssimokawa free(asyreq); 213114217Ssimokawa} 214114217Ssimokawa 215114217Ssimokawastatic void 216108441Ssimokawaset_pri_req(int fd, int pri_req) 217108441Ssimokawa{ 218109814Ssimokawa struct fw_devlstreq *data; 219109814Ssimokawa struct fw_devinfo *devinfo; 220108441Ssimokawa u_int32_t max, reg, old; 221108441Ssimokawa int i; 222108441Ssimokawa 223109814Ssimokawa data = get_dev(fd); 224108441Ssimokawa#define BUGET_REG 0xf0000218 225109814Ssimokawa for (i = 0; i < data->info_len; i++) { 226109814Ssimokawa devinfo = &data->dev[i]; 227109814Ssimokawa if (!devinfo->status) 228108441Ssimokawa continue; 229109814Ssimokawa reg = read_write_quad(fd, devinfo->eui, BUGET_REG, 1, 0); 230108441Ssimokawa printf("%d %08x:%08x, %08x", 231109814Ssimokawa devinfo->dst, devinfo->eui.hi, devinfo->eui.lo, reg); 232108441Ssimokawa if (reg > 0 && pri_req >= 0) { 233108441Ssimokawa old = (reg & 0x3f); 234108441Ssimokawa max = (reg & 0x3f00) >> 8; 235108441Ssimokawa if (pri_req > max) 236108441Ssimokawa pri_req = max; 237108441Ssimokawa printf(" 0x%x -> 0x%x\n", old, pri_req); 238109814Ssimokawa read_write_quad(fd, devinfo->eui, BUGET_REG, 0, pri_req); 239108441Ssimokawa } else { 240108441Ssimokawa printf("\n"); 241108441Ssimokawa } 242108441Ssimokawa } 243109814Ssimokawa free((void *)data); 244108441Ssimokawa} 245108441Ssimokawa 246108657Ssimokawastatic void 247108657Ssimokawaparse_bus_info_block(u_int32_t *p, int info_len) 248108441Ssimokawa{ 249108441Ssimokawa int i; 250116141Ssimokawa struct bus_info *bi; 251108441Ssimokawa 252116141Ssimokawa bi = (struct bus_info *)p; 253116141Ssimokawa printf("bus_name: 0x%04x\n" 254116141Ssimokawa "irmc:%d cmc:%d isc:%d bmc:%d pmc:%d\n" 255116141Ssimokawa "cyc_clk_acc:%d max_rec:%d max_rom:%d\n" 256116141Ssimokawa "generation:%d link_spd:%d\n" 257116141Ssimokawa "EUI64: 0x%08x 0x%08x\n", 258116141Ssimokawa bi->bus_name, 259116141Ssimokawa bi->irmc, bi->cmc, bi->isc, bi->bmc, bi->pmc, 260116141Ssimokawa bi->cyc_clk_acc, bi->max_rec, bi->max_rom, 261116141Ssimokawa bi->generation, bi->link_spd, 262116141Ssimokawa bi->eui64.hi, bi->eui64.lo); 263108441Ssimokawa} 264108441Ssimokawa 265108657Ssimokawastatic int 266108441Ssimokawaget_crom(int fd, int node, void *crom_buf, int len) 267108441Ssimokawa{ 268108441Ssimokawa struct fw_crom_buf buf; 269109991Ssimokawa int i, error; 270109814Ssimokawa struct fw_devlstreq *data; 271108441Ssimokawa 272109814Ssimokawa data = get_dev(fd); 273108441Ssimokawa 274109814Ssimokawa for (i = 0; i < data->info_len; i++) { 275109814Ssimokawa if (data->dev[i].dst == node && data->dev[i].eui.lo != 0) 276108441Ssimokawa break; 277108441Ssimokawa } 278109814Ssimokawa if (i == data->info_len) 279109814Ssimokawa errx(1, "no such node %d.", node); 280109814Ssimokawa else 281109814Ssimokawa buf.eui = data->dev[i].eui; 282109814Ssimokawa free((void *)data); 283108441Ssimokawa 284108441Ssimokawa buf.len = len; 285108441Ssimokawa buf.ptr = crom_buf; 286117474Ssimokawa bzero(crom_buf, len); 287108441Ssimokawa if ((error = ioctl(fd, FW_GCROM, &buf)) < 0) { 288108441Ssimokawa err(1, "ioctl"); 289108441Ssimokawa } 290109814Ssimokawa 291108441Ssimokawa return error; 292108441Ssimokawa} 293108441Ssimokawa 294108657Ssimokawastatic void 295108441Ssimokawashow_crom(u_int32_t *crom_buf) 296108441Ssimokawa{ 297108441Ssimokawa int i; 298108441Ssimokawa struct crom_context cc; 299108441Ssimokawa char *desc, info[256]; 300108441Ssimokawa static char *key_types = "ICLD"; 301108441Ssimokawa struct csrreg *reg; 302108441Ssimokawa struct csrdirectory *dir; 303108441Ssimokawa struct csrhdr *hdr; 304113584Ssimokawa u_int16_t crc; 305108441Ssimokawa 306113584Ssimokawa printf("first quad: 0x%08x ", *crom_buf); 307108441Ssimokawa hdr = (struct csrhdr *)crom_buf; 308108441Ssimokawa if (hdr->info_len == 1) { 309108441Ssimokawa /* minimum ROM */ 310108441Ssimokawa struct csrreg *reg; 311108441Ssimokawa reg = (struct csrreg *)hdr; 312108441Ssimokawa printf("verndor ID: 0x%06x\n", reg->val); 313108441Ssimokawa return; 314108441Ssimokawa } 315113584Ssimokawa printf("info_len=%d crc_len=%d crc=0x%04x", 316113584Ssimokawa hdr->info_len, hdr->crc_len, hdr->crc); 317113584Ssimokawa crc = crom_crc(crom_buf+1, hdr->crc_len); 318113584Ssimokawa if (crc == hdr->crc) 319113584Ssimokawa printf("(OK)\n"); 320113584Ssimokawa else 321113584Ssimokawa printf("(NG)\n"); 322108441Ssimokawa parse_bus_info_block(crom_buf+1, hdr->info_len); 323108441Ssimokawa 324108441Ssimokawa crom_init_context(&cc, crom_buf); 325108441Ssimokawa dir = cc.stack[0].dir; 326113584Ssimokawa printf("root_directory: len=0x%04x(%d) crc=0x%04x", 327108441Ssimokawa dir->crc_len, dir->crc_len, dir->crc); 328113584Ssimokawa crc = crom_crc((u_int32_t *)&dir->entry[0], dir->crc_len); 329113584Ssimokawa if (crc == dir->crc) 330113584Ssimokawa printf("(OK)\n"); 331113584Ssimokawa else 332113584Ssimokawa printf("(NG)\n"); 333108657Ssimokawa if (dir->crc_len < 1) 334108657Ssimokawa return; 335108441Ssimokawa while (cc.depth >= 0) { 336108441Ssimokawa desc = crom_desc(&cc, info, sizeof(info)); 337108441Ssimokawa reg = crom_get(&cc); 338108441Ssimokawa for (i = 0; i < cc.depth; i++) 339108441Ssimokawa printf("\t"); 340108441Ssimokawa printf("%02x(%c:%02x) %06x %s: %s\n", 341108441Ssimokawa reg->key, 342108441Ssimokawa key_types[(reg->key & CSRTYPE_MASK)>>6], 343108441Ssimokawa reg->key & CSRKEY_MASK, reg->val, 344108441Ssimokawa desc, info); 345108441Ssimokawa crom_next(&cc); 346108441Ssimokawa } 347108441Ssimokawa} 348108441Ssimokawa 349108441Ssimokawa#define DUMP_FORMAT "%08x %08x %08x %08x %08x %08x %08x %08x\n" 350108441Ssimokawa 351108657Ssimokawastatic void 352108441Ssimokawadump_crom(u_int32_t *p) 353108441Ssimokawa{ 354108441Ssimokawa int len=1024, i; 355108441Ssimokawa 356108441Ssimokawa for (i = 0; i < len/(4*8); i ++) { 357108441Ssimokawa printf(DUMP_FORMAT, 358108441Ssimokawa p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 359108441Ssimokawa p += 8; 360108441Ssimokawa } 361108441Ssimokawa} 362108441Ssimokawa 363108657Ssimokawastatic void 364108441Ssimokawaload_crom(char *filename, u_int32_t *p) 365108441Ssimokawa{ 366108441Ssimokawa FILE *file; 367108441Ssimokawa int len=1024, i; 368108441Ssimokawa 369108441Ssimokawa if ((file = fopen(filename, "r")) == NULL) 370108441Ssimokawa err(1, "load_crom"); 371108441Ssimokawa for (i = 0; i < len/(4*8); i ++) { 372108441Ssimokawa fscanf(file, DUMP_FORMAT, 373108441Ssimokawa p, p+1, p+2, p+3, p+4, p+5, p+6, p+7); 374108441Ssimokawa p += 8; 375108441Ssimokawa } 376108441Ssimokawa} 377108441Ssimokawa 378108441Ssimokawastatic void 379108441Ssimokawashow_topology_map(int fd) 380108441Ssimokawa{ 381108441Ssimokawa struct fw_topology_map *tmap; 382108441Ssimokawa union fw_self_id sid; 383108441Ssimokawa int i; 384108441Ssimokawa static char *port_status[] = {" ", "-", "P", "C"}; 385108441Ssimokawa static char *pwr_class[] = {" 0W", "15W", "30W", "45W", 386108441Ssimokawa "-1W", "-2W", "-5W", "-9W"}; 387108441Ssimokawa static char *speed[] = {"S100", "S200", "S400", "S800"}; 388108441Ssimokawa tmap = malloc(sizeof(struct fw_topology_map)); 389108441Ssimokawa if (tmap == NULL) 390108441Ssimokawa return; 391108441Ssimokawa if (ioctl(fd, FW_GTPMAP, tmap) < 0) { 392108441Ssimokawa err(1, "ioctl"); 393108441Ssimokawa } 394108441Ssimokawa printf("crc_len: %d generation:%d node_count:%d sid_count:%d\n", 395108441Ssimokawa tmap->crc_len, tmap->generation, 396108441Ssimokawa tmap->node_count, tmap->self_id_count); 397108441Ssimokawa printf("id link gap_cnt speed delay cIRM power port0 port1 port2" 398108441Ssimokawa " ini more\n"); 399108441Ssimokawa for (i = 0; i < tmap->crc_len - 2; i++) { 400108441Ssimokawa sid = tmap->self_id[i]; 401108441Ssimokawa if (sid.p0.sequel) { 402108441Ssimokawa printf("%02d sequel packet\n", sid.p0.phy_id); 403108441Ssimokawa continue; 404108441Ssimokawa } 405110070Ssimokawa printf("%02d %2d %2d %4s %d %d %3s" 406108441Ssimokawa " %s %s %s %d %d\n", 407108441Ssimokawa sid.p0.phy_id, 408108441Ssimokawa sid.p0.link_active, 409108441Ssimokawa sid.p0.gap_count, 410108441Ssimokawa speed[sid.p0.phy_speed], 411108441Ssimokawa sid.p0.phy_delay, 412108441Ssimokawa sid.p0.contender, 413108441Ssimokawa pwr_class[sid.p0.power_class], 414108441Ssimokawa port_status[sid.p0.port0], 415108441Ssimokawa port_status[sid.p0.port1], 416108441Ssimokawa port_status[sid.p0.port2], 417108441Ssimokawa sid.p0.initiated_reset, 418108441Ssimokawa sid.p0.more_packets 419108441Ssimokawa ); 420108441Ssimokawa } 421108441Ssimokawa free(tmap); 422108441Ssimokawa} 423108441Ssimokawa 424108441Ssimokawaint 425108441Ssimokawamain(int argc, char **argv) 426108441Ssimokawa{ 427109991Ssimokawa char devname[256]; 428108441Ssimokawa u_int32_t crom_buf[1024/4]; 429109991Ssimokawa int fd, i, tmp, ch, len=1024; 430108441Ssimokawa 431109991Ssimokawa for (i = 0; i < 4; i++) { 432109991Ssimokawa snprintf(devname, sizeof(devname), "/dev/fw%d", i); 433109991Ssimokawa if ((fd = open(devname, O_RDWR)) >= 0) 434109991Ssimokawa break; 435109991Ssimokawa } 436109991Ssimokawa if (fd < 0) 437108441Ssimokawa err(1, "open"); 438108441Ssimokawa 439108441Ssimokawa if (argc < 2) { 440108441Ssimokawa list_dev(fd); 441108441Ssimokawa } 442108441Ssimokawa 443114217Ssimokawa while ((ch = getopt(argc, argv, "g:o:s:b:rtc:d:l:R:S:")) != -1) 444108441Ssimokawa switch(ch) { 445108441Ssimokawa case 'g': 446108441Ssimokawa tmp = strtol(optarg, NULL, 0); 447108441Ssimokawa send_phy_config(fd, -1, tmp); 448108441Ssimokawa break; 449114217Ssimokawa case 'o': 450114217Ssimokawa tmp = strtol(optarg, NULL, 0); 451114217Ssimokawa send_link_on(fd, tmp); 452114217Ssimokawa break; 453114217Ssimokawa case 's': 454114217Ssimokawa tmp = strtol(optarg, NULL, 0); 455114217Ssimokawa reset_start(fd, tmp); 456114217Ssimokawa break; 457108441Ssimokawa case 'b': 458108441Ssimokawa tmp = strtol(optarg, NULL, 0); 459108441Ssimokawa set_pri_req(fd, tmp); 460108441Ssimokawa break; 461108441Ssimokawa case 'r': 462108441Ssimokawa if(ioctl(fd, FW_IBUSRST, &tmp) < 0) 463108441Ssimokawa err(1, "ioctl"); 464108441Ssimokawa break; 465108441Ssimokawa case 't': 466108441Ssimokawa show_topology_map(fd); 467108441Ssimokawa break; 468108441Ssimokawa case 'c': 469108441Ssimokawa tmp = strtol(optarg, NULL, 0); 470108441Ssimokawa get_crom(fd, tmp, crom_buf, len); 471108441Ssimokawa show_crom(crom_buf); 472108441Ssimokawa break; 473108441Ssimokawa case 'd': 474108441Ssimokawa tmp = strtol(optarg, NULL, 0); 475108441Ssimokawa get_crom(fd, tmp, crom_buf, len); 476108441Ssimokawa dump_crom(crom_buf); 477108441Ssimokawa break; 478108441Ssimokawa case 'l': 479108441Ssimokawa load_crom(optarg, crom_buf); 480108441Ssimokawa show_crom(crom_buf); 481108441Ssimokawa break; 482109737Ssimokawa#define TAG (1<<6) 483109737Ssimokawa#define CHANNEL 63 484109737Ssimokawa case 'R': 485109737Ssimokawa dvrecv(fd, optarg, TAG | CHANNEL, -1); 486109737Ssimokawa break; 487109737Ssimokawa case 'S': 488109737Ssimokawa dvsend(fd, optarg, TAG | CHANNEL, -1); 489109737Ssimokawa break; 490108441Ssimokawa default: 491108441Ssimokawa usage(); 492108441Ssimokawa } 493108441Ssimokawa return 0; 494108441Ssimokawa} 495