Browse Source

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: (55 commits)
  ieee1394: sbp2: code formatting around work_struct stuff
  ieee1394: nodemgr: remove a kcalloc
  ieee1394: conditionally export ieee1394_bus_type
  ieee1394: Consolidate driver registering
  ieee1394: sbp2: convert from PCI DMA to generic DMA
  ieee1394: nodemgr: spaces to tabs
  ieee1394: nodemgr: fix deadlock in shutdown
  ieee1394: nodemgr: remove duplicate assignment
  sbp2: make 1bit bitfield unsigned
  ieee1394: schedule *_oui sysfs attributes for removal
  ieee1394: schedule unused symbol exports for removal
  ieee1394: dv1394: schedule for feature removal
  ieee1394: raw1394: defer feature removal of old isoch interface
  ieee1394: ohci1394: call PMac code in shutdown only for proper machines
  ieee1394: ohci1394: reformat PPC_PMAC platform code
  ieee1394: ohci1394: add PPC_PMAC platform code to driver probe
  ieee1394: sbp2: wrap two functions into one
  ieee1394: sbp2: update comment on things to do
  ieee1394: sbp2: use list_move_tail()
  ieee1394: sbp2: more concise names for types and variables
  ...
Linus Torvalds 18 years ago
parent
commit
c99767974e

+ 33 - 5
Documentation/feature-removal-schedule.txt

@@ -30,11 +30,39 @@ Who:	Adrian Bunk <bunk@stusta.de>
 ---------------------------
 ---------------------------
 
 
 What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
-When:	November 2006
-Why:	Deprecated in favour of the new ioctl-based rawiso interface, which is
-	more efficient.  You should really be using libraw1394 for raw1394
-	access anyway.
-Who:	Jody McIntyre <scjody@modernduck.com>
+When:	June 2007
+Why:	Deprecated in favour of the more efficient and robust rawiso interface.
+	Affected are applications which use the deprecated part of libraw1394
+	(raw1394_iso_write, raw1394_start_iso_write, raw1394_start_iso_rcv,
+	raw1394_stop_iso_rcv) or bypass	libraw1394.
+Who:	Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
+
+---------------------------
+
+What:	dv1394 driver (CONFIG_IEEE1394_DV1394)
+When:	June 2007
+Why:	Replaced by raw1394 + userspace libraries, notably libiec61883.  This
+	shift of application support has been indicated on www.linux1394.org
+	and developers' mailinglists for quite some time.  Major applications
+	have been converted, with the exception of ffmpeg and hence xine.
+	Piped output of dvgrab2 is a partial equivalent to dv1394.
+Who:	Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
+
+---------------------------
+
+What:	ieee1394 core's unused exports (CONFIG_IEEE1394_EXPORT_FULL_API)
+When:	January 2007
+Why:	There are no projects known to use these exported symbols, except
+	dfg1394 (uses one symbol whose functionality is core-internal now).
+Who:	Stefan Richter <stefanr@s5r6.in-berlin.de>
+
+---------------------------
+
+What:	ieee1394's *_oui sysfs attributes (CONFIG_IEEE1394_OUI_DB)
+When:	January 2007
+Files:	drivers/ieee1394/: oui.db, oui2c.sh
+Why:	big size, little value
+Who:	Stefan Richter <stefanr@s5r6.in-berlin.de>
 
 
 ---------------------------
 ---------------------------
 
 

+ 8 - 18
drivers/ieee1394/Kconfig

@@ -36,7 +36,7 @@ config IEEE1394_VERBOSEDEBUG
 	  else says N.
 	  else says N.
 
 
 config IEEE1394_OUI_DB
 config IEEE1394_OUI_DB
-	bool "OUI Database built-in"
+	bool "OUI Database built-in (deprecated)"
 	depends on IEEE1394
 	depends on IEEE1394
 	help
 	help
 	  If you say Y here, then an OUI list (vendor unique ID's) will be
 	  If you say Y here, then an OUI list (vendor unique ID's) will be
@@ -67,16 +67,11 @@ config IEEE1394_CONFIG_ROM_IP1394
 	  eth1394 option below.
 	  eth1394 option below.
 
 
 config IEEE1394_EXPORT_FULL_API
 config IEEE1394_EXPORT_FULL_API
-	bool "Export all symbols of ieee1394's API"
+	bool "Export all symbols of ieee1394's API (deprecated)"
 	depends on IEEE1394
 	depends on IEEE1394
 	default n
 	default n
 	help
 	help
-	  Export all symbols of ieee1394's driver programming interface, even
-	  those that are not currently used by the standard IEEE 1394 drivers.
-
-	  This option does not affect the interface to userspace applications.
-	  Say Y here if you want to compile externally developed drivers that
-	  make extended use of ieee1394's API. It is otherwise safe to say N.
+	  This option will be removed soon.  Don't worry, say N.
 
 
 comment "Device Drivers"
 comment "Device Drivers"
 	depends on IEEE1394
 	depends on IEEE1394
@@ -125,7 +120,7 @@ comment "SBP-2 support (for storage devices) requires SCSI"
 
 
 config IEEE1394_SBP2
 config IEEE1394_SBP2
 	tristate "SBP-2 support (Harddisks etc.)"
 	tristate "SBP-2 support (Harddisks etc.)"
-	depends on IEEE1394 && SCSI && (PCI || BROKEN)
+	depends on IEEE1394 && SCSI
 	help
 	help
 	  This option enables you to use SBP-2 devices connected to an IEEE
 	  This option enables you to use SBP-2 devices connected to an IEEE
 	  1394 bus.  SBP-2 devices include storage devices like harddisks and
 	  1394 bus.  SBP-2 devices include storage devices like harddisks and
@@ -161,17 +156,12 @@ config IEEE1394_ETH1394
 	  MCAP, therefore multicast support is significantly limited.
 	  MCAP, therefore multicast support is significantly limited.
 
 
 config IEEE1394_DV1394
 config IEEE1394_DV1394
-	tristate "OHCI-DV I/O support"
+	tristate "OHCI-DV I/O support (deprecated)"
 	depends on IEEE1394 && IEEE1394_OHCI1394
 	depends on IEEE1394 && IEEE1394_OHCI1394
 	help
 	help
-	  This driver allows you to transmit and receive DV (digital video)
-	  streams on an OHCI-1394 card using a simple frame-oriented
-	  interface.
-
-	  The user-space API for dv1394 is documented in dv1394.h.
-
-	  To compile this driver as a module, say M here: the
-	  module will be called dv1394.
+	  The dv1394 driver will be removed from Linux in a future release.
+	  Its functionality is now provided by raw1394 together with libraries
+	  such as libiec61883.
 
 
 config IEEE1394_RAWIO
 config IEEE1394_RAWIO
 	tristate "Raw IEEE1394 I/O support"
 	tristate "Raw IEEE1394 I/O support"

+ 4 - 1
drivers/ieee1394/Makefile

@@ -3,8 +3,11 @@
 #
 #
 
 
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
-		 highlevel.o csr.o nodemgr.o oui.o dma.o iso.o \
+		 highlevel.o csr.o nodemgr.o dma.o iso.o \
 		 csr1212.o config_roms.o
 		 csr1212.o config_roms.o
+ifdef CONFIG_IEEE1394_OUI_DB
+ieee1394-objs += oui.o
+endif
 
 
 obj-$(CONFIG_IEEE1394) += ieee1394.o
 obj-$(CONFIG_IEEE1394) += ieee1394.o
 obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
 obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o

+ 3 - 5
drivers/ieee1394/csr.c

@@ -158,12 +158,10 @@ static void host_reset(struct hpsb_host *host)
  */
  */
 static inline void calculate_expire(struct csr_control *csr)
 static inline void calculate_expire(struct csr_control *csr)
 {
 {
-	unsigned long usecs =
-		(csr->split_timeout_hi & 0x07) * USEC_PER_SEC +
-		(csr->split_timeout_lo >> 19) * 125L;
-
-	csr->expire = usecs_to_jiffies(usecs > 100000L ? usecs : 100000L);
+	unsigned int usecs = (csr->split_timeout_hi & 7) * 1000000 +
+			     (csr->split_timeout_lo >> 19) * 125;
 
 
+	csr->expire = usecs_to_jiffies(usecs > 100000 ? usecs : 100000);
 	HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
 	HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%u", csr->expire, HZ);
 }
 }
 
 

+ 8 - 16
drivers/ieee1394/dv1394.c

@@ -1536,27 +1536,20 @@ static ssize_t dv1394_read(struct file *file,  char __user *buffer, size_t count
 
 
 static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 {
-	struct video_card *video;
+	struct video_card *video = file_to_video_card(file);
 	unsigned long flags;
 	unsigned long flags;
 	int ret = -EINVAL;
 	int ret = -EINVAL;
 	void __user *argp = (void __user *)arg;
 	void __user *argp = (void __user *)arg;
 
 
 	DECLARE_WAITQUEUE(wait, current);
 	DECLARE_WAITQUEUE(wait, current);
 
 
-	lock_kernel();
-	video = file_to_video_card(file);
-
 	/* serialize this to prevent multi-threaded mayhem */
 	/* serialize this to prevent multi-threaded mayhem */
 	if (file->f_flags & O_NONBLOCK) {
 	if (file->f_flags & O_NONBLOCK) {
-		if (!mutex_trylock(&video->mtx)) {
-			unlock_kernel();
+		if (!mutex_trylock(&video->mtx))
 			return -EAGAIN;
 			return -EAGAIN;
-		}
 	} else {
 	} else {
-		if (mutex_lock_interruptible(&video->mtx)) {
-			unlock_kernel();
+		if (mutex_lock_interruptible(&video->mtx))
 			return -ERESTARTSYS;
 			return -ERESTARTSYS;
-		}
 	}
 	}
 
 
 	switch(cmd)
 	switch(cmd)
@@ -1780,7 +1773,6 @@ static long dv1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 
  out:
  out:
 	mutex_unlock(&video->mtx);
 	mutex_unlock(&video->mtx);
-	unlock_kernel();
 	return ret;
 	return ret;
 }
 }
 
 
@@ -2188,12 +2180,8 @@ static struct ieee1394_device_id dv1394_id_table[] = {
 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
 
 
 static struct hpsb_protocol_driver dv1394_driver = {
 static struct hpsb_protocol_driver dv1394_driver = {
-	.name		= "DV/1394 Driver",
+	.name		= "dv1394",
 	.id_table	= dv1394_id_table,
 	.id_table	= dv1394_id_table,
-	.driver         = {
-		.name	= "dv1394",
-		.bus	= &ieee1394_bus_type,
-	},
 };
 };
 
 
 
 
@@ -2587,6 +2575,10 @@ static int __init dv1394_init_module(void)
 {
 {
 	int ret;
 	int ret;
 
 
+	printk(KERN_WARNING
+	       "WARNING: The dv1394 driver is unsupported and will be removed "
+	       "from Linux soon. Use raw1394 instead.\n");
+
 	cdev_init(&dv1394_cdev, &dv1394_fops);
 	cdev_init(&dv1394_cdev, &dv1394_fops);
 	dv1394_cdev.owner = THIS_MODULE;
 	dv1394_cdev.owner = THIS_MODULE;
 	kobject_set_name(&dv1394_cdev.kobj, "dv1394");
 	kobject_set_name(&dv1394_cdev.kobj, "dv1394");

+ 1 - 3
drivers/ieee1394/eth1394.c

@@ -474,12 +474,10 @@ static struct ieee1394_device_id eth1394_id_table[] = {
 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
 
 
 static struct hpsb_protocol_driver eth1394_proto_driver = {
 static struct hpsb_protocol_driver eth1394_proto_driver = {
-	.name		= "IPv4 over 1394 Driver",
+	.name		= ETH1394_DRIVER_NAME,
 	.id_table	= eth1394_id_table,
 	.id_table	= eth1394_id_table,
 	.update		= eth1394_update,
 	.update		= eth1394_update,
 	.driver		= {
 	.driver		= {
-		.name		= ETH1394_DRIVER_NAME,
-		.bus		= &ieee1394_bus_type,
 		.probe		= eth1394_probe,
 		.probe		= eth1394_probe,
 		.remove		= eth1394_remove,
 		.remove		= eth1394_remove,
 	},
 	},

+ 0 - 1
drivers/ieee1394/highlevel.h

@@ -24,7 +24,6 @@ struct hpsb_address_serve {
 /* Only the following structures are of interest to actual highlevel drivers. */
 /* Only the following structures are of interest to actual highlevel drivers. */
 
 
 struct hpsb_highlevel {
 struct hpsb_highlevel {
-	struct module *owner;
 	const char *name;
 	const char *name;
 
 
 	/* Any of the following pointers can legally be NULL, except for
 	/* Any of the following pointers can legally be NULL, except for

+ 24 - 17
drivers/ieee1394/hosts.c

@@ -44,9 +44,10 @@ static void delayed_reset_bus(struct work_struct *work)
 
 
 	CSR_SET_BUS_INFO_GENERATION(host->csr.rom, generation);
 	CSR_SET_BUS_INFO_GENERATION(host->csr.rom, generation);
 	if (csr1212_generate_csr_image(host->csr.rom) != CSR1212_SUCCESS) {
 	if (csr1212_generate_csr_image(host->csr.rom) != CSR1212_SUCCESS) {
-		/* CSR image creation failed, reset generation field and do not
-		 * issue a bus reset. */
-		CSR_SET_BUS_INFO_GENERATION(host->csr.rom, host->csr.generation);
+		/* CSR image creation failed.
+		 * Reset generation field and do not issue a bus reset. */
+		CSR_SET_BUS_INFO_GENERATION(host->csr.rom,
+					    host->csr.generation);
 		return;
 		return;
 	}
 	}
 
 
@@ -54,7 +55,8 @@ static void delayed_reset_bus(struct work_struct *work)
 
 
 	host->update_config_rom = 0;
 	host->update_config_rom = 0;
 	if (host->driver->set_hw_config_rom)
 	if (host->driver->set_hw_config_rom)
-		host->driver->set_hw_config_rom(host, host->csr.rom->bus_info_data);
+		host->driver->set_hw_config_rom(host,
+						host->csr.rom->bus_info_data);
 
 
 	host->csr.gen_timestamp[host->csr.generation] = jiffies;
 	host->csr.gen_timestamp[host->csr.generation] = jiffies;
 	hpsb_reset_bus(host, SHORT_RESET);
 	hpsb_reset_bus(host, SHORT_RESET);
@@ -70,7 +72,8 @@ static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
 	return -1;
 	return -1;
 }
 }
 
 
-static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg)
+static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command,
+			unsigned long arg)
 {
 {
 	return -1;
 	return -1;
 }
 }
@@ -128,10 +131,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 		return NULL;
 		return NULL;
 
 
 	h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h);
 	h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h);
-	if (!h->csr.rom) {
-		kfree(h);
-		return NULL;
-	}
+	if (!h->csr.rom)
+		goto fail;
 
 
 	h->hostdata = h + 1;
 	h->hostdata = h + 1;
 	h->driver = drv;
 	h->driver = drv;
@@ -151,16 +152,15 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 	init_timer(&h->timeout);
 	init_timer(&h->timeout);
 	h->timeout.data = (unsigned long) h;
 	h->timeout.data = (unsigned long) h;
 	h->timeout.function = abort_timedouts;
 	h->timeout.function = abort_timedouts;
-	h->timeout_interval = HZ / 20; // 50ms by default
+	h->timeout_interval = HZ / 20; /* 50ms, half of minimum SPLIT_TIMEOUT */
 
 
 	h->topology_map = h->csr.topology_map + 3;
 	h->topology_map = h->csr.topology_map + 3;
 	h->speed_map = (u8 *)(h->csr.speed_map + 2);
 	h->speed_map = (u8 *)(h->csr.speed_map + 2);
 
 
 	mutex_lock(&host_num_alloc);
 	mutex_lock(&host_num_alloc);
-
 	while (nodemgr_for_each_host(&hostnum, alloc_hostnum_cb))
 	while (nodemgr_for_each_host(&hostnum, alloc_hostnum_cb))
 		hostnum++;
 		hostnum++;
-
+	mutex_unlock(&host_num_alloc);
 	h->id = hostnum;
 	h->id = hostnum;
 
 
 	memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
 	memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
@@ -171,13 +171,19 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 	h->class_dev.class = &hpsb_host_class;
 	h->class_dev.class = &hpsb_host_class;
 	snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id);
 	snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id);
 
 
-	device_register(&h->device);
-	class_device_register(&h->class_dev);
+	if (device_register(&h->device))
+		goto fail;
+	if (class_device_register(&h->class_dev)) {
+		device_unregister(&h->device);
+		goto fail;
+	}
 	get_device(&h->device);
 	get_device(&h->device);
 
 
-	mutex_unlock(&host_num_alloc);
-
 	return h;
 	return h;
+
+fail:
+	kfree(h);
+	return NULL;
 }
 }
 
 
 int hpsb_add_host(struct hpsb_host *host)
 int hpsb_add_host(struct hpsb_host *host)
