[PATCH 14/133] [Jaunty SRU] ARM.imx51 Freescale:ENGR00107483 Revert [MX37] failed to test our MSC driver with USBCV 1.3."

Brad Figg brad.figg at canonical.com
Thu Jul 9 16:48:04 UTC 2009


From: Lily Zhang <r58066 at freescale.com>

This reverts commit 648bc6939d98667791010759987fe26f5c479e59.

Signed-off-by: Lily Zhang <r58066 at freescale.com>
Signed-off-by: Brad Figg <brad.figg at canonical.com>
---
 drivers/usb/gadget/arcotg_udc.c   |   99 +++++++++++++++++++++++++++---------
 drivers/usb/gadget/arcotg_udc.h   |    2 +-
 drivers/usb/gadget/file_storage.c |    2 +
 3 files changed, 77 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index bb8f761..2a5d78f 100644
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -908,8 +908,8 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 	int is_iso = 0;
 
 	/* catch various bogus parameters */
-	if (!_req || !req->req.buf || (ep_index(ep)
-				      && !list_empty(&req->queue))) {
+	if (!_req || !req->req.complete || !req->req.buf
+			|| !list_empty(&req->queue)) {
 		VDBG("%s, bad params\n", __func__);
 		return -EINVAL;
 	}
@@ -964,6 +964,10 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 		return -ENOMEM;
 	}
 
+	/* Update ep0 state */
+	if ((ep_index(ep) == 0))
+		udc->ep0_state = DATA_STATE_XMIT;
+
 	/* irq handler advances the queue */
 	if (req != NULL)
 		list_add_tail(&req->queue, &ep->queue);
@@ -1093,6 +1097,7 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value)
 	spin_unlock_irqrestore(&ep->udc->lock, flags);
 
 	if (ep_index(ep) == 0) {
+		udc->ep0_state = WAIT_FOR_SETUP;
 		udc->ep0_dir = 0;
 	}
 out:
@@ -1304,6 +1309,7 @@ static void ep0stall(struct fsl_udc *udc)
 	tmp = fsl_readl(&dr_regs->endptctrl[0]);
 	tmp |= EPCTRL_TX_EP_STALL | EPCTRL_RX_EP_STALL;
 	fsl_writel(tmp, &dr_regs->endptctrl[0]);
+	udc->ep0_state = WAIT_FOR_SETUP;
 	udc->ep0_dir = 0;
 }
 
@@ -1318,10 +1324,26 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
 		udc->ep0_dir = USB_DIR_IN;
 	else
 		udc->ep0_dir = USB_DIR_OUT;
+
 	ep = &udc->eps[0];
+	udc->ep0_state = WAIT_FOR_OUT_STATUS;
+
 	req->ep = ep;
 	req->req.length = 0;
-	status = fsl_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+	req->req.complete = NULL;
+	req->dtd_count = 0;
+
+	if (fsl_req_to_dtd(req) == 0)
+		status = fsl_queue_td(ep, req);
+	else
+		return -ENOMEM;
+
+	if (status)
+		ERR("Can't queue ep0 status request \n");
+	list_add_tail(&req->queue, &ep->queue);
+
 	return status;
 }
 
@@ -1387,20 +1409,29 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 	}
 
 	udc->ep0_dir = USB_DIR_IN;
-	/* Borrow the per device data_req */
-	/* status_req had been used to prime status */
-	req = udc->data_req;
+	/* Borrow the per device status_req */
+	req = udc->status_req;
 	/* Fill in the reqest structure */
 	*((u16 *) req->req.buf) = cpu_to_le16(tmp);
 	req->ep = ep;
 	req->req.length = 2;
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+	req->req.complete = NULL;
+	req->dtd_count = 0;
+
+	/* prime the data phase */
+	if ((fsl_req_to_dtd(req) == 0))
+		status = fsl_queue_td(ep, req);
+	else			/* no mem */
+		goto stall;
 
-	status = fsl_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
 	if (status) {
-		udc_reset_ep_queue(udc, 0);
 		ERR("Can't respond to getstatus request \n");
 		goto stall;
 	}
+	list_add_tail(&req->queue, &ep->queue);
+	udc->ep0_state = DATA_STATE_XMIT;
 	return;
 stall:
 	ep0stall(udc);
