s5p: usbd: control the usb disconnecting
authorMinkyu Kang <mk7.kang@samsung.com>
Mon, 20 Dec 2010 07:48:42 +0000 (16:48 +0900)
committerMinkyu Kang <mk7.kang@samsung.com>
Mon, 20 Dec 2010 07:48:42 +0000 (16:48 +0900)
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
arch/arm/cpu/armv7/s5p-common/usb-hs-otg-dma.c
arch/arm/cpu/armv7/s5p-common/usb-hs-otg.c
arch/arm/cpu/armv7/s5p-common/usb_downloader.c
common/cmd_usbd.c
include/usbd.h

index ec3c5fb..34efb43 100644 (file)
@@ -1247,6 +1247,8 @@ static void s5p_usb_reset(void)
        /*clear device address */
        s5p_otg_write_reg(s5p_otg_read_reg(OTG_DCFG) & ~(0x7f << 4),
                        OTG_DCFG);
+
+       s5p_usb_connected = 0;
 }
 
 static int s5p_usb_set_init(void)
@@ -1259,8 +1261,7 @@ static int s5p_usb_set_init(void)
        if (((status & 0x6) >> 1) == USB_HIGH) {
                s5p_usb_set_max_pktsize(USB_HIGH);
        } else if (((status & 0x6) >> 1) == USB_FULL) {
-               puts("Error: Don't support Full_Speed\n");
-               return 0;
+               s5p_usb_set_max_pktsize(USB_FULL);
        } else {
                puts("Error: Neither High_Speed nor Full_Speed\n");
                return 0;
@@ -1350,14 +1351,14 @@ void s5p_udc_int_hndlr(void)
        s5p_otg_write_reg(int_status, OTG_GINTSTS);
 
        if (int_status & INT_RESET) {
+               debug("INT RESET\n");
                s5p_otg_write_reg(INT_RESET, OTG_GINTSTS);
                s5p_usb_reset();
-               debug("INT RESET\n");
        }
 
        if (int_status & INT_ENUMDONE) {
-               s5p_otg_write_reg(INT_ENUMDONE, OTG_GINTSTS);
                debug("INT ENUMDONE\n");
+               s5p_otg_write_reg(INT_ENUMDONE, OTG_GINTSTS);
 
                tmp = s5p_usb_set_init();
                if (tmp == 0)
index 0cceb29..1f0ddd9 100644 (file)
@@ -1413,6 +1413,8 @@ static void s5p_usb_reset(void)
        /*clear device address */
        s5p_otg_write_reg(s5p_otg_read_reg(OTG_DCFG) & ~(0x7f << 4),
                        OTG_DCFG);
+
+       s5p_usb_connected = 0;
 }
 
 static int s5p_usb_set_init(void)
@@ -1425,8 +1427,7 @@ static int s5p_usb_set_init(void)
        if (((status & 0x6) >> 1) == USB_HIGH) {
                s5p_usb_set_max_pktsize(USB_HIGH);
        } else if (((status & 0x6) >> 1) == USB_FULL) {
-               puts("Error: Don't support Full_Speed\n");
-               return 0;
+               s5p_usb_set_max_pktsize(USB_FULL);
        } else {
                puts("Error: Neither High_Speed nor Full_Speed\n");
                return 0;
index 428e9a1..4105d8a 100644 (file)
@@ -200,17 +200,20 @@ static void down_start(void)
 #endif
 }
 
-static void down_cancel(void)
+static void down_cancel(int mode)
 {
 #ifdef CONFIG_S5PC1XXFB
        if (!s5p_no_lcd_support()) {
                exit_font();
 
                /* clear fb */
-               fb_clear(100);
+               fb_clear(120);
        }
 #endif
-       run_command("run ubifsboot", 0);
+       if (mode)
+               run_command("usbdown", 0);
+       else
+               run_command("run ubifsboot", 0);
 }
 
 /*
@@ -226,6 +229,11 @@ static int usb_receive_packet(void)
                        s5p_usb_clear_irq();
                }
 
+               if (!s5p_usb_connected) {
+                       puts("Disconnected!!\n");
+                       return 0;
+               }
+
                if (s5p_receive_done) {
                        s5p_receive_done = 0;
                        return otg.dn_filesize;
index ccafe8a..3a22ed2 100644 (file)
@@ -1110,7 +1110,10 @@ static int process_data(struct usbd_ops *usbd)
 
                /* Receive image by using dma */
                recvlen = usbd->recv_data();
-               if (recvlen < len) {
+               if (recvlen == 0) {
+                       send_ack(usbd, STATUS_ERROR);
+                       return 0;
+               } else if (recvlen < len) {
                        printf("Error: wrong image size -> %d/%d\n",
                                        (int)recvlen, (int)len);
 
@@ -1445,7 +1448,7 @@ int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        /* init the usb controller */
        if (!usbd->usb_init()) {
-               usbd->down_cancel();
+               usbd->down_cancel(0);
                return 0;
        }
        mmc = find_mmc_device(usbd->mmc_dev);
@@ -1467,7 +1470,7 @@ int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        return 0;
                }
        } else {
-               usbd->down_cancel();
+               usbd->down_cancel(1);
                return 0;
        }
 
@@ -1479,8 +1482,13 @@ int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                usbd->recv_setup(usbd->rx_data, usbd->rx_len);
 
                if (usbd->recv_data()) {
-                       if (process_data(usbd) == 0)
+                       if (process_data(usbd) == 0) {
+                               usbd->down_cancel(1);
                                return 0;
+                       }
+               } else {
+                       usbd->down_cancel(1);
+                       return 0;
                }
        }
 
index ff77c01..7db07f8 100644 (file)
@@ -136,7 +136,7 @@ struct usbd_ops {
        void (*set_progress)(int);
        void (*cpu_reset)(void);
        void (*down_start)(void);
-       void (*down_cancel)(void);
+       void (*down_cancel)(int);
 };
 
 /* This function is interfaced between USB Device Controller and USB Downloader