Browse Source

UTP download image to SD card + code cleanup

Add ability to download image to sd card using manufacturing tool.
Works 90% of the time but still occasionally fails. Example command
in XML would be "pipesd dev=0 skip=2" to download the file to mmc 0
device, starting at block 2.

Signed-off-by: Trace Russell <b45800@freescale.com>
Trace Russell 11 năm trước cách đây
mục cha
commit
46271147c9

+ 1 - 1
arch/arm/lib/board.c

@@ -558,7 +558,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
 	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
 #ifdef CONFIG_VF610
 	malloc_start = 0x3F000000;
-    mem_malloc_init (malloc_start, 256<<10);
+    mem_malloc_init (malloc_start, 400<<10);
 #else
 	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
 	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);

+ 5 - 134
drivers/usb/gadget/arcotg_udc.c

@@ -40,7 +40,6 @@ typedef int pm_message_t;
 #define __devinit
 #define pr_warning printf
 #define pr_debug(args...)
-//#define VDBG(str, args...) printf(str "\n", ## args)
 
 #define	DRIVER_DESC	"ARC USBOTG Device Controller driver"
 #define	DRIVER_AUTHOR	"Freescale Semiconductor"
@@ -959,7 +958,6 @@ out:
 static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
 		dma_addr_t *dma, int *is_last)
 {
-	//VDBG("top of build_dtd\n");
 	u32 swap_temp;
 	struct ep_td_struct *dtd;
 
@@ -1438,8 +1436,6 @@ static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 	struct fsl_usb2_platform_data *pdata;
 
 	udc = container_of(gadget, struct fsl_udc, gadget);
-	//if (udc->transceiver)
-		//return otg_set_power(udc->transceiver, mA);
 	pdata = udc->pdata;
 	if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_draw) {
 		pdata->xcvr_ops->set_vbus_draw(pdata->xcvr_ops, pdata, mA);
@@ -1654,7 +1650,6 @@ static void setup_received_irq(struct fsl_udc *udc,
 		return;
 	case USB_REQ_SET_CONFIGURATION:
 		spin_unlock(&udc->lock);
-		//fsl_vbus_draw(gadget, mA);
 		spin_lock(&udc->lock);
 	     break;
 	case USB_REQ_CLEAR_FEATURE:
@@ -1721,7 +1716,6 @@ static void setup_received_irq(struct fsl_udc *udc,
 			u32 tmp;
 
 			mdelay(10);
-			//fsl_platform_set_test_mode(udc->pdata, ptc);
 			tmp = fsl_readl(&dr_regs->portsc1) | (ptc << 16);
 			fsl_writel(tmp, &dr_regs->portsc1);
 			printk(KERN_INFO "udc: switch to test mode 0x%x.\n", ptc);
@@ -2399,11 +2393,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	/* lock is needed but whether should use this lock or another */
 	spin_lock_irqsave(&udc_controller->lock, flags);
 
-	//driver->driver.bus = 0;
 	udc_controller->pdata->port_enables = 1;
 	/* hook up the driver */
 	udc_controller->driver = driver;
-	//udc_controller->gadget.dev.driver = &driver->driver;
 	spin_unlock_irqrestore(&udc_controller->lock, flags);
 	dr_clk_gate(true);
 
@@ -2411,41 +2403,16 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	retval = driver->bind(&udc_controller->gadget);
 	if (retval) {
 		VDBG("bind udc driver to gadget driver --> %d", retval);
-		//udc_controller->gadget.dev.driver = 0;
 		udc_controller->driver = 0;
 		dr_clk_gate(false);
 		goto out;
 	}
-	if (0) {
-#if 0
-	if (udc_controller->transceiver) {
-		printk(KERN_INFO "Suspend udc for OTG auto detect\n");
-		udc_controller->suspended = 1;
-		dr_wake_up_enable(udc_controller, true);
+	/* Enable DR IRQ reg and Set usbcmd reg  Run bit */
+	dr_controller_run(udc_controller);
+	if (udc_controller->stopped)
 		dr_clk_gate(false);
-		/* export udc suspend/resume call to OTG */
-		udc_controller->gadget.dev.driver->suspend = (dev_sus)fsl_udc_suspend;
-		udc_controller->gadget.dev.driver->resume = (dev_res)fsl_udc_resume;
-
-		/* connect to bus through transceiver */
-		retval = otg_set_peripheral(udc_controller->transceiver,
-					    &udc_controller->gadget);
-		if (retval < 0) {
-			ERR("can't bind to transceiver\n");
-			driver->unbind(&udc_controller->gadget);
-			udc_controller->gadget.dev.driver = 0;
-			udc_controller->driver = 0;
-			return retval;
-		}
-#endif
-	} else {
-		/* Enable DR IRQ reg and Set usbcmd reg  Run bit */
-		dr_controller_run(udc_controller);
-		if (udc_controller->stopped)
-			dr_clk_gate(false);
-	}
 	printk(KERN_INFO "%s: bind to driver \n",
-			udc_controller->gadget.name);
+		udc_controller->gadget.name);
 
 out:
 	if (retval) {
@@ -2471,11 +2438,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 	if (udc_controller->stopped)
 		dr_clk_gate(true);
 
-#if 0
-	if (udc_controller->transceiver)
-		(void)otg_set_peripheral(udc_controller->transceiver, 0);
-#endif
-
 	/* stop DR, disable intr */
 	dr_controller_stop(udc_controller);
 
@@ -2498,7 +2460,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 	/* unbind gadget and unhook driver. */
 	driver->unbind(&udc_controller->gadget);
-	//udc_controller->gadget.dev.driver = 0;
 	udc_controller->driver = 0;
 
 	if (udc_controller->gadget.is_otg) {
@@ -2686,7 +2647,6 @@ int fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
 	}
 	udc_controller->gadget.is_otg = 1;
 #endif
-	//dr_regs = get_dr_regs();
 	dr_regs = (void *) OTG_BASE_ADDR;
 	if (!dr_regs) {
 		ret = -ENOMEM;
@@ -2700,14 +2660,7 @@ int fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
 	set_usb_phy1_clk();
 	enable_usboh3_clk(1);
 	enable_usb_phy1_clk(1);
-	//usb_phy_enable();
-#if 0
-	if (pdata->init && pdata->init(pdata)) {
-		pdata->lowpower = false;
-		ret = -ENODEV;
-		goto err2a;
-	}
-#endif
+
 	spin_lock_init(&pdata->lock);
 
 	/* Due to mx35/mx25's phy's bug */
@@ -2739,24 +2692,6 @@ int fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
 	 * leave usbintr reg untouched */
 	dr_controller_setup(udc_controller);
 
-
-#if 0
-	temp = 0;
-	/* Enable DR irq reg */
-	temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN
-        | USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN
-        | USB_INTR_DEVICE_SUSPEND | USB_INTR_SYS_ERR_EN
-	| USB_INTR_SOF_EN;
-
-	fsl_writel(temp, &dr_regs->usbintr);
-
-	/* Set controller to Run */
-	//temp = readl(USB_USBCMD);
-	//temp |= USB_CMD_RUN_STOP;
-	//writel(temp, USB_USBCMD);
-#endif
-
-
 	/* Setup gadget structure */
 	udc_controller->gadget.ops = &fsl_gadget_ops;
 	udc_controller->gadget.is_dualspeed = 1;
@@ -2765,12 +2700,6 @@ int fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
 	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
 	udc_controller->gadget.name = driver_name;
 
-	/* Setup gadget.dev and register with kernel */
-	//dev_set_name(&udc_controller->gadget.dev, "gadget");
-	//udc_controller->gadget.dev.release = fsl_udc_release;
-	//udc_controller->gadget.dev.parent = NULL;
-	//udc_controller->gadget.dev.groups = fsl_udc_attr_groups;
-
 	/* setup QH and epctrl for ep0 */
 	ep0_setup(udc_controller);
 
@@ -2829,20 +2758,6 @@ int fsl_udc_probe(struct fsl_usb2_platform_data *pdata)
 	/* let the gadget register function open the clk */
 	dr_clk_gate(false);
 
-	/* create usb charger */
-#ifdef CONFIG_IMX_USB_CHARGER
-	udc_controller->charger.dev = &pdev->dev;
-	udc_controller->charger.dp_pullup = usb_charger_pullup_dp;
-	udc_controller->charger.enable = true;
-	if (pdata->charger_base_addr)
-		udc_controller->charger.charger_base_addr = pdata->charger_base_addr;
-	if (imx_usb_create_charger(&udc_controller->charger, "imx_usb_charger"))
-		dev_err(&pdev->dev, "Can't create usb charger\n");
-#else
-	//udc_controller->charger.dp_pullup = usb_charger_pullup_dp;
-	//udc_controller->charger.enable = false;
-#endif
-
 	return 0;
 
 err3:
@@ -2866,7 +2781,6 @@ static int  fsl_udc_remove(struct fsl_usb2_platform_data *pdata)
 
 	if (!udc_controller)
 		return -ENODEV;
-	//udc_controller->done = &done;
 	/* open USB PHY clock */
 	dr_clk_gate(true);
 
@@ -2902,20 +2816,6 @@ static int  fsl_udc_remove(struct fsl_usb2_platform_data *pdata)
 
 static bool udc_can_wakeup_system(void)
 {
-#if 0
-	struct fsl_usb2_platform_data *pdata = udc_controller->pdata;
-
-	if (pdata->operating_mode == FSL_USB2_DR_OTG)
-		if (device_may_wakeup(udc_controller->transceiver->dev))
-			return true;
-		else
-			return false;
-	else
-		if (device_may_wakeup(udc_controller->gadget.dev.parent))
-			return true;
-		else
-			return false;
-#endif
 	return false;
 }
 
@@ -3114,35 +3014,6 @@ end:
 	return 0;
 }
 
-/*-------------------------------------------------------------------------
-	Register entry point for the peripheral controller driver
---------------------------------------------------------------------------*/
-
-#if 0
-static struct platform_driver udc_driver = {
-	.remove  = fsl_udc_remove,
-	/* these suspend and resume are not usb suspend and resume */
-	.suspend = fsl_udc_suspend,
-	.resume  = fsl_udc_resume,
-	.probe = fsl_udc_probe,
-	.driver  = {
-		.name = driver_name,
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init udc_init(void)
-{
-	printk(KERN_INFO "%s (%s)\n", driver_desc, DRIVER_VERSION);
-	return platform_driver_register(&udc_driver);
-}
-static void __exit udc_exit(void)
-{
-	platform_driver_unregister(&udc_driver);
-	printk(KERN_INFO "%s unregistered \n", driver_desc);
-}
-#endif
-
 int usb_gadget_handle_interrupts(void)
 {
 	return fsl_udc_irq(0, udc_controller);

+ 80 - 30
drivers/usb/gadget/fsl_updater.c

@@ -24,6 +24,26 @@
 #define UTP_FLAG_REPORT_BUSY	0x10000000
 
 struct fsg_common;
+enum utp_media_type {
+	NOMEDIA = 0,
+	SD,
+	NAND,
+	NOR,
+	SPI,
+	QSPI,
+};
+
+struct utp_pipe_info {
+	enum utp_media_type media_type;
+	int media_id;
+	unsigned long int index;
+	size_t blksz;
+} pinfo = {
+	.media_type = NOMEDIA,
+	.media_id = 0,
+	.index = 0,
+	.blksz = 0,
+};
 
 static u64 get_be64(u8 *buf)
 {
@@ -49,13 +69,15 @@ static void utp_exit(struct fsg_dev *fsg)
 	vfree(utp_context.buffer);
 }
 
-static struct utp_user_data *utp_user_data_alloc(size_t size)
+static struct utp_user_data *utp_user_data_alloc(size_t blksz, size_t size)
 {
 	struct utp_user_data *uud;
+	size_t malloc_size = size + sizeof(*uud) + blksz;
 
-	uud = kzalloc(size + sizeof(*uud), GFP_KERNEL);
+	uud = malloc(malloc_size);
 	if (!uud)
 		return uud;
+	memset(uud, 0, malloc_size);
 	uud->data.size = size + sizeof(uud->data);
 	return uud;
 }
@@ -65,10 +87,6 @@ static void utp_user_data_free(struct utp_user_data *uud)
 	kfree(uud);
 }
 
-/* The routine will not go on if utp_context.queue is empty */
-#define WAIT_ACTIVITY(queue) \
- wait_event_interruptible(utp_context.wq, !list_empty(&utp_context.queue))
-
 /* Will be called when the host wants to get the sense data */
 static int utp_get_sense(struct fsg_common *common)
 {
@@ -265,23 +283,6 @@ static void utp_poll(struct fsg_common *common)
 {
 	UTP_SS_PASS(common);
 	return;
-	struct utp_context *ctx = UTP_CTX(common->fsg);
-	struct utp_user_data *uud = NULL;
-
-	if (uud) {
-		if (uud->data.flags & UTP_FLAG_STATUS) {
-			printk(KERN_WARNING "%s: exit with status %d\n",
-					__func__, uud->data.status);
-			UTP_SS_EXIT(common, uud->data.status);
-		} else {
-			pr_debug("%s: pass\n", __func__);
-			UTP_SS_PASS(common);
-		}
-		utp_user_data_free(uud);
-	} else {
-		pr_debug("%s: still busy...\n", __func__);
-		UTP_SS_BUSY(common, --ctx->counter);
-	}
 }
 
 static int utp_exec(struct fsg_common *common,
@@ -293,12 +294,13 @@ static int utp_exec(struct fsg_common *common,
 	struct utp_user_data *uud = NULL, *uud2r;
 	struct utp_context *ctx = UTP_CTX(fsg);
 
-	uud2r = utp_user_data_alloc(cmdsize + 1);
+	uud2r = utp_user_data_alloc(0, cmdsize + 1);
 	uud2r->data.flags = UTP_FLAG_COMMAND;
 	uud2r->data.payload = payload;
 	strncpy(uud2r->data.command, command, cmdsize);
 
-	uud = utp_interpret_message(uud2r); /* TODO */
+	uud = utp_interpret_message(uud2r);
+	utp_user_data_free(uud2r);
 
 	if (command[0] == '!')	/* there will be no response */
 		return 0;
@@ -416,12 +418,17 @@ static int utp_handle_message(struct fsg_common *common,
 		break;
 	case UTP_PUT: /* data from host to device */
 		pr_debug("%s: PUT, %d bytes\n", __func__, common->data_size);
-		uud2r = utp_user_data_alloc(common->data_size);
+		uud2r = utp_user_data_alloc(pinfo.blksz, common->data_size);
+		if (!uud2r) {
+			printf("utp alloc fail\n");
+			return -ENOMEM;
+		}
 		uud2r->data.bufsize = common->data_size;
 		uud2r->data.flags = UTP_FLAG_DATA;
 		utp_do_write(common, uud2r->data.data, common->data_size);
 		/* don't know what will be written */
-		uud = utp_interpret_message(uud2r); /* TODO */
+		utp_interpret_message(uud2r);
+		free(uud2r);
 		/*
 		 * Return PASS or FAIL according to uuc's status
 		 * Please open it if need to check uuc's status
@@ -453,7 +460,8 @@ static int utp_handle_message(struct fsg_common *common,
 			UTP_SS_PASS(fsg);
 		}
 #endif
-		UTP_SS_PASS(common);
+		/* workaround, normally would SS_PASS */
+		UTP_SS_BUSY(common, UTP_CTX(fsg)->counter);
 		break;
 	}
 
@@ -471,6 +479,10 @@ struct utp_user_data *utp_handle_command(char *cmd, u64 payload)
 	u32			flags, status;
 	size_t			size;
 	struct utp_user_data	*answer;
+	unsigned long int	dev;
+	unsigned long int	skip;
+	char			argbuf[20];
+	char			*tmp;
 
 	/* defaults */
 	status = 0;
@@ -481,14 +493,49 @@ struct utp_user_data *utp_handle_command(char *cmd, u64 payload)
 		status = utp_run(cmd + 2);
 		if (status)
 			flags = UTP_FLAG_STATUS;
+	} else if (strncmp(cmd, "pipesd", 6) == 0) {
+		pinfo.media_type = SD;
+		pinfo.index = 0;
+		pinfo.blksz = 512; /* TODO: find sd card block size */
+
+		cmd += 7;
+		tmp = strsep(&cmd, " ");
+		printf(tmp);
+		dev = simple_strtoul(tmp+4, NULL, 10);
+		printf("dev: %lu\n", dev);
+		pinfo.media_id = dev;
+		sprintf(argbuf, "mmc dev %lu", dev);
+
+		tmp = strsep(&cmd, " ");
+		printf(tmp);
+		skip = simple_strtoul(tmp+5, NULL, 10);
+		pinfo.index += skip;
+		utp_run(argbuf);
 	}
 
-	answer = utp_user_data_alloc(size);
+	answer = utp_user_data_alloc(0, size);
 	if (flags & UTP_FLAG_STATUS)
 		answer->data.status = status;
 	return answer;
 }
 
+int utp_pipe_sd(u8 *data, size_t bufsize)
+{
+	pr_debug("got data chunk, size: %zx\n", bufsize);
+	unsigned int blkcnt;
+	char argbuf[100];
+
+	blkcnt = bufsize / pinfo.blksz;
+	pr_debug("blkcnt: %x, index: %lx, bufsize: %zx\n", blkcnt, pinfo.index, bufsize);
+
+	sprintf(argbuf, "mmc write %x %lx %x", data, pinfo.index, blkcnt);
+	utp_run(argbuf);
+	pr_debug("after write to sd\n");
+	pinfo.index += blkcnt;
+
+	return 0;
+}
+
 struct utp_user_data *utp_interpret_message(struct utp_user_data *uud2r)
 {
 	struct utp_user_data *answer;
@@ -499,7 +546,10 @@ struct utp_user_data *utp_interpret_message(struct utp_user_data *uud2r)
 		if (answer)
 			return answer;
 	} else if (msg->flags & UTP_FLAG_DATA) {
-		/* TODO */
+		switch(pinfo.media_type) {
+		case SD:
+			utp_pipe_sd(msg->data, msg->bufsize);
+		}
 	}
 	return NULL;
 }

+ 1 - 1
drivers/usb/gadget/fsl_updater.h

@@ -26,7 +26,7 @@
 static int utp_init(struct fsg_dev *fsg);
 static void utp_exit(struct fsg_dev *fsg);
 
-static struct utp_user_data *utp_user_data_alloc(size_t size);
+static struct utp_user_data *utp_user_data_alloc(size_t align, size_t size);
 static void utp_user_data_free(struct utp_user_data *uud);
 static int utp_get_sense(struct fsg_common *common);
 static int utp_do_read(struct fsg_common *common, void *data, size_t size);