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

Commit c8a9a498 authored by Stefan Richter's avatar Stefan Richter
Browse files

firewire: fw-ohci: add self ID error check



Discard self ID buffer contents if
  - the selfIDError flag is set,
  - any of the self ID packets has bit errors.

Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: default avatarJarod Wilson <jwilson@redhat.com>
parent 2ed0f181
Loading
Loading
Loading
Loading
+10 −4
Original line number Original line Diff line number Diff line
@@ -1019,20 +1019,26 @@ static void bus_reset_tasklet(unsigned long data)
	ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
	ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
			       OHCI1394_NodeID_nodeNumber);
			       OHCI1394_NodeID_nodeNumber);


	reg = reg_read(ohci, OHCI1394_SelfIDCount);
	if (reg & OHCI1394_SelfIDCount_selfIDError) {
		fw_notify("inconsistent self IDs\n");
		return;
	}
	/*
	/*
	 * The count in the SelfIDCount register is the number of
	 * The count in the SelfIDCount register is the number of
	 * bytes in the self ID receive buffer.  Since we also receive
	 * bytes in the self ID receive buffer.  Since we also receive
	 * the inverted quadlets and a header quadlet, we shift one
	 * the inverted quadlets and a header quadlet, we shift one
	 * bit extra to get the actual number of self IDs.
	 * bit extra to get the actual number of self IDs.
	 */
	 */

	self_id_count = (reg >> 3) & 0x3ff;
	self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
	generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
	generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
	rmb();
	rmb();


	for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
	for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
		if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
		if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1]) {
			fw_error("inconsistent self IDs\n");
			fw_notify("inconsistent self IDs\n");
			return;
		}
		ohci->self_id_buffer[j] =
		ohci->self_id_buffer[j] =
				cond_le32_to_cpu(ohci->self_id_cpu[i]);
				cond_le32_to_cpu(ohci->self_id_cpu[i]);
	}
	}
+1 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
#define  OHCI1394_HCControl_softReset		0x00010000
#define  OHCI1394_HCControl_softReset		0x00010000
#define OHCI1394_SelfIDBuffer                 0x064
#define OHCI1394_SelfIDBuffer                 0x064
#define OHCI1394_SelfIDCount                  0x068
#define OHCI1394_SelfIDCount                  0x068
#define  OHCI1394_SelfIDCount_selfIDError	0x80000000
#define OHCI1394_IRMultiChanMaskHiSet         0x070
#define OHCI1394_IRMultiChanMaskHiSet         0x070
#define OHCI1394_IRMultiChanMaskHiClear       0x074
#define OHCI1394_IRMultiChanMaskHiClear       0x074
#define OHCI1394_IRMultiChanMaskLoSet         0x078
#define OHCI1394_IRMultiChanMaskLoSet         0x078