patch-2.3.99-pre3 linux/drivers/ieee1394/ieee1394_core.c
Next file: linux/drivers/ieee1394/ieee1394_core.h
Previous file: linux/drivers/ieee1394/ieee1394.h
Back to the patch index
Back to the overall index
- Lines: 359
- Date:
Wed Mar 22 00:02:48 2000
- Orig file:
v2.3.99-pre2/linux/drivers/ieee1394/ieee1394_core.c
- Orig date:
Sun Feb 20 21:12:39 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
@@ -2,11 +2,12 @@
* IEEE 1394 for Linux
*
* Core support: hpsb_packet management, packet handling and forwarding to
- * csr or lowlevel code
+ * highlevel or lowlevel code
*
* Copyright (C) 1999, 2000 Andreas E. Bombe
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/string.h>
@@ -62,7 +63,7 @@
packet->header = header;
if (data_size) {
- data = kmalloc(data_size + 4, kmflags);
+ data = kmalloc(data_size + 8, kmflags);
if (data == NULL) {
kfree(header);
kfree(packet);
@@ -70,18 +71,14 @@
}
packet->data = data;
- packet->data_size = data_size - 4;
+ packet->data_size = data_size;
}
INIT_LIST_HEAD(&packet->list);
sema_init(&packet->state_change, 0);
packet->state = unused;
packet->generation = get_hpsb_generation();
-
-#ifdef __BIG_ENDIAN
- /* set default */
packet->data_be = 1;
-#endif
return packet;
}
@@ -133,59 +130,55 @@
{
int nodeid = -1;
int rest_of_selfids = num_of_selfids;
- quadlet_t *sidp = host->topology_map;
- quadlet_t sid = *sidp;
+ struct selfid *sid = (struct selfid *)host->topology_map;
+ struct ext_selfid *esid;
int esid_seq = 23;
- int i;
while (rest_of_selfids--) {
- sid = *(sidp++);
-
- if (!(sid & 0x00800000) /* !extended */) {
+ if (!sid->extended) {
nodeid++;
esid_seq = 0;
-
- if (((sid >> 24) & NODE_MASK) != nodeid) {
+
+ if (sid->phy_id != nodeid) {
HPSB_INFO("SelfIDs failed monotony check with "
- "%d", (sid >> 24) & NODE_MASK);
+ "%d", sid->phy_id);
return 0;
}
-
- /* "if is contender and link active" */
- if ((sid & (1<<11)) && (sid & (1<<22))) {
- host->irm_id = LOCAL_BUS | ((sid >> 24)
- & NODE_MASK);
+
+ if (sid->contender && sid->link_active) {
+ host->irm_id = LOCAL_BUS | sid->phy_id;
}
} else {
- if ((((sid >> 24) & NODE_MASK) != nodeid)
- || (((sid >> 20) & 0x7) != esid_seq)) {
+ esid = (struct ext_selfid *)sid;
+
+ if ((esid->phy_id != nodeid)
+ || (esid->seq_nr != esid_seq)) {
HPSB_INFO("SelfIDs failed monotony check with "
- "%d/%d", (sid >> 24) & NODE_MASK,
- (sid >> 20) & 0x7);
+ "%d/%d", esid->phy_id, esid->seq_nr);
return 0;
}
esid_seq++;
}
+ sid++;
}
-
- sidp--;
- while (sid & 0x00800000 /* extended */) {
- /* check that no ports go to a parent */
- for (i = 2; i < 18; i += 2) {
- if ((sid & (0x3 << i)) == (0x2 << i)) {
+
+ esid = (struct ext_selfid *)(sid - 1);
+ while (esid->extended) {
+ if ((esid->porta == 0x2) || (esid->portb == 0x2)
+ || (esid->portc == 0x2) || (esid->portd == 0x2)
+ || (esid->porte == 0x2) || (esid->portf == 0x2)
+ || (esid->portg == 0x2) || (esid->porth == 0x2)) {
HPSB_INFO("SelfIDs failed root check on "
"extended SelfID");
return 0;
- }
}
- sid = *(sidp--);
+ esid--;
}
- for (i = 2; i < 8; i += 2) {
- if ((sid & (0x3 << i)) == (0x2 << i)) {
+ sid = (struct selfid *)esid;
+ if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) {
HPSB_INFO("SelfIDs failed root check");
return 0;
- }
}
return nodeid + 1;
@@ -196,7 +189,8 @@
char speedcap[nodecount];
char cldcnt[nodecount];
u8 *map = host->speed_map;
- quadlet_t *sidp;
+ struct selfid *sid;
+ struct ext_selfid *esid;
int i, j, n;
for (i = 0; i < (nodecount * 64); i += 64) {
@@ -210,22 +204,26 @@
}
/* find direct children count and speed */
- for (sidp = &host->topology_map[host->selfid_count-1],
+ for (sid = (struct selfid *)&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]++;
- }
- }
+ (void *)sid >= (void *)host->topology_map; sid--) {
+ if (sid->extended) {
+ esid = (struct ext_selfid *)sid;
+
+ if (esid->porta == 0x3) cldcnt[n]++;
+ if (esid->portb == 0x3) cldcnt[n]++;
+ if (esid->portc == 0x3) cldcnt[n]++;
+ if (esid->portd == 0x3) cldcnt[n]++;
+ if (esid->porte == 0x3) cldcnt[n]++;
+ if (esid->portf == 0x3) cldcnt[n]++;
+ if (esid->portg == 0x3) cldcnt[n]++;
+ if (esid->porth == 0x3) cldcnt[n]++;
} else {
- for (i = 2; i < 8; i += 2) {
- if ((*sidp & (0x3 << i)) == (0x3 << i)) {
- cldcnt[n]++;
- }
- }
- speedcap[n] = (*sidp >> 14) & 0x3;
+ if (sid->port0 == 0x3) cldcnt[n]++;
+ if (sid->port1 == 0x3) cldcnt[n]++;
+ if (sid->port2 == 0x3) cldcnt[n]++;
+
+ speedcap[n] = sid->speed;
n--;
}
}
@@ -262,7 +260,7 @@
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
{
if (host->in_bus_reset) {
- printk("including selfid 0x%x\n", sid);
+ HPSB_DEBUG("including selfid 0x%x", sid);
host->topology_map[host->selfid_count++] = sid;
} else {
/* FIXME - info on which host */
@@ -293,7 +291,12 @@
}
/* irm_id is kept up to date by check_selfids() */
- host->is_irm = (host->irm_id == host->node_id);
+ if (host->irm_id == host->node_id) {
+ host->is_irm = 1;
+ host->is_busmgr = 1;
+ host->busmgr_id = host->node_id;
+ host->csr.bus_manager_id = host->node_id;
+ }
host->reset_retries = 0;
inc_hpsb_generation();
@@ -346,6 +349,7 @@
packet->speed_code = host->speed_map[(host->node_id & NODE_MASK) * 64
+ (packet->node_id & NODE_MASK)];
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
switch (packet->speed_code) {
case 2:
dump_packet("send packet 400:", packet->header,
@@ -359,6 +363,7 @@
dump_packet("send packet 100:", packet->header,
packet->header_size);
}
+#endif
return host->template->transmit_packet(host, packet);
}
@@ -459,12 +464,14 @@
{
struct hpsb_packet *p;
+ dsize += (dsize % 4 ? 4 - (dsize % 4) : 0);
+
p = alloc_hpsb_packet(dsize);
if (p == NULL) {
/* FIXME - send data_error response */
return NULL;
}
-
+
p->type = async;
p->state = unused;
p->host = host;
@@ -472,6 +479,10 @@
p->tlabel = (data[0] >> 10) & 0x3f;
p->no_waiter = 1;
+ if (dsize % 4) {
+ p->data[dsize / 4] = 0;
+ }
+
return p;
}
@@ -479,21 +490,12 @@
packet = create_reply_packet(host, data, length); \
if (packet == NULL) break
-inline void swap_quadlets_on_le(quadlet_t *q)
-{
-#ifdef __LITTLE_ENDIAN
- quadlet_t saved = q[0];
- q[0] = q[1];
- q[1] = saved;
-#endif
-}
-
-
void handle_incoming_packet(struct hpsb_host *host, int tcode, quadlet_t *data,
size_t size)
{
struct hpsb_packet *packet;
int length, rcode, extcode;
+ int source = data[1] >> 16;
u64 addr;
/* big FIXME - no error checking is done for an out of bounds length */
@@ -501,7 +503,7 @@
switch (tcode) {
case TCODE_WRITEQ:
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, data+3, addr, 4);
+ rcode = highlevel_write(host, source, data+3, addr, 4);
if (((data[0] >> 16) & NODE_MASK) != NODE_MASK) {
/* not a broadcast write, reply */
@@ -513,7 +515,8 @@
case TCODE_WRITEB:
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, data+4, addr, data[3]>>16);
+ rcode = highlevel_write(host, source, data+4, addr,
+ data[3]>>16);
if (((data[0] >> 16) & NODE_MASK) != NODE_MASK) {
/* not a broadcast write, reply */
@@ -527,7 +530,7 @@
PREP_REPLY_PACKET(0);
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_read(host, data, addr, 4);
+ rcode = highlevel_read(host, source, data, addr, 4);
fill_async_readquad_resp(packet, rcode, *data);
send_packet_nocare(packet);
break;
@@ -537,7 +540,8 @@
PREP_REPLY_PACKET(length);
addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_read(host, packet->data, addr, length);
+ rcode = highlevel_read(host, source, packet->data, addr,
+ length);
fill_async_readblock_resp(packet, rcode, length);
send_packet_nocare(packet);
break;
@@ -556,35 +560,32 @@
switch (length) {
case 4:
- rcode = highlevel_lock(host, packet->data, addr,
+ rcode = highlevel_lock(host, source, packet->data, addr,
data[4], 0, extcode);
fill_async_lock_resp(packet, rcode, extcode, 4);
break;
case 8:
if ((extcode != EXTCODE_FETCH_ADD)
&& (extcode != EXTCODE_LITTLE_ADD)) {
- rcode = highlevel_lock(host, packet->data, addr,
+ rcode = highlevel_lock(host, source,
+ packet->data, addr,
data[5], data[4],
extcode);
fill_async_lock_resp(packet, rcode, extcode, 4);
} else {
- swap_quadlets_on_le(data + 4);
- rcode = highlevel_lock64(host,
+ rcode = highlevel_lock64(host, source,
(octlet_t *)packet->data, addr,
*(octlet_t *)(data + 4), 0ULL,
extcode);
- swap_quadlets_on_le(packet->data);
fill_async_lock_resp(packet, rcode, extcode, 8);
}
break;
case 16:
- swap_quadlets_on_le(data + 4);
- swap_quadlets_on_le(data + 6);
- rcode = highlevel_lock64(host, (octlet_t *)packet->data,
- addr, *(octlet_t *)(data + 6),
+ rcode = highlevel_lock64(host, source,
+ (octlet_t *)packet->data, addr,
+ *(octlet_t *)(data + 6),
*(octlet_t *)(data + 4),
extcode);
- swap_quadlets_on_le(packet->data);
fill_async_lock_resp(packet, rcode, extcode, 8);
break;
default:
@@ -609,7 +610,9 @@
return;
}
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
dump_packet("received packet:", data, size);
+#endif
tcode = (data[0] >> 4) & 0xf;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)