- 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)
This commit is contained in:
Hidetoshi Shimokawa 2003-05-11 10:32:20 +00:00
parent e34c1b685e
commit 6902ee83c7

View File

@ -113,9 +113,10 @@ static device_method_t firewire_methods[] = {
}; };
char linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"}; char linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"};
#define MAX_GAPHOP 16 /* IEEE-1394a Table C-2 Gap count as a function of hops*/
u_int gap_cnt[] = {1, 1, 4, 6, 9, 12, 14, 17, #define MAX_GAPHOP 15
20, 23, 25, 28, 31, 33, 36, 39, 42}; 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; 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"); printf("\n");
if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) { 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; fc->status = FWBUSMGRDONE;
CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm); CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
fw_bmr(fc);
} else { } else {
fc->status = FWBUSMGRELECT; fc->status = FWBUSMGRELECT;
callout_reset(&fc->bmr_callout, hz/8, callout_reset(&fc->bmr_callout, hz/8,
(void *)fw_try_bmr, (void *)fc); (void *)fw_try_bmr, (void *)fc);
} }
} else { } else
fc->status = FWBUSMGRDONE; 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, callout_reset(&fc->busprobe_callout, hz/4,
(void *)fw_bus_probe, (void *)fc); (void *)fw_bus_probe, (void *)fc);
} }
@ -1888,15 +1882,12 @@ fw_try_bmr_callback(struct fw_xfer *xfer)
bmr = fc->nodeid; bmr = fc->nodeid;
CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f); CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
device_printf(fc->bdev, "new bus manager %d ", fw_xfer_free(xfer);
CSRARC(fc, BUS_MGR_ID));
if(bmr == fc->nodeid){
printf("(me)\n");
fw_bmr(fc); fw_bmr(fc);
}else{ return;
printf("\n");
}
error: error:
device_printf(fc->bdev, "bus manager election failed\n");
fw_xfer_free(xfer); 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 */ /* Check to see if the current root node is cycle master capable */
self_id = &fc->topology_map->self_id[fc->max_node]; self_id = &fc->topology_map->self_id[fc->max_node];
if (fc->max_node > 0) { 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; cmstr = fc->max_node;
else else {
/* XXX shall we be cycle master? */ device_printf(fc->bdev,
"root node is not cycle master capable\n");
/* XXX shall we be the cycle master? */
cmstr = fc->nodeid; cmstr = fc->nodeid;
/* XXX bus reset? */ /* XXX need bus reset */
}
} else } else
cmstr = -1; 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 ) if(fc->max_hop <= MAX_GAPHOP )
fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]); fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]);
/* If we are the cycle master, nothing to do */ /* If we are the cycle master, nothing to do */
@ -2070,7 +2074,7 @@ fw_bmr(struct firewire_comm *fc)
fwdev.status = FWDEVINIT; fwdev.status = FWDEVINIT;
/* Set cmstr bit on the cycle master */ /* Set cmstr bit on the cycle master */
fwmem_write_quad(&fwdev, NULL, 0/*spd*/, 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); fw_asy_callback_free);
return 0; return 0;