@@ -1414,10 +1445,7 @@ static void setup_received_irq(struct fsl_udc *udc,
 	u16 wLength = le16_to_cpu(setup->wLength);
 
 	udc_reset_ep_queue(udc, 0);
-	if (setup->bRequestType & USB_DIR_IN) {
-		if (ep0_prime_status(udc, EP_DIR_OUT))
-			ep0stall(udc);
-	}
+
 	/* We process some stardard setup requests here */
 	switch (setup->bRequest) {
 	case USB_REQ_GET_STATUS:
@@ -1508,11 +1536,11 @@ static void setup_received_irq(struct fsl_udc *udc,
 				?  USB_DIR_IN : USB_DIR_OUT;
 		spin_unlock(&udc->lock);
 		if (udc->driver->setup(&udc->gadget,
-				&udc->local_setup_buff) < 0) {
-			/* cancel status phase */
-			udc_reset_ep_queue(udc, 0);
+				&udc->local_setup_buff) < 0)
 			ep0stall(udc);
-		}
+		spin_lock(&udc->lock);
+		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
+				?  DATA_STATE_XMIT : DATA_STATE_RECV;
 	} else {
 		/* No data phase, IN status from gadget */
 		udc->ep0_dir = USB_DIR_IN;
@@ -1520,8 +1548,9 @@ static void setup_received_irq(struct fsl_udc *udc,
 		if (udc->driver->setup(&udc->gadget,
 				&udc->local_setup_buff) < 0)
 			ep0stall(udc);
+		spin_lock(&udc->lock);
+		udc->ep0_state = WAIT_FOR_OUT_STATUS;
 	}
-	spin_lock(&udc->lock);
 }
 
 /* Process request for Data or Status phase of ep0
@@ -1535,7 +1564,30 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
 		fsl_writel(new_address << USB_DEVICE_ADDRESS_BIT_POS,
 				&dr_regs->deviceaddr);
 	}
+
 	done(ep0, req, 0);
+
+	switch (udc->ep0_state) {
+	case DATA_STATE_XMIT:
+		/* receive status phase */
+		if (ep0_prime_status(udc, EP_DIR_OUT))
+			ep0stall(udc);
+		break;
+	case DATA_STATE_RECV:
+		/* send status phase */
+		if (ep0_prime_status(udc, EP_DIR_IN))
+			ep0stall(udc);
+		break;
+	case WAIT_FOR_OUT_STATUS:
+		udc->ep0_state = WAIT_FOR_SETUP;
+		break;
+	case WAIT_FOR_SETUP:
+		ERR("Unexpect ep0 packets \n");
+		break;
+	default:
+		ep0stall(udc);
+		break;
+	}
 }
 
 /* Tripwire mechanism to ensure a setup packet payload is extracted without
@@ -1873,6 +1925,7 @@ static void reset_irq(struct fsl_udc *udc)
 	/* Clear usb state */
 	udc->resume_state = 0;
 	udc->ep0_dir = 0;
+	udc->ep0_state = WAIT_FOR_SETUP;
 	udc->remote_wakeup = 0;	/* default to 0 on reset */
 	udc->gadget.b_hnp_enable = 0;
 	udc->gadget.a_hnp_support = 0;
@@ -2053,6 +2106,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 		/* Enable DR IRQ reg and Set usbcmd reg  Run bit */
 		dr_controller_run(udc_controller);
 		udc_controller->usb_state = USB_STATE_ATTACHED;
+		udc_controller->ep0_state = WAIT_FOR_SETUP;
 		udc_controller->ep0_dir = 0;
 	}
 	printk(KERN_INFO "%s: bind to driver %s \n",
@@ -2085,6 +2139,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 	/* in fact, no needed */
 	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
 	udc_controller->ep0_dir = 0;
 
 	/* stand operation */
@@ -2434,14 +2489,9 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
 	/* FIXME: fsl_alloc_request() ignores ep argument */
 	udc->status_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL),
 			struct fsl_req, req);
-	/* for future use */
+	/* allocate a small amount of memory to get valid address */
 	udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
 	udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf);
-	/* Initialize ep0 data request structure */
-	udc->data_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL),
-			struct fsl_req, req);
-	udc->data_req->req.buf = kmalloc(8, GFP_KERNEL);
-	udc->data_req->req.dma = virt_to_phys(udc->data_req->req.buf);
 
 	udc->resume_state = USB_STATE_NOTATTACHED;
 	udc->usb_state = USB_STATE_POWERED;
@@ -2699,8 +2749,6 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
 	/* Free allocated memory */
 	kfree(udc_controller->status_req->req.buf);
 	kfree(udc_controller->status_req);
-	kfree(udc_controller->data_req->req.buf);
-	kfree(udc_controller->data_req);
 	kfree(udc_controller->eps);
 
 	dma_pool_destroy(udc_controller->td_pool);
@@ -2795,6 +2843,7 @@ static int fsl_udc_resume(struct platform_device *pdev)
 		dr_controller_run(udc_controller);
 	}
 	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
 	udc_controller->ep0_dir = 0;
 
 	printk(KERN_INFO "USB Gadget resumed\n");
diff --git a/drivers/usb/gadget/arcotg_udc.h b/drivers/usb/gadget/arcotg_udc.h
index aa5e6e7..aa57bd8 100644
--- a/drivers/usb/gadget/arcotg_udc.h
+++ b/drivers/usb/gadget/arcotg_udc.h
@@ -560,7 +560,6 @@ struct fsl_udc {
 
 	struct ep_queue_head *ep_qh;	/* Endpoints Queue-Head */
 	struct fsl_req *status_req;	/* ep0 status request */
-	struct fsl_req *data_req;	/* ep0 data request */
 	struct dma_pool *td_pool;	/* dma pool for DTD */
 	enum fsl_usb2_phy_modes phy_mode;
 
@@ -573,6 +572,7 @@ struct fsl_udc {
 	u32 resume_state;	/* USB state to resume */
 	u32 usb_state;		/* USB current state */
 	u32 usb_next_state;	/* USB next state */
+	u32 ep0_state;		/* Endpoint zero state */
 	u32 ep0_dir;		/* Endpoint zero direction: can be
 				   USB_DIR_IN or USB_DIR_OUT */
 	u32 usb_sof_count;	/* SOF count */
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c4e62a6..d77ad4a 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -712,6 +712,8 @@ static void set_bulk_out_req_length(struct fsg_dev *fsg,
 	if (rem > 0)
 		length += fsg->bulk_out_maxpacket - rem;
 	bh->outreq->length = length;
+	if (bh->bulk_out_intended_length == 31)
+		bh->outreq->length = 31;
 }
 
 static struct fsg_dev			*the_fsg;
-- 
1.6.0.4





More information about the kernel-team mailing list