@@ -229,7 +235,8 @@ int hpsb_update_config_rom_image(struct hpsb_host *host)
 	if (time_before(jiffies, host->csr.gen_timestamp[next_gen] + 60 * HZ))
 	if (time_before(jiffies, host->csr.gen_timestamp[next_gen] + 60 * HZ))
 		/* Wait 60 seconds from the last time this generation number was
 		/* Wait 60 seconds from the last time this generation number was
 		 * used. */
 		 * used. */
-		reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
+		reset_delay =
+			(60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
 	else
 	else
 		/* Wait 1 second in case some other code wants to change the
 		/* Wait 1 second in case some other code wants to change the
 		 * Config ROM in the near future. */
 		 * Config ROM in the near future. */

+ 2 - 2
drivers/ieee1394/ieee1394_core.c

@@ -1237,10 +1237,10 @@ EXPORT_SYMBOL(highlevel_remove_host);
 /** nodemgr.c **/
 /** nodemgr.c **/
 EXPORT_SYMBOL(hpsb_node_fill_packet);
 EXPORT_SYMBOL(hpsb_node_fill_packet);
 EXPORT_SYMBOL(hpsb_node_write);
 EXPORT_SYMBOL(hpsb_node_write);
-EXPORT_SYMBOL(hpsb_register_protocol);
+EXPORT_SYMBOL(__hpsb_register_protocol);
 EXPORT_SYMBOL(hpsb_unregister_protocol);
 EXPORT_SYMBOL(hpsb_unregister_protocol);
-EXPORT_SYMBOL(ieee1394_bus_type);
 #ifdef CONFIG_IEEE1394_EXPORT_FULL_API
 #ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(ieee1394_bus_type);
 EXPORT_SYMBOL(nodemgr_for_each_host);
 EXPORT_SYMBOL(nodemgr_for_each_host);
 #endif
 #endif
 
 

+ 280 - 185
drivers/ieee1394/nodemgr.c

@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/kthread.h>
+#include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/freezer.h>
 #include <linux/freezer.h>
 #include <asm/atomic.h>
 #include <asm/atomic.h>
@@ -67,7 +68,7 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
 {
 {
 	quadlet_t q;
 	quadlet_t q;
 	u8 i, *speed, old_speed, good_speed;
 	u8 i, *speed, old_speed, good_speed;
-	int ret;
+	int error;
 
 
 	speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
 	speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
 	old_speed = *speed;
 	old_speed = *speed;
@@ -79,9 +80,9 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
 	 * just finished its initialization. */
 	 * just finished its initialization. */
 	for (i = IEEE1394_SPEED_100; i <= old_speed; i++) {
 	for (i = IEEE1394_SPEED_100; i <= old_speed; i++) {
 		*speed = i;
 		*speed = i;
-		ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
-				&q, sizeof(quadlet_t));
-		if (ret)
+		error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
+				  &q, sizeof(quadlet_t));
+		if (error)
 			break;
 			break;
 		*buffer = q;
 		*buffer = q;
 		good_speed = i;
 		good_speed = i;
@@ -95,19 +96,19 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
 		return 0;
 		return 0;
 	}
 	}
 	*speed = old_speed;
 	*speed = old_speed;
-	return ret;
+	return error;
 }
 }
 
 
 static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
 static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
-                            void *buffer, void *__ci)
+			    void *buffer, void *__ci)
 {
 {
 	struct nodemgr_csr_info *ci = (struct nodemgr_csr_info*)__ci;
 	struct nodemgr_csr_info *ci = (struct nodemgr_csr_info*)__ci;
-	int i, ret;
+	int i, error;
 
 
 	for (i = 1; ; i++) {
 	for (i = 1; ; i++) {
-		ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
-				buffer, length);
-		if (!ret) {
+		error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
+				  buffer, length);
+		if (!error) {
 			ci->speed_unverified = 0;
 			ci->speed_unverified = 0;
 			break;
 			break;
 		}
 		}
@@ -118,14 +119,14 @@ static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
 		/* The ieee1394_core guessed the node's speed capability from
 		/* The ieee1394_core guessed the node's speed capability from
 		 * the self ID.  Check whether a lower speed works. */
 		 * the self ID.  Check whether a lower speed works. */
 		if (ci->speed_unverified && length == sizeof(quadlet_t)) {
 		if (ci->speed_unverified && length == sizeof(quadlet_t)) {
-			ret = nodemgr_check_speed(ci, addr, buffer);
-			if (!ret)
+			error = nodemgr_check_speed(ci, addr, buffer);
+			if (!error)
 				break;
 				break;
 		}
 		}
 		if (msleep_interruptible(334))
 		if (msleep_interruptible(334))
 			return -EINTR;
 			return -EINTR;
 	}
 	}
-	return ret;
+	return error;
 }
 }
 
 
 static int nodemgr_get_max_rom(quadlet_t *bus_info_data, void *__ci)
 static int nodemgr_get_max_rom(quadlet_t *bus_info_data, void *__ci)
@@ -260,9 +261,20 @@ static struct device nodemgr_dev_template_ne = {
 	.release	= nodemgr_release_ne,
 	.release	= nodemgr_release_ne,
 };
 };
 
 
+/* This dummy driver prevents the host devices from being scanned. We have no
+ * useful drivers for them yet, and there would be a deadlock possible if the
+ * driver core scans the host device while the host's low-level driver (i.e.
+ * the host's parent device) is being removed. */
+static struct device_driver nodemgr_mid_layer_driver = {
+	.bus		= &ieee1394_bus_type,
+	.name		= "nodemgr",
+	.owner		= THIS_MODULE,
+};
+
 struct device nodemgr_dev_template_host = {
 struct device nodemgr_dev_template_host = {
 	.bus		= &ieee1394_bus_type,
 	.bus		= &ieee1394_bus_type,
 	.release	= nodemgr_release_host,
 	.release	= nodemgr_release_host,
+	.driver		= &nodemgr_mid_layer_driver,
 };
 };
 
 
 
 
@@ -307,8 +319,8 @@ static ssize_t fw_drv_show_##field (struct device_driver *drv, char *buf) \
 	return sprintf(buf, format_string, (type)driver->field);\
 	return sprintf(buf, format_string, (type)driver->field);\
 }								\
 }								\
 static struct driver_attribute driver_attr_drv_##field = {	\
 static struct driver_attribute driver_attr_drv_##field = {	\
-        .attr = {.name = __stringify(field), .mode = S_IRUGO },	\
-        .show   = fw_drv_show_##field,				\
+	.attr = {.name = __stringify(field), .mode = S_IRUGO },	\
+	.show   = fw_drv_show_##field,				\
 };
 };
 
 
 
 
@@ -362,7 +374,7 @@ static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
 #endif
 #endif
 	spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
 	spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
 
 
-	return sprintf(buf, "0x%016llx\n", tm);
+	return sprintf(buf, "0x%016llx\n", (unsigned long long)tm);
 }
 }
 static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
 static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
 #endif /* HPSB_DEBUG_TLABELS */
 #endif /* HPSB_DEBUG_TLABELS */
@@ -374,11 +386,11 @@ static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute
 	int state = simple_strtoul(buf, NULL, 10);
 	int state = simple_strtoul(buf, NULL, 10);
 
 
 	if (state == 1) {
 	if (state == 1) {
-		down_write(&dev->bus->subsys.rwsem);
-		device_release_driver(dev);
 		ud->ignore_driver = 1;
 		ud->ignore_driver = 1;
-		up_write(&dev->bus->subsys.rwsem);
-	} else if (!state)
+		down_write(&ieee1394_bus_type.subsys.rwsem);
+		device_release_driver(dev);
+		up_write(&ieee1394_bus_type.subsys.rwsem);
+	} else if (state == 0)
 		ud->ignore_driver = 0;
 		ud->ignore_driver = 0;
 
 
 	return count;
 	return count;
@@ -413,11 +425,14 @@ static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
 static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
 static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
 
 
 
 
