[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux1394-devel
Subject:    Re: [work in progress] firewire: ohci: handle register access failure in SCLK domain
From:       Stefan Richter <stefanr () s5r6 ! in-berlin ! de>
Date:       2012-03-04 20:19:53
Message-ID: 20120304211953.747bbd2f () stein
[Download RAW message or body]

On Mar 04 Stefan Richter wrote:
> perhaps we should add optimizations for OHCI 1.0 chips because these
> supposedly do not exhibit a regAccessFail flag.

Like this for example.  Maybe we even want to whitelist a few known
good OHCI 1.1 controllers.  But which ones?  There is even a TI chip
among the affected ones.
---
 drivers/firewire/ohci.c |   34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -188,7 +188,8 @@ struct fw_ohci {
 	int generation;
 	int request_generation;	/* for timestamping incoming requests */
 	unsigned quirks;
-	unsigned int pri_req_max;
+	unsigned pri_req_max;
+	unsigned version;
 	u32 bus_time;
 	bool is_root;
 	bool csr_state_setclear_abdicate;
@@ -583,6 +584,14 @@ static int reg_rw_sclk(struct fw_ohci *o
 {
 	int i, ret;
 
+	if (ohci->version < OHCI_VERSION_1_1) {
+		if (read)
+			*data = reg_read(ohci, offset);
+		else
+			reg_write(ohci, offset, *data);
+		return 0;
+	}
+
 	for (i = 0; ; i++) {
 		ret = __reg_rw_sclk(ohci, offset, data, read);
 		if (ret != -EAGAIN)
@@ -2325,7 +2334,7 @@ static int ohci_enable(struct fw_card *c
 {
 	struct fw_ohci *ohci = fw_ohci(card);
 	struct pci_dev *dev = to_pci_dev(card->device);
-	u32 lps, seconds, version, irqs, reg;
+	u32 lps, seconds, irqs, reg;
 	int i, ret;
 
 	if (software_reset(ohci)) {
@@ -2356,7 +2365,14 @@ static int ohci_enable(struct fw_card *c
 		dev_err(card->device, "failed to set Link Power Status\n");
 		return -EIO;
 	}
-	reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_regAccessFail);
+
+	ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
+	if (ohci->version >= OHCI_VERSION_1_1) {
+		reg_write(ohci, OHCI1394_InitialChannelsAvailableHi,
+			  0xfffffffe);
+		card->broadcast_channel_auto_allocated = true;
+		reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_regAccessFail);
+	}
 
 	if (ohci->quirks & QUIRK_TI_SLLZ059) {
 		ret = probe_tsb41ba3d(ohci);
@@ -2391,13 +2407,6 @@ static int ohci_enable(struct fw_card *c
 	if (ret < 0)
 		return ret;
 
-	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
-	if (version >= OHCI_VERSION_1_1) {
-		reg_write(ohci, OHCI1394_InitialChannelsAvailableHi,
-			  0xfffffffe);
-		card->broadcast_channel_auto_allocated = true;
-	}
-
 	/* Get implemented bits of the priority arbitration request counter. */
 	ret = reg_write_sclk_wait(ohci, OHCI1394_FairnessControl, 0x3f);
 	if (ret < 0)
@@ -3588,7 +3597,7 @@ static int __devinit pci_probe(struct pc
 			       const struct pci_device_id *ent)
 {
 	struct fw_ohci *ohci;
-	u32 bus_options, max_receive, link_speed, version;
+	u32 bus_options, max_receive, link_speed;
 	u64 guid;
 	int i, err;
 	size_t size;
@@ -3720,11 +3729,10 @@ static int __devinit pci_probe(struct pc
 	if (err)
 		goto fail_contexts;
 
-	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
 	dev_notice(&dev->dev,
 		  "added OHCI v%x.%x device as card %d, "
 		  "%d IR + %d IT contexts, quirks 0x%x\n",
-		  version >> 16, version & 0xff, ohci->card.index,
+		  ohci->version >> 16, ohci->version & 0xff, ohci->card.index,
 		  ohci->n_ir, ohci->n_it, ohci->quirks);
 
 	return 0;

-- 
Stefan Richter
-=====-===-- --== --=--
http://arcgraph.de/sr/

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
mailing list linux1394-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux1394-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic