patch-2.3.47 linux/drivers/ieee1394/ieee1394_core.c
Next file: linux/drivers/ieee1394/ieee1394_syms.c
Previous file: linux/drivers/ieee1394/hosts.h
Back to the patch index
Back to the overall index
- Lines: 131
- Date:
Sun Feb 20 20:32:50 2000
- Orig file:
v2.3.46/linux/drivers/ieee1394/ieee1394_core.c
- Orig date:
Fri Jan 21 18:19:16 2000
diff -u --recursive --new-file v2.3.46/linux/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
@@ -4,7 +4,7 @@
* Core support: hpsb_packet management, packet handling and forwarding to
* csr or lowlevel code
*
- * Copyright (C) 1999 Andreas E. Bombe
+ * Copyright (C) 1999, 2000 Andreas E. Bombe
*/
#include <linux/kernel.h>
@@ -191,6 +191,74 @@
return nodeid + 1;
}
+static void build_speed_map(struct hpsb_host *host, int nodecount)
+{
+ char speedcap[nodecount];
+ char cldcnt[nodecount];
+ u8 *map = host->speed_map;
+ quadlet_t *sidp;
+ int i, j, n;
+
+ for (i = 0; i < (nodecount * 64); i += 64) {
+ for (j = 0; j < nodecount; j++) {
+ map[i+j] = SPEED_400;
+ }
+ }
+
+ for (i = 0; i < nodecount; i++) {
+ cldcnt[i] = 0;
+ }
+
+ /* find direct children count and speed */
+ for (sidp = &host->topology_map[host->selfid_count-1],
+ n = nodecount - 1;
+ sidp >= host->topology_map; sidp--) {
+ if (*sidp & 0x00800000 /* extended */) {
+ for (i = 2; i < 18; i += 2) {
+ if ((*sidp & (0x3 << i)) == (0x3 << i)) {
+ cldcnt[n]++;
+ }
+ }
+ } else {
+ for (i = 2; i < 8; i += 2) {
+ if ((*sidp & (0x3 << i)) == (0x3 << i)) {
+ cldcnt[n]++;
+ }
+ }
+ speedcap[n] = (*sidp >> 14) & 0x3;
+ n--;
+ }
+ }
+
+ /* set self mapping */
+ for (i = nodecount - 1; i; i--) {
+ map[64*i + i] = speedcap[i];
+ }
+
+ /* fix up direct children count to total children count;
+ * also fix up speedcaps for sibling and parent communication */
+ for (i = 1; i < nodecount; i++) {
+ for (j = cldcnt[i], n = i - 1; j > 0; j--) {
+ cldcnt[i] += cldcnt[n];
+ speedcap[n] = MIN(speedcap[n], speedcap[i]);
+ n -= cldcnt[n] + 1;
+ }
+ }
+
+ for (n = 0; n < nodecount; n++) {
+ for (i = n - cldcnt[n]; i <= n; i++) {
+ for (j = 0; j < (n - cldcnt[n]); j++) {
+ map[j*64 + i] = map[i*64 + j] =
+ MIN(map[i*64 + j], speedcap[n]);
+ }
+ for (j = n + 1; j < nodecount; j++) {
+ map[j*64 + i] = map[i*64 + j] =
+ MIN(map[i*64 + j], speedcap[n]);
+ }
+ }
+ }
+}
+
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
{
if (host->in_bus_reset) {
@@ -204,8 +272,6 @@
void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
{
-
-
host->node_id = 0xffc0 | phyid;
host->in_bus_reset = 0;
host->is_root = isroot;
@@ -219,9 +285,11 @@
return;
} else {
HPSB_NOTICE("stopping out-of-control reset loop");
- HPSB_NOTICE("warning - topology map will therefore not "
- "be valid");
+ HPSB_NOTICE("warning - topology map and speed map will "
+ "therefore not be valid");
}
+ } else {
+ build_speed_map(host, host->node_count);
}
/* irm_id is kept up to date by check_selfids() */
@@ -275,8 +343,22 @@
}
packet->state = queued;
+ packet->speed_code = host->speed_map[(host->node_id & NODE_MASK) * 64
+ + (packet->node_id & NODE_MASK)];
- dump_packet("send packet:", packet->header, packet->header_size);
+ switch (packet->speed_code) {
+ case 2:
+ dump_packet("send packet 400:", packet->header,
+ packet->header_size);
+ break;
+ case 1:
+ dump_packet("send packet 200:", packet->header,
+ packet->header_size);
+ break;
+ default:
+ dump_packet("send packet 100:", packet->header,
+ packet->header_size);
+ }
return host->template->transmit_packet(host, packet);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)