-static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count)
+static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf,
+			     size_t count)
 {
 {
+	int error = 0;
+
 	if (simple_strtoul(buf, NULL, 10) == 1)
 	if (simple_strtoul(buf, NULL, 10) == 1)
-		bus_rescan_devices(&ieee1394_bus_type);
-	return count;
+		error = bus_rescan_devices(&ieee1394_bus_type);
+	return error ? error : count;
 }
 }
 static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
 static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
 {
 {
@@ -433,7 +448,7 @@ static ssize_t fw_set_ignore_drivers(struct bus_type *bus, const char *buf, size
 
 
 	if (state == 1)
 	if (state == 1)
 		ignore_drivers = 1;
 		ignore_drivers = 1;
-	else if (!state)
+	else if (state == 0)
 		ignore_drivers = 0;
 		ignore_drivers = 0;
 
 
 	return count;
 	return count;
@@ -526,7 +541,7 @@ static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
 	int length = 0;
 	int length = 0;
 	char *scratch = buf;
 	char *scratch = buf;
 
 
-        driver = container_of(drv, struct hpsb_protocol_driver, driver);
+	driver = container_of(drv, struct hpsb_protocol_driver, driver);
 
 
 	for (id = driver->id_table; id->match_flags != 0; id++) {
 	for (id = driver->id_table; id->match_flags != 0; id++) {
 		int need_coma = 0;
 		int need_coma = 0;
@@ -583,7 +598,11 @@ static void nodemgr_create_drv_files(struct hpsb_protocol_driver *driver)
 	int i;
 	int i;
 
 
 	for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++)
 	for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++)
-		driver_create_file(drv, fw_drv_attrs[i]);
+		if (driver_create_file(drv, fw_drv_attrs[i]))
+			goto fail;
+	return;
+fail:
+	HPSB_ERR("Failed to add sysfs attribute for driver %s", driver->name);
 }
 }
 
 
 
 
@@ -603,7 +622,12 @@ static void nodemgr_create_ne_dev_files(struct node_entry *ne)
 	int i;
 	int i;
 
 
 	for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++)
 	for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++)
-		device_create_file(dev, fw_ne_attrs[i]);
+		if (device_create_file(dev, fw_ne_attrs[i]))
+			goto fail;
+	return;
+fail:
+	HPSB_ERR("Failed to add sysfs attribute for node %016Lx",
+		 (unsigned long long)ne->guid);
 }
 }
 
 
 
 
@@ -613,11 +637,16 @@ static void nodemgr_create_host_dev_files(struct hpsb_host *host)
 	int i;
 	int i;
 
 
 	for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++)
 	for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++)
-		device_create_file(dev, fw_host_attrs[i]);
+		if (device_create_file(dev, fw_host_attrs[i]))
+			goto fail;
+	return;
+fail:
+	HPSB_ERR("Failed to add sysfs attribute for host %d", host->id);
 }
 }
 
 
 
 
-static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid);
+static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
+					       nodeid_t nodeid);
 
 
 static void nodemgr_update_host_dev_links(struct hpsb_host *host)
 static void nodemgr_update_host_dev_links(struct hpsb_host *host)
 {
 {
@@ -628,12 +657,18 @@ static void nodemgr_update_host_dev_links(struct hpsb_host *host)
 	sysfs_remove_link(&dev->kobj, "busmgr_id");
 	sysfs_remove_link(&dev->kobj, "busmgr_id");
 	sysfs_remove_link(&dev->kobj, "host_id");
 	sysfs_remove_link(&dev->kobj, "host_id");
 
 
-	if ((ne = find_entry_by_nodeid(host, host->irm_id)))
-		sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id");
-	if ((ne = find_entry_by_nodeid(host, host->busmgr_id)))
-		sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id");
-	if ((ne = find_entry_by_nodeid(host, host->node_id)))
-		sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id");
+	if ((ne = find_entry_by_nodeid(host, host->irm_id)) &&
+	    sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id"))
+		goto fail;
+	if ((ne = find_entry_by_nodeid(host, host->busmgr_id)) &&
+	    sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id"))
+		goto fail;
+	if ((ne = find_entry_by_nodeid(host, host->node_id)) &&
+	    sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id"))
+		goto fail;
+	return;
+fail:
+	HPSB_ERR("Failed to update sysfs attributes for host %d", host->id);
 }
 }
 
 
 static void nodemgr_create_ud_dev_files(struct unit_directory *ud)
 static void nodemgr_create_ud_dev_files(struct unit_directory *ud)
@@ -642,32 +677,39 @@ static void nodemgr_create_ud_dev_files(struct unit_directory *ud)
 	int i;
 	int i;
 
 
 	for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++)
 	for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++)
-		device_create_file(dev, fw_ud_attrs[i]);
-
+		if (device_create_file(dev, fw_ud_attrs[i]))
+			goto fail;
 	if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
 	if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
-		device_create_file(dev, &dev_attr_ud_specifier_id);
-
+		if (device_create_file(dev, &dev_attr_ud_specifier_id))
+			goto fail;
 	if (ud->flags & UNIT_DIRECTORY_VERSION)
 	if (ud->flags & UNIT_DIRECTORY_VERSION)
-		device_create_file(dev, &dev_attr_ud_version);
-
+		if (device_create_file(dev, &dev_attr_ud_version))
+			goto fail;
 	if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) {
 	if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) {
-		device_create_file(dev, &dev_attr_ud_vendor_id);
-		if (ud->vendor_name_kv)
-			device_create_file(dev, &dev_attr_ud_vendor_name_kv);
+		if (device_create_file(dev, &dev_attr_ud_vendor_id))
+			goto fail;
+		if (ud->vendor_name_kv &&
+		    device_create_file(dev, &dev_attr_ud_vendor_name_kv))
+			goto fail;
 	}
 	}
-
 	if (ud->flags & UNIT_DIRECTORY_MODEL_ID) {
 	if (ud->flags & UNIT_DIRECTORY_MODEL_ID) {
-		device_create_file(dev, &dev_attr_ud_model_id);
-		if (ud->model_name_kv)
-			device_create_file(dev, &dev_attr_ud_model_name_kv);
+		if (device_create_file(dev, &dev_attr_ud_model_id))
+			goto fail;
+		if (ud->model_name_kv &&
+		    device_create_file(dev, &dev_attr_ud_model_name_kv))
+			goto fail;
 	}
 	}
+	return;
+fail:
+	HPSB_ERR("Failed to add sysfs attributes for unit %s",
+		 ud->device.bus_id);
 }
 }
 
 
 
 
 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
 {
 {
-        struct hpsb_protocol_driver *driver;
-        struct unit_directory *ud;
+	struct hpsb_protocol_driver *driver;
+	struct unit_directory *ud;
 	struct ieee1394_device_id *id;
 	struct ieee1394_device_id *id;
 
 
 	/* We only match unit directories */
 	/* We only match unit directories */
@@ -675,55 +717,77 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
 		return 0;
 		return 0;
 
 
 	ud = container_of(dev, struct unit_directory, device);
 	ud = container_of(dev, struct unit_directory, device);
-	driver = container_of(drv, struct hpsb_protocol_driver, driver);
-
 	if (ud->ne->in_limbo || ud->ignore_driver)
 	if (ud->ne->in_limbo || ud->ignore_driver)
 		return 0;
 		return 0;
 
 
-        for (id = driver->id_table; id->match_flags != 0; id++) {
-                if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
-                    id->vendor_id != ud->vendor_id)
-                        continue;
+	/* We only match drivers of type hpsb_protocol_driver */
+	if (drv == &nodemgr_mid_layer_driver)
+		return 0;
 
 
-                if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
-                    id->model_id != ud->model_id)
-                        continue;
+	driver = container_of(drv, struct hpsb_protocol_driver, driver);
+	for (id = driver->id_table; id->match_flags != 0; id++) {
+		if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
+		    id->vendor_id != ud->vendor_id)
+			continue;
 
 
-                if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
-                    id->specifier_id != ud->specifier_id)
-                        continue;
+		if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
+		    id->model_id != ud->model_id)
+			continue;
 
 
-                if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
-                    id->version != ud->version)
-                        continue;
+		if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
+		    id->specifier_id != ud->specifier_id)
+			continue;
+
+		if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
+		    id->version != ud->version)
+			continue;
 
 
 		return 1;
 		return 1;
-        }
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 
 
+static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
+
 static void nodemgr_remove_uds(struct node_entry *ne)
 static void nodemgr_remove_uds(struct node_entry *ne)
 {
 {
-	struct class_device *cdev, *next;
-	struct unit_directory *ud;
-
-	list_for_each_entry_safe(cdev, next, &nodemgr_ud_class.children, node) {
-		ud = container_of(cdev, struct unit_directory, class_dev);
-
-		if (ud->ne != ne)
-			continue;
-
+	struct class_device *cdev;
+	struct unit_directory *tmp, *ud;
+
+	/* Iteration over nodemgr_ud_class.children has to be protected by
+	 * nodemgr_ud_class.sem, but class_device_unregister() will eventually
+	 * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time,
+	 * release the semaphore, and then unregister the ud. Since this code
+	 * may be called from other contexts besides the knodemgrds, protect the
+	 * gap after release of the semaphore by nodemgr_serialize_remove_uds.
+	 */
+	mutex_lock(&nodemgr_serialize_remove_uds);
+	for (;;) {
+		ud = NULL;
+		down(&nodemgr_ud_class.sem);
+		list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
+			tmp = container_of(cdev, struct unit_directory,
+					   class_dev);
+			if (tmp->ne == ne) {
+				ud = tmp;
+				break;
+			}
+		}
+		up(&nodemgr_ud_class.sem);
+		if (ud == NULL)
+			break;
 		class_device_unregister(&ud->class_dev);
 		class_device_unregister(&ud->class_dev);
 		device_unregister(&ud->device);
 		device_unregister(&ud->device);
 	}
 	}
+	mutex_unlock(&nodemgr_serialize_remove_uds);
 }
 }
 
 
 
 
 static void nodemgr_remove_ne(struct node_entry *ne)
 static void nodemgr_remove_ne(struct node_entry *ne)
 {
 {
-	struct device *dev = &ne->device;
+	struct device *dev;
 
 
 	dev = get_device(&ne->device);
 	dev = get_device(&ne->device);
 	if (!dev)
 	if (!dev)
@@ -748,7 +812,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data)
 
 
 static void nodemgr_remove_host_dev(struct device *dev)
 static void nodemgr_remove_host_dev(struct device *dev)
 {
 {
-	device_for_each_child(dev, NULL, __nodemgr_remove_host_dev);
+	WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev));
 	sysfs_remove_link(&dev->kobj, "irm_id");
 	sysfs_remove_link(&dev->kobj, "irm_id");
 	sysfs_remove_link(&dev->kobj, "busmgr_id");
 	sysfs_remove_link(&dev->kobj, "busmgr_id");
 	sysfs_remove_link(&dev->kobj, "host_id");
 	sysfs_remove_link(&dev->kobj, "host_id");
@@ -762,16 +826,16 @@ static void nodemgr_update_bus_options(struct node_entry *ne)
 #endif
 #endif
 	quadlet_t busoptions = be32_to_cpu(ne->csr->bus_info_data[2]);
 	quadlet_t busoptions = be32_to_cpu(ne->csr->bus_info_data[2]);
 
 
-	ne->busopt.irmc         = (busoptions >> 31) & 1;
-	ne->busopt.cmc          = (busoptions >> 30) & 1;
-	ne->busopt.isc          = (busoptions >> 29) & 1;
-	ne->busopt.bmc          = (busoptions >> 28) & 1;
-	ne->busopt.pmc          = (busoptions >> 27) & 1;
-	ne->busopt.cyc_clk_acc  = (busoptions >> 16) & 0xff;
-	ne->busopt.max_rec      = 1 << (((busoptions >> 12) & 0xf) + 1);
+	ne->busopt.irmc		= (busoptions >> 31) & 1;
+	ne->busopt.cmc		= (busoptions >> 30) & 1;
+	ne->busopt.isc		= (busoptions >> 29) & 1;
+	ne->busopt.bmc		= (busoptions >> 28) & 1;
+	ne->busopt.pmc		= (busoptions >> 27) & 1;
+	ne->busopt.cyc_clk_acc	= (busoptions >> 16) & 0xff;
+	ne->busopt.max_rec	= 1 << (((busoptions >> 12) & 0xf) + 1);
 	ne->busopt.max_rom	= (busoptions >> 8) & 0x3;
 	ne->busopt.max_rom	= (busoptions >> 8) & 0x3;
-	ne->busopt.generation   = (busoptions >> 4) & 0xf;
-	ne->busopt.lnkspd       = busoptions & 0x7;
+	ne->busopt.generation	= (busoptions >> 4) & 0xf;
+	ne->busopt.lnkspd	= busoptions & 0x7;
 
 
 	HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
 	HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
 		     "cyc_clk_acc=%d max_rec=%d max_rom=%d gen=%d lspd=%d",
 		     "cyc_clk_acc=%d max_rec=%d max_rom=%d gen=%d lspd=%d",
@@ -792,7 +856,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
 
 
 	ne = kzalloc(sizeof(*ne), GFP_KERNEL);
 	ne = kzalloc(sizeof(*ne), GFP_KERNEL);
 	if (!ne)
 	if (!ne)
-		return NULL;
+		goto fail_alloc;
 
 
 	ne->host = host;
 	ne->host = host;
 	ne->nodeid = nodeid;
 	ne->nodeid = nodeid;
@@ -815,12 +879,15 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
 	snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx",
 	snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx",
 		 (unsigned long long)(ne->guid));
 		 (unsigned long long)(ne->guid));
 
 
-	device_register(&ne->device);
-	class_device_register(&ne->class_dev);
+	if (device_register(&ne->device))
+		goto fail_devreg;
+	if (class_device_register(&ne->class_dev))
+		goto fail_classdevreg;
 	get_device(&ne->device);
 	get_device(&ne->device);
 
 
