Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/ieee1394/csr1212.c  |  132 ++++++++++++++++++++++--------------
 25-akpm/drivers/ieee1394/eth1394.c  |   54 ++------------
 25-akpm/drivers/ieee1394/ohci1394.c |    6 +
 25-akpm/drivers/ieee1394/pcilynx.c  |    4 -
 25-akpm/drivers/ieee1394/sbp2.c     |    2 
 5 files changed, 101 insertions(+), 97 deletions(-)

diff -puN drivers/ieee1394/csr1212.c~bk-ieee1394 drivers/ieee1394/csr1212.c
--- 25/drivers/ieee1394/csr1212.c~bk-ieee1394	2004-09-16 23:05:41.537187632 -0700
+++ 25-akpm/drivers/ieee1394/csr1212.c	2004-09-16 23:05:41.551185504 -0700
@@ -87,7 +87,8 @@ static const u_int8_t csr1212_key_id_typ
 
 static inline void free_keyval(struct csr1212_keyval *kv)
 {
-	if (kv->key.type == CSR1212_KV_TYPE_LEAF)
+	if ((kv->key.type == CSR1212_KV_TYPE_LEAF) &&
+	    (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM))
 		CSR1212_FREE(kv->value.leaf.data);
 
 	CSR1212_FREE(kv);
@@ -155,7 +156,7 @@ static inline struct csr1212_keyval *csr
 {
 	struct csr1212_keyval *kv;
 
-	for (kv = kv_list; kv != NULL; kv = kv->next) {
+	for (kv = kv_list->next; kv && (kv != kv_list); kv = kv->next) {
 		if (kv->offset == offset)
 			return kv;
 	}
@@ -181,9 +182,9 @@ struct csr1212_csr *csr1212_create_csr(s
 		return NULL;
 	}
 
-        /* The keyval key id is not used for the root node, but a valid key id
-         * that can be used for a directory needs to be passed to
-         * csr1212_new_directory(). */
+	/* The keyval key id is not used for the root node, but a valid key id
+	 * that can be used for a directory needs to be passed to
+	 * csr1212_new_directory(). */
 	csr->root_kv = csr1212_new_directory(CSR1212_KV_ID_VENDOR);
 	if (!csr->root_kv) {
 		CSR1212_FREE(csr->cache_head);
@@ -709,7 +710,7 @@ void _csr1212_destroy_keyval(struct csr1
 					tail->next = k->value.directory.dentries_head;
 					k->value.directory.dentries_head->prev = tail;
 					tail = k->value.directory.dentries_tail;
-                                }
+				}
 			}
 			free_keyval(k);
 			k = a;
@@ -796,7 +797,8 @@ static int csr1212_append_new_cache(stru
 		return CSR1212_ENOMEM;
 	}
 	cache->ext_rom->offset = csr_addr - CSR1212_REGISTER_SPACE_BASE;
-	cache->ext_rom->value.leaf.len = 0;
+	cache->ext_rom->value.leaf.len = -1;
+	cache->ext_rom->value.leaf.data = cache->data;
 
 	/* Add cache to tail of cache list */
 	cache->prev = csr->cache_tail;
@@ -864,20 +866,20 @@ static int csr1212_generate_layout_subdi
 			default:
 			case CSR1212_KV_TYPE_IMMEDIATE:
 			case CSR1212_KV_TYPE_CSR_OFFSET:
-				continue;
+				break;
 			case CSR1212_KV_TYPE_LEAF:
 			case CSR1212_KV_TYPE_DIRECTORY:
 				/* Remove from list */
-				if (dkv->prev)
+				if (dkv->prev && (dkv->prev->next == dkv))
 					dkv->prev->next = dkv->next;
-				if (dkv->next)
+				if (dkv->next && (dkv->next->prev == dkv))
 					dkv->next->prev = dkv->prev;
-				if (dkv == *layout_tail)
-					*layout_tail = dkv->prev;
+				//if (dkv == *layout_tail)
+				//	*layout_tail = dkv->prev;
 
 				/* Special case: Extended ROM leafs */
 				if (dkv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
-					dkv->value.leaf.len = 0; /* initialize to zero */
+					dkv->value.leaf.len = -1;
 					/* Don't add Extended ROM leafs in the layout list,
 					 * they are handled differently. */
 					break;
@@ -919,8 +921,8 @@ size_t csr1212_generate_layout_order(str
 }
 
 struct csr1212_keyval *csr1212_generate_positions(struct csr1212_csr_rom_cache *cache,
-                                                  struct csr1212_keyval *start_kv,
-                                                  int start_pos)
+						  struct csr1212_keyval *start_kv,
+						  int start_pos)
 {
 	struct csr1212_keyval *kv = start_kv;
 	struct csr1212_keyval *okv = start_kv;
@@ -930,7 +932,10 @@ struct csr1212_keyval *csr1212_generate_
 	cache->layout_head = kv;
 
 	while(kv && pos < cache->size) {
-		kv->offset = cache->offset + pos;
+		/* Special case: Extended ROM leafs */
+		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
+			kv->offset = cache->offset + pos;
+		}
 
 		switch(kv->key.type) {
 		case CSR1212_KV_TYPE_LEAF:
@@ -1090,6 +1095,9 @@ int csr1212_generate_csr_image(struct cs
 	bi->crc_length = bi->length;
 	bi->crc = csr1212_crc16(bi->data, bi->crc_length);
 
+	csr->root_kv->next = NULL;
+	csr->root_kv->prev = NULL;
+
 	agg_size = csr1212_generate_layout_order(csr->root_kv);
 
 	init_offset = csr->bus_info_len;
@@ -1158,6 +1166,17 @@ int csr1212_generate_csr_image(struct cs
 
 		/* Copy the data into the cache buffer */
 		csr1212_fill_cache(cache);
+
+		if (cache != csr->cache_head) {
+			/* Set the length and CRC of the extended ROM. */
+			struct csr1212_keyval_img *kvi =
+				(struct csr1212_keyval_img*)cache->data;
+
+			kvi->length = CSR1212_CPU_TO_BE16(bytes_to_quads(cache->len) - 1);
+			kvi->crc = csr1212_crc16(kvi->data,
+						 bytes_to_quads(cache->len) - 1);
+
+		}
 	}
 
 	return CSR1212_SUCCESS;
@@ -1174,11 +1193,6 @@ int csr1212_read(struct csr1212_csr *csr
 			       &cache->data[bytes_to_quads(offset - cache->offset)],
 			       len);
 			return CSR1212_SUCCESS;
-		} else if (((offset < cache->offset) &&
-			    ((offset + len) >= cache->offset)) ||
-			   ((offset >= cache->offset) &&
-			    ((offset + len) > (cache->offset + cache->size)))) {
-			return CSR1212_EINVAL;
 		}
 	}
 	return CSR1212_ENOENT;
@@ -1227,8 +1241,8 @@ static int csr1212_parse_bus_info_block(
 		return CSR1212_EINVAL;
 
 #if 0
-        /* Apparently there are too many differnt wrong implementations of the
-         * CRC algorithm that verifying them is moot. */
+	/* Apparently there are too many differnt wrong implementations of the
+	 * CRC algorithm that verifying them is moot. */
 	if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
 	    (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
 		return CSR1212_EINVAL;
@@ -1249,10 +1263,9 @@ static int csr1212_parse_bus_info_block(
 	return CSR1212_SUCCESS;
 }
 
-static inline int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
-					  csr1212_quad_t ki,
-					  u_int32_t kv_pos,
-					  struct csr1212_csr_rom_cache *cache)
+static int csr1212_parse_dir_entry(struct csr1212_keyval *dir,
+				   csr1212_quad_t ki,
+				   u_int32_t kv_pos)
 {
 	int ret = CSR1212_SUCCESS;
 	struct csr1212_keyval *k = NULL;
@@ -1291,7 +1304,7 @@ static inline int csr1212_parse_dir_entr
 			goto fail;
 		}
 
-		k = csr1212_find_keyval_offset(cache->layout_head, offset);
+		k = csr1212_find_keyval_offset(dir, offset);
 
 		if (k)
 			break;		/* Found it. */
@@ -1309,11 +1322,10 @@ static inline int csr1212_parse_dir_entr
 		k->valid = 0;	/* Contents not read yet so it's not valid. */
 		k->offset = offset;
 
-		k->prev = cache->layout_tail;
-		k->next = NULL;
-		if (cache->layout_tail)
-			cache->layout_tail->next = k;
-		cache->layout_tail = k;
+		k->prev = dir;
+		k->next = dir->next;
+		dir->next->prev = k;
+		dir->next = k;
 	}
 	ret = csr1212_attach_keyval_to_directory(dir, k);
 
@@ -1325,6 +1337,7 @@ fail:
 	return ret;
 }
 
+
 int csr1212_parse_keyval(struct csr1212_keyval *kv,
 			 struct csr1212_csr_rom_cache *cache)
 {
@@ -1338,8 +1351,8 @@ int csr1212_parse_keyval(struct csr1212_
 	kvi_len = CSR1212_BE16_TO_CPU(kvi->length);
 
 #if 0
-        /* Apparently there are too many differnt wrong implementations of the
-         * CRC algorithm that verifying them is moot. */
+	/* Apparently there are too many differnt wrong implementations of the
+	 * CRC algorithm that verifying them is moot. */
 	if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
 	    (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc)) {
 		ret = CSR1212_EINVAL;
@@ -1353,22 +1366,19 @@ int csr1212_parse_keyval(struct csr1212_
 			csr1212_quad_t ki = kvi->data[i];
 
 			/* Some devices put null entries in their unit
-			 * directories.  If we come across such and entry,
+			 * directories.  If we come across such an entry,
 			 * then skip it. */
 			if (ki == 0x0)
 				continue;
 			ret = csr1212_parse_dir_entry(kv, ki,
 						      (kv->offset +
-						       quads_to_bytes(i + 1)),
-						      cache);
+						       quads_to_bytes(i + 1)));
 		}
 		kv->value.directory.len = kvi_len;
 		break;
 
 	case CSR1212_KV_TYPE_LEAF:
-		if (kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
-			kv->value.leaf.data = cache->data;
-		} else {
+		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
 			kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
 			if (!kv->value.leaf.data)
 			{
@@ -1399,7 +1409,6 @@ int _csr1212_read_keyval(struct csr1212_
 	u_int32_t *cache_ptr;
 	u_int16_t kv_len = 0;
 
-
 	if (!csr || !kv)
 		return CSR1212_EINVAL;
 
@@ -1413,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_
 
 	if (!cache) {
 		csr1212_quad_t q;
-		struct csr1212_csr_rom_cache *nc;
+		u_int32_t cache_size;
 
 		/* Only create a new cache for Extended ROM leaves. */
 		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM)
@@ -1425,12 +1434,20 @@ int _csr1212_read_keyval(struct csr1212_
 			return CSR1212_EIO;
 		}
 
-		kv->value.leaf.len = quads_to_bytes(CSR1212_BE32_TO_CPU(q)>>16);
+		kv->value.leaf.len = CSR1212_BE32_TO_CPU(q) >> 16;
+
+		cache_size = (quads_to_bytes(kv->value.leaf.len + 1) +
+			      (csr->max_rom - 1)) & ~(csr->max_rom - 1);
 
-		nc = csr1212_rom_cache_malloc(kv->offset, kv->value.leaf.len);
-		cache->next = nc;
-		nc->prev = cache;
-		csr->cache_tail = nc;
+		cache = csr1212_rom_cache_malloc(kv->offset, cache_size);
+		if (!cache)
+			return CSR1212_ENOMEM;
+
+		kv->value.leaf.data = &cache->data[1];
+		csr->cache_tail->next = cache;
+		cache->prev = csr->cache_tail;
+		cache->next = NULL;
+		csr->cache_tail = cache;
 		cache->filled_head =
 			CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
 		if (!cache->filled_head) {
@@ -1443,6 +1460,10 @@ int _csr1212_read_keyval(struct csr1212_
 		cache->filled_head->next = NULL;
 		cache->filled_head->prev = NULL;
 		cache->data[0] = q;
+
+		/* Don't read the entire extended ROM now.  Pieces of it will
+		 * be read when entries inside it are read. */
+		return csr1212_parse_keyval(kv, cache);
 	}
 
 	cache_index = kv->offset - cache->offset;
@@ -1548,6 +1569,7 @@ int _csr1212_read_keyval(struct csr1212_
 int csr1212_parse_csr(struct csr1212_csr *csr)
 {
 	static const int mr_map[] = { 4, 64, 1024, 0 };
+	struct csr1212_dentry *dentry;
 	int ret;
 
 	if (!csr || !csr->ops->bus_read)
@@ -1570,7 +1592,21 @@ int csr1212_parse_csr(struct csr1212_csr
 		csr->bus_info_len;
 
 	csr->root_kv->valid = 0;
+	csr->root_kv->next = csr->root_kv;
+	csr->root_kv->prev = csr->root_kv;
 	csr1212_get_keyval(csr, csr->root_kv);
 
+	/* Scan through the Root directory finding all extended ROM regions
+	 * and make cache regions for them */
+	for (dentry = csr->root_kv->value.directory.dentries_head;
+	     dentry; dentry = dentry->next) {
+		if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
+			csr1212_get_keyval(csr, dentry->kv);
+
+			if (ret != CSR1212_SUCCESS)
+				return ret;
+		}
+	}
+
 	return CSR1212_SUCCESS;
 }
diff -puN drivers/ieee1394/eth1394.c~bk-ieee1394 drivers/ieee1394/eth1394.c
--- 25/drivers/ieee1394/eth1394.c~bk-ieee1394	2004-09-16 23:05:41.538187480 -0700
+++ 25-akpm/drivers/ieee1394/eth1394.c	2004-09-16 23:06:09.592922512 -0700
@@ -89,7 +89,7 @@
 #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
 
 static char version[] __devinitdata =
-	"$Rev: 1224 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 1231 $ Ben Collins <bcollins@debian.org>";
 
 struct fragment_info {
 	struct list_head list;
@@ -1768,53 +1768,17 @@ fail:
 	return 0;  /* returning non-zero causes serious problems */
 }
 
-static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	switch(cmd) {
-		case SIOCETHTOOL:
-			return ether1394_ethtool_ioctl(dev, ifr->ifr_data);
-
-		case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
-		case SIOCGMIIREG:		/* Read MII PHY register. */
-		case SIOCSMIIREG:		/* Write MII PHY register. */
-		default:
-			return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-static int ether1394_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
-{
-	u32 ethcmd;
-
-	if (get_user(ethcmd, (u32 __user *)useraddr))
-		return -EFAULT;
-
-	switch (ethcmd) {
-		case ETHTOOL_GDRVINFO: {
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-			strcpy (info.driver, driver_name);
-			strcpy (info.version, "$Rev: 1224 $");
-			/* FIXME XXX provide sane businfo */
-			strcpy (info.bus_info, "ieee1394");
-			if (copy_to_user (useraddr, &info, sizeof (info)))
-				return -EFAULT;
-			break;
-		}
-		case ETHTOOL_GSET:
-		case ETHTOOL_SSET:
-		case ETHTOOL_NWAY_RST:
-		case ETHTOOL_GLINK:
-		case ETHTOOL_GMSGLVL:
-		case ETHTOOL_SMSGLVL:
-		default:
-			return -EOPNOTSUPP;
-	}
-
-	return 0;
+	strcpy (info->driver, driver_name);
+	strcpy (info->version, "$Rev: 1224 $");
+	/* FIXME XXX provide sane businfo */
+	strcpy (info->bus_info, "ieee1394");
 }
 
+static struct ethtool_ops ethtool_ops = {
+	.get_drvinfo = ether1394_get_drvinfo
+};
 
 static int __init ether1394_init_module (void)
 {
diff -puN drivers/ieee1394/ohci1394.c~bk-ieee1394 drivers/ieee1394/ohci1394.c
--- 25/drivers/ieee1394/ohci1394.c~bk-ieee1394	2004-09-16 23:05:41.540187176 -0700
+++ 25-akpm/drivers/ieee1394/ohci1394.c	2004-09-16 23:05:41.777151152 -0700
@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_
 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 1223 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 1226 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 static int phys_dma = 1;
@@ -2545,6 +2545,10 @@ static void insert_dma_buffer(struct dma
 	idx = (idx + d->num_desc - 1 ) % d->num_desc;
 	d->prg_cpu[idx]->branchAddress |= le32_to_cpu(0x00000001);
 
+	/* To avoid a race, ensure 1394 interface hardware sees the inserted
+	 * context program descriptors before it sees the wakeup bit set. */
+	wmb();
+	
 	/* wake up the dma context if necessary */
 	if (!(reg_read(ohci, d->ctrlSet) & 0x400)) {
 		PRINT(KERN_INFO,
diff -puN drivers/ieee1394/pcilynx.c~bk-ieee1394 drivers/ieee1394/pcilynx.c
--- 25/drivers/ieee1394/pcilynx.c~bk-ieee1394	2004-09-16 23:05:41.542186872 -0700
+++ 25-akpm/drivers/ieee1394/pcilynx.c	2004-09-16 23:05:41.779150848 -0700
@@ -500,7 +500,7 @@ static void send_next(struct ti_lynx *ly
         pcl.async_error_next = PCL_NEXT_INVALID;
         pcl.pcl_status = 0;
         pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size;
-#ifdef __BIG_ENDIAN
+#ifndef __BIG_ENDIAN
         pcl.buffer[0].control |= PCL_BIGENDIAN;
 #endif
         pcl.buffer[0].pointer = d->header_dma;
@@ -1697,7 +1697,7 @@ static int __devinit add_card(struct pci
         pcl.async_error_next = PCL_NEXT_INVALID;
 
         pcl.buffer[0].control = PCL_CMD_RCV | 16;
-#ifdef __BIG_ENDIAN
+#ifndef __BIG_ENDIAN
 	pcl.buffer[0].control |= PCL_BIGENDIAN;
 #endif
 	pcl.buffer[1].control = PCL_LAST_BUFF | 4080;
diff -puN drivers/ieee1394/sbp2.c~bk-ieee1394 drivers/ieee1394/sbp2.c
--- 25/drivers/ieee1394/sbp2.c~bk-ieee1394	2004-09-16 23:05:41.543186720 -0700
+++ 25-akpm/drivers/ieee1394/sbp2.c	2004-09-16 23:05:41.781150544 -0700
@@ -78,7 +78,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 1219 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 1231 $ Ben Collins <bcollins@debian.org>";
 
 /*
  * Module load parameter definitions
_