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

Commit 85ec688c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull firewire fixes from Stefan Richter:
 "Fix a use-after-free regression since v3.4 and an initialization
  regression since v3.10"

* tag 'firewire-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394:
  firewire: ohci: fix probe failure with Agere/LSI controllers
  firewire: net: fix use after free
parents 7bffc481 0ca49345
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -929,8 +929,6 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,
	if (rcode == RCODE_COMPLETE) {
	if (rcode == RCODE_COMPLETE) {
		fwnet_transmit_packet_done(ptask);
		fwnet_transmit_packet_done(ptask);
	} else {
	} else {
		fwnet_transmit_packet_failed(ptask);

		if (printk_timed_ratelimit(&j,  1000) || rcode != last_rcode) {
		if (printk_timed_ratelimit(&j,  1000) || rcode != last_rcode) {
			dev_err(&ptask->dev->netdev->dev,
			dev_err(&ptask->dev->netdev->dev,
				"fwnet_write_complete failed: %x (skipped %d)\n",
				"fwnet_write_complete failed: %x (skipped %d)\n",
@@ -938,9 +936,11 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,


			errors_skipped = 0;
			errors_skipped = 0;
			last_rcode = rcode;
			last_rcode = rcode;
		} else
		} else {
			errors_skipped++;
			errors_skipped++;
		}
		}
		fwnet_transmit_packet_failed(ptask);
	}
}
}


static int fwnet_send_packet(struct fwnet_packet_task *ptask)
static int fwnet_send_packet(struct fwnet_packet_task *ptask)
+2 −13
Original line number Original line Diff line number Diff line
@@ -290,7 +290,6 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define QUIRK_NO_MSI			0x10
#define QUIRK_NO_MSI			0x10
#define QUIRK_TI_SLLZ059		0x20
#define QUIRK_TI_SLLZ059		0x20
#define QUIRK_IR_WAKE			0x40
#define QUIRK_IR_WAKE			0x40
#define QUIRK_PHY_LCTRL_TIMEOUT		0x80


/* In case of multiple matches in ohci_quirks[], only the first one is used. */
/* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct {
static const struct {
@@ -303,10 +302,7 @@ static const struct {
		QUIRK_BE_HEADERS},
		QUIRK_BE_HEADERS},


	{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
	{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
		QUIRK_PHY_LCTRL_TIMEOUT | QUIRK_NO_MSI},
		QUIRK_NO_MSI},

	{PCI_VENDOR_ID_ATT, PCI_ANY_ID, PCI_ANY_ID,
		QUIRK_PHY_LCTRL_TIMEOUT},


	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
		QUIRK_RESET_PACKET},
		QUIRK_RESET_PACKET},
@@ -353,7 +349,6 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
	", disable MSI = "		__stringify(QUIRK_NO_MSI)
	", disable MSI = "		__stringify(QUIRK_NO_MSI)
	", TI SLLZ059 erratum = "	__stringify(QUIRK_TI_SLLZ059)
	", TI SLLZ059 erratum = "	__stringify(QUIRK_TI_SLLZ059)
	", IR wake unreliable = "	__stringify(QUIRK_IR_WAKE)
	", IR wake unreliable = "	__stringify(QUIRK_IR_WAKE)
	", phy LCtrl timeout = "	__stringify(QUIRK_PHY_LCTRL_TIMEOUT)
	")");
	")");


#define OHCI_PARAM_DEBUG_AT_AR		1
#define OHCI_PARAM_DEBUG_AT_AR		1
@@ -2299,9 +2294,6 @@ static int ohci_enable(struct fw_card *card,
	 * TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but
	 * TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but
	 * cannot actually use the phy at that time.  These need tens of
	 * cannot actually use the phy at that time.  These need tens of
	 * millisecods pause between LPS write and first phy access too.
	 * millisecods pause between LPS write and first phy access too.
	 *
	 * But do not wait for 50msec on Agere/LSI cards.  Their phy
	 * arbitration state machine may time out during such a long wait.
	 */
	 */


	reg_write(ohci, OHCI1394_HCControlSet,
	reg_write(ohci, OHCI1394_HCControlSet,
@@ -2309,11 +2301,8 @@ static int ohci_enable(struct fw_card *card,
		  OHCI1394_HCControl_postedWriteEnable);
		  OHCI1394_HCControl_postedWriteEnable);
	flush_writes(ohci);
	flush_writes(ohci);


	if (!(ohci->quirks & QUIRK_PHY_LCTRL_TIMEOUT))
	for (lps = 0, i = 0; !lps && i < 3; i++) {
		msleep(50);
		msleep(50);

	for (lps = 0, i = 0; !lps && i < 150; i++) {
		msleep(1);
		lps = reg_read(ohci, OHCI1394_HCControlSet) &
		lps = reg_read(ohci, OHCI1394_HCControlSet) &
		      OHCI1394_HCControl_LPS;
		      OHCI1394_HCControl_LPS;
	}
	}