From owner-svn-src-projects@FreeBSD.ORG Sat Feb 28 17:57:09 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 61F271065679; Sat, 28 Feb 2009 17:57:09 +0000 (UTC) (envelope-from jb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4730A8FC30; Sat, 28 Feb 2009 17:57:09 +0000 (UTC) (envelope-from jb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1SHv9vK017145; Sat, 28 Feb 2009 17:57:09 GMT (envelope-from jb@svn.freebsd.org) Received: (from jb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1SHv9dm017140; Sat, 28 Feb 2009 17:57:09 GMT (envelope-from jb@svn.freebsd.org) Message-Id: <200902281757.n1SHv9dm017140@svn.freebsd.org> From: John Birrell Date: Sat, 28 Feb 2009 17:57:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189182 - projects/jbuild/sys/dev/firewire X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Feb 2009 17:57:20 -0000 Author: jb Date: Sat Feb 28 17:57:08 2009 New Revision: 189182 URL: http://svn.freebsd.org/changeset/base/189182 Log: MFC Modified: projects/jbuild/sys/dev/firewire/firewire.c projects/jbuild/sys/dev/firewire/firewire.h projects/jbuild/sys/dev/firewire/fwohci.c projects/jbuild/sys/dev/firewire/fwohci_pci.c projects/jbuild/sys/dev/firewire/fwohcireg.h projects/jbuild/sys/dev/firewire/fwohcivar.h projects/jbuild/sys/dev/firewire/fwphyreg.h projects/jbuild/sys/dev/firewire/if_fwe.c projects/jbuild/sys/dev/firewire/if_fwip.c projects/jbuild/sys/dev/firewire/sbp.c Modified: projects/jbuild/sys/dev/firewire/firewire.c ============================================================================== --- projects/jbuild/sys/dev/firewire/firewire.c Sat Feb 28 17:56:25 2009 (r189181) +++ projects/jbuild/sys/dev/firewire/firewire.c Sat Feb 28 17:57:08 2009 (r189182) @@ -77,7 +77,7 @@ struct crom_src_buf { struct crom_chunk hw; }; -int firewire_debug=0, try_bmr=1, hold_count=3; +int firewire_debug=0, try_bmr=1, hold_count=0; SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0, "FireWire driver debug flag"); SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem"); @@ -430,6 +430,31 @@ firewire_attach(device_t dev) fwdev_makedev(sc); + fc->crom_src_buf = (struct crom_src_buf *)malloc( + sizeof(struct crom_src_buf), + M_FW, M_NOWAIT | M_ZERO); + if (fc->crom_src_buf == NULL) { + device_printf(fc->dev, "%s: Malloc Failure crom src buff\n", __func__); + return ENOMEM; + } + fc->topology_map = (struct fw_topology_map *)malloc( + sizeof(struct fw_topology_map), + M_FW, M_NOWAIT | M_ZERO); + if (fc->topology_map == NULL) { + device_printf(fc->dev, "%s: Malloc Failure topology map\n", __func__); + free(fc->crom_src_buf, M_FW); + return ENOMEM; + } + fc->speed_map = (struct fw_speed_map *)malloc( + sizeof(struct fw_speed_map), + M_FW, M_NOWAIT | M_ZERO); + if (fc->speed_map == NULL) { + device_printf(fc->dev, "%s: Malloc Failure speed map\n", __func__); + free(fc->crom_src_buf, M_FW); + free(fc->topology_map, M_FW); + return ENOMEM; + } + mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF); mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF); CALLOUT_INIT(&fc->timeout_callout); @@ -451,7 +476,9 @@ firewire_attach(device_t dev) bus_generic_attach(dev); /* bus_reset */ + FW_GLOCK(fc); fw_busreset(fc, FWBUSNOTREADY); + FW_GUNLOCK(fc); fc->ibr(fc); return 0; @@ -642,11 +669,6 @@ fw_init_crom(struct firewire_comm *fc) { struct crom_src *src; - fc->crom_src_buf = (struct crom_src_buf *) - malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO); - if (fc->crom_src_buf == NULL) - return; - src = &fc->crom_src_buf->src; bzero(src, sizeof(struct crom_src)); @@ -663,7 +685,7 @@ fw_init_crom(struct firewire_comm *fc) src->businfo.cyc_clk_acc = 100; src->businfo.max_rec = fc->maxrec; src->businfo.max_rom = MAXROM_4; - src->businfo.generation = 1; + src->businfo.generation = 0; src->businfo.link_spd = fc->speed; src->businfo.eui64.hi = fc->eui.hi; @@ -682,9 +704,6 @@ fw_reset_crom(struct firewire_comm *fc) struct crom_src *src; struct crom_chunk *root; - if (fc->crom_src_buf == NULL) - fw_init_crom(fc); - buf = fc->crom_src_buf; src = fc->crom_src; root = fc->crom_root; @@ -715,18 +734,18 @@ fw_busreset(struct firewire_comm *fc, ui struct firewire_dev_comm *fdc; struct crom_src *src; device_t *devlistp; - void *newrom; int i, devcnt; - switch(fc->status){ - case FWBUSMGRELECT: + FW_GLOCK_ASSERT(fc); + if (fc->status == FWBUSMGRELECT) callout_stop(&fc->bmr_callout); - break; - default: - break; - } + fc->status = new_status; fw_reset_csr(fc); + + if (fc->status == FWBUSNOTREADY) + fw_init_crom(fc); + fw_reset_crom(fc); if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) { @@ -739,19 +758,19 @@ fw_busreset(struct firewire_comm *fc, ui free(devlistp, M_TEMP); } - newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO); src = &fc->crom_src_buf->src; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) { - /* bump generation and reload */ - src->businfo.generation ++; - /* generation must be between 0x2 and 0xF */ - if (src->businfo.generation < 2) - src->businfo.generation ++; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - bcopy(newrom, (void *)fc->config_rom, CROMSIZE); - } - free(newrom, M_FW); + /* + * If the old config rom needs to be overwritten, + * bump the businfo.generation indicator to + * indicate that we need to be reprobed + */ + if (bcmp(src, fc->config_rom, CROMSIZE) != 0) { + /* generation is a 2 bit field */ + /* valid values are only from 0 - 3 */ + src->businfo.generation = 1; + bcopy(src, (void *)fc->config_rom, CROMSIZE); + } else + src->businfo.generation = 0; } /* Call once after reboot */ @@ -807,13 +826,7 @@ void fw_init(struct firewire_comm *fc) fc->ir[i]->maxq = FWMAXQUEUE; fc->it[i]->maxq = FWMAXQUEUE; } -/* Initialize csr registers */ - fc->topology_map = (struct fw_topology_map *)malloc( - sizeof(struct fw_topology_map), - M_FW, M_NOWAIT | M_ZERO); - fc->speed_map = (struct fw_speed_map *)malloc( - sizeof(struct fw_speed_map), - M_FW, M_NOWAIT | M_ZERO); + CSRARC(fc, TOPO_MAP) = 0x3f1 << 16; CSRARC(fc, TOPO_MAP + 4) = 1; CSRARC(fc, SPED_MAP) = 0x3f1 << 16; @@ -1244,12 +1257,11 @@ fw_phy_config(struct firewire_comm *fc, fp->mode.common.tcode |= FWTCODE_PHY; if (firewire_debug) - printf("send phy_config root_node=%d gap_count=%d\n", - root_node, gap_count); + device_printf(fc->bdev, "%s: root_node=%d gap_count=%d\n", + __func__, root_node, gap_count); fw_asyreq(fc, -1, xfer); } -#if 0 /* * Dump self ID. */ @@ -1258,14 +1270,30 @@ fw_print_sid(uint32_t sid) { union fw_self_id *s; s = (union fw_self_id *) &sid; - printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d" - " p0:%d p1:%d p2:%d i:%d m:%d\n", - s->p0.phy_id, s->p0.link_active, s->p0.gap_count, - s->p0.phy_speed, s->p0.phy_delay, s->p0.contender, - s->p0.power_class, s->p0.port0, s->p0.port1, - s->p0.port2, s->p0.initiated_reset, s->p0.more_packets); + if ( s->p0.sequel ) { + if ( s->p1.sequence_num == FW_SELF_ID_PAGE0 ) { + printf("node:%d p3:%d p4:%d p5:%d p6:%d p7:%d" + "p8:%d p9:%d p10:%d\n", + s->p1.phy_id, s->p1.port3, s->p1.port4, + s->p1.port5, s->p1.port6, s->p1.port7, + s->p1.port8, s->p1.port9, s->p1.port10); + } else if (s->p2.sequence_num == FW_SELF_ID_PAGE1 ){ + printf("node:%d p11:%d p12:%d p13:%d p14:%d p15:%d\n", + s->p2.phy_id, s->p2.port11, s->p2.port12, + s->p2.port13, s->p2.port14, s->p2.port15); + } else { + printf("node:%d Unknown Self ID Page number %d\n", + s->p1.phy_id, s->p1.sequence_num); + } + } else { + printf("node:%d link:%d gap:%d spd:%d con:%d pwr:%d" + " p0:%d p1:%d p2:%d i:%d m:%d\n", + s->p0.phy_id, s->p0.link_active, s->p0.gap_count, + s->p0.phy_speed, s->p0.contender, + s->p0.power_class, s->p0.port0, s->p0.port1, + s->p0.port2, s->p0.initiated_reset, s->p0.more_packets); + } } -#endif /* * To receive self ID. @@ -1289,7 +1317,8 @@ void fw_sidrcv(struct firewire_comm* fc, self_id = &fc->topology_map->self_id[0]; for(i = 0; i < fc->sid_cnt; i ++){ if (sid[1] != ~sid[0]) { - printf("fw_sidrcv: invalid self-id packet\n"); + device_printf(fc->bdev, "%s: ERROR invalid self-id packet\n", + __func__); sid += 2; continue; } @@ -1298,9 +1327,8 @@ void fw_sidrcv(struct firewire_comm* fc, if(self_id->p0.sequel == 0){ fc->topology_map->node_count ++; c_port = 0; -#if 0 - fw_print_sid(sid[0]); -#endif + if (firewire_debug) + fw_print_sid(sid[0]); node = self_id->p0.phy_id; if(fc->max_node < node){ fc->max_node = self_id->p0.phy_id; @@ -1335,7 +1363,6 @@ void fw_sidrcv(struct firewire_comm* fc, self_id++; fc->topology_map->self_id_count ++; } - device_printf(fc->bdev, "%d nodes", fc->max_node + 1); /* CRC */ fc->topology_map->crc = fw_crc16( (uint32_t *)&fc->topology_map->generation, @@ -1354,16 +1381,11 @@ void fw_sidrcv(struct firewire_comm* fc, bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4); fc->max_hop = fc->max_node - i_branch; - printf(", maxhop <= %d", fc->max_hop); - - if(fc->irm == -1 ){ - printf(", Not found IRM capable node"); - }else{ - printf(", cable IRM = %d", fc->irm); - if (fc->irm == fc->nodeid) - printf(" (me)"); - } - printf("\n"); + device_printf(fc->bdev, "%d nodes, maxhop <= %d %s irm(%d) %s\n", + fc->max_node + 1, fc->max_hop, + (fc->irm == -1) ? "Not IRM capable" : "cable IRM", + fc->irm, + (fc->irm == fc->nodeid) ? " (me) " : ""); if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) { if (fc->irm == fc->nodeid) { @@ -1395,10 +1417,23 @@ fw_bus_probe(struct firewire_comm *fc) fc->status = FWBUSEXPLORE; /* Invalidate all devices, just after bus reset. */ + if (firewire_debug) + device_printf(fc->bdev, "%s:" + "iterate and invalidate all nodes\n", + __func__); STAILQ_FOREACH(fwdev, &fc->devices, link) if (fwdev->status != FWDEVINVAL) { fwdev->status = FWDEVINVAL; fwdev->rcnt = 0; + if (firewire_debug) + device_printf(fc->bdev, "%s:" + "Invalidate Dev ID: %08x%08x\n", + __func__, fwdev->eui.hi, fwdev->eui.lo); + } else { + if (firewire_debug) + device_printf(fc->bdev, "%s:" + "Dev ID: %08x%08x already invalid\n", + __func__, fwdev->eui.hi, fwdev->eui.lo); } splx(s); @@ -1407,13 +1442,13 @@ fw_bus_probe(struct firewire_comm *fc) static int fw_explore_read_quads(struct fw_device *fwdev, int offset, - uint32_t *quad, int n) + uint32_t *quad, int length) { struct fw_xfer *xfer; uint32_t tmp; int i, error; - for (i = 0; i < n; i ++, offset += sizeof(uint32_t)) { + for (i = 0; i < length; i ++, offset += sizeof(uint32_t)) { xfer = fwmem_read_quad(fwdev, NULL, -1, 0xffff, 0xf0000000 | offset, (void *)&tmp, fw_xferwake); @@ -1490,7 +1525,8 @@ fw_explore_node(struct fw_device *dfwdev uint32_t *csr; struct csrhdr *hdr; struct bus_info *binfo; - int err, node, spd; + int err, node; + uint32_t speed_test = 0; fc = dfwdev->fc; csr = dfwdev->csrrom; @@ -1498,28 +1534,48 @@ fw_explore_node(struct fw_device *dfwdev /* First quad */ err = fw_explore_read_quads(dfwdev, CSRROMOFF, &csr[0], 1); - if (err) + if (err) { + device_printf(fc->bdev, "%s: node%d: explore_read_quads failure\n", + __func__, node); + dfwdev->status = FWDEVINVAL; return (-1); + } hdr = (struct csrhdr *)&csr[0]; if (hdr->info_len != 4) { if (firewire_debug) - printf("node%d: wrong bus info len(%d)\n", - node, hdr->info_len); + device_printf(fc->bdev, "%s: node%d: wrong bus info len(%d)\n", + __func__, node, hdr->info_len); + dfwdev->status = FWDEVINVAL; return (-1); } /* bus info */ err = fw_explore_read_quads(dfwdev, CSRROMOFF + 0x04, &csr[1], 4); - if (err) + if (err) { + device_printf(fc->bdev, "%s: node%d: error reading 0x04\n", + __func__, node); + dfwdev->status = FWDEVINVAL; return (-1); + } binfo = (struct bus_info *)&csr[1]; if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) { - if (firewire_debug) - printf("node%d: invalid bus name 0x%08x\n", - node, binfo->bus_name); + device_printf(fc->bdev, "%s: node%d: invalid bus name 0x%08x\n", + __func__, node, binfo->bus_name); + dfwdev->status = FWDEVINVAL; return (-1); } - spd = fc->speed_map->speed[fc->nodeid][node]; + + if (firewire_debug) + device_printf(fc->bdev, "%s: node(%d) BUS INFO BLOCK:\n" + "irmc(%d) cmc(%d) isc(%d) bmc(%d) pmc(%d) " + "cyc_clk_acc(%d) max_rec(%d) max_rom(%d) " + "generation(%d) link_spd(%d)\n", + __func__, node, + binfo->irmc, binfo->cmc, binfo->isc, + binfo->bmc, binfo->pmc, binfo->cyc_clk_acc, + binfo->max_rec, binfo->max_rom, + binfo->generation, binfo->link_spd); + STAILQ_FOREACH(fwdev, &fc->devices, link) if (FW_EUI64_EQUAL(fwdev->eui, binfo->eui64)) break; @@ -1528,12 +1584,46 @@ fw_explore_node(struct fw_device *dfwdev fwdev = malloc(sizeof(struct fw_device), M_FW, M_NOWAIT | M_ZERO); if (fwdev == NULL) { - if (firewire_debug) - printf("node%d: no memory\n", node); + device_printf(fc->bdev, "%s: node%d: no memory\n", + __func__, node); return (-1); } fwdev->fc = fc; fwdev->eui = binfo->eui64; + /* + * Pre-1394a-2000 didn't have link_spd in + * the Bus Info block, so try and use the + * speed map value. + * 1394a-2000 compliant devices only use + * the Bus Info Block link spd value, so + * ignore the speed map alltogether. SWB + */ + if ( binfo->link_spd == FWSPD_S100 /* 0 */) { + device_printf(fc->bdev, "%s" + "Pre 1394a-2000 detected\n", + __func__); + fwdev->speed = fc->speed_map->speed[fc->nodeid][node]; + } else + fwdev->speed = binfo->link_spd; + /* + * Test this speed with a read to the CSRROM. + * If it fails, slow down the speed and retry. + */ + while (fwdev->speed > 0) { + err = fw_explore_read_quads(fwdev, CSRROMOFF, + &speed_test, 1); + if (err) + fwdev->speed--; + else + break; + + } + if (fwdev->speed != binfo->link_spd) + device_printf(fc->bdev, "%s: fwdev->speed(%s)" + " set lower than binfo->link_spd(%s)\n", + __func__, + linkspeed[fwdev->speed], + linkspeed[binfo->link_spd]); /* inesrt into sorted fwdev list */ pfwdev = NULL; STAILQ_FOREACH(tfwdev, &fc->devices, link) { @@ -1549,17 +1639,16 @@ fw_explore_node(struct fw_device *dfwdev STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link); device_printf(fc->bdev, "New %s device ID:%08x%08x\n", - linkspeed[spd], + linkspeed[fwdev->speed], fwdev->eui.hi, fwdev->eui.lo); } fwdev->dst = node; fwdev->status = FWDEVINIT; - fwdev->speed = spd; /* unchanged ? */ if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { if (firewire_debug) - printf("node%d: crom unchanged\n", node); + device_printf(fc->dev, "node%d: crom unchanged\n", node); return (0); } @@ -1615,12 +1704,22 @@ fw_explore(struct firewire_comm *fc) for (node = 0; node <= fc->max_node; node ++) { /* We don't probe myself and linkdown nodes */ - if (node == fc->nodeid) + if (node == fc->nodeid) { + if (firewire_debug) + device_printf(fc->bdev, "%s:" + "found myself node(%d) fc->nodeid(%d) fc->max_node(%d)\n", + __func__, node, fc->nodeid, fc->max_node); continue; + } else if (firewire_debug) { + device_printf(fc->bdev, "%s:" + "node(%d) fc->max_node(%d) found\n", + __func__, node, fc->max_node); + } fwsid = fw_find_self_id(fc, node); if (!fwsid || !fwsid->p0.link_active) { if (firewire_debug) - printf("node%d: link down\n", node); + device_printf(fc->bdev, "%s: node%d: link down\n", + __func__, node); continue; } nodes[todo++] = node; @@ -1635,8 +1734,8 @@ fw_explore(struct firewire_comm *fc) if (err) nodes[todo2++] = nodes[i]; if (firewire_debug) - printf("%s: node %d, err = %d\n", - __FUNCTION__, node, err); + device_printf(fc->bdev, "%s: node %d, err = %d\n", + __func__, node, err); } todo = todo2; } @@ -1686,11 +1785,18 @@ fw_attach_dev(struct firewire_comm *fc) fwdev->status = FWDEVATTACHED; } else if (fwdev->status == FWDEVINVAL) { fwdev->rcnt ++; + if (firewire_debug) + device_printf(fc->bdev, "%s:" + "fwdev->rcnt(%d), hold_count(%d)\n", + __func__, fwdev->rcnt, hold_count); if (fwdev->rcnt > hold_count) { /* * Remove devices which have not been seen * for a while. */ + device_printf(fc->bdev, "%s:" + "Removing missing device ID:%08x%08x\n", + __func__, fwdev->eui.hi, fwdev->eui.lo); STAILQ_REMOVE(&fc->devices, fwdev, fw_device, link); free(fwdev, M_FW); @@ -1699,16 +1805,16 @@ fw_attach_dev(struct firewire_comm *fc) } err = device_get_children(fc->bdev, &devlistp, &devcnt); - if( err != 0 ) - return; - for( i = 0 ; i < devcnt ; i++){ - if (device_get_state(devlistp[i]) >= DS_ATTACHED) { - fdc = device_get_softc(devlistp[i]); - if (fdc->post_explore != NULL) - fdc->post_explore(fdc); + if( err == 0 ) { + for( i = 0 ; i < devcnt ; i++){ + if (device_get_state(devlistp[i]) >= DS_ATTACHED) { + fdc = device_get_softc(devlistp[i]); + if (fdc->post_explore != NULL) + fdc->post_explore(fdc); + } } + free(devlistp, M_TEMP); } - free(devlistp, M_TEMP); return; } @@ -1788,8 +1894,9 @@ fw_rcv_copy(struct fw_rcv_buf *rb) for (i = 0; i < rb->nvec; i++, rb->vec++) { len = MIN(rb->vec->iov_len, plen); if (res < len) { - printf("rcv buffer(%d) is %d bytes short.\n", - rb->xfer->recv.pay_len, len - res); + device_printf(rb->fc->bdev, "%s:" + " rcv buffer(%d) is %d bytes short.\n", + __func__, rb->xfer->recv.pay_len, len - res); len = res; } bcopy(rb->vec->iov_base, p, len); @@ -1836,13 +1943,15 @@ fw_rcv(struct fw_rcv_buf *rb) rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src, fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tcode); if(rb->xfer == NULL) { - printf("fw_rcv: unknown response " - "%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n", - tcode_str[tcode], tcode, - fp->mode.hdr.src, - fp->mode.hdr.tlrt >> 2, - fp->mode.hdr.tlrt & 3, - fp->mode.rresq.data); + device_printf(rb->fc->bdev, "%s: " + "unknown response " + "%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n", + __func__, + tcode_str[tcode], tcode, + fp->mode.hdr.src, + fp->mode.hdr.tlrt >> 2, + fp->mode.hdr.tlrt & 3, + fp->mode.rresq.data); #if 0 printf("try ad-hoc work around!!\n"); rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src, @@ -1874,7 +1983,8 @@ fw_rcv(struct fw_rcv_buf *rb) #endif break; default: - printf("unexpected flag 0x%02x\n", rb->xfer->flag); + device_printf(rb->fc->bdev, "%s: " + "unexpected flag 0x%02x\n", __func__, rb->xfer->flag); } return; case FWTCODE_WREQQ: @@ -1885,17 +1995,23 @@ fw_rcv(struct fw_rcv_buf *rb) bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi, fp->mode.rreqq.dest_lo); if(bind == NULL){ - printf("Unknown service addr 0x%04x:0x%08x %s(%x)" + device_printf(rb->fc->bdev, "%s: " + "Unknown service addr 0x%04x:0x%08x %s(%x)" #if defined(__DragonFly__) || __FreeBSD_version < 500000 - " src=0x%x data=%lx\n", + " src=0x%x data=%lx\n", #else - " src=0x%x data=%x\n", + " src=0x%x data=%x\n", #endif - fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo, - tcode_str[tcode], tcode, - fp->mode.hdr.src, ntohl(fp->mode.wreqq.data)); + __func__, + fp->mode.wreqq.dest_hi, + fp->mode.wreqq.dest_lo, + tcode_str[tcode], tcode, + fp->mode.hdr.src, + ntohl(fp->mode.wreqq.data)); + if (rb->fc->status == FWBUSINIT) { - printf("fw_rcv: cannot respond(bus reset)!\n"); + device_printf(rb->fc->bdev, "%s: cannot respond(bus reset)!\n", + __func__); return; } rb->xfer = fw_xfer_alloc(M_FWXFER); @@ -1941,9 +2057,9 @@ fw_rcv(struct fw_rcv_buf *rb) len += rb->vec[i].iov_len; rb->xfer = STAILQ_FIRST(&bind->xferlist); if (rb->xfer == NULL) { -#if 1 - printf("Discard a packet for this bind.\n"); -#endif + device_printf(rb->fc->bdev, "%s: " + "Discard a packet for this bind.\n", + __func__); return; } STAILQ_REMOVE_HEAD(&bind->xferlist, link); @@ -1994,7 +2110,8 @@ fw_rcv(struct fw_rcv_buf *rb) } #endif default: - printf("fw_rcv: unknow tcode %d\n", tcode); + device_printf(rb->fc->bdev,"%s: unknown tcode %d\n", + __func__, tcode); break; } } @@ -2167,6 +2284,12 @@ fw_crc16(uint32_t *ptr, uint32_t len){ return((uint16_t) crc); } +/* + * Find the root node, if it is not + * Cycle Master Capable, then we should + * override this and become the Cycle + * Master + */ static int fw_bmr(struct firewire_comm *fc) { @@ -2191,13 +2314,13 @@ fw_bmr(struct firewire_comm *fc) } else cmstr = -1; - device_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID)); + device_printf(fc->bdev, "bus manager %d %s\n", + CSRARC(fc, BUS_MGR_ID), + (CSRARC(fc, BUS_MGR_ID) != fc->nodeid) ? "(me)" : ""); if(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) { /* We are not the bus manager */ - printf("\n"); return(0); } - printf("(me)\n"); /* Optimize gapcount */ if(fc->max_hop <= MAX_GAPHOP ) Modified: projects/jbuild/sys/dev/firewire/firewire.h ============================================================================== --- projects/jbuild/sys/dev/firewire/firewire.h Sat Feb 28 17:56:25 2009 (r189181) +++ projects/jbuild/sys/dev/firewire/firewire.h Sat Feb 28 17:57:08 2009 (r189182) @@ -99,9 +99,16 @@ struct fw_reg_req_t { #define FWRCODE_ER_TYPE 6 #define FWRCODE_ER_ADDR 7 +/* + * Defined 1394a-2000 + * Table 5B-1 + */ #define FWSPD_S100 0 #define FWSPD_S200 1 #define FWSPD_S400 2 +#define FWSPD_S800 3 +#define FWSPD_S1600 4 +#define FWSPD_S3200 5 #define FWP_TL_VALID (1 << 7) @@ -277,10 +284,18 @@ struct fw_devlstreq { struct fw_devinfo dev[FW_MAX_DEVLST]; }; +/* + * Defined in IEEE 1394a-2000 + * 4.3.4.1 + */ #define FW_SELF_ID_PORT_CONNECTED_TO_CHILD 3 #define FW_SELF_ID_PORT_CONNECTED_TO_PARENT 2 #define FW_SELF_ID_PORT_NOT_CONNECTED 1 #define FW_SELF_ID_PORT_NOT_EXISTS 0 + +#define FW_SELF_ID_PAGE0 0 +#define FW_SELF_ID_PAGE1 1 + #if BYTE_ORDER == BIG_ENDIAN union fw_self_id { struct { @@ -290,7 +305,7 @@ union fw_self_id { link_active:1, gap_count:6, phy_speed:2, - phy_delay:2, + reserved:2, contender:1, power_class:3, port0:2, @@ -305,18 +320,32 @@ union fw_self_id { phy_id:6, sequel:1, sequence_num:3, - :2, - porta:2, - portb:2, - portc:2, - portd:2, - porte:2, - portf:2, - portg:2, - porth:2, - :1, + reserved2:2, + port3:2, + port4:2, + port5:2, + port6:2, + port7:2, + port8:2, + port9:2, + port10:2, + reserved1:1, more_packets:1; } p1; + struct { + uint32_t + id:2, + phy_id:6, + sequel:1, + sequence_num:3, + :2, + port11:2, + port12:2, + port13:2, + port14:2, + port15:2, + :8; + } p2; }; #else union fw_self_id { @@ -328,7 +357,7 @@ union fw_self_id { port0:2, power_class:3, contender:1, - phy_delay:2, + reserved:2, phy_speed:2, gap_count:6, link_active:1, @@ -339,20 +368,34 @@ union fw_self_id { struct { uint32_t more_packets:1, reserved1:1, - porth:2, - portg:2, - portf:2, - porte:2, - portd:2, - portc:2, - portb:2, - porta:2, + port10:2, + port9:2, + port8:2, + port7:2, + port6:2, + port5:2, + port4:2, + port3:2, reserved2:2, sequence_num:3, sequel:1, phy_id:6, id:2; } p1; + struct { + uint32_t + reserved3:8, + port15:2, + port14:2, + port13:2, + port12:2, + port11:2, + reserved4:2, + sequence_num:3, + sequel:1, + phy_id:6, + id:2; + } p2; }; #endif Modified: projects/jbuild/sys/dev/firewire/fwohci.c ============================================================================== --- projects/jbuild/sys/dev/firewire/fwohci.c Sat Feb 28 17:56:25 2009 (r189181) +++ projects/jbuild/sys/dev/firewire/fwohci.c Sat Feb 28 17:57:08 2009 (r189182) @@ -306,8 +306,8 @@ fwohci_set_bus_manager(struct firewire_c if((bm & 0x3f) == 0x3f) bm = node; if (firewire_debug) - device_printf(sc->fc.dev, - "fw_set_bus_manager: %d->%d (loop=%d)\n", bm, node, i); + device_printf(sc->fc.dev, "%s: %d->%d (loop=%d)\n", + __func__, bm, node, i); return(bm); } @@ -332,7 +332,7 @@ again: } if(i >= MAX_RETRY) { if (firewire_debug) - device_printf(sc->fc.dev, "phy read failed(1).\n"); + device_printf(sc->fc.dev, "%s: failed(1).\n", __func__); if (++retry < MAX_RETRY) { DELAY(100); goto again; @@ -343,15 +343,16 @@ again: if ((stat & OHCI_INT_REG_FAIL) != 0 || ((fun >> PHYDEV_REGADDR) & 0xf) != addr) { if (firewire_debug) - device_printf(sc->fc.dev, "phy read failed(2).\n"); + device_printf(sc->fc.dev, "%s: failed(2).\n", __func__); if (++retry < MAX_RETRY) { DELAY(100); goto again; } } - if (firewire_debug || retry >= MAX_RETRY) + if (firewire_debug > 1 || retry >= MAX_RETRY) device_printf(sc->fc.dev, - "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry); + "%s:: 0x%x loop=%d, retry=%d\n", + __func__, addr, i, retry); #undef MAX_RETRY return((fun >> PHYDEV_RDDATA )& 0xff); } @@ -1003,7 +1004,7 @@ again: if (maxdesc < db_tr->dbcnt) { maxdesc = db_tr->dbcnt; if (firewire_debug) - device_printf(sc->fc.dev, "maxdesc: %d\n", maxdesc); + device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc); } /* last db */ LAST_DB(db_tr, db); @@ -1842,12 +1843,13 @@ fwohci_intr_core(struct fwohci_softc *sc struct firewire_comm *fc = (struct firewire_comm *)sc; uint32_t node_id, plen; + FW_GLOCK_ASSERT(fc); if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) { fc->status = FWBUSRESET; /* Disable bus reset interrupt until sid recv. */ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R); - device_printf(fc->dev, "BUS reset\n"); + device_printf(fc->dev, "%s: BUS reset\n", __func__); OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST); OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC); @@ -1884,10 +1886,11 @@ fwohci_intr_core(struct fwohci_softc *sc plen = OREAD(sc, OHCI_SID_CNT); fc->nodeid = node_id & 0x3f; - device_printf(fc->dev, "node_id=0x%08x, gen=%d, ", - node_id, (plen >> 16) & 0xff); + device_printf(fc->dev, "%s: node_id=0x%08x, SelfID Count=%d, ", + __func__, fc->nodeid, (plen >> 16) & 0xff); if (!(node_id & OHCI_NODE_VALID)) { - printf("Bus reset failure\n"); + device_printf(fc->dev, "%s: Bus reset failure\n", + __func__); goto sidout; } @@ -1996,9 +1999,11 @@ fwohci_task_busreset(void *arg, int pend { struct fwohci_softc *sc = (struct fwohci_softc *)arg; + FW_GLOCK(&sc->fc); fw_busreset(&sc->fc, FWBUSRESET); OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0])); OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2])); + FW_GUNLOCK(&sc->fc); } static void @@ -2010,6 +2015,10 @@ fwohci_task_sid(void *arg, int pending) int i, plen; + /* + * We really should have locking + * here. Not sure why it's not + */ plen = OREAD(sc, OHCI_SID_CNT); if (plen & OHCI_SID_ERR) { @@ -2029,14 +2038,13 @@ fwohci_task_sid(void *arg, int pending) } for (i = 0; i < plen / 4; i ++) buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i+1]); -#if 1 /* XXX needed?? */ + /* pending all pre-bus_reset packets */ fwohci_txd(sc, &sc->atrq); fwohci_txd(sc, &sc->atrs); fwohci_arcv(sc, &sc->arrs, -1); fwohci_arcv(sc, &sc->arrq, -1); fw_drain_txq(fc); -#endif fw_sidrcv(fc, buf, plen); free(buf, M_FW); } @@ -2061,6 +2069,7 @@ fwohci_check_stat(struct fwohci_softc *s { uint32_t stat, irstat, itstat; + FW_GLOCK_ASSERT(&sc->fc); stat = OREAD(sc, FWOHCI_INTSTAT); if (stat == 0xffffffff) { device_printf(sc->fc.dev, @@ -2090,29 +2099,24 @@ fwohci_check_stat(struct fwohci_softc *s return (FILTER_HANDLED); } -int -fwohci_filt(void *arg) -{ - struct fwohci_softc *sc = (struct fwohci_softc *)arg; - - if (!(sc->intmask & OHCI_INT_EN)) { - /* polling mode */ - return (FILTER_STRAY); - } - return (fwohci_check_stat(sc)); -} - void fwohci_intr(void *arg) { - fwohci_filt(arg); + struct fwohci_softc *sc = (struct fwohci_softc *)arg; + + FW_GLOCK(&sc->fc); + fwohci_check_stat(sc); + FW_GUNLOCK(&sc->fc); } void fwohci_poll(struct firewire_comm *fc, int quick, int count) { struct fwohci_softc *sc = (struct fwohci_softc *)fc; + + FW_GLOCK(fc); fwohci_check_stat(sc); + FW_GUNLOCK(fc); } static void @@ -2466,6 +2470,7 @@ fwohci_ibr(struct firewire_comm *fc) device_printf(fc->dev, "Initiate bus reset\n"); sc = (struct fwohci_softc *)fc; + FW_GLOCK(fc); /* * Make sure our cached values from the config rom are * initialised. @@ -2486,6 +2491,7 @@ fwohci_ibr(struct firewire_comm *fc) fun |= FW_PHY_ISBR | FW_PHY_RHB; fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun); #endif + FW_GUNLOCK(fc); } void @@ -2973,7 +2979,7 @@ err: db_tr = STAILQ_NEXT(db_tr, link); resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK; - } while (resCount == 0) + } printf(" done\n"); dbch->top = db_tr; dbch->buf_offset = dbch->xferq.psize - resCount; Modified: projects/jbuild/sys/dev/firewire/fwohci_pci.c ============================================================================== --- projects/jbuild/sys/dev/firewire/fwohci_pci.c Sat Feb 28 17:56:25 2009 (r189181) +++ projects/jbuild/sys/dev/firewire/fwohci_pci.c Sat Feb 28 17:57:08 2009 (r189182) @@ -334,14 +334,11 @@ fwohci_pci_attach(device_t self) return ENXIO; } - err = bus_setup_intr(self, sc->irq_res, - INTR_TYPE_NET | INTR_MPSAFE, -#if FWOHCI_INTFILT - fwohci_filt, NULL, sc, &sc->ih); -#else - NULL, (driver_intr_t *) fwohci_intr, sc, &sc->ih); -#endif + INTR_TYPE_NET | INTR_MPSAFE, + NULL, (driver_intr_t *) fwohci_intr, + sc, &sc->ih); + #if defined(__DragonFly__) || __FreeBSD_version < 500000 /* XXX splcam() should mask this irq for sbp.c*/ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***