Home | History | Annotate | Download | only in fastboot
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 #include <errno.h>
     33 
     34 #include <sys/time.h>
     35 
     36 #include "usb.h"
     37 
     38 static unsigned arg_size = 4096;
     39 static unsigned arg_count = 4096;
     40 
     41 long long NOW(void)
     42 {
     43     struct timeval tv;
     44     gettimeofday(&tv, 0);
     45 
     46     return (((long long) tv.tv_sec) * ((long long) 1000000)) +
     47         (((long long) tv.tv_usec));
     48 }
     49 
     50 int printifc(usb_ifc_info *info)
     51 {
     52     printf("dev: csp=%02x/%02x/%02x v=%04x p=%04x  ",
     53            info->dev_class, info->dev_subclass, info->dev_protocol,
     54            info->dev_vendor, info->dev_product);
     55     printf("ifc: csp=%02x/%02x/%02x%s%s\n",
     56            info->ifc_class, info->ifc_subclass, info->ifc_protocol,
     57            info->has_bulk_in ? " in" : "",
     58            info->has_bulk_out ? " out" : "");
     59     return -1;
     60 }
     61 
     62 int match_null(usb_ifc_info *info)
     63 {
     64     if(info->dev_vendor != 0x18d1) return -1;
     65     if(info->ifc_class != 0xff) return -1;
     66     if(info->ifc_subclass != 0xfe) return -1;
     67     if(info->ifc_protocol != 0x01) return -1;
     68     return 0;
     69 }
     70 
     71 int match_zero(usb_ifc_info *info)
     72 {
     73     if(info->dev_vendor != 0x18d1) return -1;
     74     if(info->ifc_class != 0xff) return -1;
     75     if(info->ifc_subclass != 0xfe) return -1;
     76     if(info->ifc_protocol != 0x02) return -1;
     77     return 0;
     78 }
     79 
     80 int match_loop(usb_ifc_info *info)
     81 {
     82     if(info->dev_vendor != 0x18d1) return -1;
     83     if(info->ifc_class != 0xff) return -1;
     84     if(info->ifc_subclass != 0xfe) return -1;
     85     if(info->ifc_protocol != 0x03) return -1;
     86     return 0;
     87 }
     88 
     89 int test_null(usb_handle *usb)
     90 {
     91     int i;
     92     unsigned char buf[4096];
     93     memset(buf, 0xee, 4096);
     94     long long t0, t1;
     95 
     96     t0 = NOW();
     97     for(i = 0; i < arg_count; i++) {
     98         if(usb_write(usb, buf, arg_size) != arg_size) {
     99             fprintf(stderr,"write failed (%s)\n", strerror(errno));
    100             return -1;
    101         }
    102     }
    103     t1 = NOW();
    104     fprintf(stderr,"%d bytes in %lld uS\n", arg_count * arg_size, (t1 - t0));
    105     return 0;
    106 }
    107 
    108 int test_zero(usb_handle *usb)
    109 {
    110     int i;
    111     unsigned char buf[4096];
    112     long long t0, t1;
    113 
    114     t0 = NOW();
    115     for(i = 0; i < arg_count; i++) {
    116         if(usb_read(usb, buf, arg_size) != arg_size) {
    117             fprintf(stderr,"read failed (%s)\n", strerror(errno));
    118             return -1;
    119         }
    120     }
    121     t1 = NOW();
    122     fprintf(stderr,"%d bytes in %lld uS\n", arg_count * arg_size, (t1 - t0));
    123     return 0;
    124 }
    125 
    126 struct
    127 {
    128     const char *cmd;
    129     ifc_match_func match;
    130     int (*test)(usb_handle *usb);
    131     const char *help;
    132 } tests[] = {
    133     { "list", printifc,   0,         "list interfaces" },
    134     { "send", match_null, test_null, "send to null interface" },
    135     { "recv", match_zero, test_zero, "recv from zero interface" },
    136     { "loop", match_loop, 0,         "exercise loopback interface" },
    137     {},
    138 };
    139 
    140 int usage(void)
    141 {
    142     int i;
    143 
    144     fprintf(stderr,"usage: usbtest <testname>\n\navailable tests:\n");
    145     for(i = 0; tests[i].cmd; i++) {
    146         fprintf(stderr," %-8s %s\n", tests[i].cmd, tests[i].help);
    147     }
    148     return -1;
    149 }
    150 
    151 int process_args(int argc, char **argv)
    152 {
    153     while(argc-- > 0) {
    154         char *arg = *argv++;
    155         if(!strncmp(arg,"count=",6)) {
    156             arg_count = atoi(arg + 6);
    157         } else if(!strncmp(arg,"size=",5)) {
    158             arg_size = atoi(arg + 5);
    159         } else {
    160             fprintf(stderr,"unknown argument: %s\n", arg);
    161             return -1;
    162         }
    163     }
    164 
    165     if(arg_count == 0) {
    166         fprintf(stderr,"count may not be zero\n");
    167         return -1;
    168     }
    169 
    170     if(arg_size > 4096) {
    171         fprintf(stderr,"size may not be greater than 4096\n");
    172         return -1;
    173     }
    174 
    175     return 0;
    176 }
    177 
    178 int main(int argc, char **argv)
    179 {
    180     usb_handle *usb;
    181     int i;
    182 
    183     if(argc < 2)
    184         return usage();
    185 
    186     if(argc > 2) {
    187         if(process_args(argc - 2, argv + 2))
    188             return -1;
    189     }
    190 
    191     for(i = 0; tests[i].cmd; i++) {
    192         if(!strcmp(argv[1], tests[i].cmd)) {
    193             usb = usb_open(tests[i].match);
    194             if(tests[i].test) {
    195                 if(usb == 0) {
    196                     fprintf(stderr,"usbtest: %s: could not find interface\n",
    197                             tests[i].cmd);
    198                     return -1;
    199                 }
    200                 if(tests[i].test(usb)) {
    201                     fprintf(stderr,"usbtest: %s: FAIL\n", tests[i].cmd);
    202                     return -1;
    203                 } else {
    204                     fprintf(stderr,"usbtest: %s: OKAY\n", tests[i].cmd);
    205                 }
    206             }
    207             return 0;
    208         }
    209     }
    210 
    211     return usage();
    212 }
    213