-	if (ne->guid_vendor_oui)
-		device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui);
+	if (ne->guid_vendor_oui &&
+	    device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui))
+		goto fail_addoiu;
 	nodemgr_create_ne_dev_files(ne);
 	nodemgr_create_ne_dev_files(ne);
 
 
 	nodemgr_update_bus_options(ne);
 	nodemgr_update_bus_options(ne);
@@ -830,17 +897,28 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
 		   NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
 		   NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
 
 
 	return ne;
 	return ne;
+
+fail_addoiu:
+	put_device(&ne->device);
+fail_classdevreg:
+	device_unregister(&ne->device);
+fail_devreg:
+	kfree(ne);
+fail_alloc:
+	HPSB_ERR("Failed to create node ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
+		 NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
+
+	return NULL;
 }
 }
 
 
 
 
 static struct node_entry *find_entry_by_guid(u64 guid)
 static struct node_entry *find_entry_by_guid(u64 guid)
 {
 {
-	struct class *class = &nodemgr_ne_class;
 	struct class_device *cdev;
 	struct class_device *cdev;
 	struct node_entry *ne, *ret_ne = NULL;
 	struct node_entry *ne, *ret_ne = NULL;
 
 
-	down_read(&class->subsys.rwsem);
-	list_for_each_entry(cdev, &class->children, node) {
+	down(&nodemgr_ne_class.sem);
+	list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
 		ne = container_of(cdev, struct node_entry, class_dev);
 		ne = container_of(cdev, struct node_entry, class_dev);
 
 
 		if (ne->guid == guid) {
 		if (ne->guid == guid) {
@@ -848,20 +926,20 @@ static struct node_entry *find_entry_by_guid(u64 guid)
 			break;
 			break;
 		}
 		}
 	}
 	}
-	up_read(&class->subsys.rwsem);
+	up(&nodemgr_ne_class.sem);
 
 
-        return ret_ne;
+	return ret_ne;
 }
 }
 
 
 
 
-static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid)
+static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
+					       nodeid_t nodeid)
 {
 {
-	struct class *class = &nodemgr_ne_class;
 	struct class_device *cdev;
 	struct class_device *cdev;
 	struct node_entry *ne, *ret_ne = NULL;
 	struct node_entry *ne, *ret_ne = NULL;
 
 
-	down_read(&class->subsys.rwsem);
-	list_for_each_entry(cdev, &class->children, node) {
+	down(&nodemgr_ne_class.sem);
+	list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
 		ne = container_of(cdev, struct node_entry, class_dev);
 		ne = container_of(cdev, struct node_entry, class_dev);
 
 
 		if (ne->host == host && ne->nodeid == nodeid) {
 		if (ne->host == host && ne->nodeid == nodeid) {
@@ -869,7 +947,7 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t
 			break;
 			break;
 		}
 		}
 	}
 	}
-	up_read(&class->subsys.rwsem);
+	up(&nodemgr_ne_class.sem);
 
 
 	return ret_ne;
 	return ret_ne;
 }
 }
@@ -891,13 +969,25 @@ static void nodemgr_register_device(struct node_entry *ne,
 	snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
 	snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u",
 		 ne->device.bus_id, ud->id);
 		 ne->device.bus_id, ud->id);
 
 
-	device_register(&ud->device);
-	class_device_register(&ud->class_dev);
+	if (device_register(&ud->device))
+		goto fail_devreg;
+	if (class_device_register(&ud->class_dev))
+		goto fail_classdevreg;
 	get_device(&ud->device);
 	get_device(&ud->device);
 
 
-	if (ud->vendor_oui)
-		device_create_file(&ud->device, &dev_attr_ud_vendor_oui);
+	if (ud->vendor_oui &&
+	    device_create_file(&ud->device, &dev_attr_ud_vendor_oui))
+		goto fail_addoui;
 	nodemgr_create_ud_dev_files(ud);
 	nodemgr_create_ud_dev_files(ud);
+
+	return;
+
+fail_addoui:
+	put_device(&ud->device);
+fail_classdevreg:
+	device_unregister(&ud->device);
+fail_devreg:
+	HPSB_ERR("Failed to create unit %s", ud->device.bus_id);
 }	
 }	
 
 
 
 
@@ -977,10 +1067,9 @@ static struct unit_directory *nodemgr_process_unit_directory
 			/* Logical Unit Number */
 			/* Logical Unit Number */
 			if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
 			if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
 				if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
 				if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
-					ud_child = kmalloc(sizeof(*ud_child), GFP_KERNEL);
+					ud_child = kmemdup(ud, sizeof(*ud_child), GFP_KERNEL);
 					if (!ud_child)
 					if (!ud_child)
 						goto unit_directory_error;
 						goto unit_directory_error;
-					memcpy(ud_child, ud, sizeof(*ud_child));
 					nodemgr_register_device(ne, ud_child, &ne->device);
 					nodemgr_register_device(ne, ud_child, &ne->device);
 					ud_child = NULL;
 					ud_child = NULL;
 					
 					
@@ -1094,10 +1183,16 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
 		last_key_id = kv->key.id;
 		last_key_id = kv->key.id;
 	}
 	}
 
 
-	if (ne->vendor_oui)
-		device_create_file(&ne->device, &dev_attr_ne_vendor_oui);
-	if (ne->vendor_name_kv)
-		device_create_file(&ne->device, &dev_attr_ne_vendor_name_kv);
+	if (ne->vendor_oui &&
+	    device_create_file(&ne->device, &dev_attr_ne_vendor_oui))
+		goto fail;
+	if (ne->vendor_name_kv &&
+	    device_create_file(&ne->device, &dev_attr_ne_vendor_name_kv))
+		goto fail;
+	return;
+fail:
+	HPSB_ERR("Failed to add sysfs attribute for node %016Lx",
+		 (unsigned long long)ne->guid);
 }
 }
 
 
 #ifdef CONFIG_HOTPLUG
 #ifdef CONFIG_HOTPLUG
@@ -1161,16 +1256,20 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
 #endif /* CONFIG_HOTPLUG */
 #endif /* CONFIG_HOTPLUG */
 
 
 
 
-int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
+int __hpsb_register_protocol(struct hpsb_protocol_driver *drv,
+			     struct module *owner)
 {
 {
-	int ret;
+	int error;
 
 
-	/* This will cause a probe for devices */
-	ret = driver_register(&driver->driver);
-	if (!ret)
-		nodemgr_create_drv_files(driver);
+	drv->driver.bus = &ieee1394_bus_type;
+	drv->driver.owner = owner;
+	drv->driver.name = drv->name;
 
 
-	return ret;
+	/* This will cause a probe for devices */
+	error = driver_register(&drv->driver);
+	if (!error)
+		nodemgr_create_drv_files(drv);
+	return error;
 }
 }
 
 
 void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
 void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
@@ -1298,26 +1397,25 @@ static void nodemgr_node_scan_one(struct host_info *hi,
 
 
 static void nodemgr_node_scan(struct host_info *hi, int generation)
 static void nodemgr_node_scan(struct host_info *hi, int generation)
 {
 {
-        int count;
-        struct hpsb_host *host = hi->host;
-        struct selfid *sid = (struct selfid *)host->topology_map;
-        nodeid_t nodeid = LOCAL_BUS;
+	int count;
+	struct hpsb_host *host = hi->host;
+	struct selfid *sid = (struct selfid *)host->topology_map;
+	nodeid_t nodeid = LOCAL_BUS;
 
 
-        /* Scan each node on the bus */
-        for (count = host->selfid_count; count; count--, sid++) {
-                if (sid->extended)
-                        continue;
+	/* Scan each node on the bus */
+	for (count = host->selfid_count; count; count--, sid++) {
+		if (sid->extended)
+			continue;
 
 
-                if (!sid->link_active) {
-                        nodeid++;
-                        continue;
-                }
-                nodemgr_node_scan_one(hi, nodeid++, generation);
-        }
+		if (!sid->link_active) {
+			nodeid++;
+			continue;
+		}
+		nodemgr_node_scan_one(hi, nodeid++, generation);
+	}
 }
 }
 
 
 
 
-/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
 static void nodemgr_suspend_ne(struct node_entry *ne)
 static void nodemgr_suspend_ne(struct node_entry *ne)
 {
 {
 	struct class_device *cdev;
 	struct class_device *cdev;
@@ -1327,21 +1425,22 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
 		   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 		   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 
 
 	ne->in_limbo = 1;
 	ne->in_limbo = 1;
-	device_create_file(&ne->device, &dev_attr_ne_in_limbo);
+	WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
 
 
-	down_write(&ne->device.bus->subsys.rwsem);
+	down(&nodemgr_ud_class.sem);
 	list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
 	list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
 		ud = container_of(cdev, struct unit_directory, class_dev);
 		ud = container_of(cdev, struct unit_directory, class_dev);
-
 		if (ud->ne != ne)
 		if (ud->ne != ne)
 			continue;
 			continue;
 
 
+		down_write(&ieee1394_bus_type.subsys.rwsem);
 		if (ud->device.driver &&
 		if (ud->device.driver &&
 		    (!ud->device.driver->suspend ||
 		    (!ud->device.driver->suspend ||
 		      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
 		      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
 			device_release_driver(&ud->device);
 			device_release_driver(&ud->device);
+		up_write(&ieee1394_bus_type.subsys.rwsem);
 	}
 	}
-	up_write(&ne->device.bus->subsys.rwsem);
+	up(&nodemgr_ud_class.sem);
 }
 }
 
 
 
 
@@ -1353,45 +1452,47 @@ static void nodemgr_resume_ne(struct node_entry *ne)
 	ne->in_limbo = 0;
 	ne->in_limbo = 0;
 	device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
 	device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
 
 
-	down_read(&nodemgr_ud_class.subsys.rwsem);
-	down_read(&ne->device.bus->subsys.rwsem);
+	down(&nodemgr_ud_class.sem);
 	list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
 	list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
 		ud = container_of(cdev, struct unit_directory, class_dev);
 		ud = container_of(cdev, struct unit_directory, class_dev);
-
 		if (ud->ne != ne)
 		if (ud->ne != ne)
 			continue;
 			continue;
 
 
+		down_read(&ieee1394_bus_type.subsys.rwsem);
 		if (ud->device.driver && ud->device.driver->resume)
 		if (ud->device.driver && ud->device.driver->resume)
 			ud->device.driver->resume(&ud->device);
 			ud->device.driver->resume(&ud->device);
+		up_read(&ieee1394_bus_type.subsys.rwsem);
 	}
 	}
-	up_read(&ne->device.bus->subsys.rwsem);
-	up_read(&nodemgr_ud_class.subsys.rwsem);
+	up(&nodemgr_ud_class.sem);
 
 
 	HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
 	HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
 		   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 		   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 }
 }
 
 
 
 
-/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
 static void nodemgr_update_pdrv(struct node_entry *ne)
 static void nodemgr_update_pdrv(struct node_entry *ne)
 {
 {
 	struct unit_directory *ud;
 	struct unit_directory *ud;
 	struct hpsb_protocol_driver *pdrv;
 	struct hpsb_protocol_driver *pdrv;
 	struct class_device *cdev;
 	struct class_device *cdev;
 
 
+	down(&nodemgr_ud_class.sem);
 	list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
 	list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
 		ud = container_of(cdev, struct unit_directory, class_dev);
 		ud = container_of(cdev, struct unit_directory, class_dev);
-		if (ud->ne != ne || !ud->device.driver)
+		if (ud->ne != ne)
 			continue;
 			continue;
 
 
-		pdrv = container_of(ud->device.driver, struct hpsb_protocol_driver, driver);
-
-		if (pdrv->update && pdrv->update(ud)) {
-			down_write(&ud->device.bus->subsys.rwsem);
-			device_release_driver(&ud->device);
-			up_write(&ud->device.bus->subsys.rwsem);
+		down_write(&ieee1394_bus_type.subsys.rwsem);
+		if (ud->device.driver) {
+			pdrv = container_of(ud->device.driver,
+					    struct hpsb_protocol_driver,
+					    driver);
+			if (pdrv->update && pdrv->update(ud))
+				device_release_driver(&ud->device);
 		}
 		}
+		up_write(&ieee1394_bus_type.subsys.rwsem);
 	}
 	}
+	up(&nodemgr_ud_class.sem);
 }
 }
 
 
 
 
@@ -1405,7 +1506,7 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
 {
 {
 	const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
 	const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
 	quadlet_t bc_remote, bc_local;
 	quadlet_t bc_remote, bc_local;
-	int ret;
+	int error;
 
 
 	if (!ne->host->is_irm || ne->generation != generation ||
 	if (!ne->host->is_irm || ne->generation != generation ||
 	    ne->nodeid == ne->host->node_id)
 	    ne->nodeid == ne->host->node_id)
@@ -1414,16 +1515,14 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
 	bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
 	bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
 
 
 	/* Check if the register is implemented and 1394a compliant. */
 	/* Check if the register is implemented and 1394a compliant. */
-	ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
-			sizeof(bc_remote));
-	if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
+	error = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
+			  sizeof(bc_remote));
+	if (!error && bc_remote & cpu_to_be32(0x80000000) &&
 	    bc_remote != bc_local)
 	    bc_remote != bc_local)
 		hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
 		hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
 }
 }
 
 
 
 
