rpms/kernel/devel kernel.spec, 1.469, 1.470 linux-2.6-firewire-git-pending.patch, 1.10, 1.11 linux-2.6-firewire-git-update.patch, 1.7, 1.8
Jarod Wilson (jwilson)
fedora-extras-commits at redhat.com
Mon Mar 3 21:13:29 UTC 2008
Author: jwilson
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv18680
Modified Files:
kernel.spec linux-2.6-firewire-git-pending.patch
linux-2.6-firewire-git-update.patch
Log Message:
* Mon Mar 03 2008 Jarod Wilson <jwilson at redhat.com>
- Rebase firewire to latest linux1394-2.6.git tree
- firewire-sbp2: permit drives to suspend (#243210)
- firewire: restore bus power on resume on older PowerPC Macs
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.469
retrieving revision 1.470
diff -u -r1.469 -r1.470
--- kernel.spec 3 Mar 2008 16:05:03 -0000 1.469
+++ kernel.spec 3 Mar 2008 21:12:45 -0000 1.470
@@ -1144,11 +1144,11 @@
#ApplyPatch linux-2.6-ext4-stable-queue.patch
# linux1394 git patches
-#ApplyPatch linux-2.6-firewire-git-update.patch
-#C=$(wc -l $RPM_SOURCE_DIR/linux-2.6-firewire-git-pending.patch | awk '{print $1}')
-#if [ "$C" -gt 10 ]; then
-#ApplyPatch linux-2.6-firewire-git-pending.patch
-#fi
+ApplyPatch linux-2.6-firewire-git-update.patch
+C=$(wc -l $RPM_SOURCE_DIR/linux-2.6-firewire-git-pending.patch | awk '{print $1}')
+if [ "$C" -gt 10 ]; then
+ApplyPatch linux-2.6-firewire-git-pending.patch
+fi
# usb video
ApplyPatch linux-2.6-uvcvideo.patch
@@ -1744,6 +1744,11 @@
%kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL} -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.conf %{with_xen} xen
%changelog
+* Mon Mar 03 2008 Jarod Wilson <jwilson at redhat.com>
+- Rebase firewire to latest linux1394-2.6.git tree
+- firewire-sbp2: permit drives to suspend (#243210)
+- firewire: restore bus power on resume on older PowerPC Macs
+
* Mon Mar 03 2008 Kyle McMartin <kmcmartin at redhat.com>
- Add virtio_blk patch from Jeremy Katz
linux-2.6-firewire-git-pending.patch:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.10 -r 1.11 linux-2.6-firewire-git-pending.patch
Index: linux-2.6-firewire-git-pending.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-firewire-git-pending.patch,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- linux-2.6-firewire-git-pending.patch 2 Mar 2008 05:54:10 -0000 1.10
+++ linux-2.6-firewire-git-pending.patch 3 Mar 2008 21:12:45 -0000 1.11
@@ -3,1722 +3,485 @@
# tree, which we think we're going to want...
#
-The generation of incoming requests was filled in in wrong byte order on
-machines with big endian CPU.
+read_bus_info_block() is repeatedly called by workqueue jobs.
+These will step on each others toes eventually if there are multiple
+workqueue threads, and we end up with corrupt config ROM images.
Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
-Cc: sparclinux at vger.kernel.org
-Cc: linuxppc-dev at ozlabs.org
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
---
+ drivers/firewire/fw-device.c | 41 +++++++++++++++++++++++------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
-This patch is a shot in the dark, based on a warning when building with
-C=1 CHECKFLAGS="-D__CHECK_ENDIAN__". Is it really a fix, or was the
-previous code accidentally correct?
-
-This needs to be tested on different big endian PCs, if possible with
-the Apple Uninorth FireWire controller and other types of controllers.
-One test which involves ohci->request_generation is simply with an SBP-2
-device (harddisk, CD-ROM...). Does SBP-2 login etc. work?
-
-If possible, also test whether the device remains accessible after
-forcing a bus reset, e.g. by "echo br short > firecontrol". You need
-the easy to build utility firecontrol and a libraw1394 with "juju"
-backend. See wiki.linux1394.org for directions.
-
-
- drivers/firewire/fw-ohci.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: linux/drivers/firewire/fw-ohci.c
-===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -375,7 +375,7 @@ static __le32 *handle_ar_packet(struct a
- */
-
- if (p.ack + 16 == 0x09)
-- ohci->request_generation = (buffer[2] >> 16) & 0xff;
-+ ohci->request_generation = (p.header[2] >> 16) & 0xff;
- else if (ctx == &ohci->ar_request_ctx)
- fw_core_handle_request(&ohci->card, &p);
- else
-
---
-Stefan Richter
--=====-==--- --=- =-===
-http://arcgraph.de/sr/
-
-
-Kills warnings from 'make C=1 CHECKFLAGS="-D__CHECK_ENDIAN__" modules':
-
-drivers/firewire/fw-transaction.c:771:10: warning: incorrect type in assignment (different base types)
-drivers/firewire/fw-transaction.c:771:10: expected unsigned int [unsigned] [usertype] <noident>
-drivers/firewire/fw-transaction.c:771:10: got restricted unsigned int [usertype] <noident>
-drivers/firewire/fw-transaction.h:93:10: warning: incorrect type in assignment (different base types)
-drivers/firewire/fw-transaction.h:93:10: expected unsigned int [unsigned] [usertype] <noident>
-drivers/firewire/fw-transaction.h:93:10: got restricted unsigned int [usertype] <noident>
-drivers/firewire/fw-ohci.c:1490:8: warning: restricted degrades to integer
-drivers/firewire/fw-ohci.c:1490:35: warning: restricted degrades to integer
-drivers/firewire/fw-ohci.c:1516:5: warning: cast to restricted type
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
-Cc: sparclinux at vger.kernel.org
-Cc: linuxppc-dev at ozlabs.org
-Signed-off-by: Jarod Wilson <jwilson at redhat.com>
----
- drivers/firewire/fw-ohci.c | 4 ++--
- drivers/firewire/fw-transaction.c | 2 +-
- drivers/firewire/fw-transaction.h | 6 +++---
- 3 files changed, 6 insertions(+), 6 deletions(-)
-
-Index: linux/drivers/firewire/fw-ohci.c
-===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -1487,7 +1487,7 @@ static int handle_ir_dualbuffer_packet(s
- void *p, *end;
- int i;
-
-- if (db->first_res_count > 0 && db->second_res_count > 0) {
-+ if (db->first_res_count != 0 && db->second_res_count != 0) {
- if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
- /* This descriptor isn't done yet, stop iteration. */
- return 0;
-@@ -1513,7 +1513,7 @@ static int handle_ir_dualbuffer_packet(s
- memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
- i += ctx->base.header_size;
- ctx->excess_bytes +=
-- (le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff;
-+ (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
- p += ctx->base.header_size + 4;
- }
- ctx->header_length = i;
-Index: linux/drivers/firewire/fw-transaction.c
-===================================================================
---- linux.orig/drivers/firewire/fw-transaction.c
-+++ linux/drivers/firewire/fw-transaction.c
-@@ -751,7 +751,7 @@ handle_topology_map(struct fw_card *card
- void *payload, size_t length, void *callback_data)
- {
- int i, start, end;
-- u32 *map;
-+ __be32 *map;
-
- if (!TCODE_IS_READ_REQUEST(tcode)) {
- fw_send_response(card, request, RCODE_TYPE_ERROR);
-Index: linux/drivers/firewire/fw-transaction.h
-===================================================================
---- linux.orig/drivers/firewire/fw-transaction.h
-+++ linux/drivers/firewire/fw-transaction.h
-@@ -85,12 +85,12 @@
- static inline void
- fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
- {
-- u32 *dst = _dst;
-- u32 *src = _src;
-+ u32 *dst = _dst;
-+ __be32 *src = _src;
- int i;
-
- for (i = 0; i < size / 4; i++)
-- dst[i] = cpu_to_be32(src[i]);
-+ dst[i] = be32_to_cpu(src[i]);
- }
-
- static inline void
-
---
-Stefan Richter
--=====-==--- --=- =-===
-http://arcgraph.de/sr/
-
-
-Patch "firewire: fw-sbp2: fix NULL pointer deref. in scsi_remove_device"
-had the unintended effect that firewire-sbp2 could not be unloaded
-anymore until all SBP-2 devices were unplugged.
-
-We now fix the NULL pointer bug by reacquiring a reference to the sdev
-instead of holding a reference to the sdev (and to the module) all the
-time.
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
-
-This applies on top of current linux-2.6.git master as well as on top of
-linux1394-2.6.git master.
-
-
- drivers/firewire/fw-sbp2.c | 46 +++++++++++++++++++++----------------
- 1 file changed, 27 insertions(+), 19 deletions(-)
-
-Index: linux/drivers/firewire/fw-sbp2.c
+Index: linux/drivers/firewire/fw-device.c
===================================================================
---- linux.orig/drivers/firewire/fw-sbp2.c
-+++ linux/drivers/firewire/fw-sbp2.c
-@@ -122,7 +122,6 @@ static const char sbp2_driver_name[] = "
- struct sbp2_logical_unit {
- struct sbp2_target *tgt;
- struct list_head link;
-- struct scsi_device *sdev;
- struct fw_address_handler address_handler;
- struct list_head orb_list;
-
-@@ -139,6 +138,7 @@ struct sbp2_logical_unit {
- int generation;
- int retries;
- struct delayed_work work;
-+ bool has_sdev;
- bool blocked;
- };
-
-@@ -751,20 +751,33 @@ static void sbp2_unblock(struct sbp2_tar
- scsi_unblock_requests(shost);
+--- linux.orig/drivers/firewire/fw-device.c
++++ linux/drivers/firewire/fw-device.c
+@@ -400,6 +400,9 @@ read_rom(struct fw_device *device, int g
+ return callback_data.rcode;
}
-+static int sbp2_lun2int(u16 lun)
-+{
-+ struct scsi_lun eight_bytes_lun;
-+
-+ memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
[...1727 lines suppressed...]
-Shut up two "may be used uninitialised in this function" warnings due to
-PPC32's implementation of dma_alloc_coherent().
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
-
-Wasn't there a macro somewhere for this?
-
-Also, could this be better done in PPC32's dma_alloc_coherent()?
-At least this kind of workaround here doesn't add anything to the
-compiled result.
-
- drivers/firewire/fw-ohci.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: linux-2.6.25-rc3/drivers/firewire/fw-ohci.c
-===================================================================
---- linux-2.6.25-rc3.orig/drivers/firewire/fw-ohci.c
-+++ linux-2.6.25-rc3/drivers/firewire/fw-ohci.c
-@@ -544,7 +544,7 @@ static int
- context_add_buffer(struct context *ctx)
- {
- struct descriptor_buffer *desc;
-- dma_addr_t bus_addr;
-+ dma_addr_t uninitialized_var(bus_addr);
- int offset;
- /*
-@@ -1334,7 +1334,7 @@ ohci_set_config_rom(struct fw_card *card
- unsigned long flags;
- int retval = -EBUSY;
- __be32 *next_config_rom;
-- dma_addr_t next_config_rom_bus;
-+ dma_addr_t uninitialized_var(next_config_rom_bus);
-
- ohci = fw_ohci(card);
-
-
---
-Stefan Richter
--=====-==--- --== ----=
-http://arcgraph.de/sr/
-
-
-This way firewire-ohci can be used for remote debugging like ohci1394.
-
-Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
----
- Documentation/debugging-via-ohci1394.txt | 13 ++++++++-----
- drivers/firewire/fw-ohci.c | 9 +++++++++
- lib/Kconfig.debug | 10 ++++++++++
- 3 files changed, 27 insertions(+), 5 deletions(-)
-
-Index: linux/Documentation/debugging-via-ohci1394.txt
-===================================================================
---- linux.orig/Documentation/debugging-via-ohci1394.txt
-+++ linux/Documentation/debugging-via-ohci1394.txt
-@@ -41,11 +41,14 @@ to a working state and enables physical
- This can be turned off by ohci1394's module parameter phys_dma=0.
-
- The alternative firewire-ohci driver in drivers/firewire uses filtered physical
--DMA, hence is not yet suitable for remote debugging.
--
--Because ohci1394 depends on the PCI enumeration to be completed, an
--initialization routine which runs pretty early (long before console_init()
--which makes the printk buffer appear on the console can be called) was written.
-+DMA by default, which is more secure but not suitable for remote debugging.
-+Compile the driver with CONFIG_FIREWIRE_OHCI_REMOTE_DMA to get unfiltered
-+physical DMA.
-+
-+Because ohci1394 and firewire-ohci depend on the PCI enumeration to be
-+completed, an initialization routine which runs pretty early has been
-+implemented for x86. This routine runs long before console_init() can be
-+called, i.e. before the printk buffer appears on the console.
-
- To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
- Provide code for enabling DMA over FireWire early on boot) and pass the
-Index: linux/drivers/firewire/fw-ohci.c
++ case FW_NODE_INITIATED_RESET:
++ device = node->data;
++ if (device == NULL)
++ goto create;
++
++ device->node_id = node->node_id;
++ smp_wmb(); /* update node_id before generation */
++ device->generation = card->generation;
++ if (atomic_cmpxchg(&device->state,
++ FW_DEVICE_RUNNING,
++ FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
++ PREPARE_DELAYED_WORK(&device->work, fw_device_refresh);
++ schedule_delayed_work(&device->work, INITIAL_DELAY);
++ }
++ break;
++
+ case FW_NODE_UPDATED:
+ if (!node->link_on || node->data == NULL)
+ break;
+Index: linux/drivers/firewire/fw-topology.c
===================================================================
---- linux.orig/drivers/firewire/fw-ohci.c
-+++ linux/drivers/firewire/fw-ohci.c
-@@ -1091,6 +1091,11 @@ static void bus_reset_tasklet(unsigned l
- reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
- }
-
-+#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
-+ reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0);
-+ reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0);
-+#endif
-+
- spin_unlock_irqrestore(&ohci->lock, flags);
-
- if (free_rom)
-@@ -1429,6 +1434,9 @@ static int ohci_cancel_packet(struct fw_
- static int
- ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
- {
-+#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
-+ return 0;
-+#else
- struct fw_ohci *ohci = fw_ohci(card);
- unsigned long flags;
- int n, retval = 0;
-@@ -1460,6 +1468,7 @@ ohci_enable_phys_dma(struct fw_card *car
- out:
- spin_unlock_irqrestore(&ohci->lock, flags);
- return retval;
-+#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
- }
+--- linux.orig/drivers/firewire/fw-topology.c
++++ linux/drivers/firewire/fw-topology.c
+@@ -107,6 +107,7 @@ static struct fw_node *fw_node_create(u3
+ node->node_id = LOCAL_BUS | SELF_ID_PHY_ID(sid);
+ node->link_on = SELF_ID_LINK_ON(sid);
+ node->phy_speed = SELF_ID_PHY_SPEED(sid);
++ node->initiated_reset = SELF_ID_PHY_INITIATOR(sid);
+ node->port_count = port_count;
+
+ atomic_set(&node->ref_count, 1);
+@@ -430,6 +431,8 @@ update_tree(struct fw_card *card, struct
+ event = FW_NODE_LINK_OFF;
+ else if (!node0->link_on && node1->link_on)
+ event = FW_NODE_LINK_ON;
++ else if (node1->initiated_reset && node1->link_on)
++ event = FW_NODE_INITIATED_RESET;
+ else
+ event = FW_NODE_UPDATED;
+
+Index: linux/drivers/firewire/fw-topology.h
+===================================================================
+--- linux.orig/drivers/firewire/fw-topology.h
++++ linux/drivers/firewire/fw-topology.h
+@@ -20,11 +20,12 @@
+ #define __fw_topology_h
+
+ enum {
+- FW_NODE_CREATED = 0x00,
+- FW_NODE_UPDATED = 0x01,
+- FW_NODE_DESTROYED = 0x02,
+- FW_NODE_LINK_ON = 0x03,
+- FW_NODE_LINK_OFF = 0x04,
++ FW_NODE_CREATED,
++ FW_NODE_UPDATED,
++ FW_NODE_DESTROYED,
++ FW_NODE_LINK_ON,
++ FW_NODE_LINK_OFF,
++ FW_NODE_INITIATED_RESET,
+ };
- static u64
-Index: linux/lib/Kconfig.debug
-===================================================================
---- linux.orig/lib/Kconfig.debug
-+++ linux/lib/Kconfig.debug
-@@ -592,6 +592,16 @@ config LATENCYTOP
- Enable this option if you want to use the LatencyTOP tool
- to find out which userspace is blocking on what kernel operations.
-
-+config FIREWIRE_OHCI_REMOTE_DMA
-+ bool "Remote debugging via firewire-ohci"
-+ depends on FIREWIRE_OHCI
-+ help
-+ This option lets you use the FireWire bus for remote debugging.
-+ It enables unfiltered remote DMA in the firewire-ohci driver.
-+ See Documentation/debugging-via-ohci1394.txt for more information.
-+
-+ If unsure, say N.
-+
- config PROVIDE_OHCI1394_DMA_INIT
- bool "Provide code for enabling DMA over FireWire early on boot"
- depends on PCI && X86
+ struct fw_node {
--
Stefan Richter
--=====-==--- --=- ===--
+-=====-==--- --== ---==
http://arcgraph.de/sr/
linux-2.6-firewire-git-update.patch:
Index: linux-2.6-firewire-git-update.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-firewire-git-update.patch,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- linux-2.6-firewire-git-update.patch 21 Feb 2008 04:40:21 -0000 1.7
+++ linux-2.6-firewire-git-update.patch 3 Mar 2008 21:12:45 -0000 1.8
@@ -1,905 +1,1102 @@
-git diff in linux1394-git tree vs. 2.6.25-rc1, 02/20/2008
+git diff in linux1394-git tree vs. 2.6.25-rc3-git4, 03/03/2008
- Documentation/debugging-via-ohci1394.txt | 17 +-
- drivers/firewire/fw-cdev.c | 8 +-
- drivers/firewire/fw-device.c | 48 +++--
- drivers/firewire/fw-device.h | 2 +-
- drivers/firewire/fw-sbp2.c | 358 +++++++++++++++++++++++-------
- drivers/ieee1394/sbp2.c | 22 ++-
- drivers/ieee1394/sbp2.h | 2 +
- 7 files changed, 345 insertions(+), 112 deletions(-)
-
----
+ Documentation/debugging-via-ohci1394.txt | 13 ++-
+ drivers/firewire/fw-card.c | 38 ----------
+ drivers/firewire/fw-device.h | 27 ++++---
+ drivers/firewire/fw-ohci.c | 114 +++++++++++++++++++++-------
+ drivers/firewire/fw-sbp2.c | 120 ++++++++++++------------------
+ drivers/firewire/fw-transaction.c | 2 +-
+ drivers/firewire/fw-transaction.h | 10 +--
+ drivers/ieee1394/csr.c | 6 +-
+ drivers/ieee1394/dv1394.c | 3 +-
+ drivers/ieee1394/nodemgr.c | 6 +-
+ drivers/ieee1394/ohci1394.c | 109 ++++++++++++---------------
+ drivers/ieee1394/raw1394.c | 1 -
+ drivers/ieee1394/sbp2.c | 7 +-
+ drivers/ieee1394/video1394.c | 3 +-
+ lib/Kconfig.debug | 10 +++
+ 15 files changed, 233 insertions(+), 236 deletions(-)
diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
-index de4804e..c360d4e 100644
+index c360d4e..371ba27 100644
--- a/Documentation/debugging-via-ohci1394.txt
+++ b/Documentation/debugging-via-ohci1394.txt
-@@ -36,14 +36,15 @@ available (notebooks) or too slow for extensive debug information (like ACPI).
- Drivers
- -------
-
--The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize
--the OHCI-1394 controllers to a working state and can be used to enable
--physical DMA. By default you only have to load the driver, and physical
--DMA access will be granted to all remote nodes, but it can be turned off
--when using the ohci1394 driver.
--
--Because these drivers depend on the PCI enumeration to be completed, an
--initialization routine which can runs pretty early (long before console_init(),
-+The ohci1394 driver in drivers/ieee1394 initializes the OHCI-1394 controllers
-+to a working state and enables physical DMA by default for all remote nodes.
-+This can be turned off by ohci1394's module parameter phys_dma=0.
-+
-+The alternative firewire-ohci driver in drivers/firewire uses filtered physical
-+DMA, hence is not yet suitable for remote debugging.
-+
-+Because ohci1394 depends on the PCI enumeration to be completed, an
-+initialization routine which runs pretty early (long before console_init()
- which makes the printk buffer appear on the console can be called) was written.
+@@ -41,11 +41,14 @@ to a working state and enables physical DMA by default for all remote nodes.
+ This can be turned off by ohci1394's module parameter phys_dma=0.
+
+ The alternative firewire-ohci driver in drivers/firewire uses filtered physical
+-DMA, hence is not yet suitable for remote debugging.
+-
+-Because ohci1394 depends on the PCI enumeration to be completed, an
+-initialization routine which runs pretty early (long before console_init()
+-which makes the printk buffer appear on the console can be called) was written.
++DMA by default, which is more secure but not suitable for remote debugging.
++Compile the driver with CONFIG_FIREWIRE_OHCI_REMOTE_DMA to get unfiltered
++physical DMA.
++
++Because ohci1394 and firewire-ohci depend on the PCI enumeration to be
++completed, an initialization routine which runs pretty early has been
++implemented for x86. This routine runs long before console_init() can be
++called, i.e. before the printk buffer appears on the console.
To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
-diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
-index 7e73cba..44ccee2 100644
---- a/drivers/firewire/fw-cdev.c
-+++ b/drivers/firewire/fw-cdev.c
-@@ -109,15 +109,17 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
- struct client *client;
- unsigned long flags;
+ Provide code for enabling DMA over FireWire early on boot) and pass the
+diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
+index a034627..140b34d 100644
+--- a/drivers/firewire/fw-card.c
++++ b/drivers/firewire/fw-card.c
+@@ -398,7 +398,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
+ {
+ static atomic_t index = ATOMIC_INIT(-1);
-- device = fw_device_from_devt(inode->i_rdev);
-+ device = fw_device_get_by_devt(inode->i_rdev);
- if (device == NULL)
- return -ENODEV;
-
- client = kzalloc(sizeof(*client), GFP_KERNEL);
-- if (client == NULL)
-+ if (client == NULL) {
-+ fw_device_put(device);
- return -ENOMEM;
-+ }
+- kref_init(&card->kref);
+ atomic_set(&card->device_count, 0);
+ card->index = atomic_inc_return(&index);
+ card->driver = driver;
+@@ -429,12 +428,6 @@ fw_card_add(struct fw_card *card,
+ card->link_speed = link_speed;
+ card->guid = guid;
+
+- /*
+- * The subsystem grabs a reference when the card is added and
+- * drops it when the driver calls fw_core_remove_card.
+- */
+- fw_card_get(card);
+-
+ mutex_lock(&card_mutex);
+ config_rom = generate_config_rom(card, &length);
+ list_add_tail(&card->link, &card_list);
+@@ -540,40 +533,9 @@ fw_core_remove_card(struct fw_card *card)
+ cancel_delayed_work_sync(&card->work);
+ fw_flush_transactions(card);
+ del_timer_sync(&card->flush_timer);
+-
+- fw_card_put(card);
+ }
+ EXPORT_SYMBOL(fw_core_remove_card);
+
+-struct fw_card *
+-fw_card_get(struct fw_card *card)
+-{
+- kref_get(&card->kref);
+-
+- return card;
+-}
+-EXPORT_SYMBOL(fw_card_get);
+-
+-static void
+-release_card(struct kref *kref)
+-{
+- struct fw_card *card = container_of(kref, struct fw_card, kref);
+-
+- kfree(card);
+-}
+-
+-/*
+- * An assumption for fw_card_put() is that the card driver allocates
+- * the fw_card struct with kalloc and that it has been shut down
+- * before the last ref is dropped.
+- */
+-void
+-fw_card_put(struct fw_card *card)
+-{
+- kref_put(&card->kref, release_card);
+-}
+-EXPORT_SYMBOL(fw_card_put);
+-
+ int
+ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
+ {
+diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
+index 78ecd39..0d771fd 100644
+--- a/drivers/firewire/fw-device.h
++++ b/drivers/firewire/fw-device.h
+@@ -64,28 +64,24 @@ struct fw_device {
+ struct fw_attribute_group attribute_group;
+ };
-- client->device = fw_device_get(device);
-+ client->device = device;
- INIT_LIST_HEAD(&client->event_list);
- INIT_LIST_HEAD(&client->resource_list);
- spin_lock_init(&client->lock);
-diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
-index de9066e..2ab13e0 100644
---- a/drivers/firewire/fw-device.c
-+++ b/drivers/firewire/fw-device.c
-@@ -358,12 +358,9 @@ static ssize_t
- guid_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- struct fw_device *device = fw_device(dev);
-- u64 guid;
-
-- guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4];
--
-- return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
-- (unsigned long long)guid);
-+ return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
-+ device->config_rom[3], device->config_rom[4]);
- }
-
- static struct device_attribute fw_device_attributes[] = {
-@@ -610,12 +607,14 @@ static DECLARE_RWSEM(idr_rwsem);
- static DEFINE_IDR(fw_device_idr);
- int fw_cdev_major;
+-static inline struct fw_device *
+-fw_device(struct device *dev)
++static inline struct fw_device *fw_device(struct device *dev)
+ {
+ return container_of(dev, struct fw_device, device);
+ }
--struct fw_device *fw_device_from_devt(dev_t devt)
-+struct fw_device *fw_device_get_by_devt(dev_t devt)
+-static inline int
+-fw_device_is_shutdown(struct fw_device *device)
++static inline int fw_device_is_shutdown(struct fw_device *device)
{
- struct fw_device *device;
+ return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN;
+ }
- down_read(&idr_rwsem);
- device = idr_find(&fw_device_idr, MINOR(devt));
-+ if (device)
-+ fw_device_get(device);
- up_read(&idr_rwsem);
+-static inline struct fw_device *
+-fw_device_get(struct fw_device *device)
++static inline struct fw_device *fw_device_get(struct fw_device *device)
+ {
+ get_device(&device->device);
return device;
-@@ -627,13 +626,14 @@ static void fw_device_shutdown(struct work_struct *work)
- container_of(work, struct fw_device, work.work);
- int minor = MINOR(device->device.devt);
+ }
-- down_write(&idr_rwsem);
-- idr_remove(&fw_device_idr, minor);
-- up_write(&idr_rwsem);
--
- fw_device_cdev_remove(device);
- device_for_each_child(&device->device, NULL, shutdown_unit);
- device_unregister(&device->device);
-+
-+ down_write(&idr_rwsem);
-+ idr_remove(&fw_device_idr, minor);
-+ up_write(&idr_rwsem);
-+ fw_device_put(device);
+-static inline void
+-fw_device_put(struct fw_device *device)
++static inline void fw_device_put(struct fw_device *device)
+ {
+ put_device(&device->device);
}
+@@ -104,12 +100,23 @@ struct fw_unit {
+ struct fw_attribute_group attribute_group;
+ };
- static struct device_type fw_device_type = {
-@@ -682,10 +682,13 @@ static void fw_device_init(struct work_struct *work)
- }
+-static inline struct fw_unit *
+-fw_unit(struct device *dev)
++static inline struct fw_unit *fw_unit(struct device *dev)
+ {
+ return container_of(dev, struct fw_unit, device);
+ }
- err = -ENOMEM;
++static inline struct fw_unit *fw_unit_get(struct fw_unit *unit)
++{
++ get_device(&unit->device);
+
-+ fw_device_get(device);
- down_write(&idr_rwsem);
- if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
- err = idr_get_new(&fw_device_idr, device, &minor);
- up_write(&idr_rwsem);
++ return unit;
++}
+
- if (err < 0)
- goto error;
++static inline void fw_unit_put(struct fw_unit *unit)
++{
++ put_device(&unit->device);
++}
++
+ #define CSR_OFFSET 0x40
+ #define CSR_LEAF 0x80
+ #define CSR_DIRECTORY 0xc0
+diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
+index 7ebad3c..28ea78c 100644
+--- a/drivers/firewire/fw-ohci.c
++++ b/drivers/firewire/fw-ohci.c
+@@ -33,6 +33,10 @@
+ #include <asm/page.h>
+ #include <asm/system.h>
+
++#ifdef CONFIG_PPC_PMAC
++#include <asm/pmac_feature.h>
++#endif
++
+ #include "fw-ohci.h"
+ #include "fw-transaction.h"
-@@ -717,13 +720,22 @@ static void fw_device_init(struct work_struct *work)
+@@ -175,6 +179,7 @@ struct fw_ohci {
+ int generation;
+ int request_generation;
+ u32 bus_seconds;
++ bool old_uninorth;
+
+ /*
+ * Spinlock for accessing fw_ohci data. Never call out of
+@@ -311,15 +316,22 @@ static int ar_context_add_page(struct ar_context *ctx)
+ return 0;
+ }
+
++#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
++#define cond_le32_to_cpu(v) \
++ (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v))
++#else
++#define cond_le32_to_cpu(v) le32_to_cpu(v)
++#endif
++
+ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ {
+ struct fw_ohci *ohci = ctx->ohci;
+ struct fw_packet p;
+ u32 status, length, tcode;
+
+- p.header[0] = le32_to_cpu(buffer[0]);
+- p.header[1] = le32_to_cpu(buffer[1]);
+- p.header[2] = le32_to_cpu(buffer[2]);
++ p.header[0] = cond_le32_to_cpu(buffer[0]);
++ p.header[1] = cond_le32_to_cpu(buffer[1]);
++ p.header[2] = cond_le32_to_cpu(buffer[2]);
+
+ tcode = (p.header[0] >> 4) & 0x0f;
+ switch (tcode) {
+@@ -331,7 +343,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ break;
+
+ case TCODE_READ_BLOCK_REQUEST :
+- p.header[3] = le32_to_cpu(buffer[3]);
++ p.header[3] = cond_le32_to_cpu(buffer[3]);
+ p.header_length = 16;
+ p.payload_length = 0;
+ break;
+@@ -340,7 +352,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+ case TCODE_READ_BLOCK_RESPONSE:
+ case TCODE_LOCK_REQUEST:
+ case TCODE_LOCK_RESPONSE:
+- p.header[3] = le32_to_cpu(buffer[3]);
++ p.header[3] = cond_le32_to_cpu(buffer[3]);
+ p.header_length = 16;
+ p.payload_length = p.header[3] >> 16;
+ break;
+@@ -357,7 +369,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
+
+ /* FIXME: What to do about evt_* errors? */
+ length = (p.header_length + p.payload_length + 3) / 4;
+- status = le32_to_cpu(buffer[length]);
++ status = cond_le32_to_cpu(buffer[length]);
+
+ p.ack = ((status >> 16) & 0x1f) - 16;
+ p.speed = (status >> 21) & 0x7;
+@@ -375,7 +387,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
*/
- if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
-- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
-+ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
- fw_device_shutdown(&device->work.work);
-- else
-- fw_notify("created new fw device %s "
-- "(%d config rom retries, S%d00)\n",
-- device->device.bus_id, device->config_rom_retries,
-- 1 << device->max_speed);
-+ } else {
-+ if (device->config_rom_retries)
-+ fw_notify("created device %s: GUID %08x%08x, S%d00, "
-+ "%d config ROM retries\n",
-+ device->device.bus_id,
-+ device->config_rom[3], device->config_rom[4],
-+ 1 << device->max_speed,
-+ device->config_rom_retries);
-+ else
-+ fw_notify("created device %s: GUID %08x%08x, S%d00\n",
-+ device->device.bus_id,
-+ device->config_rom[3], device->config_rom[4],
-+ 1 << device->max_speed);
-+ }
+
+ if (p.ack + 16 == 0x09)
+- ohci->request_generation = (buffer[2] >> 16) & 0xff;
++ ohci->request_generation = (p.header[2] >> 16) & 0xff;
+ else if (ctx == &ohci->ar_request_ctx)
+ fw_core_handle_request(&ohci->card, &p);
+ else
+@@ -532,7 +544,7 @@ static int
+ context_add_buffer(struct context *ctx)
+ {
+ struct descriptor_buffer *desc;
+- dma_addr_t bus_addr;
++ dma_addr_t uninitialized_var(bus_addr);
+ int offset;
/*
- * Reschedule the IRM work if we just finished reading the
-@@ -741,7 +753,9 @@ static void fw_device_init(struct work_struct *work)
- idr_remove(&fw_device_idr, minor);
- up_write(&idr_rwsem);
- error:
-- put_device(&device->device);
-+ fw_device_put(device); /* fw_device_idr's reference */
+@@ -1022,13 +1034,14 @@ static void bus_reset_tasklet(unsigned long data)
+ */
+
+ self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
+- generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
++ generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
+ rmb();
+
+ for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
+ if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
+ fw_error("inconsistent self IDs\n");
+- ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]);
++ ohci->self_id_buffer[j] =
++ cond_le32_to_cpu(ohci->self_id_cpu[i]);
+ }
+ rmb();
+
+@@ -1091,6 +1104,11 @@ static void bus_reset_tasklet(unsigned long data)
+ reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header);
+ }
+
++#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
++ reg_write(ohci, OHCI1394_PhyReqFilterHiSet, ~0);
++ reg_write(ohci, OHCI1394_PhyReqFilterLoSet, ~0);
++#endif
+
-+ put_device(&device->device); /* our reference */
+ spin_unlock_irqrestore(&ohci->lock, flags);
+
+ if (free_rom)
+@@ -1316,7 +1334,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
+ unsigned long flags;
+ int retval = -EBUSY;
+ __be32 *next_config_rom;
+- dma_addr_t next_config_rom_bus;
++ dma_addr_t uninitialized_var(next_config_rom_bus);
+
+ ohci = fw_ohci(card);
+
+@@ -1429,6 +1447,9 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
+ static int
+ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+ {
++#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
++ return 0;
++#else
+ struct fw_ohci *ohci = fw_ohci(card);
+ unsigned long flags;
+ int n, retval = 0;
+@@ -1460,6 +1481,7 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+ out:
+ spin_unlock_irqrestore(&ohci->lock, flags);
+ return retval;
++#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
}
- static int update_unit(struct device *dev, void *data)
-diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
-index 0854fe2..43808c0 100644
---- a/drivers/firewire/fw-device.h
-+++ b/drivers/firewire/fw-device.h
-@@ -77,13 +77,13 @@ fw_device_is_shutdown(struct fw_device *device)
+ static u64
+@@ -1487,7 +1509,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
+ void *p, *end;
+ int i;
+
+- if (db->first_res_count > 0 && db->second_res_count > 0) {
++ if (db->first_res_count != 0 && db->second_res_count != 0) {
+ if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
+ /* This descriptor isn't done yet, stop iteration. */
+ return 0;
+@@ -1513,7 +1535,7 @@ static int handle_ir_dualbuffer_packet(struct context *context,
+ memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
+ i += ctx->base.header_size;
+ ctx->excess_bytes +=
+- (le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff;
++ (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
+ p += ctx->base.header_size + 4;
+ }
+ ctx->header_length = i;
+@@ -2039,6 +2061,35 @@ static const struct fw_card_driver ohci_driver = {
+ .stop_iso = ohci_stop_iso,
+ };
+
++#ifdef CONFIG_PPC_PMAC
++static void ohci_pmac_on(struct pci_dev *dev)
++{
++ 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);
++ }
++ }
++}
++
++static void ohci_pmac_off(struct pci_dev *dev)
++{
++ if (machine_is(powermac)) {
++ struct device_node *ofn = pci_device_to_OF_node(dev);
++
++ if (ofn) {
++ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
++ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
++ }
++ }
++}
++#else
++#define ohci_pmac_on(dev)
++#define ohci_pmac_off(dev)
++#endif /* CONFIG_PPC_PMAC */
++
+ static int __devinit
+ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ {
+@@ -2048,6 +2099,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ int err;
+ size_t size;
+
++ ohci_pmac_on(dev);
++
+ ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
+ if (ohci == NULL) {
+ fw_error("Could not malloc fw_ohci data.\n");
+@@ -2059,13 +2112,17 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ err = pci_enable_device(dev);
+ if (err) {
+ fw_error("Failed to enable OHCI hardware.\n");
+- goto fail_put_card;
++ goto fail_free;
+ }
+
+ pci_set_master(dev);
+ pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0);
+ pci_set_drvdata(dev, ohci);
+
++#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
++ ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE &&
++ dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW;
++#endif
+ spin_lock_init(&ohci->lock);
+
+ tasklet_init(&ohci->bus_reset_tasklet,
+@@ -2151,8 +2208,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+ pci_release_region(dev, 0);
+ fail_disable:
+ pci_disable_device(dev);
+- fail_put_card:
+- fw_card_put(&ohci->card);
++ fail_free:
++ kfree(&ohci->card);
+
+ return err;
}
+@@ -2180,39 +2237,42 @@ static void pci_remove(struct pci_dev *dev)
+ pci_iounmap(dev, ohci->registers);
+ pci_release_region(dev, 0);
+ pci_disable_device(dev);
+- fw_card_put(&ohci->card);
++ ohci_pmac_off(dev);
++ kfree(&ohci->card);
- struct fw_device *fw_device_get(struct fw_device *device);
-+struct fw_device *fw_device_get_by_devt(dev_t devt);
- void fw_device_put(struct fw_device *device);
- int fw_device_enable_phys_dma(struct fw_device *device);
+ fw_notify("Removed fw-ohci device.\n");
+ }
- void fw_device_cdev_update(struct fw_device *device);
- void fw_device_cdev_remove(struct fw_device *device);
+ #ifdef CONFIG_PM
+-static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
++static int pci_suspend(struct pci_dev *dev, pm_message_t state)
+ {
+- struct fw_ohci *ohci = pci_get_drvdata(pdev);
++ struct fw_ohci *ohci = pci_get_drvdata(dev);
+ int err;
+
+ software_reset(ohci);
+- free_irq(pdev->irq, ohci);
+- err = pci_save_state(pdev);
++ free_irq(dev->irq, ohci);
++ err = pci_save_state(dev);
+ if (err) {
+ fw_error("pci_save_state failed\n");
+ return err;
+ }
+- err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
++ err = pci_set_power_state(dev, pci_choose_state(dev, state));
+ if (err)
+ fw_error("pci_set_power_state failed with %d\n", err);
++ ohci_pmac_off(dev);
--struct fw_device *fw_device_from_devt(dev_t devt);
- extern int fw_cdev_major;
+ return 0;
+ }
- struct fw_unit {
+-static int pci_resume(struct pci_dev *pdev)
++static int pci_resume(struct pci_dev *dev)
+ {
+- struct fw_ohci *ohci = pci_get_drvdata(pdev);
++ struct fw_ohci *ohci = pci_get_drvdata(dev);
+ int err;
+
+- pci_set_power_state(pdev, PCI_D0);
+- pci_restore_state(pdev);
+- err = pci_enable_device(pdev);
++ ohci_pmac_on(dev);
++ pci_set_power_state(dev, PCI_D0);
++ pci_restore_state(dev);
++ err = pci_enable_device(dev);
+ if (err) {
+ fw_error("pci_enable_device failed\n");
+ return err;
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index 19ece9b..5259491 100644
+index 03069a4..d6d62c6 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
-@@ -28,14 +28,15 @@
- * and many others.
- */
-
-+#include <linux/blkdev.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
- #include <linux/kernel.h>
-+#include <linux/mod_devicetable.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
--#include <linux/mod_devicetable.h>
--#include <linux/device.h>
- #include <linux/scatterlist.h>
--#include <linux/dma-mapping.h>
--#include <linux/blkdev.h>
- #include <linux/string.h>
- #include <linux/stringify.h>
- #include <linux/timer.h>
-@@ -47,9 +48,9 @@
- #include <scsi/scsi_device.h>
- #include <scsi/scsi_host.h>
-
--#include "fw-transaction.h"
--#include "fw-topology.h"
- #include "fw-device.h"
-+#include "fw-topology.h"
-+#include "fw-transaction.h"
+@@ -174,9 +174,6 @@ struct sbp2_target {
+ #define SBP2_ORB_NULL 0x80000000
+ #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
- /*
- * So far only bridges from Oxford Semiconductor are known to support
-@@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
- * Avoids access beyond actual disk limits on devices with an off-by-one bug.
- * Don't use this with devices which don't have this bug.
- *
-+ * - delay inquiry
-+ * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
-+ *
- * - override internal blacklist
- * Instead of adding to the built-in blacklist, use only the workarounds
- * specified in the module load parameter.
-@@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
- #define SBP2_WORKAROUND_INQUIRY_36 0x2
- #define SBP2_WORKAROUND_MODE_SENSE_8 0x4
- #define SBP2_WORKAROUND_FIX_CAPACITY 0x8
-+#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
-+#define SBP2_INQUIRY_DELAY 12
- #define SBP2_WORKAROUND_OVERRIDE 0x100
-
- static int sbp2_param_workarounds;
-@@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
- ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
- ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
- ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
-+ ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
- ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
- ", or a combination)");
+-#define SBP2_DIRECTION_TO_MEDIA 0x0
+-#define SBP2_DIRECTION_FROM_MEDIA 0x1
+-
+ /* Unit directory keys */
+ #define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a
+ #define SBP2_CSR_FIRMWARE_REVISION 0x3c
+@@ -223,8 +220,8 @@ struct sbp2_status {
+ };
-@@ -132,6 +139,7 @@ struct sbp2_logical_unit {
- int generation;
- int retries;
- struct delayed_work work;
-+ bool blocked;
+ struct sbp2_pointer {
+- u32 high;
+- u32 low;
++ __be32 high;
++ __be32 low;
};
- /*
-@@ -141,16 +149,18 @@ struct sbp2_logical_unit {
- struct sbp2_target {
- struct kref kref;
- struct fw_unit *unit;
-+ const char *bus_id;
-+ struct list_head lu_list;
+ struct sbp2_orb {
+@@ -252,8 +249,8 @@ struct sbp2_management_orb {
+ struct {
+ struct sbp2_pointer password;
+ struct sbp2_pointer response;
+- u32 misc;
+- u32 length;
++ __be32 misc;
++ __be32 length;
+ struct sbp2_pointer status_fifo;
+ } request;
+ __be32 response[4];
+@@ -262,20 +259,17 @@ struct sbp2_management_orb {
+ struct sbp2_status status;
+ };
- u64 management_agent_address;
- int directory_id;
- int node_id;
- int address_high;
+-#define LOGIN_RESPONSE_GET_LOGIN_ID(v) ((v).misc & 0xffff)
+-#define LOGIN_RESPONSE_GET_LENGTH(v) (((v).misc >> 16) & 0xffff)
-
-- unsigned workarounds;
-- struct list_head lu_list;
--
-+ unsigned int workarounds;
- unsigned int mgt_orb_timeout;
-+
-+ int dont_block; /* counter for each logical unit */
-+ int blocked; /* ditto */
+ struct sbp2_login_response {
+- u32 misc;
++ __be32 misc;
+ struct sbp2_pointer command_block_agent;
+- u32 reconnect_hold;
++ __be32 reconnect_hold;
};
+ #define COMMAND_ORB_DATA_SIZE(v) ((v))
+ #define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16)
+ #define COMMAND_ORB_PAGE_TABLE_PRESENT ((1) << 19)
+ #define COMMAND_ORB_MAX_PAYLOAD(v) ((v) << 20)
+ #define COMMAND_ORB_SPEED(v) ((v) << 24)
+-#define COMMAND_ORB_DIRECTION(v) ((v) << 27)
++#define COMMAND_ORB_DIRECTION ((1) << 27)
+ #define COMMAND_ORB_REQUEST_FORMAT(v) ((v) << 29)
+ #define COMMAND_ORB_NOTIFY ((1) << 31)
+
+@@ -284,7 +278,7 @@ struct sbp2_command_orb {
+ struct {
+ struct sbp2_pointer next;
+ struct sbp2_pointer data_descriptor;
+- u32 misc;
++ __be32 misc;
+ u8 command_block[12];
+ } request;
+ struct scsi_cmnd *cmd;
+@@ -453,8 +447,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
+ unsigned long flags;
+
+ orb->pointer.high = 0;
+- orb->pointer.low = orb->request_bus;
+- fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer));
++ orb->pointer.low = cpu_to_be32(orb->request_bus);
+
+ spin_lock_irqsave(&device->card->lock, flags);
+ list_add_tail(&orb->link, &lu->orb_list);
+@@ -530,31 +523,31 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ if (dma_mapping_error(orb->response_bus))
+ goto fail_mapping_response;
+
+- orb->request.response.high = 0;
+- orb->request.response.low = orb->response_bus;
++ orb->request.response.high = 0;
++ orb->request.response.low = cpu_to_be32(orb->response_bus);
+
+- orb->request.misc =
++ orb->request.misc = cpu_to_be32(
+ MANAGEMENT_ORB_NOTIFY |
+ MANAGEMENT_ORB_FUNCTION(function) |
+- MANAGEMENT_ORB_LUN(lun_or_login_id);
+- orb->request.length =
+- MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response));
++ MANAGEMENT_ORB_LUN(lun_or_login_id));
++ orb->request.length = cpu_to_be32(
++ MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response)));
+
+- orb->request.status_fifo.high = lu->address_handler.offset >> 32;
+- orb->request.status_fifo.low = lu->address_handler.offset;
++ orb->request.status_fifo.high =
++ cpu_to_be32(lu->address_handler.offset >> 32);
++ orb->request.status_fifo.low =
++ cpu_to_be32(lu->address_handler.offset);
+
+ if (function == SBP2_LOGIN_REQUEST) {
+ /* Ask for 2^2 == 4 seconds reconnect grace period */
+- orb->request.misc |=
++ orb->request.misc |= cpu_to_be32(
+ MANAGEMENT_ORB_RECONNECT(2) |
+- MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login);
++ MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login));
+ timeout = lu->tgt->mgt_orb_timeout;
+ } else {
+ timeout = SBP2_ORB_TIMEOUT;
+ }
+
+- fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
+-
+ init_completion(&orb->done);
+ orb->base.callback = complete_management_orb;
+
+@@ -599,8 +592,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ sizeof(orb->response), DMA_FROM_DEVICE);
+ fail_mapping_response:
+ if (response)
+- fw_memcpy_from_be32(response,
+- orb->response, sizeof(orb->response));
++ memcpy(response, orb->response, sizeof(orb->response));
+ kref_put(&orb->base.kref, free_orb);
+
+ return retval;
+@@ -695,10 +687,8 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
+ if (!tgt->dont_block && !lu->blocked &&
+ lu->generation != card->generation) {
+ lu->blocked = true;
+- if (++tgt->blocked == 1) {
++ if (++tgt->blocked == 1)
+ scsi_block_requests(shost);
+- fw_notify("blocked %s\n", lu->tgt->bus_id);
+- }
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+ }
+@@ -725,10 +715,8 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
+ }
+ spin_unlock_irqrestore(&card->lock, flags);
+
+- if (unblock) {
++ if (unblock)
+ scsi_unblock_requests(shost);
+- fw_notify("unblocked %s\n", lu->tgt->bus_id);
+- }
+ }
/*
-@@ -160,7 +170,7 @@ struct sbp2_target {
- */
- #define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */
- #define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
--#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
-+#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
- #define SBP2_ORB_NULL 0x80000000
- #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
+@@ -790,7 +778,7 @@ static void sbp2_release_target(struct kref *kref)
+ scsi_remove_host(shost);
+ fw_notify("released %s\n", tgt->bus_id);
-@@ -297,7 +307,7 @@ struct sbp2_command_orb {
- static const struct {
- u32 firmware_revision;
- u32 model;
-- unsigned workarounds;
-+ unsigned int workarounds;
- } sbp2_workarounds_table[] = {
- /* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
- .firmware_revision = 0x002800,
-@@ -305,6 +315,11 @@ static const struct {
- .workarounds = SBP2_WORKAROUND_INQUIRY_36 |
- SBP2_WORKAROUND_MODE_SENSE_8,
- },
-+ /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
-+ .firmware_revision = 0x002800,
-+ .model = 0x000000,
-+ .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
-+ },
- /* Initio bridges, actually only needed for some older ones */ {
- .firmware_revision = 0x000200,
- .model = ~0,
-@@ -501,6 +516,9 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
- unsigned int timeout;
- int retval = -ENOMEM;
+- put_device(&tgt->unit->device);
++ fw_unit_put(tgt->unit);
+ scsi_host_put(shost);
+ fw_device_put(device);
+ }
+@@ -855,11 +843,10 @@ static void sbp2_login(struct work_struct *work)
+ tgt->address_high = local_node_id << 16;
+ sbp2_set_generation(lu, generation);
-+ if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device))
-+ return 0;
-+
- orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
- if (orb == NULL)
- return -ENOMEM;
-@@ -553,20 +571,20 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
-
- retval = -EIO;
- if (sbp2_cancel_orbs(lu) == 0) {
-- fw_error("orb reply timed out, rcode=0x%02x\n",
-- orb->base.rcode);
-+ fw_error("%s: orb reply timed out, rcode=0x%02x\n",
-+ lu->tgt->bus_id, orb->base.rcode);
- goto out;
+- /* Get command block agent offset and login id. */
+ lu->command_block_agent_address =
+- ((u64) (response.command_block_agent.high & 0xffff) << 32) |
+- response.command_block_agent.low;
+- lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
++ ((u64)(be32_to_cpu(response.command_block_agent.high) & 0xffff)
++ << 32) | be32_to_cpu(response.command_block_agent.low);
++ lu->login_id = be32_to_cpu(response.misc) & 0xffff;
+
+ fw_notify("%s: logged in to LUN %04x (%d retries)\n",
+ tgt->bus_id, lu->lun, lu->retries);
+@@ -1091,6 +1078,7 @@ static int sbp2_probe(struct device *dev)
+ goto fail_shost_put;
+
+ fw_device_get(device);
++ fw_unit_get(unit);
+
+ /* Initialize to values that won't match anything in our table. */
+ firmware_revision = 0xff000000;
+@@ -1106,8 +1094,6 @@ static int sbp2_probe(struct device *dev)
+
+ sbp2_init_workarounds(tgt, model, firmware_revision);
+
+- get_device(&unit->device);
+-
+ /* Do the login in a workqueue so we can easily reschedule retries. */
+ list_for_each_entry(lu, &tgt->lu_list, link)
+ sbp2_queue_work(lu, 0);
+@@ -1339,9 +1325,12 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ * tables.
+ */
+ if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
+- orb->request.data_descriptor.high = lu->tgt->address_high;
+- orb->request.data_descriptor.low = sg_dma_address(sg);
+- orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
++ orb->request.data_descriptor.high =
++ cpu_to_be32(lu->tgt->address_high);
++ orb->request.data_descriptor.low =
++ cpu_to_be32(sg_dma_address(sg));
++ orb->request.misc |=
++ cpu_to_be32(COMMAND_ORB_DATA_SIZE(sg_dma_len(sg)));
+ return 0;
}
- if (orb->base.rcode != RCODE_COMPLETE) {
-- fw_error("management write failed, rcode 0x%02x\n",
-- orb->base.rcode);
-+ fw_error("%s: management write failed, rcode 0x%02x\n",
-+ lu->tgt->bus_id, orb->base.rcode);
- goto out;
+@@ -1362,16 +1351,14 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ goto fail_page_table;
+ }
+ l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
+- orb->page_table[j].low = sg_addr;
+- orb->page_table[j].high = (l << 16);
++ orb->page_table[j].low = cpu_to_be32(sg_addr);
++ orb->page_table[j].high = cpu_to_be32(l << 16);
+ sg_addr += l;
+ sg_len -= l;
+ j++;
+ }
}
- if (STATUS_GET_RESPONSE(orb->status) != 0 ||
- STATUS_GET_SBP_STATUS(orb->status) != 0) {
-- fw_error("error status: %d:%d\n",
-+ fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id,
- STATUS_GET_RESPONSE(orb->status),
- STATUS_GET_SBP_STATUS(orb->status));
+- fw_memcpy_to_be32(orb->page_table, orb->page_table,
+- sizeof(orb->page_table[0]) * j);
+ orb->page_table_bus =
+ dma_map_single(device->card->device, orb->page_table,
+ sizeof(orb->page_table), DMA_TO_DEVICE);
+@@ -1385,11 +1372,10 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ * initiator (i.e. us), but data_descriptor can refer to data
+ * on other nodes so we need to put our ID in descriptor.high.
+ */
+- orb->request.data_descriptor.high = lu->tgt->address_high;
+- orb->request.data_descriptor.low = orb->page_table_bus;
+- orb->request.misc |=
+- COMMAND_ORB_PAGE_TABLE_PRESENT |
+- COMMAND_ORB_DATA_SIZE(j);
++ orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high);
++ orb->request.data_descriptor.low = cpu_to_be32(orb->page_table_bus);
++ orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT |
++ COMMAND_ORB_DATA_SIZE(j));
+
+ return 0;
+
+@@ -1435,8 +1421,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+ orb->done = done;
+ orb->cmd = cmd;
+
+- orb->request.next.high = SBP2_ORB_NULL;
+- orb->request.next.low = 0x0;
++ orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
+ /*
+ * At speed 100 we can do 512 bytes per packet, at speed 200,
+ * 1024 bytes per packet etc. The SBP-2 max_payload field
+@@ -1445,25 +1430,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+ */
+ max_payload = min(device->max_speed + 7,
+ device->card->max_receive - 1);
+- orb->request.misc =
++ orb->request.misc = cpu_to_be32(
+ COMMAND_ORB_MAX_PAYLOAD(max_payload) |
+ COMMAND_ORB_SPEED(device->max_speed) |
+- COMMAND_ORB_NOTIFY;
++ COMMAND_ORB_NOTIFY);
+
+ if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+- orb->request.misc |=
+- COMMAND_ORB_DIRECTION(SBP2_DIRECTION_FROM_MEDIA);
+- else if (cmd->sc_data_direction == DMA_TO_DEVICE)
+- orb->request.misc |=
+- COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
++ orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION);
+
+ if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
goto out;
-@@ -590,29 +608,147 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
- static void
- complete_agent_reset_write(struct fw_card *card, int rcode,
-- void *payload, size_t length, void *data)
-+ void *payload, size_t length, void *done)
-+{
-+ complete(done);
-+}
-+
-+static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
+- fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
+-
+- memset(orb->request.command_block,
+- 0, sizeof(orb->request.command_block));
+ memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
+
+ orb->base.callback = complete_command_orb;
+@@ -1491,11 +1468,8 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
+
+ sdev->allow_restart = 1;
+
+- /*
+- * Update the dma alignment (minimum alignment requirements for
+- * start and end of DMA transfers) to be a sector
+- */
+- blk_queue_update_dma_alignment(sdev->request_queue, 511);
++ /* SBP-2 requires quadlet alignment of the data buffers. */
++ blk_queue_update_dma_alignment(sdev->request_queue, 4 - 1);
+
+ if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
+ sdev->inquiry_len = 36;
+diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
+index 7fcc59d..99529e5 100644
+--- a/drivers/firewire/fw-transaction.c
++++ b/drivers/firewire/fw-transaction.c
+@@ -751,7 +751,7 @@ handle_topology_map(struct fw_card *card, struct fw_request *request,
+ void *payload, size_t length, void *callback_data)
{
-- struct fw_transaction *t = data;
-+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
-+ DECLARE_COMPLETION_ONSTACK(done);
-+ struct fw_transaction t;
-+ static u32 z;
-+
-+ fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
-+ lu->tgt->node_id, lu->generation, device->max_speed,
-+ lu->command_block_agent_address + SBP2_AGENT_RESET,
-+ &z, sizeof(z), complete_agent_reset_write, &done);
-+ wait_for_completion(&done);
-+}
+ int i, start, end;
+- u32 *map;
++ __be32 *map;
+
+ if (!TCODE_IS_READ_REQUEST(tcode)) {
+ fw_send_response(card, request, RCODE_TYPE_ERROR);
+diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
+index 09cb728..1a22a23 100644
+--- a/drivers/firewire/fw-transaction.h
++++ b/drivers/firewire/fw-transaction.h
+@@ -86,12 +86,12 @@
+ static inline void
+ fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
+ {
+- u32 *dst = _dst;
+- u32 *src = _src;
++ u32 *dst = _dst;
++ __be32 *src = _src;
+ int i;
-- kfree(t);
-+static void
-+complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
-+ void *payload, size_t length, void *data)
-+{
-+ kfree(data);
+ for (i = 0; i < size / 4; i++)
+- dst[i] = cpu_to_be32(src[i]);
++ dst[i] = be32_to_cpu(src[i]);
}
--static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
-+static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
- {
- struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- struct fw_transaction *t;
-- static u32 zero;
-+ static u32 z;
-
-- t = kzalloc(sizeof(*t), GFP_ATOMIC);
-+ t = kmalloc(sizeof(*t), GFP_ATOMIC);
- if (t == NULL)
-- return -ENOMEM;
-+ return;
-
- fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
- lu->tgt->node_id, lu->generation, device->max_speed,
- lu->command_block_agent_address + SBP2_AGENT_RESET,
-- &zero, sizeof(zero), complete_agent_reset_write, t);
-+ &z, sizeof(z), complete_agent_reset_write_no_wait, t);
-+}
+ static inline void
+@@ -221,7 +221,6 @@ struct fw_card {
+ const struct fw_card_driver *driver;
+ struct device *device;
+ atomic_t device_count;
+- struct kref kref;
-- return 0;
-+static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
-+{
-+ struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card;
-+ unsigned long flags;
-+
-+ /* serialize with comparisons of lu->generation and card->generation */
-+ spin_lock_irqsave(&card->lock, flags);
-+ lu->generation = generation;
-+ spin_unlock_irqrestore(&card->lock, flags);
-+}
-+
-+static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
-+{
-+ /*
-+ * We may access dont_block without taking card->lock here:
-+ * All callers of sbp2_allow_block() and all callers of sbp2_unblock()
-+ * are currently serialized against each other.
-+ * And a wrong result in sbp2_conditionally_block()'s access of
-+ * dont_block is rather harmless, it simply misses its first chance.
-+ */
-+ --lu->tgt->dont_block;
-+}
+ int node_id;
+ int generation;
+@@ -263,9 +262,6 @@ struct fw_card {
+ int bm_generation;
+ };
+
+-struct fw_card *fw_card_get(struct fw_card *card);
+-void fw_card_put(struct fw_card *card);
+-
+ /*
+ * The iso packet format allows for an immediate header/payload part
+ * stored in 'header' immediately after the packet info plus an
+diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
+index 52ac83e..c90be40 100644
+--- a/drivers/ieee1394/csr.c
++++ b/drivers/ieee1394/csr.c
+@@ -133,8 +133,7 @@ static void host_reset(struct hpsb_host *host)
+ host->csr.state &= ~0x100;
+ }
+
+- host->csr.topology_map[1] =
+- cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1);
++ be32_add_cpu(&host->csr.topology_map[1], 1);
+ host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16
+ | host->selfid_count);
+ host->csr.topology_map[0] =
+@@ -142,8 +141,7 @@ static void host_reset(struct hpsb_host *host)
+ | csr_crc16(host->csr.topology_map + 1,
+ host->selfid_count + 2));
+
+- host->csr.speed_map[1] =
+- cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1);
++ be32_add_cpu(&host->csr.speed_map[1], 1);
+ host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16
+ | csr_crc16(host->csr.speed_map+1,
+ 0x3f1));
+diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
+index 6572211..8c72f36 100644
+--- a/drivers/ieee1394/dv1394.c
++++ b/drivers/ieee1394/dv1394.c
+@@ -2179,8 +2179,7 @@ static struct ieee1394_device_id dv1394_id_table[] = {
+ MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
+
+ static struct hpsb_protocol_driver dv1394_driver = {
+- .name = "dv1394",
+- .id_table = dv1394_id_table,
++ .name = "dv1394",
+ };
+
+
+diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
+index 511e432..70afa37 100644
+--- a/drivers/ieee1394/nodemgr.c
++++ b/drivers/ieee1394/nodemgr.c
+@@ -701,7 +701,11 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
+ return 0;
+
+ driver = container_of(drv, struct hpsb_protocol_driver, driver);
+- for (id = driver->id_table; id->match_flags != 0; id++) {
++ id = driver->id_table;
++ if (!id)
++ return 0;
+
-+/*
-+ * Blocks lu->tgt if all of the following conditions are met:
-+ * - Login, INQUIRY, and high-level SCSI setup of all of the target's
-+ * logical units have been finished (indicated by dont_block == 0).
-+ * - lu->generation is stale.
-+ *
-+ * Note, scsi_block_requests() must be called while holding card->lock,
-+ * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to
-+ * unblock the target.
-+ */
-+static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
++ for (; id->match_flags != 0; id++) {
+ if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
+ id->vendor_id != ud->vendor_id)
+ continue;
+diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
+index 969de2a..29b8910 100644
+--- a/drivers/ieee1394/ohci1394.c
++++ b/drivers/ieee1394/ohci1394.c
+@@ -2993,15 +2993,9 @@ do { \
+ return err; \
+ } while (0)
+
+-static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+- const struct pci_device_id *ent)
+-{
+- struct hpsb_host *host;
+- struct ti_ohci *ohci; /* shortcut to currently handled device */
+- resource_size_t ohci_base;
+-
+ #ifdef CONFIG_PPC_PMAC
+- /* Necessary on some machines if ohci1394 was loaded/ unloaded before */
++static void ohci1394_pmac_on(struct pci_dev *dev)
+{
-+ struct sbp2_target *tgt = lu->tgt;
-+ struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
-+ struct Scsi_Host *shost =
-+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&card->lock, flags);
-+ if (!tgt->dont_block && !lu->blocked &&
-+ lu->generation != card->generation) {
-+ lu->blocked = true;
-+ if (++tgt->blocked == 1) {
-+ scsi_block_requests(shost);
-+ fw_notify("blocked %s\n", lu->tgt->bus_id);
-+ }
-+ }
-+ spin_unlock_irqrestore(&card->lock, flags);
+ if (machine_is(powermac)) {
+ struct device_node *ofn = pci_device_to_OF_node(dev);
+
+@@ -3010,8 +3004,32 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1);
+ }
+ }
+}
+
-+/*
-+ * Unblocks lu->tgt as soon as all its logical units can be unblocked.
-+ * Note, it is harmless to run scsi_unblock_requests() outside the
-+ * card->lock protected section. On the other hand, running it inside
-+ * the section might clash with shost->host_lock.
-+ */
-+static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
++static void ohci1394_pmac_off(struct pci_dev *dev)
+{
-+ struct sbp2_target *tgt = lu->tgt;
-+ struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
-+ struct Scsi_Host *shost =
-+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+ unsigned long flags;
-+ bool unblock = false;
-+
-+ spin_lock_irqsave(&card->lock, flags);
-+ if (lu->blocked && lu->generation == card->generation) {
-+ lu->blocked = false;
-+ unblock = --tgt->blocked == 0;
-+ }
-+ spin_unlock_irqrestore(&card->lock, flags);
++ if (machine_is(powermac)) {
++ struct device_node *ofn = pci_device_to_OF_node(dev);
+
-+ if (unblock) {
-+ scsi_unblock_requests(shost);
-+ fw_notify("unblocked %s\n", lu->tgt->bus_id);
++ if (ofn) {
++ pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0);
++ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0);
++ }
+ }
+}
-+
-+/*
-+ * Prevents future blocking of tgt and unblocks it.
-+ * Note, it is harmless to run scsi_unblock_requests() outside the
-+ * card->lock protected section. On the other hand, running it inside
-+ * the section might clash with shost->host_lock.
-+ */
-+static void sbp2_unblock(struct sbp2_target *tgt)
-+{
-+ struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
-+ struct Scsi_Host *shost =
-+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&card->lock, flags);
-+ ++tgt->dont_block;
-+ spin_unlock_irqrestore(&card->lock, flags);
-+
-+ scsi_unblock_requests(shost);
- }
-
- static void sbp2_release_target(struct kref *kref)
-@@ -621,23 +757,24 @@ static void sbp2_release_target(struct kref *kref)
- struct sbp2_logical_unit *lu, *next;
- struct Scsi_Host *shost =
- container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-- struct fw_device *device = fw_device(tgt->unit->device.parent);
-+
-+ /* prevent deadlocks */
-+ sbp2_unblock(tgt);
-
- list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
-- if (lu->sdev)
-+ if (lu->sdev) {
- scsi_remove_device(lu->sdev);
--
-- if (!fw_device_is_shutdown(device))
-- sbp2_send_management_orb(lu, tgt->node_id,
-- lu->generation, SBP2_LOGOUT_REQUEST,
-- lu->login_id, NULL);
-+ scsi_device_put(lu->sdev);
-+ }
-+ sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
-+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
++#else
++#define ohci1394_pmac_on(dev)
++#define ohci1394_pmac_off(dev)
+ #endif /* CONFIG_PPC_PMAC */
- fw_core_remove_address_handler(&lu->address_handler);
- list_del(&lu->link);
- kfree(lu);
- }
- scsi_remove_host(shost);
-- fw_notify("released %s\n", tgt->unit->device.bus_id);
-+ fw_notify("released %s\n", tgt->bus_id);
++static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
++ const struct pci_device_id *ent)
++{
++ struct hpsb_host *host;
++ struct ti_ohci *ohci; /* shortcut to currently handled device */
++ resource_size_t ohci_base;
++
++ ohci1394_pmac_on(dev);
+ if (pci_enable_device(dev))
+ FAIL(-ENXIO, "Failed to enable OHCI hardware");
+ pci_set_master(dev);
+@@ -3203,16 +3221,16 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+ #undef FAIL
+ }
- put_device(&tgt->unit->device);
- scsi_host_put(shost);
-@@ -666,33 +803,43 @@ static void sbp2_login(struct work_struct *work)
+-static void ohci1394_pci_remove(struct pci_dev *pdev)
++static void ohci1394_pci_remove(struct pci_dev *dev)
{
- struct sbp2_logical_unit *lu =
- container_of(work, struct sbp2_logical_unit, work.work);
-- struct Scsi_Host *shost =
-- container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
-+ struct sbp2_target *tgt = lu->tgt;
-+ struct fw_device *device = fw_device(tgt->unit->device.parent);
-+ struct Scsi_Host *shost;
- struct scsi_device *sdev;
- struct scsi_lun eight_bytes_lun;
-- struct fw_unit *unit = lu->tgt->unit;
-- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_login_response response;
- int generation, node_id, local_node_id;
-
-+ if (fw_device_is_shutdown(device))
-+ goto out;
-+
- generation = device->generation;
- smp_rmb(); /* node_id must not be older than generation */
- node_id = device->node_id;
- local_node_id = device->card->node_id;
-
-+ /* If this is a re-login attempt, log out, or we might be rejected. */
-+ if (lu->sdev)
-+ sbp2_send_management_orb(lu, device->node_id, generation,
-+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-+
- if (sbp2_send_management_orb(lu, node_id, generation,
- SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
-- if (lu->retries++ < 5)
-+ if (lu->retries++ < 5) {
- sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
-- else
-- fw_error("failed to login to %s LUN %04x\n",
-- unit->device.bus_id, lu->lun);
-+ } else {
-+ fw_error("%s: failed to login to LUN %04x\n",
-+ tgt->bus_id, lu->lun);
-+ /* Let any waiting I/O fail from now on. */
-+ sbp2_unblock(lu->tgt);
-+ }
- goto out;
+ struct ti_ohci *ohci;
+- struct device *dev;
++ struct device *device;
+
+- ohci = pci_get_drvdata(pdev);
++ ohci = pci_get_drvdata(dev);
+ if (!ohci)
+ return;
+
+- dev = get_device(&ohci->host->device);
++ device = get_device(&ohci->host->device);
+
+ switch (ohci->init_state) {
+ case OHCI_INIT_DONE:
+@@ -3246,7 +3264,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ /* Soft reset before we start - this disables
+ * interrupts and clears linkEnable and LPS. */
+ ohci_soft_reset(ohci);
+- free_irq(ohci->dev->irq, ohci);
++ free_irq(dev->irq, ohci);
+
+ case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE:
+ /* The ohci_soft_reset() stops all DMA contexts, so we
+@@ -3257,12 +3275,12 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ free_dma_trm_ctx(&ohci->at_resp_context);
+
+ case OHCI_INIT_HAVE_SELFID_BUFFER:
+- pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
++ pci_free_consistent(dev, OHCI1394_SI_DMA_BUF_SIZE,
+ ohci->selfid_buf_cpu,
+ ohci->selfid_buf_bus);
+
+ case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER:
+- pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
++ pci_free_consistent(dev, OHCI_CONFIG_ROM_LEN,
+ ohci->csr_config_rom_cpu,
+ ohci->csr_config_rom_bus);
+
+@@ -3270,35 +3288,24 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ iounmap(ohci->registers);
+
+ case OHCI_INIT_HAVE_MEM_REGION:
+- release_mem_region(pci_resource_start(ohci->dev, 0),
++ release_mem_region(pci_resource_start(dev, 0),
+ OHCI1394_REGISTER_SIZE);
+
+-#ifdef CONFIG_PPC_PMAC
+- /* 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);
+-
+- 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 */
++ ohci1394_pmac_off(dev);
+
+ case OHCI_INIT_ALLOC_HOST:
+- pci_set_drvdata(ohci->dev, NULL);
++ pci_set_drvdata(dev, NULL);
}
-- lu->generation = generation;
-- lu->tgt->node_id = node_id;
-- lu->tgt->address_high = local_node_id << 16;
-+ tgt->node_id = node_id;
-+ tgt->address_high = local_node_id << 16;
-+ sbp2_set_generation(lu, generation);
-
- /* Get command block agent offset and login id. */
- lu->command_block_agent_address =
-@@ -700,8 +847,8 @@ static void sbp2_login(struct work_struct *work)
- response.command_block_agent.low;
- lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
-
-- fw_notify("logged in to %s LUN %04x (%d retries)\n",
-- unit->device.bus_id, lu->lun, lu->retries);
-+ fw_notify("%s: logged in to LUN %04x (%d retries)\n",
-+ tgt->bus_id, lu->lun, lu->retries);
-
- #if 0
- /* FIXME: The linux1394 sbp2 does this last step. */
-@@ -711,26 +858,62 @@ static void sbp2_login(struct work_struct *work)
- PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
- sbp2_agent_reset(lu);
-
-+ /* This was a re-login. */
-+ if (lu->sdev) {
-+ sbp2_cancel_orbs(lu);
-+ sbp2_conditionally_unblock(lu);
-+ goto out;
-+ }
-+
-+ if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
-+ ssleep(SBP2_INQUIRY_DELAY);
-+
- memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
- eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
- eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
-+ shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-
- sdev = __scsi_add_device(shost, 0, 0,
- scsilun_to_int(&eight_bytes_lun), lu);
-- if (IS_ERR(sdev)) {
-- sbp2_send_management_orb(lu, node_id, generation,
-- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-- /*
-- * Set this back to sbp2_login so we fall back and
-- * retry login on bus reset.
-- */
-- PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
-- } else {
-- lu->sdev = sdev;
-+ /*
-+ * FIXME: We are unable to perform reconnects while in sbp2_login().
-+ * Therefore __scsi_add_device() will get into trouble if a bus reset
-+ * happens in parallel. It will either fail or leave us with an
-+ * unusable sdev. As a workaround we check for this and retry the
-+ * whole login and SCSI probing.
-+ */
-+
-+ /* Reported error during __scsi_add_device() */
-+ if (IS_ERR(sdev))
-+ goto out_logout_login;
-+
-+ /* Unreported error during __scsi_add_device() */
-+ smp_rmb(); /* get current card generation */
-+ if (generation != device->card->generation) {
-+ scsi_remove_device(sdev);
- scsi_device_put(sdev);
-+ goto out_logout_login;
- }
-+
-+ /* No error during __scsi_add_device() */
-+ lu->sdev = sdev;
-+ sbp2_allow_block(lu);
-+ goto out;
-+
-+ out_logout_login:
-+ smp_rmb(); /* generation may have changed */
-+ generation = device->generation;
-+ smp_rmb(); /* node_id must not be older than generation */
-+
-+ sbp2_send_management_orb(lu, device->node_id, generation,
-+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-+ /*
-+ * If a bus reset happened, sbp2_update will have requeued
-+ * lu->work already. Reset the work from reconnect to login.
-+ */
-+ PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
- out:
-- sbp2_target_put(lu->tgt);
-+ sbp2_target_put(tgt);
+- if (dev)
+- put_device(dev);
++ if (device)
++ put_device(device);
}
- static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
-@@ -755,6 +938,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
- lu->sdev = NULL;
- lu->lun = lun_entry & 0xffff;
- lu->retries = 0;
-+ lu->blocked = false;
-+ ++tgt->dont_block;
- INIT_LIST_HEAD(&lu->orb_list);
- INIT_DELAYED_WORK(&lu->work, sbp2_login);
-
-@@ -813,7 +998,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
- if (timeout > tgt->mgt_orb_timeout)
- fw_notify("%s: config rom contains %ds "
- "management ORB timeout, limiting "
-- "to %ds\n", tgt->unit->device.bus_id,
-+ "to %ds\n", tgt->bus_id,
- timeout / 1000,
- tgt->mgt_orb_timeout / 1000);
- break;
-@@ -836,12 +1021,12 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
- u32 firmware_revision)
- {
- int i;
-- unsigned w = sbp2_param_workarounds;
-+ unsigned int w = sbp2_param_workarounds;
-
- if (w)
- fw_notify("Please notify linux1394-devel at lists.sourceforge.net "
- "if you need the workarounds parameter for %s\n",
-- tgt->unit->device.bus_id);
-+ tgt->bus_id);
-
- if (w & SBP2_WORKAROUND_OVERRIDE)
- goto out;
-@@ -863,8 +1048,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
- if (w)
- fw_notify("Workarounds for %s: 0x%x "
- "(firmware_revision 0x%06x, model_id 0x%06x)\n",
-- tgt->unit->device.bus_id,
-- w, firmware_revision, model);
-+ tgt->bus_id, w, firmware_revision, model);
- tgt->workarounds = w;
- }
-
-@@ -888,6 +1072,7 @@ static int sbp2_probe(struct device *dev)
- tgt->unit = unit;
- kref_init(&tgt->kref);
- INIT_LIST_HEAD(&tgt->lu_list);
-+ tgt->bus_id = unit->device.bus_id;
-
- if (fw_device_enable_phys_dma(device) < 0)
- goto fail_shost_put;
-@@ -938,10 +1123,13 @@ static void sbp2_reconnect(struct work_struct *work)
+ #ifdef CONFIG_PM
+-static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state)
++static int ohci1394_pci_suspend(struct pci_dev *dev, pm_message_t state)
{
- struct sbp2_logical_unit *lu =
- container_of(work, struct sbp2_logical_unit, work.work);
-- struct fw_unit *unit = lu->tgt->unit;
-- struct fw_device *device = fw_device(unit->device.parent);
-+ struct sbp2_target *tgt = lu->tgt;
-+ struct fw_device *device = fw_device(tgt->unit->device.parent);
- int generation, node_id, local_node_id;
-
-+ if (fw_device_is_shutdown(device))
-+ goto out;
-+
- generation = device->generation;
- smp_rmb(); /* node_id must not be older than generation */
- node_id = device->node_id;
-@@ -950,10 +1138,17 @@ static void sbp2_reconnect(struct work_struct *work)
- if (sbp2_send_management_orb(lu, node_id, generation,
- SBP2_RECONNECT_REQUEST,
- lu->login_id, NULL) < 0) {
-- if (lu->retries++ >= 5) {
-- fw_error("failed to reconnect to %s\n",
-- unit->device.bus_id);
-- /* Fall back and try to log in again. */
-+ /*
-+ * If reconnect was impossible even though we are in the
-+ * current generation, fall back and try to log in again.
-+ *
-+ * We could check for "Function rejected" status, but
-+ * looking at the bus generation as simpler and more general.
-+ */
-+ smp_rmb(); /* get current card generation */
-+ if (generation == device->card->generation ||
-+ lu->retries++ >= 5) {
-+ fw_error("%s: failed to reconnect\n", tgt->bus_id);
- lu->retries = 0;
- PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
- }
-@@ -961,17 +1156,18 @@ static void sbp2_reconnect(struct work_struct *work)
- goto out;
+ int err;
+- struct ti_ohci *ohci = pci_get_drvdata(pdev);
++ struct ti_ohci *ohci = pci_get_drvdata(dev);
+
+ if (!ohci) {
+ printk(KERN_ERR "%s: tried to suspend nonexisting host\n",
+@@ -3326,32 +3333,23 @@ static int ohci1394_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+ ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT);
+ ohci_soft_reset(ohci);
+
+- err = pci_save_state(pdev);
++ err = pci_save_state(dev);
+ if (err) {
+ PRINT(KERN_ERR, "pci_save_state failed with %d", err);
+ return err;
}
+- err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
++ err = pci_set_power_state(dev, pci_choose_state(dev, state));
+ if (err)
+ DBGMSG("pci_set_power_state failed with %d", err);
+-
+-/* PowerMac suspend code comes last */
+-#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, 0);
+- }
+-#endif /* CONFIG_PPC_PMAC */
++ ohci1394_pmac_off(dev);
-- lu->generation = generation;
-- lu->tgt->node_id = node_id;
-- lu->tgt->address_high = local_node_id << 16;
-+ tgt->node_id = node_id;
-+ tgt->address_high = local_node_id << 16;
-+ sbp2_set_generation(lu, generation);
-
-- fw_notify("reconnected to %s LUN %04x (%d retries)\n",
-- unit->device.bus_id, lu->lun, lu->retries);
-+ fw_notify("%s: reconnected to LUN %04x (%d retries)\n",
-+ tgt->bus_id, lu->lun, lu->retries);
-
- sbp2_agent_reset(lu);
- sbp2_cancel_orbs(lu);
-+ sbp2_conditionally_unblock(lu);
- out:
-- sbp2_target_put(lu->tgt);
-+ sbp2_target_put(tgt);
+ return 0;
}
- static void sbp2_update(struct fw_unit *unit)
-@@ -986,6 +1182,7 @@ static void sbp2_update(struct fw_unit *unit)
- * Iteration over tgt->lu_list is therefore safe here.
- */
- list_for_each_entry(lu, &tgt->lu_list, link) {
-+ sbp2_conditionally_block(lu);
- lu->retries = 0;
- sbp2_queue_work(lu, 0);
- }
-@@ -1063,7 +1260,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
-
- if (status != NULL) {
- if (STATUS_GET_DEAD(*status))
-- sbp2_agent_reset(orb->lu);
-+ sbp2_agent_reset_no_wait(orb->lu);
-
- switch (STATUS_GET_RESPONSE(*status)) {
- case SBP2_STATUS_REQUEST_COMPLETE:
-@@ -1089,6 +1286,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
- * or when sending the write (less likely).
- */
- result = DID_BUS_BUSY << 16;
-+ sbp2_conditionally_block(orb->lu);
- }
-
- dma_unmap_single(device->card->device, orb->base.request_bus,
-@@ -1197,7 +1395,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
- struct sbp2_logical_unit *lu = cmd->device->hostdata;
- struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- struct sbp2_command_orb *orb;
-- unsigned max_payload;
-+ unsigned int max_payload;
- int retval = SCSI_MLQUEUE_HOST_BUSY;
-
- /*
-@@ -1275,6 +1473,10 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
+-static int ohci1394_pci_resume(struct pci_dev *pdev)
++static int ohci1394_pci_resume(struct pci_dev *dev)
{
- struct sbp2_logical_unit *lu = sdev->hostdata;
-
-+ /* (Re-)Adding logical units via the SCSI stack is not supported. */
-+ if (!lu)
-+ return -ENOSYS;
-+
- sdev->allow_restart = 1;
-
- /*
-@@ -1319,7 +1521,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
- {
- struct sbp2_logical_unit *lu = cmd->device->hostdata;
+ int err;
+- struct ti_ohci *ohci = pci_get_drvdata(pdev);
++ struct ti_ohci *ohci = pci_get_drvdata(dev);
+
+ if (!ohci) {
+ printk(KERN_ERR "%s: tried to resume nonexisting host\n",
+@@ -3360,19 +3358,10 @@ static int ohci1394_pci_resume(struct pci_dev *pdev)
+ }
+ DBGMSG("resume called");
-- fw_notify("sbp2_scsi_abort\n");
-+ fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id);
- sbp2_agent_reset(lu);
- sbp2_cancel_orbs(lu);
+-/* 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);
++ ohci1394_pmac_on(dev);
++ pci_set_power_state(dev, PCI_D0);
++ pci_restore_state(dev);
++ err = pci_enable_device(dev);
+ if (err) {
+ PRINT(KERN_ERR, "pci_enable_device failed with %d", err);
+ return err;
+diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
+index 37e7e10..3634785 100644
+--- a/drivers/ieee1394/raw1394.c
++++ b/drivers/ieee1394/raw1394.c
+@@ -2959,7 +2959,6 @@ MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
+
+ static struct hpsb_protocol_driver raw1394_driver = {
+ .name = "raw1394",
+- .id_table = raw1394_id_table,
+ };
+ /******************************************************************************/
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
-index 28e155a..29e6663 100644
+index 9e2b196..29e6663 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
-@@ -183,6 +183,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
- * Avoids access beyond actual disk limits on devices with an off-by-one bug.
- * Don't use this with devices which don't have this bug.
- *
-+ * - delay inquiry
-+ * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
-+ *
- * - override internal blacklist
- * Instead of adding to the built-in blacklist, use only the workarounds
- * specified in the module load parameter.
-@@ -195,6 +198,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
- ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
- ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
- ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
-+ ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
- ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
- ", or a combination)");
-
-@@ -357,6 +361,11 @@ static const struct {
- .workarounds = SBP2_WORKAROUND_INQUIRY_36 |
- SBP2_WORKAROUND_MODE_SENSE_8,
- },
-+ /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
-+ .firmware_revision = 0x002800,
-+ .model_id = 0x000000,
-+ .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
-+ },
- /* Initio bridges, actually only needed for some older ones */ {
- .firmware_revision = 0x000200,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
-@@ -914,6 +923,9 @@ static int sbp2_start_device(struct sbp2_lu *lu)
- sbp2_agent_reset(lu, 1);
- sbp2_max_speed_and_size(lu);
-
-+ if (lu->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
-+ ssleep(SBP2_INQUIRY_DELAY);
-+
- error = scsi_add_device(lu->shost, 0, lu->ud->id, 0);
- if (error) {
- SBP2_ERR("scsi_add_device failed");
-@@ -1962,14 +1974,14 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
- {
- struct sbp2_lu *lu = (struct sbp2_lu *)sdev->host->hostdata[0];
-
-+ if (sdev->lun != 0 || sdev->id != lu->ud->id || sdev->channel != 0)
-+ return -ENODEV;
-+
+@@ -1980,11 +1980,8 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
lu->sdev = sdev;
sdev->allow_restart = 1;
@@ -913,16 +1110,38 @@
if (lu->workarounds & SBP2_WORKAROUND_INQUIRY_36)
sdev->inquiry_len = 36;
-diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
-index d2ecb0d..80d8e09 100644
---- a/drivers/ieee1394/sbp2.h
-+++ b/drivers/ieee1394/sbp2.h
-@@ -343,6 +343,8 @@ enum sbp2lu_state_types {
- #define SBP2_WORKAROUND_INQUIRY_36 0x2
- #define SBP2_WORKAROUND_MODE_SENSE_8 0x4
- #define SBP2_WORKAROUND_FIX_CAPACITY 0x8
-+#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
-+#define SBP2_INQUIRY_DELAY 12
- #define SBP2_WORKAROUND_OVERRIDE 0x100
+diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
+index bd28adf..cc240b2 100644
+--- a/drivers/ieee1394/video1394.c
++++ b/drivers/ieee1394/video1394.c
+@@ -1315,8 +1315,7 @@ static struct ieee1394_device_id video1394_id_table[] = {
+ MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
+
+ static struct hpsb_protocol_driver video1394_driver = {
+- .name = VIDEO1394_DRIVER_NAME,
+- .id_table = video1394_id_table,
++ .name = VIDEO1394_DRIVER_NAME,
+ };
+
- #endif /* SBP2_H */
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 0796c1a..4e370e1 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -592,6 +592,16 @@ config LATENCYTOP
+ Enable this option if you want to use the LatencyTOP tool
+ to find out which userspace is blocking on what kernel operations.
+
++config FIREWIRE_OHCI_REMOTE_DMA
++ bool "Remote debugging via firewire-ohci"
++ depends on FIREWIRE_OHCI
++ help
++ This option lets you use the FireWire bus for remote debugging.
++ It enables unfiltered remote DMA in the firewire-ohci driver.
++ See Documentation/debugging-via-ohci1394.txt for more information.
++
++ If unsure, say N.
++
+ config PROVIDE_OHCI1394_DMA_INIT
+ bool "Provide code for enabling DMA over FireWire early on boot"
+ depends on PCI && X86
More information about the fedora-extras-commits
mailing list