summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-05-11 10:32:20 +0000
committersimokawa <simokawa@FreeBSD.org>2003-05-11 10:32:20 +0000
commit2d4780fd3a431ff83b576afcefb980fc85f5b8b4 (patch)
treee60b707e5da4b6f508329c2595d16aa06694df0c
parentd8ecf9f7b2fdb9096f11169506a48b7dcd814d0b (diff)
downloadFreeBSD-src-2d4780fd3a431ff83b576afcefb980fc85f5b8b4.zip
FreeBSD-src-2d4780fd3a431ff83b576afcefb980fc85f5b8b4.tar.gz
- Use moderate gap counts listed in IEEE1394a.
- Simplify and correct the bus manager election process. - Check link_active when choosing cycle master. - Fix location of the cmr bit. Approved by: re (scottl)
-rw-r--r--sys/dev/firewire/firewire.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c
index 2b03ce0..6447d4c 100644
--- a/sys/dev/firewire/firewire.c
+++ b/sys/dev/firewire/firewire.c
@@ -113,9 +113,10 @@ static device_method_t firewire_methods[] = {
};
char linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"};
-#define MAX_GAPHOP 16
-u_int gap_cnt[] = {1, 1, 4, 6, 9, 12, 14, 17,
- 20, 23, 25, 28, 31, 33, 36, 39, 42};
+/* IEEE-1394a Table C-2 Gap count as a function of hops*/
+#define MAX_GAPHOP 15
+u_int gap_cnt[] = { 5, 5, 7, 8, 10, 13, 16, 18,
+ 21, 24, 26, 29, 32, 35, 37, 40};
extern struct cdevsw firewire_cdevsw;
@@ -1107,25 +1108,18 @@ void fw_sidrcv(struct firewire_comm* fc, u_int32_t *sid, u_int len)
printf("\n");
if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
- if (fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)) {
+ if (fc->irm == fc->nodeid) {
fc->status = FWBUSMGRDONE;
CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
+ fw_bmr(fc);
} else {
fc->status = FWBUSMGRELECT;
callout_reset(&fc->bmr_callout, hz/8,
(void *)fw_try_bmr, (void *)fc);
}
- } else {
+ } else
fc->status = FWBUSMGRDONE;
-#if 0
- device_printf(fc->bdev, "BMR = %x\n",
- CSRARC(fc, BUS_MGR_ID));
-#endif
- }
- if(fc->irm == ((CSRARC(fc, NODE_IDS) >> 16 ) & 0x3f)){
- /* I am BMGR */
- fw_bmr(fc);
- }
+
callout_reset(&fc->busprobe_callout, hz/4,
(void *)fw_bus_probe, (void *)fc);
}
@@ -1888,15 +1882,12 @@ fw_try_bmr_callback(struct fw_xfer *xfer)
bmr = fc->nodeid;
CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
- device_printf(fc->bdev, "new bus manager %d ",
- CSRARC(fc, BUS_MGR_ID));
- if(bmr == fc->nodeid){
- printf("(me)\n");
- fw_bmr(fc);
- }else{
- printf("\n");
- }
+ fw_xfer_free(xfer);
+ fw_bmr(fc);
+ return;
+
error:
+ device_printf(fc->bdev, "bus manager election failed\n");
fw_xfer_free(xfer);
}
@@ -2047,15 +2038,28 @@ fw_bmr(struct firewire_comm *fc)
/* Check to see if the current root node is cycle master capable */
self_id = &fc->topology_map->self_id[fc->max_node];
if (fc->max_node > 0) {
- if (self_id->p0.contender)
+ /* XXX check cmc bit of businfo block rather than contender */
+ if (self_id->p0.link_active && self_id->p0.contender)
cmstr = fc->max_node;
- else
- /* XXX shall we be cycle master? */
+ else {
+ device_printf(fc->bdev,
+ "root node is not cycle master capable\n");
+ /* XXX shall we be the cycle master? */
cmstr = fc->nodeid;
- /* XXX bus reset? */
+ /* XXX need bus reset */
+ }
} else
cmstr = -1;
- /* If I am the bus manager, optimize gapcount */
+
+ device_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
+ 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 )
fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]);
/* If we are the cycle master, nothing to do */
@@ -2070,7 +2074,7 @@ fw_bmr(struct firewire_comm *fc)
fwdev.status = FWDEVINIT;
/* Set cmstr bit on the cycle master */
fwmem_write_quad(&fwdev, NULL, 0/*spd*/,
- 0xffff, 0xf0000000 | STATE_SET, htonl(1 << 16),
+ 0xffff, 0xf0000000 | STATE_SET, htonl(1 << 8),
fw_asy_callback_free);
return 0;
OpenPOWER on IntegriCloud