-/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader because the
- * calls to nodemgr_update_pdrv() and nodemgr_suspend_ne() here require it. */
 static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
 static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
 {
 {
 	struct device *dev;
 	struct device *dev;
@@ -1456,7 +1555,6 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
 static void nodemgr_node_probe(struct host_info *hi, int generation)
 static void nodemgr_node_probe(struct host_info *hi, int generation)
 {
 {
 	struct hpsb_host *host = hi->host;
 	struct hpsb_host *host = hi->host;
-	struct class *class = &nodemgr_ne_class;
 	struct class_device *cdev;
 	struct class_device *cdev;
 	struct node_entry *ne;
 	struct node_entry *ne;
 
 
@@ -1469,18 +1567,18 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
 	 * while probes are time-consuming. (Well, those probes need some
 	 * while probes are time-consuming. (Well, those probes need some
 	 * improvement...) */
 	 * improvement...) */
 
 
-	down_read(&class->subsys.rwsem);
-	list_for_each_entry(cdev, &class->children, node) {
+	down(&nodemgr_ne_class.sem);
+	list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
 		ne = container_of(cdev, struct node_entry, class_dev);
 		ne = container_of(cdev, struct node_entry, class_dev);
 		if (!ne->needs_probe)
 		if (!ne->needs_probe)
 			nodemgr_probe_ne(hi, ne, generation);
 			nodemgr_probe_ne(hi, ne, generation);
 	}
 	}
-	list_for_each_entry(cdev, &class->children, node) {
+	list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
 		ne = container_of(cdev, struct node_entry, class_dev);
 		ne = container_of(cdev, struct node_entry, class_dev);
 		if (ne->needs_probe)
 		if (ne->needs_probe)
 			nodemgr_probe_ne(hi, ne, generation);
 			nodemgr_probe_ne(hi, ne, generation);
 	}
 	}
-        up_read(&class->subsys.rwsem);
+	up(&nodemgr_ne_class.sem);
 
 
 
 
 	/* If we had a bus reset while we were scanning the bus, it is
 	/* If we had a bus reset while we were scanning the bus, it is
@@ -1498,15 +1596,14 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
 	 * just removed.  */
 	 * just removed.  */
 
 
 	if (generation == get_hpsb_generation(host))
 	if (generation == get_hpsb_generation(host))
-		bus_rescan_devices(&ieee1394_bus_type);
-
-	return;
+		if (bus_rescan_devices(&ieee1394_bus_type))
+			HPSB_DEBUG("bus_rescan_devices had an error");
 }
 }
 
 
 static int nodemgr_send_resume_packet(struct hpsb_host *host)
 static int nodemgr_send_resume_packet(struct hpsb_host *host)
 {
 {
 	struct hpsb_packet *packet;
 	struct hpsb_packet *packet;
-	int ret = 1;
+	int error = -ENOMEM;
 
 
 	packet = hpsb_make_phypacket(host,
 	packet = hpsb_make_phypacket(host,
 			EXTPHYPACKET_TYPE_RESUME |
 			EXTPHYPACKET_TYPE_RESUME |
@@ -1514,12 +1611,12 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host)
 	if (packet) {
 	if (packet) {
 		packet->no_waiter = 1;
 		packet->no_waiter = 1;
 		packet->generation = get_hpsb_generation(host);
 		packet->generation = get_hpsb_generation(host);
-		ret = hpsb_send_packet(packet);
+		error = hpsb_send_packet(packet);
 	}
 	}
-	if (ret)
+	if (error)
 		HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
 		HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
 			  host->id);
 			  host->id);
-	return ret;
+	return error;
 }
 }
 
 
 /* Perform a few high-level IRM responsibilities. */
 /* Perform a few high-level IRM responsibilities. */
@@ -1692,19 +1789,18 @@ exit:
 
 
 int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
 int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
 {
 {
-	struct class *class = &hpsb_host_class;
 	struct class_device *cdev;
 	struct class_device *cdev;
 	struct hpsb_host *host;
 	struct hpsb_host *host;
 	int error = 0;
 	int error = 0;
 
 
-	down_read(&class->subsys.rwsem);
-	list_for_each_entry(cdev, &class->children, node) {
+	down(&hpsb_host_class.sem);
+	list_for_each_entry(cdev, &hpsb_host_class.children, node) {
 		host = container_of(cdev, struct hpsb_host, class_dev);
 		host = container_of(cdev, struct hpsb_host, class_dev);
 
 
 		if ((error = cb(host, __data)))
 		if ((error = cb(host, __data)))
 			break;
 			break;
 	}
 	}
-	up_read(&class->subsys.rwsem);
+	up(&hpsb_host_class.sem);
 
 
 	return error;
 	return error;
 }
 }
@@ -1726,10 +1822,10 @@ int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
 
 
 void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
 void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
 {
 {
-        pkt->host = ne->host;
-        pkt->generation = ne->generation;
+	pkt->host = ne->host;
+	pkt->generation = ne->generation;
 	barrier();
 	barrier();
-        pkt->node_id = ne->nodeid;
+	pkt->node_id = ne->nodeid;
 }
 }
 
 
 int hpsb_node_write(struct node_entry *ne, u64 addr,
 int hpsb_node_write(struct node_entry *ne, u64 addr,
@@ -1789,26 +1885,25 @@ static struct hpsb_highlevel nodemgr_highlevel = {
 
 
 int init_ieee1394_nodemgr(void)
 int init_ieee1394_nodemgr(void)
 {
 {
-	int ret;
+	int error;
 
 
-	ret = class_register(&nodemgr_ne_class);
-	if (ret < 0)
-		return ret;
+	error = class_register(&nodemgr_ne_class);
+	if (error)
+		return error;
 
 
-	ret = class_register(&nodemgr_ud_class);
-	if (ret < 0) {
+	error = class_register(&nodemgr_ud_class);
+	if (error) {
 		class_unregister(&nodemgr_ne_class);
 		class_unregister(&nodemgr_ne_class);
-		return ret;
+		return error;
 	}
 	}
-
+	error = driver_register(&nodemgr_mid_layer_driver);
 	hpsb_register_highlevel(&nodemgr_highlevel);
 	hpsb_register_highlevel(&nodemgr_highlevel);
-
 	return 0;
 	return 0;
 }
 }
 
 
 void cleanup_ieee1394_nodemgr(void)
 void cleanup_ieee1394_nodemgr(void)
 {
 {
-        hpsb_unregister_highlevel(&nodemgr_highlevel);
+	hpsb_unregister_highlevel(&nodemgr_highlevel);
 
 
 	class_unregister(&nodemgr_ud_class);
 	class_unregister(&nodemgr_ud_class);
 	class_unregister(&nodemgr_ne_class);
 	class_unregister(&nodemgr_ne_class);

+ 6 - 1
drivers/ieee1394/nodemgr.h

@@ -144,7 +144,12 @@ struct hpsb_protocol_driver {
 	struct device_driver driver;
 	struct device_driver driver;
 };
 };
 
 
-int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
+int __hpsb_register_protocol(struct hpsb_protocol_driver *, struct module *);
+static inline int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
+{
+	return __hpsb_register_protocol(driver, THIS_MODULE);
+}
+
 void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
 void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
 
 
 static inline int hpsb_node_entry_valid(struct node_entry *ne)
 static inline int hpsb_node_entry_valid(struct node_entry *ne)

+ 95 - 45
drivers/ieee1394/ohci1394.c

@@ -468,7 +468,6 @@ static int get_nb_iso_ctx(struct ti_ohci *ohci, int reg)
 /* Global initialization */
 /* Global initialization */
 static void ohci_initialize(struct ti_ohci *ohci)
 static void ohci_initialize(struct ti_ohci *ohci)
 {
 {
-	char irq_buf[16];
 	quadlet_t buf;
 	quadlet_t buf;
 	int num_ports, i;
 	int num_ports, i;
 
 
@@ -586,11 +585,10 @@ static void ohci_initialize(struct ti_ohci *ohci)
 	reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
 	reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
 
 
 	buf = reg_read(ohci, OHCI1394_Version);
 	buf = reg_read(ohci, OHCI1394_Version);
-	sprintf (irq_buf, "%d", ohci->dev->irq);
-	PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s]  "
+	PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%d]  "
 	      "MMIO=[%llx-%llx]  Max Packet=[%d]  IR/IT contexts=[%d/%d]",
 	      "MMIO=[%llx-%llx]  Max Packet=[%d]  IR/IT contexts=[%d/%d]",
 	      ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
 	      ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
-	      ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf,
+	      ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq,
 	      (unsigned long long)pci_resource_start(ohci->dev, 0),
 	      (unsigned long long)pci_resource_start(ohci->dev, 0),
 	      (unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
 	      (unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
 	      ohci->max_packet_size,
 	      ohci->max_packet_size,
@@ -3217,6 +3215,18 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
 	struct ti_ohci *ohci;	/* shortcut to currently handled device */
 	struct ti_ohci *ohci;	/* shortcut to currently handled device */
 	resource_size_t ohci_base;
 	resource_size_t ohci_base;
 
 
+#ifdef CONFIG_PPC_PMAC
+	/* Necessary on some machines if ohci1394 was loaded/ unloaded before */
+	if (machine_is(powermac)) {
+		struct device_node *ofn = pci_device_to_OF_node(dev);
+
+		if (ofn) {
+			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 1);
+			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+		}
+	}
+#endif /* CONFIG_PPC_PMAC */
+
         if (pci_enable_device(dev))
         if (pci_enable_device(dev))
 		FAIL(-ENXIO, "Failed to enable OHCI hardware");
 		FAIL(-ENXIO, "Failed to enable OHCI hardware");
         pci_set_master(dev);
         pci_set_master(dev);
@@ -3505,17 +3515,14 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
 #endif
 #endif
 
 
 #ifdef CONFIG_PPC_PMAC
 #ifdef CONFIG_PPC_PMAC
-	/* On UniNorth, power down the cable and turn off the chip
-	 * clock when the module is removed to save power on
-	 * laptops. Turning it back ON is done by the arch code when
-	 * pci_enable_device() is called */
-	{
-		struct device_node* of_node;
+	/* On UniNorth, power down the cable and turn off the chip clock
+	 * to save power on laptops */
+	if (machine_is(powermac)) {
+		struct device_node* ofn = pci_device_to_OF_node(ohci->dev);
 
 
-		of_node = pci_device_to_OF_node(ohci->dev);
-		if (of_node) {
-			pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
-			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node, 0, 0);
+		if (ofn) {
+			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
+			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
 		}
 		}
 	}
 	}
 #endif /* CONFIG_PPC_PMAC */
 #endif /* CONFIG_PPC_PMAC */
@@ -3529,59 +3536,102 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
 }
 }
 
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
-static int ohci1394_pci_resume (struct pci_dev *pdev)
-{
-/* PowerMac resume code comes first */
-#ifdef CONFIG_PPC_PMAC
-	if (machine_is(powermac)) {
-		struct device_node *of_node;
-
-		/* Re-enable 1394 */
-		of_node = pci_device_to_OF_node (pdev);
-		if (of_node)
-			pmac_call_feature (PMAC_FTR_1394_ENABLE, of_node, 0, 1);
-	}
-#endif /* CONFIG_PPC_PMAC */
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	return pci_enable_device(pdev);
-}
-
-static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
+static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 {
 	int err;
 	int err;
+	struct ti_ohci *ohci = pci_get_drvdata(pdev);
 
 
 	printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
 	printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
 	       OHCI1394_DRIVER_NAME);
 	       OHCI1394_DRIVER_NAME);
 
 
+	if (!ohci) {
+		printk(KERN_ERR "%s: tried to suspend nonexisting host\n",
+		       OHCI1394_DRIVER_NAME);
+		return -ENXIO;
+	}
+	DBGMSG("suspend called");
+
+	/* Clear the async DMA contexts and stop using the controller */
+	hpsb_bus_reset(ohci->host);
+
+	/* See ohci1394_pci_remove() for comments on this sequence */
+	reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
+	reg_write(ohci, OHCI1394_BusOptions,
+		  (reg_read(ohci, OHCI1394_BusOptions) & 0x0000f007) |
+		  0x00ff0000);
+	reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
+	reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
+	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
+	reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
+	reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);
+	reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);
+	set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4));
+	reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
+	ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT);
+	ohci_soft_reset(ohci);
+
 	err = pci_save_state(pdev);
 	err = pci_save_state(pdev);
 	if (err) {
 	if (err) {
-		printk(KERN_ERR "%s: pci_save_state failed with %d\n",
-		       OHCI1394_DRIVER_NAME, err);
+		PRINT(KERN_ERR, "pci_save_state failed with %d", err);
 		return err;
 		return err;
 	}
 	}
 	err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
 	err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
