소스 검색

Merge tag 'char-misc-3.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
 "Here are 3 fixes for the mei and thunderbolt drivers that resolve some
  reported issues.

  All have been in linux-next for a while"

* tag 'char-misc-3.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  thunderbolt: Clear hops before overwriting
  mei: nfc: fix memory leak in error path
  mei: reset client state on queued connect request
Linus Torvalds 11 년 전
부모
커밋
7acaf5202a
3개의 변경된 파일26개의 추가작업 그리고 7개의 파일을 삭제
  1. 1 0
      drivers/misc/mei/client.c
  2. 5 6
      drivers/misc/mei/nfc.c
  3. 20 1
      drivers/thunderbolt/path.c

+ 1 - 0
drivers/misc/mei/client.c

@@ -601,6 +601,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
 		cl->timer_count = MEI_CONNECT_TIMEOUT;
 		cl->timer_count = MEI_CONNECT_TIMEOUT;
 		list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
 		list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
 	} else {
 	} else {
+		cl->state = MEI_FILE_INITIALIZING;
 		list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 		list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
 	}
 	}
 
 

+ 5 - 6
drivers/misc/mei/nfc.c

@@ -342,9 +342,10 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 	ndev = (struct mei_nfc_dev *) cldev->priv_data;
 	ndev = (struct mei_nfc_dev *) cldev->priv_data;
 	dev = ndev->cl->dev;
 	dev = ndev->cl->dev;
 
 
+	err = -ENOMEM;
 	mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL);
 	mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL);
 	if (!mei_buf)
 	if (!mei_buf)
-		return -ENOMEM;
+		goto out;
 
 
 	hdr = (struct mei_nfc_hci_hdr *) mei_buf;
 	hdr = (struct mei_nfc_hci_hdr *) mei_buf;
 	hdr->cmd = MEI_NFC_CMD_HCI_SEND;
 	hdr->cmd = MEI_NFC_CMD_HCI_SEND;
@@ -354,12 +355,9 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 	hdr->data_size = length;
 	hdr->data_size = length;
 
 
 	memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length);
 	memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length);
-
 	err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE);
 	err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE);
 	if (err < 0)
 	if (err < 0)
-		return err;
-
-	kfree(mei_buf);
+		goto out;
 
 
 	if (!wait_event_interruptible_timeout(ndev->send_wq,
 	if (!wait_event_interruptible_timeout(ndev->send_wq,
 				ndev->recv_req_id == ndev->req_id, HZ)) {
 				ndev->recv_req_id == ndev->req_id, HZ)) {
@@ -368,7 +366,8 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
 	} else {
 	} else {
 		ndev->req_id++;
 		ndev->req_id++;
 	}
 	}
-
+out:
+	kfree(mei_buf);
 	return err;
 	return err;
 }
 }
 
 

+ 20 - 1
drivers/thunderbolt/path.c

@@ -150,7 +150,26 @@ int tb_path_activate(struct tb_path *path)
 
 
 	/* Activate hops. */
 	/* Activate hops. */
 	for (i = path->path_length - 1; i >= 0; i--) {
 	for (i = path->path_length - 1; i >= 0; i--) {
-		struct tb_regs_hop hop;
+		struct tb_regs_hop hop = { 0 };
+
+		/*
+		 * We do (currently) not tear down paths setup by the firmeware.
+		 * If a firmware device is unplugged and plugged in again then
+		 * it can happen that we reuse some of the hops from the (now
+		 * defunct) firmeware path. This causes the hotplug operation to
+		 * fail (the pci device does not show up). Clearing the hop
+		 * before overwriting it fixes the problem.
+		 *
+		 * Should be removed once we discover and tear down firmeware
+		 * paths.
+		 */
+		res = tb_port_write(path->hops[i].in_port, &hop, TB_CFG_HOPS,
+				    2 * path->hops[i].in_hop_index, 2);
+		if (res) {
+			__tb_path_deactivate_hops(path, i);
+			__tb_path_deallocate_nfc(path, 0);
+			goto err;
+		}
 
 
 		/* dword 0 */
 		/* dword 0 */
 		hop.next_hop = path->hops[i].next_hop_index;
 		hop.next_hop = path->hops[i].next_hop_index;