소스 검색

usb: fix TRB_TRANSFER return null pointer issue

xhci_wait_for_event() wait TRB_TRANSFER may return null
pointer, shoud checkit avoid crash.
Read usb device info maybe failed, should check it and
do not register usb device. uboot should rescan usb
device and register.

Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Minda Chen 7 달 전
부모
커밋
de86bf5edc
2개의 변경된 파일20개의 추가작업 그리고 6개의 파일을 삭제
  1. 18 6
      common/usb.c
  2. 2 0
      drivers/usb/host/xhci-ring.c

+ 18 - 6
common/usb.c

@@ -1144,20 +1144,32 @@ int usb_select_config(struct usb_device *dev)
 	memset(dev->mf, 0, sizeof(dev->mf));
 	memset(dev->prod, 0, sizeof(dev->prod));
 	memset(dev->serial, 0, sizeof(dev->serial));
-	if (dev->descriptor.iManufacturer)
-		usb_string(dev, dev->descriptor.iManufacturer,
+	if (dev->descriptor.iManufacturer) {
+		err = usb_string(dev, dev->descriptor.iManufacturer,
 			   dev->mf, sizeof(dev->mf));
-	if (dev->descriptor.iProduct)
-		usb_string(dev, dev->descriptor.iProduct,
+		if (err < 0)
+			goto decriptor_err;
+	} if (dev->descriptor.iProduct) {
+		err = usb_string(dev, dev->descriptor.iProduct,
 			   dev->prod, sizeof(dev->prod));
-	if (dev->descriptor.iSerialNumber)
-		usb_string(dev, dev->descriptor.iSerialNumber,
+		if (err < 0)
+			goto decriptor_err;
+	}
+	if (dev->descriptor.iSerialNumber) {
+		err = usb_string(dev, dev->descriptor.iSerialNumber,
 			   dev->serial, sizeof(dev->serial));
+		if (err < 0)
+			goto decriptor_err;
+	}
 	debug("Manufacturer %s\n", dev->mf);
 	debug("Product      %s\n", dev->prod);
 	debug("SerialNumber %s\n", dev->serial);
 
 	return 0;
+
+decriptor_err:
+	printf("failed to get usb device info %d\n", err);
+	return err;
 }
 
 int usb_setup_device(struct usb_device *dev, bool do_read,

+ 2 - 0
drivers/usb/host/xhci-ring.c

@@ -499,6 +499,8 @@ static void abort_td(struct usb_device *udev, int ep_index)
 	xhci_queue_command(ctrl, NULL, udev->slot_id, ep_index, TRB_STOP_RING);
 
 	event = xhci_wait_for_event(ctrl, TRB_TRANSFER);
+	if (!event)
+		return;
 	field = le32_to_cpu(event->trans_event.flags);
 	BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id);
 	BUG_ON(TRB_TO_EP_INDEX(field) != ep_index);