From ea028a97eca8c07525da7487f7d0ee2e909f78b8 Mon Sep 17 00:00:00 2001 From: simokawa Date: Sat, 25 Jan 2003 14:47:33 +0000 Subject: [PATCH] Change API of FW_GDEVLST ioctl. - include information about itself. - define struct fw_devinfo and use it in struct fw_devlstreq. - unify EUI64 representation using struct fw_eui64. --- sys/dev/firewire/firewire.h | 24 +++++++----- sys/dev/firewire/firewirereg.h | 2 +- sys/dev/firewire/fwdev.c | 30 +++++++++------ sys/dev/firewire/fwohci.c | 19 ++++----- sys/dev/firewire/if_fwe.c | 15 +++++--- usr.sbin/fwcontrol/fwcontrol.c | 70 ++++++++++++++++++++-------------- 6 files changed, 92 insertions(+), 68 deletions(-) diff --git a/sys/dev/firewire/firewire.h b/sys/dev/firewire/firewire.h index 6ac583c73f06..e07dfd7e768d 100644 --- a/sys/dev/firewire/firewire.h +++ b/sys/dev/firewire/firewire.h @@ -310,6 +310,11 @@ struct fw_pkt { struct fw_eui64 { u_int32_t hi, lo; }; +#define FW_EUI64_BYTE(eui, x) \ + ((((x)<4)? \ + ((eui)->hi >> (8*(3-(x)))): \ + ((eui)->lo >> (8*(7-(x)))) \ + ) & 0xff) struct fw_asyreq { struct fw_asyreq_t{ @@ -328,11 +333,17 @@ struct fw_asyreq { u_int32_t data[512]; }; +struct fw_devinfo { + struct fw_eui64 eui; + u_int16_t dst; + u_int16_t status; +}; + +#define FW_MAX_DEVLST 70 struct fw_devlstreq { - int n; - struct fw_eui64 eui[64]; - u_int16_t dst[64]; - u_int16_t status[64]; + u_int16_t n; + u_int16_t info_len; + struct fw_devinfo dev[FW_MAX_DEVLST]; }; #define FW_SELF_ID_PORT_CONNECTED_TO_CHILD 3 @@ -430,11 +441,6 @@ struct fw_speed_map { u_int8_t speed[64][64]; }; -struct fw_map_buf { - int len; - void *ptr; -}; - struct fw_crom_buf { struct fw_eui64 eui; int len; diff --git a/sys/dev/firewire/firewirereg.h b/sys/dev/firewire/firewirereg.h index 05f6d3e27e1f..a2c994e6f40d 100644 --- a/sys/dev/firewire/firewirereg.h +++ b/sys/dev/firewire/firewirereg.h @@ -135,7 +135,7 @@ struct firewire_comm{ #define FWBUSEXPDONE 7 #define FWBUSCOMPLETION 10 int nisodma; - u_int8_t eui[8]; + struct fw_eui64 eui; STAILQ_HEAD(fw_queue, fw_xfer); struct fw_xferq *arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH]; diff --git a/sys/dev/firewire/fwdev.c b/sys/dev/firewire/fwdev.c index d096ba13d9ef..7233f353239d 100644 --- a/sys/dev/firewire/fwdev.c +++ b/sys/dev/firewire/fwdev.c @@ -531,15 +531,13 @@ fw_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, fw_proc *td) struct fw_xferq *ir, *it; struct fw_xfer *xfer; struct fw_pkt *fp; + struct fw_devinfo *devinfo; struct fw_devlstreq *fwdevlst = (struct fw_devlstreq *)data; struct fw_asyreq *asyreq = (struct fw_asyreq *)data; struct fw_isochreq *ichreq = (struct fw_isochreq *)data; struct fw_isobufreq *ibufreq = (struct fw_isobufreq *)data; struct fw_asybindreq *bindreq = (struct fw_asybindreq *)data; -#if 0 - struct fw_map_buf *map_buf = (struct fw_map_buf *)data; -#endif struct fw_crom_buf *crom_buf = (struct fw_crom_buf *)data; if (DEV_FWMEM(dev)) @@ -842,19 +840,27 @@ fw_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, fw_proc *td) err = fw_bindadd(sc->fc, fwb); break; case FW_GDEVLST: - i = 0; - for(fwdev = TAILQ_FIRST(&sc->fc->devices); fwdev != NULL; - fwdev = TAILQ_NEXT(fwdev, link)){ - if(i < fwdevlst->n){ - fwdevlst->dst[i] = fwdev->dst; - fwdevlst->status[i] = - (fwdev->status == FWDEVATTACHED)?1:0; - fwdevlst->eui[i].hi = fwdev->eui.hi; - fwdevlst->eui[i].lo = fwdev->eui.lo; + i = len = 1; + /* myself */ + devinfo = &fwdevlst->dev[0]; + devinfo->dst = sc->fc->nodeid; + devinfo->status = 0; /* XXX */ + devinfo->eui.hi = sc->fc->eui.hi; + devinfo->eui.lo = sc->fc->eui.lo; + for (fwdev = TAILQ_FIRST(&sc->fc->devices); fwdev != NULL; + fwdev = TAILQ_NEXT(fwdev, link)) { + if(len < FW_MAX_DEVLST){ + devinfo = &fwdevlst->dev[len++]; + devinfo->dst = fwdev->dst; + devinfo->status = + (fwdev->status == FWDEVINVAL)?0:1; + devinfo->eui.hi = fwdev->eui.hi; + devinfo->eui.lo = fwdev->eui.lo; } i++; } fwdevlst->n = i; + fwdevlst->info_len = len; break; case FW_GTPMAP: bcopy(sc->fc->topology_map, data, diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c index 94f763d7471c..ea6e3d2be69e 100644 --- a/sys/dev/firewire/fwohci.c +++ b/sys/dev/firewire/fwohci.c @@ -579,6 +579,7 @@ fwohci_init(struct fwohci_softc *sc, device_t dev) { int i; u_int32_t reg; + u_int8_t ui[8]; reg = OREAD(sc, OHCI_VERSION); device_printf(dev, "OHCI version %x.%x (ROM=%d)\n", @@ -682,19 +683,13 @@ fwohci_init(struct fwohci_softc *sc, device_t dev) if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0) return ENOMEM; - reg = OREAD(sc, FWOHCIGUID_H); - for( i = 0 ; i < 4 ; i ++){ - sc->fc.eui[3 - i] = reg & 0xff; - reg = reg >> 8; - } - reg = OREAD(sc, FWOHCIGUID_L); - for( i = 0 ; i < 4 ; i ++){ - sc->fc.eui[7 - i] = reg & 0xff; - reg = reg >> 8; - } + sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H); + sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L); + for( i = 0 ; i < 8 ; i ++) + ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i); device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - sc->fc.eui[0], sc->fc.eui[1], sc->fc.eui[2], sc->fc.eui[3], - sc->fc.eui[4], sc->fc.eui[5], sc->fc.eui[6], sc->fc.eui[7]); + ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]); + sc->fc.ioctl = fwohci_ioctl; sc->fc.cyctimer = fwohci_cyctimer; sc->fc.set_bmr = fwohci_set_bus_manager; diff --git a/sys/dev/firewire/if_fwe.c b/sys/dev/firewire/if_fwe.c index 5c777053163d..65658075fbae 100644 --- a/sys/dev/firewire/if_fwe.c +++ b/sys/dev/firewire/if_fwe.c @@ -146,6 +146,7 @@ fwe_attach(device_t dev) struct ifnet *ifp; int unit, s; u_char *eaddr; + struct fw_eui64 *eui; fwe = ((struct fwe_softc *)device_get_softc(dev)); unit = device_get_unit(dev); @@ -168,12 +169,14 @@ fwe_attach(device_t dev) #define LOCAL (0x02) #define GROUP (0x01) eaddr = &fwe->eth_softc.arpcom.ac_enaddr[0]; - eaddr[0] = (fwe->fd.fc->eui[0] | LOCAL) & ~GROUP; - eaddr[1] = fwe->fd.fc->eui[1]; - eaddr[2] = fwe->fd.fc->eui[2]; - eaddr[3] = fwe->fd.fc->eui[5]; - eaddr[4] = fwe->fd.fc->eui[6]; - eaddr[5] = fwe->fd.fc->eui[7]; + + eui = &fwe->fd.fc->eui; + eaddr[0] = (FW_EUI64_BYTE(eui, 0) | LOCAL) & ~GROUP; + eaddr[1] = FW_EUI64_BYTE(eui, 1); + eaddr[2] = FW_EUI64_BYTE(eui, 2); + eaddr[3] = FW_EUI64_BYTE(eui, 5); + eaddr[4] = FW_EUI64_BYTE(eui, 6); + eaddr[5] = FW_EUI64_BYTE(eui, 7); printf("if_fwe%d: Fake Ethernet address: " "%02x:%02x:%02x:%02x:%02x:%02x\n", unit, eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5]); diff --git a/usr.sbin/fwcontrol/fwcontrol.c b/usr.sbin/fwcontrol/fwcontrol.c index 08e0a5567a53..9783a57c71b3 100644 --- a/usr.sbin/fwcontrol/fwcontrol.c +++ b/usr.sbin/fwcontrol/fwcontrol.c @@ -72,32 +72,40 @@ usage(void) exit(0); } -static void -get_num_of_dev(int fd, struct fw_devlstreq *data) +static struct fw_devlstreq * +get_dev(int fd) { - data->n = 64; + 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 void list_dev(int fd) { - struct fw_devlstreq data; + struct fw_devlstreq *data; + struct fw_devinfo *devinfo; int i; - get_num_of_dev(fd, &data); - printf("%d devices\n", data.n); - for (i = 0; i < data.n; i++) { + data = get_dev(fd); + printf("%d devices (info_len=%d)\n", data->n, data->info_len); + for (i = 0; i < data->info_len; i++) { + devinfo = &data->dev[i]; printf("%d node %d eui:%08x%08x status:%d\n", i, - data.dst[i], - data.eui[i].hi, - data.eui[i].lo, - data.status[i] + devinfo->dst, + devinfo->eui.hi, + devinfo->eui.lo, + devinfo->status ); } + free((void *)data); } static u_int32_t @@ -165,29 +173,32 @@ send_phy_config(int fd, int root_node, int gap_count) static void set_pri_req(int fd, int pri_req) { - struct fw_devlstreq data; + struct fw_devlstreq *data; + struct fw_devinfo *devinfo; u_int32_t max, reg, old; int i; - get_num_of_dev(fd, &data); + data = get_dev(fd); #define BUGET_REG 0xf0000218 - for (i = 0; i < data.n; i++) { - if (!data.status[i]) + for (i = 0; i < data->info_len; i++) { + devinfo = &data->dev[i]; + if (!devinfo->status) continue; - reg = read_write_quad(fd, data.eui[i], BUGET_REG, 1, 0); + reg = read_write_quad(fd, devinfo->eui, BUGET_REG, 1, 0); printf("%d %08x:%08x, %08x", - data.dst[i], data.eui[i].hi, data.eui[i].lo, reg); + devinfo->dst, devinfo->eui.hi, devinfo->eui.lo, reg); if (reg > 0 && pri_req >= 0) { old = (reg & 0x3f); max = (reg & 0x3f00) >> 8; if (pri_req > max) pri_req = max; printf(" 0x%x -> 0x%x\n", old, pri_req); - read_write_quad(fd, data.eui[i], BUGET_REG, 0, pri_req); + read_write_quad(fd, devinfo->eui, BUGET_REG, 0, pri_req); } else { printf("\n"); } } + free((void *)data); } static void @@ -204,26 +215,29 @@ static int get_crom(int fd, int node, void *crom_buf, int len) { struct fw_crom_buf buf; - int i, error; - struct fw_devlstreq data; + int i, n, error; + struct fw_devlstreq *data; - get_num_of_dev(fd, &data); + data = get_dev(fd); - for (i = 0; i < data.n; i++) { - if (data.dst[i] == node && data.eui[i].lo != 0) + for (i = 0; i < data->info_len; i++) { + if (data->dev[i].dst == node && data->dev[i].eui.lo != 0) break; } - if (i != data.n) { - buf.eui = data.eui[i]; - } else { - err(1, "no such node: %d\n", node); - } + if (i == data->info_len) + errx(1, "no such node %d.", node); + else if (i == 0) + errx(1, "node %d is myself.", node); + else + buf.eui = data->dev[i].eui; + free((void *)data); buf.len = len; buf.ptr = crom_buf; if ((error = ioctl(fd, FW_GCROM, &buf)) < 0) { err(1, "ioctl"); } + return error; }