Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28897fb7 authored by Stefan Richter's avatar Stefan Richter
Browse files

firewire: ohci: TSB41BA3D support tweaks



Fix:  phy_reg_mutex must be held over the write/read_phy_reg pair which
gets PHY port status.

Only print to the log when a TSB41BA3D was found.  By far most TSB82AA2
cards have a TSB81BA3, and firewire-ohci can keep quiet about that.

Shorten some strings and comments.  Change some whitespace.

Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 25935ebe
Loading
Loading
Loading
Loading
+23 −51
Original line number Diff line number Diff line
@@ -325,7 +325,7 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
	", AR/selfID endianess = "	__stringify(QUIRK_BE_HEADERS)
	", no 1394a enhancements = "	__stringify(QUIRK_NO_1394A)
	", disable MSI = "		__stringify(QUIRK_NO_MSI)
	", workaround for TI SLLZ059 errata = "	__stringify(QUIRK_TI_SLLZ059)
	", TI SLLZ059 erratum = "	__stringify(QUIRK_TI_SLLZ059)
	")");

#define OHCI_PARAM_DEBUG_AT_AR		1
@@ -1730,11 +1730,7 @@ static int get_status_for_port(struct fw_ohci *ohci, int port_index)

	mutex_lock(&ohci->phy_reg_mutex);
	reg = write_phy_reg(ohci, 7, port_index);
	mutex_unlock(&ohci->phy_reg_mutex);
	if (reg < 0)
		return reg;

	mutex_lock(&ohci->phy_reg_mutex);
	if (reg >= 0)
		reg = read_phy_reg(ohci, 8);
	mutex_unlock(&ohci->phy_reg_mutex);
	if (reg < 0)
@@ -1754,6 +1750,7 @@ static int get_self_id_pos(struct fw_ohci *ohci, u32 self_id,
{
	int i;
	u32 entry;

	for (i = 0; i < self_id_count; i++) {
		entry = ohci->self_id_buffer[i];
		if ((self_id & 0xff000000) == (entry & 0xff000000))
@@ -1765,33 +1762,16 @@ static int get_self_id_pos(struct fw_ohci *ohci, u32 self_id,
}

/*
 * This function implements a work around for the Texas Instruments PHY
 * TSB41BA3D. This phy has a bug at least in combination with the TI
 * LLCs TSB82AA2B and TSB12LV26. The selfid coming from the locally
 * connected phy is not propagated into the selfid buffer of the OHCI
 * (see http://www.ti.com/litv/pdf/sllz059 for details).
 * The main idea is to construct the selfid ourselves.
 * TI TSB82AA2B and TSB12LV26 do not receive the selfID of a locally
 * attached TSB41BA3D phy; see http://www.ti.com/litv/pdf/sllz059.
 * Construct the selfID from phy register contents.
 * FIXME:  How to determine the selfID.i flag?
 */

static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count)
{
	int reg;
	int i;
	int pos;
	int status;
	u32 self_id;

/*
 * preset bits in self_id
 *
 * link active: 0b1
 * speed: 0b11
 * bridge: 0b00
 * contender: 0b1
 * initiated reset: 0b0
 * more packets: 0b0
 */
	self_id = 0x8040C800;
	int reg, i, pos, status;
	/* link active 1, speed 3, bridge 0, contender 1, more packets 0 */
	u32 self_id = 0x8040c800;

	reg = reg_read(ohci, OHCI1394_NodeID);
	if (!(reg & OHCI1394_NodeID_idValid)) {
@@ -1800,16 +1780,12 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count)
	}
	self_id |= ((reg & 0x3f) << 24); /* phy ID */

	mutex_lock(&ohci->phy_reg_mutex);
	reg = read_phy_reg(ohci, 4);
	mutex_unlock(&ohci->phy_reg_mutex);
	reg = ohci_read_phy_reg(&ohci->card, 4);
	if (reg < 0)
		return reg;
	self_id |= ((reg & 0x07) << 8); /* power class */

	mutex_lock(&ohci->phy_reg_mutex);
	reg = read_phy_reg(ohci, 1);
	mutex_unlock(&ohci->phy_reg_mutex);
	reg = ohci_read_phy_reg(&ohci->card, 1);
	if (reg < 0)
		return reg;
	self_id |= ((reg & 0x3f) << 16); /* gap count */
@@ -1894,7 +1870,7 @@ static void bus_reset_work(struct work_struct *work)
	if (ohci->quirks & QUIRK_TI_SLLZ059) {
		self_id_count = find_and_insert_self_id(ohci, self_id_count);
		if (self_id_count < 0) {
			fw_notify("could not construct local self IDs\n");
			fw_notify("could not construct local self ID\n");
			return;
		}
	}
@@ -2188,10 +2164,7 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci)

static int probe_tsb41ba3d(struct fw_ohci *ohci)
{
	int reg;
	int i;
	int vendor_id;
	int product_id;
	int reg, i, vendor_id, product_id;

	reg = read_phy_reg(ohci, 2);
	if (reg < 0)
@@ -2226,7 +2199,7 @@ static int ohci_enable(struct fw_card *card,
	struct fw_ohci *ohci = fw_ohci(card);
	struct pci_dev *dev = to_pci_dev(card->device);
	u32 lps, seconds, version, irqs;
	int i, ret, tsb41ba3d_found;
	int i, ret;

	if (software_reset(ohci)) {
		fw_error("Failed to reset ohci card.\n");
@@ -2258,15 +2231,14 @@ static int ohci_enable(struct fw_card *card,
	}

	if (ohci->quirks & QUIRK_TI_SLLZ059) {
		tsb41ba3d_found = probe_tsb41ba3d(ohci);
		if (tsb41ba3d_found < 0)
			return tsb41ba3d_found;
		if (!tsb41ba3d_found) {
			fw_notify("No TSB41BA3D found, "
				  "resetting QUIRK_TI_SLLZ059\n");
		ret = probe_tsb41ba3d(ohci);
		if (ret < 0)
			return ret;
		if (ret)
			fw_notify("local TSB41BA3D phy\n");
		else
			ohci->quirks &= ~QUIRK_TI_SLLZ059;
	}
	}

	reg_write(ohci, OHCI1394_HCControlClear,
		  OHCI1394_HCControl_noByteSwapData);