-#ifdef OHCI1394_DEBUG
 	if (err)
 	if (err)
-		printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n",
-		       OHCI1394_DRIVER_NAME, err);
-#endif /* OHCI1394_DEBUG */
+		DBGMSG("pci_set_power_state failed with %d", err);
 
 
 /* PowerMac suspend code comes last */
 /* PowerMac suspend code comes last */
 #ifdef CONFIG_PPC_PMAC
 #ifdef CONFIG_PPC_PMAC
 	if (machine_is(powermac)) {
 	if (machine_is(powermac)) {
-		struct device_node *of_node;
+		struct device_node *ofn = pci_device_to_OF_node(pdev);
 
 
-		/* Disable 1394 */
-		of_node = pci_device_to_OF_node (pdev);
-		if (of_node)
-			pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
+		if (ofn)
+			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
 	}
 	}
 #endif /* CONFIG_PPC_PMAC */
 #endif /* CONFIG_PPC_PMAC */
 
 
 	return 0;
 	return 0;
 }
 }
+
+static int ohci1394_pci_resume(struct pci_dev *pdev)
+{
+	int err;
+	struct ti_ohci *ohci = pci_get_drvdata(pdev);
+
+	if (!ohci) {
+		printk(KERN_ERR "%s: tried to resume nonexisting host\n",
+		       OHCI1394_DRIVER_NAME);
+		return -ENXIO;
+	}
+	DBGMSG("resume called");
+
+/* PowerMac resume code comes first */
+#ifdef CONFIG_PPC_PMAC
+	if (machine_is(powermac)) {
+		struct device_node *ofn = pci_device_to_OF_node(pdev);
+
+		if (ofn)
+			pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+	}
+#endif /* CONFIG_PPC_PMAC */
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	err = pci_enable_device(pdev);
+	if (err) {
+		PRINT(KERN_ERR, "pci_enable_device failed with %d", err);
+		return err;
+	}
+
+	/* See ohci1394_pci_probe() for comments on this sequence */
+	ohci_soft_reset(ohci);
+	reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS);
+	reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
+	reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
+	mdelay(50);
+	ohci_initialize(ohci);
+
+	return 0;
+}
 #endif /* CONFIG_PM */
 #endif /* CONFIG_PM */
 
 
 #define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
 #define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)

+ 1 - 2
drivers/ieee1394/pcilynx.c

@@ -1428,10 +1428,9 @@ static int __devinit add_card(struct pci_dev *dev,
         	struct i2c_algo_bit_data i2c_adapter_data;
         	struct i2c_algo_bit_data i2c_adapter_data;
 
 
         	error = -ENOMEM;
         	error = -ENOMEM;
-		i2c_ad = kmalloc(sizeof(*i2c_ad), GFP_KERNEL);
+		i2c_ad = kmemdup(&bit_ops, sizeof(*i2c_ad), GFP_KERNEL);
         	if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
         	if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
 
 
-		memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
                 i2c_adapter_data = bit_data;
                 i2c_adapter_data = bit_data;
                 i2c_ad->algo_data = &i2c_adapter_data;
                 i2c_ad->algo_data = &i2c_adapter_data;
                 i2c_adapter_data.data = lynx;
                 i2c_adapter_data.data = lynx;

+ 5 - 5
drivers/ieee1394/raw1394-private.h

@@ -27,12 +27,12 @@ struct file_info {
 
 
         struct hpsb_host *host;
         struct hpsb_host *host;
 
 
-        struct list_head req_pending;
-        struct list_head req_complete;
+        struct list_head req_pending;	/* protected by reqlists_lock */
+        struct list_head req_complete;	/* protected by reqlists_lock */
         spinlock_t reqlists_lock;
         spinlock_t reqlists_lock;
         wait_queue_head_t wait_complete;
         wait_queue_head_t wait_complete;
 
 
-        struct list_head addr_list;
+        struct list_head addr_list;	/* protected by host_info_lock */
 
 
         u8 __user *fcp_buffer;
         u8 __user *fcp_buffer;
 
 
@@ -63,7 +63,7 @@ struct arm_addr {
         u8     client_transactions;
         u8     client_transactions;
         u64    recvb;
         u64    recvb;
         u16    rec_length;
         u16    rec_length;
-        u8     *addr_space_buffer; /* accessed by read/write/lock */
+        u8     *addr_space_buffer; /* accessed by read/write/lock requests */
 };
 };
 
 
 struct pending_request {
 struct pending_request {
@@ -79,7 +79,7 @@ struct pending_request {
 struct host_info {
 struct host_info {
         struct list_head list;
         struct list_head list;
         struct hpsb_host *host;
         struct hpsb_host *host;
-        struct list_head file_info_list;
+        struct list_head file_info_list;  /* protected by host_info_lock */
 };
 };
 
 
 #endif  /* IEEE1394_RAW1394_PRIVATE_H */
 #endif  /* IEEE1394_RAW1394_PRIVATE_H */

+ 18 - 5
drivers/ieee1394/raw1394.c

@@ -99,6 +99,21 @@ static struct hpsb_address_ops arm_ops = {
 
 
 static void queue_complete_cb(struct pending_request *req);
 static void queue_complete_cb(struct pending_request *req);
 
 
+#include <asm/current.h>
+static void print_old_iso_deprecation(void)
+{
+	static pid_t p;
+
+	if (p == current->pid)
+		return;
+	p = current->pid;
+	printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported"
+	       " isochronous request types which will be removed in a next"
+	       " kernel release\n", current->comm);
+	printk(KERN_WARNING "raw1394: Update your software to use libraw1394's"
+	       " newer interface\n");
+}
+
 static struct pending_request *__alloc_pending_request(gfp_t flags)
 static struct pending_request *__alloc_pending_request(gfp_t flags)
 {
 {
 	struct pending_request *req;
 	struct pending_request *req;
@@ -2292,6 +2307,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
 		return sizeof(struct raw1394_request);
 		return sizeof(struct raw1394_request);
 
 
 	case RAW1394_REQ_ISO_SEND:
 	case RAW1394_REQ_ISO_SEND:
+		print_old_iso_deprecation();
 		return handle_iso_send(fi, req, node);
 		return handle_iso_send(fi, req, node);
 
 
 	case RAW1394_REQ_ARM_REGISTER:
 	case RAW1394_REQ_ARM_REGISTER:
@@ -2310,6 +2326,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
 		return reset_notification(fi, req);
 		return reset_notification(fi, req);
 
 
 	case RAW1394_REQ_ISO_LISTEN:
 	case RAW1394_REQ_ISO_LISTEN:
+		print_old_iso_deprecation();
 		handle_iso_listen(fi, req);
 		handle_iso_listen(fi, req);
 		return sizeof(struct raw1394_request);
 		return sizeof(struct raw1394_request);
 
 
@@ -2970,12 +2987,8 @@ static struct ieee1394_device_id raw1394_id_table[] = {
 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
 
 
 static struct hpsb_protocol_driver raw1394_driver = {
 static struct hpsb_protocol_driver raw1394_driver = {
-	.name = "raw1394 Driver",
+	.name = "raw1394",
 	.id_table = raw1394_id_table,
 	.id_table = raw1394_id_table,
-	.driver = {
-		   .name = "raw1394",
-		   .bus = &ieee1394_bus_type,
-		   },
 };
 };
 
 
 /******************************************************************************/
 /******************************************************************************/

File diff suppressed because it is too large
+ 306 - 414
drivers/ieee1394/sbp2.c


+ 124 - 187
drivers/ieee1394/sbp2.h

@@ -25,25 +25,25 @@
 #define SBP2_DEVICE_NAME		"sbp2"
 #define SBP2_DEVICE_NAME		"sbp2"
 
 
 /*
 /*
- * SBP2 specific structures and defines
+ * SBP-2 specific definitions
  */
  */
 
 
-#define ORB_DIRECTION_WRITE_TO_MEDIA    0x0
-#define ORB_DIRECTION_READ_FROM_MEDIA   0x1
-#define ORB_DIRECTION_NO_DATA_TRANSFER  0x2
-
-#define ORB_SET_NULL_PTR(value)			((value & 0x1) << 31)
-#define ORB_SET_NOTIFY(value)			((value & 0x1) << 31)
-#define ORB_SET_RQ_FMT(value)			((value & 0x3) << 29)	/* unused ? */
-#define ORB_SET_NODE_ID(value)			((value & 0xffff) << 16)
-#define ORB_SET_STATUS_FIFO_HI(value, id)	(value >> 32 | ORB_SET_NODE_ID(id))
-#define ORB_SET_STATUS_FIFO_LO(value)		(value & 0xffffffff)
-#define ORB_SET_DATA_SIZE(value)		(value & 0xffff)
-#define ORB_SET_PAGE_SIZE(value)		((value & 0x7) << 16)
-#define ORB_SET_PAGE_TABLE_PRESENT(value)	((value & 0x1) << 19)
-#define ORB_SET_MAX_PAYLOAD(value)		((value & 0xf) << 20)
-#define ORB_SET_SPEED(value)			((value & 0x7) << 24)
-#define ORB_SET_DIRECTION(value)		((value & 0x1) << 27)
+#define ORB_DIRECTION_WRITE_TO_MEDIA	0x0
+#define ORB_DIRECTION_READ_FROM_MEDIA	0x1
+#define ORB_DIRECTION_NO_DATA_TRANSFER	0x2
+
+#define ORB_SET_NULL_PTR(v)		(((v) & 0x1) << 31)
+#define ORB_SET_NOTIFY(v)		(((v) & 0x1) << 31)
+#define ORB_SET_RQ_FMT(v)		(((v) & 0x3) << 29)
+#define ORB_SET_NODE_ID(v)		(((v) & 0xffff) << 16)
+#define ORB_SET_STATUS_FIFO_HI(v, id)	((v) >> 32 | ORB_SET_NODE_ID(id))
+#define ORB_SET_STATUS_FIFO_LO(v)	((v) & 0xffffffff)
+#define ORB_SET_DATA_SIZE(v)		((v) & 0xffff)
+#define ORB_SET_PAGE_SIZE(v)		(((v) & 0x7) << 16)
+#define ORB_SET_PAGE_TABLE_PRESENT(v)	(((v) & 0x1) << 19)
+#define ORB_SET_MAX_PAYLOAD(v)		(((v) & 0xf) << 20)
+#define ORB_SET_SPEED(v)		(((v) & 0x7) << 24)
+#define ORB_SET_DIRECTION(v)		(((v) & 0x1) << 27)
 
 
 struct sbp2_command_orb {
 struct sbp2_command_orb {
 	u32 next_ORB_hi;
 	u32 next_ORB_hi;
@@ -64,12 +64,12 @@ struct sbp2_command_orb {
 #define SBP2_LOGICAL_UNIT_RESET		0xe
 #define SBP2_LOGICAL_UNIT_RESET		0xe
 #define SBP2_TARGET_RESET_REQUEST	0xf
 #define SBP2_TARGET_RESET_REQUEST	0xf
 
 
-#define ORB_SET_LUN(value)                      (value & 0xffff)
-#define ORB_SET_FUNCTION(value)                 ((value & 0xf) << 16)
-#define ORB_SET_RECONNECT(value)                ((value & 0xf) << 20)
-#define ORB_SET_EXCLUSIVE(value)                ((value & 0x1) << 28)
-#define ORB_SET_LOGIN_RESP_LENGTH(value)        (value & 0xffff)
-#define ORB_SET_PASSWD_LENGTH(value)            ((value & 0xffff) << 16)
+#define ORB_SET_LUN(v)			((v) & 0xffff)
+#define ORB_SET_FUNCTION(v)		(((v) & 0xf) << 16)
+#define ORB_SET_RECONNECT(v)		(((v) & 0xf) << 20)
+#define ORB_SET_EXCLUSIVE(v)		(((v) & 0x1) << 28)
+#define ORB_SET_LOGIN_RESP_LENGTH(v)	((v) & 0xffff)
+#define ORB_SET_PASSWD_LENGTH(v)	(((v) & 0xffff) << 16)
 
 
 struct sbp2_login_orb {
 struct sbp2_login_orb {
 	u32 password_hi;
 	u32 password_hi;
@@ -82,9 +82,9 @@ struct sbp2_login_orb {
 	u32 status_fifo_lo;
 	u32 status_fifo_lo;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
-#define RESPONSE_GET_LOGIN_ID(value)            (value & 0xffff)
-#define RESPONSE_GET_LENGTH(value)              ((value >> 16) & 0xffff)
-#define RESPONSE_GET_RECONNECT_HOLD(value)      (value & 0xffff)
+#define RESPONSE_GET_LOGIN_ID(v)	((v) & 0xffff)
+#define RESPONSE_GET_LENGTH(v)		(((v) >> 16) & 0xffff)
+#define RESPONSE_GET_RECONNECT_HOLD(v)	((v) & 0xffff)
 
 
 struct sbp2_login_response {
 struct sbp2_login_response {
 	u32 length_login_ID;
 	u32 length_login_ID;
@@ -93,9 +93,8 @@ struct sbp2_login_response {
 	u32 reconnect_hold;
 	u32 reconnect_hold;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
-#define ORB_SET_LOGIN_ID(value)                 (value & 0xffff)
-
-#define ORB_SET_QUERY_LOGINS_RESP_LENGTH(value) (value & 0xffff)
+#define ORB_SET_LOGIN_ID(v)                 ((v) & 0xffff)
+#define ORB_SET_QUERY_LOGINS_RESP_LENGTH(v) ((v) & 0xffff)
 
 
 struct sbp2_query_logins_orb {
 struct sbp2_query_logins_orb {
 	u32 reserved1;
 	u32 reserved1;
@@ -108,8 +107,8 @@ struct sbp2_query_logins_orb {
 	u32 status_fifo_lo;
 	u32 status_fifo_lo;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
-#define RESPONSE_GET_MAX_LOGINS(value)          (value & 0xffff)
-#define RESPONSE_GET_ACTIVE_LOGINS(value)       ((RESPONSE_GET_LENGTH(value) - 4) / 12)
+#define RESPONSE_GET_MAX_LOGINS(v)	((v) & 0xffff)
+#define RESPONSE_GET_ACTIVE_LOGINS(v)	((RESPONSE_GET_LENGTH((v)) - 4) / 12)
 
 
 struct sbp2_query_logins_response {
 struct sbp2_query_logins_response {
 	u32 length_max_logins;
 	u32 length_max_logins;
@@ -140,8 +139,8 @@ struct sbp2_logout_orb {
 	u32 status_fifo_lo;
 	u32 status_fifo_lo;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
-#define PAGE_TABLE_SET_SEGMENT_BASE_HI(value)   (value & 0xffff)
-#define PAGE_TABLE_SET_SEGMENT_LENGTH(value)    ((value & 0xffff) << 16)
+#define PAGE_TABLE_SET_SEGMENT_BASE_HI(v)	((v) & 0xffff)
+#define PAGE_TABLE_SET_SEGMENT_LENGTH(v)	(((v) & 0xffff) << 16)
 
 
 struct sbp2_unrestricted_page_table {
 struct sbp2_unrestricted_page_table {
 	u32 length_segment_base_hi;
 	u32 length_segment_base_hi;
@@ -171,23 +170,14 @@ struct sbp2_unrestricted_page_table {
 #define SFMT_DEFERRED_ERROR			0x1
 #define SFMT_DEFERRED_ERROR			0x1
 #define SFMT_VENDOR_DEPENDENT_STATUS		0x3
 #define SFMT_VENDOR_DEPENDENT_STATUS		0x3
 
 
-#define SBP2_SCSI_STATUS_GOOD			0x0
-#define SBP2_SCSI_STATUS_CHECK_CONDITION	0x2
-#define SBP2_SCSI_STATUS_CONDITION_MET		0x4
-#define SBP2_SCSI_STATUS_BUSY			0x8
-#define SBP2_SCSI_STATUS_RESERVATION_CONFLICT	0x18
-#define SBP2_SCSI_STATUS_COMMAND_TERMINATED	0x22
-
-#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT	0xff
-
-#define STATUS_GET_SRC(value)			(((value) >> 30) & 0x3)
-#define STATUS_GET_RESP(value)			(((value) >> 28) & 0x3)
-#define STATUS_GET_LEN(value)			(((value) >> 24) & 0x7)
-#define STATUS_GET_SBP_STATUS(value)		(((value) >> 16) & 0xff)
-#define STATUS_GET_ORB_OFFSET_HI(value)		((value) & 0x0000ffff)
-#define STATUS_TEST_DEAD(value)			((value) & 0x08000000)
+#define STATUS_GET_SRC(v)			(((v) >> 30) & 0x3)
+#define STATUS_GET_RESP(v)			(((v) >> 28) & 0x3)
+#define STATUS_GET_LEN(v)			(((v) >> 24) & 0x7)
+#define STATUS_GET_SBP_STATUS(v)		(((v) >> 16) & 0xff)
+#define STATUS_GET_ORB_OFFSET_HI(v)		((v) & 0x0000ffff)
+#define STATUS_TEST_DEAD(v)			((v) & 0x08000000)
 /* test 'resp' | 'dead' | 'sbp2_status' */
 /* test 'resp' | 'dead' | 'sbp2_status' */
-#define STATUS_TEST_RDS(value)			((value) & 0x38ff0000)
+#define STATUS_TEST_RDS(v)			((v) & 0x38ff0000)
 
 
 struct sbp2_status_block {
 struct sbp2_status_block {
 	u32 ORB_offset_hi_misc;
 	u32 ORB_offset_hi_misc;
@@ -195,66 +185,70 @@ struct sbp2_status_block {
 	u8 command_set_dependent[24];
 	u8 command_set_dependent[24];
 } __attribute__((packed));
 } __attribute__((packed));
 
 
+
 /*
 /*
- * Miscellaneous SBP2 related config rom defines
+ * SBP2 related configuration ROM definitions
  */
  */
 
 
-#define SBP2_UNIT_DIRECTORY_OFFSET_KEY				0xd1
-#define SBP2_CSR_OFFSET_KEY					0x54
-#define SBP2_UNIT_SPEC_ID_KEY					0x12
-#define SBP2_UNIT_SW_VERSION_KEY				0x13
-#define SBP2_COMMAND_SET_SPEC_ID_KEY				0x38
-#define SBP2_COMMAND_SET_KEY					0x39
-#define SBP2_UNIT_CHARACTERISTICS_KEY				0x3a
-#define SBP2_DEVICE_TYPE_AND_LUN_KEY				0x14
-#define SBP2_FIRMWARE_REVISION_KEY				0x3c
+#define SBP2_UNIT_DIRECTORY_OFFSET_KEY		0xd1
+#define SBP2_CSR_OFFSET_KEY			0x54
+#define SBP2_UNIT_SPEC_ID_KEY			0x12
+#define SBP2_UNIT_SW_VERSION_KEY		0x13
+#define SBP2_COMMAND_SET_SPEC_ID_KEY		0x38
+#define SBP2_COMMAND_SET_KEY			0x39
+#define SBP2_UNIT_CHARACTERISTICS_KEY		0x3a
+#define SBP2_DEVICE_TYPE_AND_LUN_KEY		0x14
+#define SBP2_FIRMWARE_REVISION_KEY		0x3c
 
 
-#define SBP2_AGENT_STATE_OFFSET					0x00ULL
-#define SBP2_AGENT_RESET_OFFSET					0x04ULL
-#define SBP2_ORB_POINTER_OFFSET					0x08ULL
-#define SBP2_DOORBELL_OFFSET					0x10ULL
-#define SBP2_UNSOLICITED_STATUS_ENABLE_OFFSET			0x14ULL
-#define SBP2_UNSOLICITED_STATUS_VALUE				0xf
+#define SBP2_AGENT_STATE_OFFSET			0x00ULL
+#define SBP2_AGENT_RESET_OFFSET			0x04ULL
+#define SBP2_ORB_POINTER_OFFSET			0x08ULL
+#define SBP2_DOORBELL_OFFSET			0x10ULL
+#define SBP2_UNSOLICITED_STATUS_ENABLE_OFFSET	0x14ULL
+#define SBP2_UNSOLICITED_STATUS_VALUE		0xf
 
 
-#define SBP2_BUSY_TIMEOUT_ADDRESS				0xfffff0000210ULL
-#define SBP2_BUSY_TIMEOUT_VALUE					0xf
+#define SBP2_BUSY_TIMEOUT_ADDRESS		0xfffff0000210ULL
+/* biggest possible value for Single Phase Retry count is 0xf */
+#define SBP2_BUSY_TIMEOUT_VALUE			0xf
 
 
-#define SBP2_AGENT_RESET_DATA					0xf
+#define SBP2_AGENT_RESET_DATA			0xf
 
 
-/*
- * Unit spec id and sw version entry for SBP-2 devices
- */
+#define SBP2_UNIT_SPEC_ID_ENTRY			0x0000609e
+#define SBP2_SW_VERSION_ENTRY			0x00010483
 
 
-#define SBP2_UNIT_SPEC_ID_ENTRY					0x0000609e
-#define SBP2_SW_VERSION_ENTRY					0x00010483
 
 
 /*
 /*
- * SCSI specific stuff
+ * SCSI specific definitions
  */
  */
 
 
-#define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
-#define SBP2_MAX_SECTORS		255	/* Max sectors supported */
-#define SBP2_MAX_CMDS			8	/* This should be safe */
+#define SBP2_MAX_SG_ELEMENT_LENGTH		0xf000
+#define SBP2_MAX_SECTORS			255
+/* There is no real limitation of the queue depth (i.e. length of the linked
+ * list of command ORBs) at the target. The chosen depth is merely an
+ * implementation detail of the sbp2 driver. */
+#define SBP2_MAX_CMDS				8
+
+#define SBP2_SCSI_STATUS_GOOD			0x0
+#define SBP2_SCSI_STATUS_CHECK_CONDITION	0x2
+#define SBP2_SCSI_STATUS_CONDITION_MET		0x4
+#define SBP2_SCSI_STATUS_BUSY			0x8
+#define SBP2_SCSI_STATUS_RESERVATION_CONFLICT	0x18
+#define SBP2_SCSI_STATUS_COMMAND_TERMINATED	0x22
+#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT	0xff
 
 
-/* Flags for detected oddities and brokeness */
-#define SBP2_WORKAROUND_128K_MAX_TRANS	0x1
-#define SBP2_WORKAROUND_INQUIRY_36	0x2
-#define SBP2_WORKAROUND_MODE_SENSE_8	0x4
-#define SBP2_WORKAROUND_FIX_CAPACITY	0x8
-#define SBP2_WORKAROUND_OVERRIDE	0x100
 
 
-/* This is the two dma types we use for cmd_dma below */
-enum cmd_dma_types {
+/*
+ * Representations of commands and devices
+ */
+
+enum sbp2_dma_types {
 	CMD_DMA_NONE,
 	CMD_DMA_NONE,
 	CMD_DMA_PAGE,
 	CMD_DMA_PAGE,
 	CMD_DMA_SINGLE
 	CMD_DMA_SINGLE
 };
 };
 
 
-/*
- * Encapsulates all the info necessary for an outstanding command.
- */
+/* Per SCSI command */
 struct sbp2_command_info {
 struct sbp2_command_info {
-
 	struct list_head list;
 	struct list_head list;
 	struct sbp2_command_orb command_orb ____cacheline_aligned;
 	struct sbp2_command_orb command_orb ____cacheline_aligned;
 	dma_addr_t command_orb_dma ____cacheline_aligned;
 	dma_addr_t command_orb_dma ____cacheline_aligned;
@@ -262,25 +256,25 @@ struct sbp2_command_info {
 	void (*Current_done)(struct scsi_cmnd *);
 	void (*Current_done)(struct scsi_cmnd *);
 
 
 	/* Also need s/g structure for each sbp2 command */
 	/* Also need s/g structure for each sbp2 command */
-	struct sbp2_unrestricted_page_table scatter_gather_element[SG_ALL] ____cacheline_aligned;
+	struct sbp2_unrestricted_page_table
+			scatter_gather_element[SG_ALL] ____cacheline_aligned;
 	dma_addr_t sge_dma ____cacheline_aligned;
 	dma_addr_t sge_dma ____cacheline_aligned;
 	void *sge_buffer;
 	void *sge_buffer;
 	dma_addr_t cmd_dma;
 	dma_addr_t cmd_dma;
-	enum cmd_dma_types dma_type;
+	enum sbp2_dma_types dma_type;
 	unsigned long dma_size;
 	unsigned long dma_size;
-	int dma_dir;
-
+	enum dma_data_direction dma_dir;
 };
 };
 
 
-struct sbp2scsi_host_info;
+/* Per FireWire host */
+struct sbp2_fwhost_info {
+	struct hpsb_host *host;
+	struct list_head logical_units;
+};
 
 
-/*
- * Information needed on a per scsi id basis (one for each sbp2 device)
- */
-struct scsi_id_instance_data {
-	/*
-	 * Various sbp2 specific structures
-	 */
+/* Per logical unit */
+struct sbp2_lu {
+	/* Operation request blocks */
 	struct sbp2_command_orb *last_orb;
 	struct sbp2_command_orb *last_orb;
 	dma_addr_t last_orb_dma;
 	dma_addr_t last_orb_dma;
 	struct sbp2_login_orb *login_orb;
 	struct sbp2_login_orb *login_orb;
@@ -297,116 +291,59 @@ struct scsi_id_instance_data {
 	dma_addr_t logout_orb_dma;
 	dma_addr_t logout_orb_dma;
 	struct sbp2_status_block status_block;
 	struct sbp2_status_block status_block;
 
 
-	/*
-	 * Stuff we need to know about the sbp2 device itself
-	 */
-	u64 sbp2_management_agent_addr;
-	u64 sbp2_command_block_agent_addr;
+	/* How to talk to the unit */
+	u64 management_agent_addr;
+	u64 command_block_agent_addr;
 	u32 speed_code;
 	u32 speed_code;
 	u32 max_payload_size;
 	u32 max_payload_size;
+	u16 lun;
 
 
-	/*
-	 * Values pulled from the device's unit directory
-	 */
-	u32 sbp2_command_set_spec_id;
-	u32 sbp2_command_set;
-	u32 sbp2_unit_characteristics;
-	u32 sbp2_lun;
-	u32 sbp2_firmware_revision;
-
-	/*
-	 * Address for the device to write status blocks to
-	 */
+	/* Address for the unit to write status blocks to */
 	u64 status_fifo_addr;
 	u64 status_fifo_addr;
 
 
-	/*
-	 * Waitqueue flag for logins, reconnects, logouts, query logins
-	 */
-	int access_complete:1;
+	/* Waitqueue flag for logins, reconnects, logouts, query logins */
+	unsigned int access_complete:1;
 
 
-	/*
-	 * Pool of command orbs, so we can have more than overlapped command per id
-	 */
-	spinlock_t sbp2_command_orb_lock;
-	struct list_head sbp2_command_orb_inuse;
-	struct list_head sbp2_command_orb_completed;
+	/* Pool of command ORBs for this logical unit */
+	spinlock_t cmd_orb_lock;
+	struct list_head cmd_orb_inuse;
+	struct list_head cmd_orb_completed;
 
 
-	struct list_head scsi_list;
+	/* Backlink to FireWire host; list of units attached to the host */
+	struct sbp2_fwhost_info *hi;
+	struct list_head lu_list;
 
 
-	/* Node entry, as retrieved from NodeMgr entries */
+	/* IEEE 1394 core's device representations */
 	struct node_entry *ne;
 	struct node_entry *ne;
 	struct unit_directory *ud;
 	struct unit_directory *ud;
 
 
-	/* A backlink to our host_info */
-	struct sbp2scsi_host_info *hi;
-
-	/* SCSI related pointers */
+	/* SCSI core's device representations */
 	struct scsi_device *sdev;
 	struct scsi_device *sdev;
-	struct Scsi_Host *scsi_host;
+	struct Scsi_Host *shost;
 
 
 	/* Device specific workarounds/brokeness */
 	/* Device specific workarounds/brokeness */
 	unsigned workarounds;
 	unsigned workarounds;
 
 
+	/* Connection state */
 	atomic_t state;
 	atomic_t state;
-	struct delayed_work protocol_work;
+
+	/* For deferred requests to the fetch agent */
+	struct work_struct protocol_work;
 };
 };
 
 
-/* For use in scsi_id_instance_data.state */
+/* For use in sbp2_lu.state */
 enum sbp2lu_state_types {
 enum sbp2lu_state_types {
 	SBP2LU_STATE_RUNNING,		/* all normal */
 	SBP2LU_STATE_RUNNING,		/* all normal */
 	SBP2LU_STATE_IN_RESET,		/* between bus reset and reconnect */
 	SBP2LU_STATE_IN_RESET,		/* between bus reset and reconnect */
 	SBP2LU_STATE_IN_SHUTDOWN	/* when sbp2_remove was called */
 	SBP2LU_STATE_IN_SHUTDOWN	/* when sbp2_remove was called */
 };
 };
 
 
-/* Sbp2 host data structure (one per IEEE1394 host) */
-struct sbp2scsi_host_info {
-	struct hpsb_host *host;		/* IEEE1394 host */
-	struct list_head scsi_ids;	/* List of scsi ids on this host */
-};
-
-/*
- * Function prototypes
- */
-
-/*
- * Various utility prototypes
- */
-static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_id);
-static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_id);
-static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb);
-static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt);
-static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id,
-							  struct scsi_cmnd *Current_SCpnt,
-							  void (*Current_done)(struct scsi_cmnd *));
-static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
-		struct sbp2_command_info *command);
-
-
-static int sbp2_start_device(struct scsi_id_instance_data *scsi_id);
-static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id);
-
-#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
-static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
-                                     u64 addr, size_t length, u16 flags);
-static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
-                                    u64 addr, size_t length, u16 flags);
-#endif
-
-/*
- * SBP-2 protocol related prototypes
- */
-static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id);
-static int sbp2_login_device(struct scsi_id_instance_data *scsi_id);
-static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id);
-static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id);
-static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
-				    quadlet_t *data, u64 addr, size_t length, u16 flags);
-static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
-static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status,
-					      unchar *sense_data);
-static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
-				      struct unit_directory *ud);
-static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);
-static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id);
+/* For use in sbp2_lu.workarounds and in the corresponding
+ * module load parameter */
+#define SBP2_WORKAROUND_128K_MAX_TRANS	0x1
+#define SBP2_WORKAROUND_INQUIRY_36	0x2
+#define SBP2_WORKAROUND_MODE_SENSE_8	0x4
+#define SBP2_WORKAROUND_FIX_CAPACITY	0x8
+#define SBP2_WORKAROUND_OVERRIDE	0x100
 
 
 #endif /* SBP2_H */
 #endif /* SBP2_H */

+ 17 - 37
drivers/ieee1394/video1394.c

@@ -714,8 +714,8 @@ static inline unsigned video1394_buffer_state(struct dma_iso_ctx *d,
 	return ret;
 	return ret;
 }
 }
 
 
-static int __video1394_ioctl(struct file *file,
-			     unsigned int cmd, unsigned long arg)
+static long video1394_ioctl(struct file *file,
+			    unsigned int cmd, unsigned long arg)
 {
 {
 	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
 	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
 	struct ti_ohci *ohci = ctx->ohci;
 	struct ti_ohci *ohci = ctx->ohci;
@@ -884,13 +884,14 @@ static int __video1394_ioctl(struct file *file,
 		struct dma_iso_ctx *d;
 		struct dma_iso_ctx *d;
 		int next_prg;
 		int next_prg;
 
 
-		if (copy_from_user(&v, argp, sizeof(v)))
+		if (unlikely(copy_from_user(&v, argp, sizeof(v))))
 			return -EFAULT;
 			return -EFAULT;
 
 
 		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
 		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
-		if (d == NULL) return -EFAULT;
+		if (unlikely(d == NULL))
+			return -EFAULT;
 
 
-		if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
+		if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
 			PRINT(KERN_ERR, ohci->host->id,
 			PRINT(KERN_ERR, ohci->host->id,
 			      "Buffer %d out of range",v.buffer);
 			      "Buffer %d out of range",v.buffer);
 			return -EINVAL;
 			return -EINVAL;
@@ -898,7 +899,7 @@ static int __video1394_ioctl(struct file *file,
 
 
 		spin_lock_irqsave(&d->lock,flags);
 		spin_lock_irqsave(&d->lock,flags);
 
 
-		if (d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED) {
+		if (unlikely(d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED)) {
 			PRINT(KERN_ERR, ohci->host->id,
 			PRINT(KERN_ERR, ohci->host->id,
 			      "Buffer %d is already used",v.buffer);
 			      "Buffer %d is already used",v.buffer);
 			spin_unlock_irqrestore(&d->lock,flags);
 			spin_unlock_irqrestore(&d->lock,flags);
@@ -949,13 +950,14 @@ static int __video1394_ioctl(struct file *file,
 		struct dma_iso_ctx *d;
 		struct dma_iso_ctx *d;
 		int i = 0;
 		int i = 0;
 
 
-		if (copy_from_user(&v, argp, sizeof(v)))
+		if (unlikely(copy_from_user(&v, argp, sizeof(v))))
 			return -EFAULT;
 			return -EFAULT;
 
 
 		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
 		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
-		if (d == NULL) return -EFAULT;
+		if (unlikely(d == NULL))
+			return -EFAULT;
 
 
-		if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
+		if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
 			PRINT(KERN_ERR, ohci->host->id,
 			PRINT(KERN_ERR, ohci->host->id,
 			      "Buffer %d out of range",v.buffer);
 			      "Buffer %d out of range",v.buffer);
 			return -EINVAL;
 			return -EINVAL;
@@ -1008,7 +1010,7 @@ static int __video1394_ioctl(struct file *file,
 		spin_unlock_irqrestore(&d->lock, flags);
 		spin_unlock_irqrestore(&d->lock, flags);
 
 
 		v.buffer=i;
 		v.buffer=i;
-		if (copy_to_user(argp, &v, sizeof(v)))
+		if (unlikely(copy_to_user(argp, &v, sizeof(v))))
 			return -EFAULT;
 			return -EFAULT;
 
 
 		return 0;
 		return 0;
@@ -1156,15 +1158,6 @@ static int __video1394_ioctl(struct file *file,
 	}
 	}
 }
 }
 
 
-static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int err;
-	lock_kernel();
-	err = __video1394_ioctl(file, cmd, arg);
-	unlock_kernel();
-	return err;
-}
-
 /*
 /*
  *	This maps the vmalloced and reserved buffer to user space.
  *	This maps the vmalloced and reserved buffer to user space.
  *
  *
@@ -1177,17 +1170,14 @@ static long video1394_ioctl(struct file *file, unsigned int cmd, unsigned long a
 static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
 static int video1394_mmap(struct file *file, struct vm_area_struct *vma)
 {
 {
 	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
 	struct file_ctx *ctx = (struct file_ctx *)file->private_data;
-	int res = -EINVAL;
 
 
-	lock_kernel();
 	if (ctx->current_ctx == NULL) {
 	if (ctx->current_ctx == NULL) {
 		PRINT(KERN_ERR, ctx->ohci->host->id,
 		PRINT(KERN_ERR, ctx->ohci->host->id,
 				"Current iso context not set");
 				"Current iso context not set");
-	} else
-		res = dma_region_mmap(&ctx->current_ctx->dma, file, vma);
-	unlock_kernel();
+		return -EINVAL;
+	}
 
 
-	return res;
+	return dma_region_mmap(&ctx->current_ctx->dma, file, vma);
 }
 }
 
 
 static unsigned int video1394_poll(struct file *file, poll_table *pt)
 static unsigned int video1394_poll(struct file *file, poll_table *pt)
@@ -1198,14 +1188,12 @@ static unsigned int video1394_poll(struct file *file, poll_table *pt)
 	struct dma_iso_ctx *d;
 	struct dma_iso_ctx *d;
 	int i;
 	int i;
 
 
-	lock_kernel();
 	ctx = file->private_data;
 	ctx = file->private_data;
 	d = ctx->current_ctx;
 	d = ctx->current_ctx;
 	if (d == NULL) {
 	if (d == NULL) {
 		PRINT(KERN_ERR, ctx->ohci->host->id,
 		PRINT(KERN_ERR, ctx->ohci->host->id,
 				"Current iso context not set");
 				"Current iso context not set");
-		mask = POLLERR;
-		goto done;
+		return POLLERR;
 	}
 	}
 
 
 	poll_wait(file, &d->waitq, pt);
 	poll_wait(file, &d->waitq, pt);
@@ -1218,8 +1206,6 @@ static unsigned int video1394_poll(struct file *file, poll_table *pt)
 		}
 		}
 	}
 	}
 	spin_unlock_irqrestore(&d->lock, flags);
 	spin_unlock_irqrestore(&d->lock, flags);
-done:
-	unlock_kernel();
 
 
 	return mask;
 	return mask;
 }
 }
@@ -1255,7 +1241,6 @@ static int video1394_release(struct inode *inode, struct file *file)
 	struct list_head *lh, *next;
 	struct list_head *lh, *next;
 	u64 mask;
 	u64 mask;
 
 
-	lock_kernel();
 	list_for_each_safe(lh, next, &ctx->context_list) {
 	list_for_each_safe(lh, next, &ctx->context_list) {
 		struct dma_iso_ctx *d;
 		struct dma_iso_ctx *d;
 		d = list_entry(lh, struct dma_iso_ctx, link);
 		d = list_entry(lh, struct dma_iso_ctx, link);
@@ -1276,7 +1261,6 @@ static int video1394_release(struct inode *inode, struct file *file)
 	kfree(ctx);
 	kfree(ctx);
 	file->private_data = NULL;
 	file->private_data = NULL;
 
 
-	unlock_kernel();
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1324,12 +1308,8 @@ static struct ieee1394_device_id video1394_id_table[] = {
 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
 
 
 static struct hpsb_protocol_driver video1394_driver = {
 static struct hpsb_protocol_driver video1394_driver = {
-	.name		= "1394 Digital Camera Driver",
+	.name		= VIDEO1394_DRIVER_NAME,
 	.id_table	= video1394_id_table,
 	.id_table	= video1394_id_table,
-	.driver		= {
-		.name	= VIDEO1394_DRIVER_NAME,
-		.bus	= &ieee1394_bus_type,
-	},
 };
 };
 
 
 
 

Some files were not shown because too many files changed in this diff