Commit e887afc9da0fec9b7bbdf6b13b920ed30006edfc

Authored by wdenk
1 parent 3863585bb1

Initial revision

Showing 3 changed files with 1372 additions and 0 deletions Side-by-side Diff

common/cmd_reginfo.c
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Subodh Nijsure, SkyStream Networks, snijsure@skystream.com
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +#include <common.h>
  25 +#include <command.h>
  26 +#include <cmd_boot.h>
  27 +#if defined(CONFIG_8xx)
  28 +#include <mpc8xx.h>
  29 +#elif defined (CONFIG_405GP)
  30 +#include <asm/processor.h>
  31 +#endif
  32 +#if (CONFIG_COMMANDS & CFG_CMD_REGINFO)
  33 +
  34 +int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  35 +{
  36 +#if defined(CONFIG_8xx)
  37 + volatile immap_t *immap = (immap_t *)CFG_IMMR;
  38 + volatile memctl8xx_t *memctl = &immap->im_memctl;
  39 + volatile sysconf8xx_t *sysconf = &immap->im_siu_conf;
  40 + volatile sit8xx_t *timers = &immap->im_sit;
  41 +
  42 + /* Hopefully more PowerPC knowledgable people will add code to display
  43 + * other useful registers
  44 + */
  45 +
  46 + printf("\nSystem Configuration registers\n");
  47 +
  48 + printf("\tIMMR\t0x%08X\n", get_immr(0));
  49 +
  50 + printf("\tSIUMCR\t0x%08X", sysconf->sc_siumcr);
  51 + printf("\tSYPCR\t0x%08X\n",sysconf->sc_sypcr);
  52 +
  53 + printf("\tSWT\t0x%08X", sysconf->sc_swt);
  54 + printf("\tSWSR\t0x%04X\n", sysconf->sc_swsr);
  55 +
  56 + printf("\tSIPEND\t0x%08X\tSIMASK\t0x%08X\n",
  57 + sysconf->sc_sipend, sysconf->sc_simask);
  58 + printf("\tSIEL\t0x%08X\tSIVEC\t0x%08X\n",
  59 + sysconf->sc_siel, sysconf->sc_sivec);
  60 + printf("\tTESR\t0x%08X\tSDCR\t0x%08X\n",
  61 + sysconf->sc_tesr, sysconf->sc_sdcr);
  62 +
  63 + printf("Memory Controller Registers\n");
  64 +
  65 + printf("\tBR0\t0x%08X\tOR0\t0x%08X \n", memctl->memc_br0, memctl->memc_or0);
  66 + printf("\tBR1\t0x%08X\tOR1\t0x%08X \n", memctl->memc_br1, memctl->memc_or1);
  67 + printf("\tBR2\t0x%08X\tOR2\t0x%08X \n", memctl->memc_br2, memctl->memc_or2);
  68 + printf("\tBR3\t0x%08X\tOR3\t0x%08X \n", memctl->memc_br3, memctl->memc_or3);
  69 + printf("\tBR4\t0x%08X\tOR4\t0x%08X \n", memctl->memc_br4, memctl->memc_or4);
  70 + printf("\tBR5\t0x%08X\tOR5\t0x%08X \n", memctl->memc_br5, memctl->memc_or5);
  71 + printf("\tBR6\t0x%08X\tOR6\t0x%08X \n", memctl->memc_br6, memctl->memc_or6);
  72 + printf("\tBR7\t0x%08X\tOR7\t0x%08X \n", memctl->memc_br7, memctl->memc_or7);
  73 + printf("\n");
  74 +
  75 + printf("\tmamr\t0x%08X\tmbmr\t0x%08X \n",
  76 + memctl->memc_mamr, memctl->memc_mbmr );
  77 + printf("\tmstat\t0x%08X\tmptpr\t0x%08X \n",
  78 + memctl->memc_mstat, memctl->memc_mptpr );
  79 + printf("\tmdr\t0x%08X \n", memctl->memc_mdr);
  80 +
  81 + printf("\nSystem Integration Timers\n");
  82 + printf("\tTBSCR\t0x%08X\tRTCSC\t0x%08X \n",
  83 + timers->sit_tbscr, timers->sit_rtcsc);
  84 + printf("\tPISCR\t0x%08X \n", timers->sit_piscr);
  85 +
  86 + /*
  87 + * May be some CPM info here?
  88 + */
  89 +
  90 +/* DBU[dave@cray.com] For the CRAY-L1, but should be generically 405gp */
  91 +#elif defined (CONFIG_405GP)
  92 + printf("\n405GP registers; MSR=%x\n",mfmsr());
  93 + printf ("\nUniversal Interrupt Controller Regs\n"
  94 +"uicsr uicsrs uicer uiccr uicpr uictr uicmsr uicvr uicvcr"
  95 +"\n"
  96 +"%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
  97 + mfdcr(uicsr),
  98 + mfdcr(uicsrs),
  99 + mfdcr(uicer),
  100 + mfdcr(uiccr),
  101 + mfdcr(uicpr),
  102 + mfdcr(uictr),
  103 + mfdcr(uicmsr),
  104 + mfdcr(uicvr),
  105 + mfdcr(uicvcr));
  106 +
  107 + printf ("\nMemory (SDRAM) Configuration\n"
  108 +"besra besrsa besrb besrsb bear mcopt1 rtr pmit\n");
  109 +
  110 + mtdcr(memcfga,mem_besra); printf ("%08x ", mfdcr(memcfgd));
  111 + mtdcr(memcfga,mem_besrsa); printf ("%08x ", mfdcr(memcfgd));
  112 + mtdcr(memcfga,mem_besrb); printf ("%08x ", mfdcr(memcfgd));
  113 + mtdcr(memcfga,mem_besrsb); printf ("%08x ", mfdcr(memcfgd));
  114 + mtdcr(memcfga,mem_bear); printf ("%08x ", mfdcr(memcfgd));
  115 + mtdcr(memcfga,mem_mcopt1); printf ("%08x ", mfdcr(memcfgd));
  116 + mtdcr(memcfga,mem_rtr); printf ("%08x ", mfdcr(memcfgd));
  117 + mtdcr(memcfga,mem_pmit); printf ("%08x ", mfdcr(memcfgd));
  118 +
  119 + printf ("\n"
  120 +"mb0cf mb1cf mb2cf mb3cf sdtr1 ecccf eccerr\n");
  121 + mtdcr(memcfga,mem_mb0cf); printf ("%08x ", mfdcr(memcfgd));
  122 + mtdcr(memcfga,mem_mb1cf); printf ("%08x ", mfdcr(memcfgd));
  123 + mtdcr(memcfga,mem_mb2cf); printf ("%08x ", mfdcr(memcfgd));
  124 + mtdcr(memcfga,mem_mb3cf); printf ("%08x ", mfdcr(memcfgd));
  125 + mtdcr(memcfga,mem_sdtr1); printf ("%08x ", mfdcr(memcfgd));
  126 + mtdcr(memcfga,mem_ecccf); printf ("%08x ", mfdcr(memcfgd));
  127 + mtdcr(memcfga,mem_eccerr); printf ("%08x ", mfdcr(memcfgd));
  128 +
  129 + printf ("\n\n"
  130 +"DMA Channels\n"
  131 +"dmasr dmasgc dmaadr\n" "%08x %08x %08x\n"
  132 +"dmacr_0 dmact_0 dmada_0 dmasa_0 dmasb_0\n" "%08x %08x %08x %08x %08x\n"
  133 +"dmacr_1 dmact_1 dmada_1 dmasa_1 dmasb_1\n" "%08x %08x %08x %08x %08x\n",
  134 +mfdcr(dmasr), mfdcr(dmasgc),mfdcr(dmaadr),
  135 +mfdcr(dmacr0), mfdcr(dmact0),mfdcr(dmada0), mfdcr(dmasa0), mfdcr(dmasb0),
  136 +mfdcr(dmacr1), mfdcr(dmact1),mfdcr(dmada1), mfdcr(dmasa1), mfdcr(dmasb1));
  137 +
  138 + printf (
  139 +"dmacr_2 dmact_2 dmada_2 dmasa_2 dmasb_2\n" "%08x %08x %08x %08x %08x\n"
  140 +"dmacr_3 dmact_3 dmada_3 dmasa_3 dmasb_3\n" "%08x %08x %08x %08x %08x\n",
  141 +mfdcr(dmacr2), mfdcr(dmact2),mfdcr(dmada2), mfdcr(dmasa2), mfdcr(dmasb2),
  142 +mfdcr(dmacr3), mfdcr(dmact3),mfdcr(dmada3), mfdcr(dmasa3), mfdcr(dmasb3) );
  143 +
  144 + printf ("\n"
  145 +"External Bus\n"
  146 +"pbear pbesr0 pbesr1 epcr\n");
  147 + mtdcr(ebccfga,pbear); printf ("%08x ", mfdcr(ebccfgd));
  148 + mtdcr(ebccfga,pbesr0); printf ("%08x ", mfdcr(ebccfgd));
  149 + mtdcr(ebccfga,pbesr1); printf ("%08x ", mfdcr(ebccfgd));
  150 + mtdcr(ebccfga,epcr); printf ("%08x ", mfdcr(ebccfgd));
  151 +
  152 + printf ("\n"
  153 +"pb0cr pb0ap pb1cr bp1ap pb2cr pb2ap pb3cr pb3ap\n");
  154 + mtdcr(ebccfga,pb0cr); printf ("%08x ", mfdcr(ebccfgd));
  155 + mtdcr(ebccfga,pb0ap); printf ("%08x ", mfdcr(ebccfgd));
  156 + mtdcr(ebccfga,pb1cr); printf ("%08x ", mfdcr(ebccfgd));
  157 + mtdcr(ebccfga,pb1ap); printf ("%08x ", mfdcr(ebccfgd));
  158 + mtdcr(ebccfga,pb2cr); printf ("%08x ", mfdcr(ebccfgd));
  159 + mtdcr(ebccfga,pb2ap); printf ("%08x ", mfdcr(ebccfgd));
  160 + mtdcr(ebccfga,pb3cr); printf ("%08x ", mfdcr(ebccfgd));
  161 + mtdcr(ebccfga,pb3ap); printf ("%08x ", mfdcr(ebccfgd));
  162 +
  163 + printf ("\n"
  164 +"pb4cr pb4ap pb5cr bp5ap pb6cr pb6ap pb7cr pb7ap\n");
  165 + mtdcr(ebccfga,pb4cr); printf ("%08x ", mfdcr(ebccfgd));
  166 + mtdcr(ebccfga,pb4ap); printf ("%08x ", mfdcr(ebccfgd));
  167 + mtdcr(ebccfga,pb5cr); printf ("%08x ", mfdcr(ebccfgd));
  168 + mtdcr(ebccfga,pb5ap); printf ("%08x ", mfdcr(ebccfgd));
  169 + mtdcr(ebccfga,pb6cr); printf ("%08x ", mfdcr(ebccfgd));
  170 + mtdcr(ebccfga,pb6ap); printf ("%08x ", mfdcr(ebccfgd));
  171 + mtdcr(ebccfga,pb7cr); printf ("%08x ", mfdcr(ebccfgd));
  172 + mtdcr(ebccfga,pb7ap); printf ("%08x ", mfdcr(ebccfgd));
  173 +
  174 + printf ("\n\n");
  175 +#endif /*(CONFIG_405GP)*/
  176 +
  177 + return 0;
  178 +}
  179 +
  180 +#endif /* CONFIG_8xx && CFG_CMD_REGINFO */
  1 +/*
  2 + * (C) Copyright 2001
  3 + * Denis Peter, MPL AG Switzerland
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + *
  23 + *
  24 + *
  25 + */
  26 +
  27 +/*
  28 + * SCSI support.
  29 + */
  30 +
  31 +#include <common.h>
  32 +#include <command.h>
  33 +#include <cmd_boot.h>
  34 +#include <asm/processor.h>
  35 +#include <scsi.h>
  36 +#include <image.h>
  37 +#include <cmd_disk.h>
  38 +#include <pci.h>
  39 +
  40 +
  41 +#undef SCSI_DEBUG
  42 +
  43 +#ifdef SCSI_DEBUG
  44 +#define PRINTF(fmt,args...) printf (fmt ,##args)
  45 +#else
  46 +#define PRINTF(fmt,args...)
  47 +#endif
  48 +
  49 +#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
  50 +
  51 +#ifdef CONFIG_SCSI_SYM53C8XX
  52 +#define SCSI_VEND_ID 0x1000
  53 +#ifndef CONFIG_SCSI_DEV_ID
  54 +#define SCSI_DEV_ID 0x0001
  55 +#else
  56 +#define SCSI_DEV_ID CONFIG_SCSI_DEV_ID
  57 +#endif
  58 +#else
  59 +#error CONFIG_SCSI_SYM53C8XX must be defined
  60 +#endif
  61 +
  62 +
  63 +static ccb tempccb; /* temporary scsi command buffer */
  64 +
  65 +static unsigned char tempbuff[512]; /* temporary data buffer */
  66 +
  67 +static int scsi_max_devs; /* number of highest available scsi device */
  68 +
  69 +static int scsi_curr_dev; /* current device */
  70 +
  71 +static block_dev_desc_t scsi_dev_desc[CFG_SCSI_MAX_DEVICE];
  72 +
  73 +/********************************************************************************
  74 + * forward declerations of some Setup Routines
  75 + */
  76 +void scsi_setup_test_unit_ready(ccb * pccb);
  77 +void scsi_setup_read_capacity(ccb * pccb);
  78 +void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks);
  79 +void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks);
  80 +void scsi_setup_inquiry(ccb * pccb);
  81 +void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
  82 +
  83 +
  84 +ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer);
  85 +
  86 +
  87 +/*********************************************************************************
  88 + * (re)-scan the scsi bus and reports scsi device info
  89 + * to the user if mode = 1
  90 + */
  91 +void scsi_scan(int mode)
  92 +{
  93 + unsigned char i,perq,modi,lun;
  94 + unsigned long capacity,blksz;
  95 + ccb* pccb=(ccb *)&tempccb;
  96 +
  97 + if(mode==1) {
  98 + printf("scanning bus for devices...\n");
  99 + }
  100 + for(i=0;i<CFG_SCSI_MAX_DEVICE;i++) {
  101 + scsi_dev_desc[i].target=0xff;
  102 + scsi_dev_desc[i].lun=0xff;
  103 + scsi_dev_desc[i].lba=0;
  104 + scsi_dev_desc[i].blksz=0;
  105 + scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
  106 + scsi_dev_desc[i].vendor[0]=0;
  107 + scsi_dev_desc[i].product[0]=0;
  108 + scsi_dev_desc[i].revision[0]=0;
  109 + scsi_dev_desc[i].removable=FALSE;
  110 + scsi_dev_desc[i].if_type=IF_TYPE_SCSI;
  111 + scsi_dev_desc[i].dev=i;
  112 + scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
  113 + scsi_dev_desc[i].block_read=scsi_read;
  114 + }
  115 + scsi_max_devs=0;
  116 + for(i=0;i<CFG_SCSI_MAX_SCSI_ID;i++) {
  117 + pccb->target=i;
  118 + for(lun=0;lun<CFG_SCSI_MAX_LUN;lun++) {
  119 + pccb->lun=lun;
  120 + pccb->pdata=(unsigned char *)&tempbuff;
  121 + pccb->datalen=512;
  122 + scsi_setup_inquiry(pccb);
  123 + if(scsi_exec(pccb)!=TRUE) {
  124 + if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
  125 + PRINTF("Selection timeout ID %d\n",pccb->target);
  126 + continue; /* selection timeout => assuming no device present */
  127 + }
  128 + scsi_print_error(pccb);
  129 + continue;
  130 + }
  131 + perq=tempbuff[0];
  132 + modi=tempbuff[1];
  133 + if((perq & 0x1f)==0x1f) {
  134 + continue; /* skip unknown devices */
  135 + }
  136 + if((modi&0x80)==0x80) /* drive is removable */
  137 + scsi_dev_desc[scsi_max_devs].removable=TRUE;
  138 + /* get info for this device */
  139 + scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].vendor[0],&tempbuff[8],8);
  140 + scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].product[0],&tempbuff[16],16);
  141 + scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].revision[0],&tempbuff[32],4);
  142 + scsi_dev_desc[scsi_max_devs].target=pccb->target;
  143 + scsi_dev_desc[scsi_max_devs].lun=pccb->lun;
  144 +
  145 + pccb->datalen=0;
  146 + scsi_setup_test_unit_ready(pccb);
  147 + if(scsi_exec(pccb)!=TRUE) {
  148 + if(scsi_dev_desc[scsi_max_devs].removable==TRUE) {
  149 + scsi_dev_desc[scsi_max_devs].type=perq;
  150 + goto removable;
  151 + }
  152 + scsi_print_error(pccb);
  153 + continue;
  154 + }
  155 + pccb->datalen=8;
  156 + scsi_setup_read_capacity(pccb);
  157 + if(scsi_exec(pccb)!=TRUE) {
  158 + scsi_print_error(pccb);
  159 + continue;
  160 + }
  161 + capacity=((unsigned long)tempbuff[0]<<24)|((unsigned long)tempbuff[1]<<16)|
  162 + ((unsigned long)tempbuff[2]<<8)|((unsigned long)tempbuff[3]);
  163 + blksz=((unsigned long)tempbuff[4]<<24)|((unsigned long)tempbuff[5]<<16)|
  164 + ((unsigned long)tempbuff[6]<<8)|((unsigned long)tempbuff[7]);
  165 + scsi_dev_desc[scsi_max_devs].lba=capacity;
  166 + scsi_dev_desc[scsi_max_devs].blksz=blksz;
  167 + scsi_dev_desc[scsi_max_devs].type=perq;
  168 + init_part(&scsi_dev_desc[scsi_max_devs]);
  169 +removable:
  170 + if(mode==1) {
  171 + printf (" Device %d: ", scsi_max_devs);
  172 + dev_print(&scsi_dev_desc[scsi_max_devs]);
  173 + } /* if mode */
  174 + scsi_max_devs++;
  175 + } /* next LUN */
  176 + }
  177 + if(scsi_max_devs>0)
  178 + scsi_curr_dev=0;
  179 + else
  180 + scsi_curr_dev=-1;
  181 +}
  182 +
  183 +
  184 +
  185 +void scsi_init(void)
  186 +{
  187 + int busdevfunc;
  188 +
  189 + busdevfunc=pci_find_device(SCSI_VEND_ID,SCSI_DEV_ID,0); /* get PCI Device ID */
  190 + if(busdevfunc==-1) {
  191 + printf("Error SCSI Controller (%04X,%04X) not found\n",SCSI_VEND_ID,SCSI_DEV_ID);
  192 + return;
  193 + }
  194 +#ifdef DEBUG
  195 + else {
  196 + printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",SCSI_VEND_ID,SCSI_DEV_ID,(busdevfunc>>16)&0xFF,(busdevfunc>>11)&0x1F,(busdevfunc>>8)&0x7);
  197 + }
  198 +#endif
  199 + scsi_low_level_init(busdevfunc);
  200 + scsi_scan(1);
  201 +}
  202 +
  203 +block_dev_desc_t * scsi_get_dev(int dev)
  204 +{
  205 + return((block_dev_desc_t *)&scsi_dev_desc[dev]);
  206 +}
  207 +
  208 +
  209 +
  210 +/******************************************************************************
  211 + * scsi boot command intepreter. Derived from diskboot
  212 + */
  213 +int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  214 +{
  215 + char *boot_device = NULL;
  216 + char *ep;
  217 + int dev, part = 0;
  218 + ulong cnt;
  219 + ulong addr;
  220 + disk_partition_t info;
  221 + image_header_t *hdr;
  222 + int rcode = 0;
  223 +
  224 + switch (argc) {
  225 + case 1:
  226 + addr = CFG_LOAD_ADDR;
  227 + boot_device = getenv ("bootdevice");
  228 + break;
  229 + case 2:
  230 + addr = simple_strtoul(argv[1], NULL, 16);
  231 + boot_device = getenv ("bootdevice");
  232 + break;
  233 + case 3:
  234 + addr = simple_strtoul(argv[1], NULL, 16);
  235 + boot_device = argv[2];
  236 + break;
  237 + default:
  238 + printf ("Usage:\n%s\n", cmdtp->usage);
  239 + return 1;
  240 + }
  241 +
  242 + if (!boot_device) {
  243 + puts ("\n** No boot device **\n");
  244 + return 1;
  245 + }
  246 +
  247 + dev = simple_strtoul(boot_device, &ep, 16);
  248 + printf("booting from dev %d\n",dev);
  249 + if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
  250 + printf ("\n** Device %d not available\n", dev);
  251 + return 1;
  252 + }
  253 +
  254 + if (*ep) {
  255 + if (*ep != ':') {
  256 + puts ("\n** Invalid boot device, use `dev[:part]' **\n");
  257 + return 1;
  258 + }
  259 + part = simple_strtoul(++ep, NULL, 16);
  260 + }
  261 + if (get_partition_info (&scsi_dev_desc[dev], part, &info)) {
  262 + printf("error reading partinfo\n");
  263 + return 1;
  264 + }
  265 + if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
  266 + printf ("\n** Invalid partition type \"%.32s\""
  267 + " (expect \"" BOOT_PART_TYPE "\")\n",
  268 + info.type);
  269 + return 1;
  270 + }
  271 +
  272 + printf ("\nLoading from SCSI device %d, partition %d: "
  273 + "Name: %.32s Type: %.32s\n",
  274 + dev, part, info.name, info.type);
  275 +
  276 + PRINTF ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
  277 + info.start, info.size, info.blksz);
  278 +
  279 + if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) {
  280 + printf ("** Read error on %d:%d\n", dev, part);
  281 + return 1;
  282 + }
  283 +
  284 + hdr = (image_header_t *)addr;
  285 +
  286 + if (hdr->ih_magic == IH_MAGIC) {
  287 +
  288 + print_image_hdr (hdr);
  289 + cnt = (hdr->ih_size + sizeof(image_header_t));
  290 + cnt += info.blksz - 1;
  291 + cnt /= info.blksz;
  292 + cnt -= 1;
  293 + } else {
  294 + printf("\n** Bad Magic Number **\n");
  295 + return 1;
  296 + }
  297 +
  298 + if (scsi_read (dev, info.start+1, cnt,
  299 + (ulong *)(addr+info.blksz)) != cnt) {
  300 + printf ("** Read error on %d:%d\n", dev, part);
  301 + return 1;
  302 + }
  303 + /* Loading ok, update default load address */
  304 + load_addr = addr;
  305 +
  306 + flush_cache (addr, (cnt+1)*info.blksz);
  307 +
  308 + /* Check if we should attempt an auto-start */
  309 + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
  310 + char *local_args[2];
  311 + extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
  312 + local_args[0] = argv[0];
  313 + local_args[1] = NULL;
  314 + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
  315 + rcode = do_bootm (cmdtp, 0, 1, local_args);
  316 + }
  317 + return rcode;
  318 +}
  319 +
  320 +/*********************************************************************************
  321 + * scsi command intepreter
  322 + */
  323 +int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  324 +{
  325 + switch (argc) {
  326 + case 0:
  327 + case 1: printf ("Usage:\n%s\n", cmdtp->usage); return 1;
  328 + case 2:
  329 + if (strncmp(argv[1],"res",3) == 0) {
  330 + printf("\nReset SCSI\n");
  331 + scsi_bus_reset();
  332 + scsi_scan(1);
  333 + return 0;
  334 + }
  335 + if (strncmp(argv[1],"inf",3) == 0) {
  336 + int i;
  337 + for (i=0; i<CFG_SCSI_MAX_DEVICE; ++i) {
  338 + if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN)
  339 + continue; /* list only known devices */
  340 + printf ("SCSI dev. %d: ", i);
  341 + dev_print(&scsi_dev_desc[i]);
  342 + }
  343 + return 0;
  344 + }
  345 + if (strncmp(argv[1],"dev",3) == 0) {
  346 + if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CFG_SCSI_MAX_DEVICE)) {
  347 + printf("\nno SCSI devices available\n");
  348 + return 1;
  349 + }
  350 + printf ("\n Device %d: ", scsi_curr_dev);
  351 + dev_print(&scsi_dev_desc[scsi_curr_dev]);
  352 + return 0;
  353 + }
  354 + if (strncmp(argv[1],"scan",4) == 0) {
  355 + scsi_scan(1);
  356 + return 0;
  357 + }
  358 + if (strncmp(argv[1],"part",4) == 0) {
  359 + int dev, ok;
  360 + for (ok=0, dev=0; dev<CFG_SCSI_MAX_DEVICE; ++dev) {
  361 + if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) {
  362 + ok++;
  363 + if (dev)
  364 + printf("\n");
  365 + PRINTF("print_part of %x\n",dev);
  366 + print_part(&scsi_dev_desc[dev]);
  367 + }
  368 + }
  369 + if (!ok)
  370 + printf("\nno SCSI devices available\n");
  371 + return 1;
  372 + }
  373 + printf ("Usage:\n%s\n", cmdtp->usage);
  374 + return 1;
  375 + case 3:
  376 + if (strncmp(argv[1],"dev",3) == 0) {
  377 + int dev = (int)simple_strtoul(argv[2], NULL, 10);
  378 + printf ("\nSCSI device %d: ", dev);
  379 + if (dev >= CFG_SCSI_MAX_DEVICE) {
  380 + printf("unknown device\n");
  381 + return 1;
  382 + }
  383 + printf ("\n Device %d: ", dev);
  384 + dev_print(&scsi_dev_desc[dev]);
  385 + if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
  386 + return 1;
  387 + }
  388 + scsi_curr_dev = dev;
  389 + printf("... is now current device\n");
  390 + return 0;
  391 + }
  392 + if (strncmp(argv[1],"part",4) == 0) {
  393 + int dev = (int)simple_strtoul(argv[2], NULL, 10);
  394 + if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) {
  395 + print_part(&scsi_dev_desc[dev]);
  396 + }
  397 + else {
  398 + printf ("\nSCSI device %d not available\n", dev);
  399 + }
  400 + return 1;
  401 + }
  402 + printf ("Usage:\n%s\n", cmdtp->usage);
  403 + return 1;
  404 + default:
  405 + /* at least 4 args */
  406 + if (strcmp(argv[1],"read") == 0) {
  407 + ulong addr = simple_strtoul(argv[2], NULL, 16);
  408 + ulong blk = simple_strtoul(argv[3], NULL, 16);
  409 + ulong cnt = simple_strtoul(argv[4], NULL, 16);
  410 + ulong n;
  411 + printf ("\nSCSI read: device %d block # %ld, count %ld ... ",
  412 + scsi_curr_dev, blk, cnt);
  413 + n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr);
  414 + printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
  415 + return 0;
  416 + }
  417 + } /* switch */
  418 + printf ("Usage:\n%s\n", cmdtp->usage);
  419 + return 1;
  420 +}
  421 +
  422 +/****************************************************************************************
  423 + * scsi_read
  424 + */
  425 +
  426 +#define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */
  427 +
  428 +ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer)
  429 +{
  430 + ulong start,blks, buf_addr;
  431 + unsigned short smallblks;
  432 + ccb* pccb=(ccb *)&tempccb;
  433 + device&=0xff;
  434 + /* Setup device
  435 + */
  436 + pccb->target=scsi_dev_desc[device].target;
  437 + pccb->lun=scsi_dev_desc[device].lun;
  438 + buf_addr=(unsigned long)buffer;
  439 + start=blknr;
  440 + blks=blkcnt;
  441 + PRINTF("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer);
  442 + do {
  443 + pccb->pdata=(unsigned char *)buf_addr;
  444 + if(blks>SCSI_MAX_READ_BLK) {
  445 + pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK;
  446 + smallblks=SCSI_MAX_READ_BLK;
  447 + scsi_setup_read_ext(pccb,start,smallblks);
  448 + start+=SCSI_MAX_READ_BLK;
  449 + blks-=SCSI_MAX_READ_BLK;
  450 + }
  451 + else {
  452 + pccb->datalen=scsi_dev_desc[device].blksz * blks;
  453 + smallblks=(unsigned short) blks;
  454 + scsi_setup_read_ext(pccb,start,smallblks);
  455 + start+=blks;
  456 + blks=0;
  457 + }
  458 + PRINTF("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
  459 + if(scsi_exec(pccb)!=TRUE) {
  460 + scsi_print_error(pccb);
  461 + blkcnt-=blks;
  462 + break;
  463 + }
  464 + buf_addr+=pccb->datalen;
  465 + } while(blks!=0);
  466 + PRINTF("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
  467 + return(blkcnt);
  468 +}
  469 +
  470 +/* copy src to dest, skipping leading and trailing blanks
  471 + * and null terminate the string
  472 + */
  473 +void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
  474 +{
  475 + int start,end;
  476 +
  477 + start=0;
  478 + while(start<len) {
  479 + if(src[start]!=' ')
  480 + break;
  481 + start++;
  482 + }
  483 + end=len-1;
  484 + while(end>start) {
  485 + if(src[end]!=' ')
  486 + break;
  487 + end--;
  488 + }
  489 + for( ; start<=end; start++) {
  490 + *dest++=src[start];
  491 + }
  492 + *dest='\0';
  493 +}
  494 +
  495 +
  496 +
  497 +/* Trim trailing blanks, and NUL-terminate string
  498 + */
  499 +void scsi_trim_trail (unsigned char *str, unsigned int len)
  500 +{
  501 + unsigned char *p = str + len - 1;
  502 +
  503 + while (len-- > 0) {
  504 + *p-- = '\0';
  505 + if (*p != ' ') {
  506 + return;
  507 + }
  508 + }
  509 +}
  510 +
  511 +
  512 +/************************************************************************************
  513 + * Some setup (fill-in) routines
  514 + */
  515 +void scsi_setup_test_unit_ready(ccb * pccb)
  516 +{
  517 + pccb->cmd[0]=SCSI_TST_U_RDY;
  518 + pccb->cmd[1]=pccb->lun<<5;
  519 + pccb->cmd[2]=0;
  520 + pccb->cmd[3]=0;
  521 + pccb->cmd[4]=0;
  522 + pccb->cmd[5]=0;
  523 + pccb->cmdlen=6;
  524 + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
  525 +}
  526 +
  527 +void scsi_setup_read_capacity(ccb * pccb)
  528 +{
  529 + pccb->cmd[0]=SCSI_RD_CAPAC;
  530 + pccb->cmd[1]=pccb->lun<<5;
  531 + pccb->cmd[2]=0;
  532 + pccb->cmd[3]=0;
  533 + pccb->cmd[4]=0;
  534 + pccb->cmd[5]=0;
  535 + pccb->cmd[6]=0;
  536 + pccb->cmd[7]=0;
  537 + pccb->cmd[8]=0;
  538 + pccb->cmd[9]=0;
  539 + pccb->cmdlen=10;
  540 + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
  541 +
  542 +}
  543 +
  544 +void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks)
  545 +{
  546 + pccb->cmd[0]=SCSI_READ10;
  547 + pccb->cmd[1]=pccb->lun<<5;
  548 + pccb->cmd[2]=((unsigned char) (start>>24))&0xff;
  549 + pccb->cmd[3]=((unsigned char) (start>>16))&0xff;
  550 + pccb->cmd[4]=((unsigned char) (start>>8))&0xff;
  551 + pccb->cmd[5]=((unsigned char) (start))&0xff;
  552 + pccb->cmd[6]=0;
  553 + pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
  554 + pccb->cmd[8]=(unsigned char) blocks & 0xff;
  555 + pccb->cmd[6]=0;
  556 + pccb->cmdlen=10;
  557 + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
  558 + PRINTF("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
  559 + pccb->cmd[0],pccb->cmd[1],
  560 + pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
  561 + pccb->cmd[7],pccb->cmd[8]);
  562 +}
  563 +
  564 +void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks)
  565 +{
  566 + pccb->cmd[0]=SCSI_READ6;
  567 + pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f);
  568 + pccb->cmd[2]=((unsigned char) (start>>8))&0xff;
  569 + pccb->cmd[3]=((unsigned char) (start))&0xff;
  570 + pccb->cmd[4]=(unsigned char) blocks & 0xff;
  571 + pccb->cmd[5]=0;
  572 + pccb->cmdlen=6;
  573 + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
  574 + PRINTF("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
  575 + pccb->cmd[0],pccb->cmd[1],
  576 + pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]);
  577 +}
  578 +
  579 +
  580 +void scsi_setup_inquiry(ccb * pccb)
  581 +{
  582 + pccb->cmd[0]=SCSI_INQUIRY;
  583 + pccb->cmd[1]=pccb->lun<<5;
  584 + pccb->cmd[2]=0;
  585 + pccb->cmd[3]=0;
  586 + if(pccb->datalen>255)
  587 + pccb->cmd[4]=255;
  588 + else
  589 + pccb->cmd[4]=(unsigned char)pccb->datalen;
  590 + pccb->cmd[5]=0;
  591 + pccb->cmdlen=6;
  592 + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
  593 +}
  594 +
  595 +#endif /* #if (CONFIG_COMMANDS & CFG_CMD_SCSI) */
  1 +/*
  2 + * (C) Copyright 2001
  3 + * Denis Peter, MPL AG Switzerland
  4 + *
  5 + * Most of this source has been derived from the Linux USB
  6 + * project.
  7 + *
  8 + * See file CREDITS for list of people who contributed to this
  9 + * project.
  10 + *
  11 + * This program is free software; you can redistribute it and/or
  12 + * modify it under the terms of the GNU General Public License as
  13 + * published by the Free Software Foundation; either version 2 of
  14 + * the License, or (at your option) any later version.
  15 + *
  16 + * This program is distributed in the hope that it will be useful,
  17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 + * GNU General Public License for more details.
  20 + *
  21 + * You should have received a copy of the GNU General Public License
  22 + * along with this program; if not, write to the Free Software
  23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 + * MA 02111-1307 USA
  25 + *
  26 + */
  27 +
  28 +#include <common.h>
  29 +#include <command.h>
  30 +
  31 +#if (CONFIG_COMMANDS & CFG_CMD_USB)
  32 +
  33 +#include <usb.h>
  34 +#include <cmd_disk.h>
  35 +
  36 +#undef CMD_USB_DEBUG
  37 +
  38 +#ifdef CMD_USB_DEBUG
  39 +#define CMD_USB_PRINTF(fmt,args...) printf (fmt ,##args)
  40 +#else
  41 +#define CMD_USB_PRINTF(fmt,args...)
  42 +#endif
  43 +static int usb_stor_curr_dev=-1; /* current device */
  44 +
  45 +/* somme display routines (info command) */
  46 +char * usb_get_class_desc(unsigned char dclass)
  47 +{
  48 + switch(dclass) {
  49 + case USB_CLASS_PER_INTERFACE:
  50 + return("See Interface");
  51 + case USB_CLASS_AUDIO:
  52 + return("Audio");
  53 + case USB_CLASS_COMM:
  54 + return("Communication");
  55 + case USB_CLASS_HID:
  56 + return("Human Interface");
  57 + case USB_CLASS_PRINTER:
  58 + return("Printer");
  59 + case USB_CLASS_MASS_STORAGE:
  60 + return("Mass Storage");
  61 + case USB_CLASS_HUB:
  62 + return("Hub");
  63 + case USB_CLASS_DATA:
  64 + return("CDC Data");
  65 + case USB_CLASS_VENDOR_SPEC:
  66 + return("Vendor specific");
  67 + default :
  68 + return("");
  69 + }
  70 +}
  71 +
  72 +void usb_display_class_sub(unsigned char dclass,unsigned char subclass,unsigned char proto)
  73 +{
  74 + switch(dclass) {
  75 + case USB_CLASS_PER_INTERFACE:
  76 + printf("See Interface");
  77 + break;
  78 + case USB_CLASS_HID:
  79 + printf("Human Interface, Subclass: ");
  80 + switch(subclass) {
  81 + case USB_SUB_HID_NONE:
  82 + printf("None");
  83 + break;
  84 + case USB_SUB_HID_BOOT:
  85 + printf("Boot ");
  86 + switch(proto) {
  87 + case USB_PROT_HID_NONE:
  88 + printf("None");
  89 + break;
  90 + case USB_PROT_HID_KEYBOARD:
  91 + printf("Keyboard");
  92 + break;
  93 + case USB_PROT_HID_MOUSE:
  94 + printf("Mouse");
  95 + break;
  96 + default:
  97 + printf("reserved");
  98 + }
  99 + break;
  100 + default:
  101 + printf("reserved");
  102 + }
  103 + break;
  104 + case USB_CLASS_MASS_STORAGE:
  105 + printf("Mass Storage, ");
  106 + switch(subclass) {
  107 + case US_SC_RBC:
  108 + printf("RBC ");
  109 + break;
  110 + case US_SC_8020:
  111 + printf("SFF-8020i (ATAPI)");
  112 + break;
  113 + case US_SC_QIC:
  114 + printf("QIC-157 (Tape)");
  115 + break;
  116 + case US_SC_UFI:
  117 + printf("UFI");
  118 + break;
  119 + case US_SC_8070:
  120 + printf("SFF-8070");
  121 + break;
  122 + case US_SC_SCSI:
  123 + printf("Transp. SCSI");
  124 + break;
  125 + default:
  126 + printf("reserved");
  127 + break;
  128 + }
  129 + printf(", ");
  130 + switch(proto) {
  131 + case US_PR_CB:
  132 + printf("Command/Bulk");
  133 + break;
  134 + case US_PR_CBI:
  135 + printf("Command/Bulk/Int");
  136 + break;
  137 + case US_PR_BULK:
  138 + printf("Bulk only");
  139 + break;
  140 + default:
  141 + printf("reserved");
  142 + }
  143 + break;
  144 + default:
  145 + printf("%s",usb_get_class_desc(dclass));
  146 + }
  147 +}
  148 +
  149 +void usb_display_string(struct usb_device *dev,int index)
  150 +{
  151 + char buffer[256];
  152 + if (index!=0) {
  153 + if (usb_string(dev,index,&buffer[0],256)>0);
  154 + printf("String: \"%s\"",buffer);
  155 + }
  156 +}
  157 +
  158 +void usb_display_desc(struct usb_device *dev)
  159 +{
  160 + if (dev->descriptor.bDescriptorType==USB_DT_DEVICE) {
  161 + printf("%d: %s, USB Revision %x.%x\n",dev->devnum,usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
  162 + (dev->descriptor.bcdUSB>>8) & 0xff,dev->descriptor.bcdUSB & 0xff);
  163 + if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
  164 + printf(" - %s %s %s\n",dev->mf,dev->prod,dev->serial);
  165 + if (dev->descriptor.bDeviceClass) {
  166 + printf(" - Class: ");
  167 + usb_display_class_sub(dev->descriptor.bDeviceClass,dev->descriptor.bDeviceSubClass,dev->descriptor.bDeviceProtocol);
  168 + printf("\n");
  169 + }
  170 + else {
  171 + printf(" - Class: (from Interface) %s\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass));
  172 + }
  173 + printf(" - PacketSize: %d Configurations: %d\n",dev->descriptor.bMaxPacketSize0,dev->descriptor.bNumConfigurations);
  174 + printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n",dev->descriptor.idVendor,dev->descriptor.idProduct,(dev->descriptor.bcdDevice>>8) & 0xff,dev->descriptor.bcdDevice & 0xff);
  175 + }
  176 +
  177 +}
  178 +
  179 +void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_device *dev)
  180 +{
  181 + printf(" Configuration: %d\n",config->bConfigurationValue);
  182 + printf(" - Interfaces: %d %s%s%dmA\n",config->bNumInterfaces,(config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ",
  183 + (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",config->MaxPower*2);
  184 + if (config->iConfiguration) {
  185 + printf(" - ");
  186 + usb_display_string(dev,config->iConfiguration);
  187 + printf("\n");
  188 + }
  189 +}
  190 +
  191 +void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_device *dev)
  192 +{
  193 + printf(" Interface: %d\n",ifdesc->bInterfaceNumber);
  194 + printf(" - Alternate Settings %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints);
  195 + printf(" - Class ");
  196 + usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol);
  197 + printf("\n");
  198 + if (ifdesc->iInterface) {
  199 + printf(" - ");
  200 + usb_display_string(dev,ifdesc->iInterface);
  201 + printf("\n");
  202 + }
  203 +}
  204 +
  205 +void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
  206 +{
  207 + printf(" - Endpoint %d %s ",epdesc->bEndpointAddress & 0xf,(epdesc->bEndpointAddress & 0x80) ? "In" : "Out");
  208 + switch((epdesc->bmAttributes & 0x03))
  209 + {
  210 + case 0: printf("Control"); break;
  211 + case 1: printf("Isochronous"); break;
  212 + case 2: printf("Bulk"); break;
  213 + case 3: printf("Interrupt"); break;
  214 + }
  215 + printf(" MaxPacket %d",epdesc->wMaxPacketSize);
  216 + if ((epdesc->bmAttributes & 0x03)==0x3)
  217 + printf(" Interval %dms",epdesc->bInterval);
  218 + printf("\n");
  219 +}
  220 +
  221 +/* main routine to diasplay the configs, interfaces and endpoints */
  222 +void usb_display_config(struct usb_device *dev)
  223 +{
  224 + struct usb_config_descriptor *config;
  225 + struct usb_interface_descriptor *ifdesc;
  226 + struct usb_endpoint_descriptor *epdesc;
  227 + int i,ii;
  228 +
  229 + config= &dev->config;
  230 + usb_display_conf_desc(config,dev);
  231 + for(i=0;i<config->no_of_if;i++) {
  232 + ifdesc= &config->if_desc[i];
  233 + usb_display_if_desc(ifdesc,dev);
  234 + for(ii=0;ii<ifdesc->no_of_ep;ii++) {
  235 + epdesc= &ifdesc->ep_desc[ii];
  236 + usb_display_ep_desc(epdesc);
  237 + }
  238 + }
  239 + printf("\n");
  240 +}
  241 +
  242 +/* shows the device tree recursively */
  243 +void usb_show_tree_graph(struct usb_device *dev,char *pre)
  244 +{
  245 + int i,index;
  246 + int has_child,last_child,port;
  247 +
  248 + index=strlen(pre);
  249 + printf(" %s",pre);
  250 + /* check if the device has connected children */
  251 + has_child=0;
  252 + for(i=0;i<dev->maxchild;i++) {
  253 + if (dev->children[i]!=NULL)
  254 + has_child=1;
  255 + }
  256 + /* check if we are the last one */
  257 + last_child=1;
  258 + if (dev->parent!=NULL) {
  259 + for(i=0;i<dev->parent->maxchild;i++) {
  260 + /* search for children */
  261 + if (dev->parent->children[i]==dev) {
  262 + /* found our pointer, see if we have a little sister */
  263 + port=i;
  264 + while(i++<dev->parent->maxchild) {
  265 + if (dev->parent->children[i]!=NULL) {
  266 + /* found a sister */
  267 + last_child=0;
  268 + break;
  269 + } /* if */
  270 + } /* while */
  271 + } /* device found */
  272 + } /* for all children of the parent */
  273 + printf("\b+-");
  274 + /* correct last child */
  275 + if (last_child) {
  276 + pre[index-1]=' ';
  277 + }
  278 + } /* if not root hub */
  279 + else
  280 + printf(" ");
  281 + printf("%d ",dev->devnum);
  282 + pre[index++]=' ';
  283 + pre[index++]= has_child ? '|' : ' ';
  284 + pre[index]=0;
  285 + printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
  286 + dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2);
  287 + if (strlen(dev->mf) ||
  288 + strlen(dev->prod) ||
  289 + strlen(dev->serial))
  290 + printf(" %s %s %s %s\n",pre,dev->mf,dev->prod,dev->serial);
  291 + printf(" %s\n",pre);
  292 + if (dev->maxchild>0) {
  293 + for(i=0;i<dev->maxchild;i++) {
  294 + if (dev->children[i]!=NULL) {
  295 + usb_show_tree_graph(dev->children[i],pre);
  296 + pre[index]=0;
  297 + }
  298 + }
  299 + }
  300 +}
  301 +
  302 +/* main routine for the tree command */
  303 +void usb_show_tree(struct usb_device *dev)
  304 +{
  305 + char preamble[32];
  306 +
  307 + memset(preamble,0,32);
  308 + usb_show_tree_graph(dev,&preamble[0]);
  309 +}
  310 +
  311 +
  312 +
  313 +/******************************************************************************
  314 + * usb boot command intepreter. Derived from diskboot
  315 + */
  316 +#ifdef CONFIG_USB_STORAGE
  317 +int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  318 +{
  319 + char *boot_device = NULL;
  320 + char *ep;
  321 + int dev, part=0, rcode;
  322 + ulong cnt;
  323 + ulong addr;
  324 + disk_partition_t info;
  325 + image_header_t *hdr;
  326 + block_dev_desc_t *stor_dev;
  327 +
  328 +
  329 + switch (argc) {
  330 + case 1:
  331 + addr = CFG_LOAD_ADDR;
  332 + boot_device = getenv ("bootdevice");
  333 + break;
  334 + case 2:
  335 + addr = simple_strtoul(argv[1], NULL, 16);
  336 + boot_device = getenv ("bootdevice");
  337 + break;
  338 + case 3:
  339 + addr = simple_strtoul(argv[1], NULL, 16);
  340 + boot_device = argv[2];
  341 + break;
  342 + default:
  343 + printf ("Usage:\n%s\n", cmdtp->usage);
  344 + return 1;
  345 + }
  346 +
  347 + if (!boot_device) {
  348 + puts ("\n** No boot device **\n");
  349 + return 1;
  350 + }
  351 +
  352 + dev = simple_strtoul(boot_device, &ep, 16);
  353 + stor_dev=usb_stor_get_dev(dev);
  354 + if (stor_dev->type == DEV_TYPE_UNKNOWN) {
  355 + printf ("\n** Device %d not available\n", dev);
  356 + return 1;
  357 + }
  358 + if (stor_dev->block_read==NULL) {
  359 + printf("storage device not initialized. Use usb scan\n");
  360 + return 1;
  361 + }
  362 + if (*ep) {
  363 + if (*ep != ':') {
  364 + puts ("\n** Invalid boot device, use `dev[:part]' **\n");
  365 + return 1;
  366 + }
  367 + part = simple_strtoul(++ep, NULL, 16);
  368 + }
  369 +
  370 + if (get_partition_info (stor_dev, part, &info)) {
  371 + /* try to boot raw .... */
  372 + strncpy(&info.type[0], BOOT_PART_TYPE, sizeof(BOOT_PART_TYPE));
  373 + strncpy(&info.name[0], "Raw", 4);
  374 + info.start=0;
  375 + info.blksz=0x200;
  376 + info.size=2880;
  377 + printf("error reading partinfo...try to boot raw\n");
  378 + }
  379 + if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
  380 + printf ("\n** Invalid partition type \"%.32s\""
  381 + " (expect \"" BOOT_PART_TYPE "\")\n",
  382 + info.type);
  383 + return 1;
  384 + }
  385 + printf ("\nLoading from USB device %d, partition %d: "
  386 + "Name: %.32s Type: %.32s\n",
  387 + dev, part, info.name, info.type);
  388 +
  389 + printf ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
  390 + info.start, info.size, info.blksz);
  391 +
  392 + if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) {
  393 + printf ("** Read error on %d:%d\n", dev, part);
  394 + return 1;
  395 + }
  396 +
  397 + hdr = (image_header_t *)addr;
  398 +
  399 + if (hdr->ih_magic == IH_MAGIC) {
  400 + print_image_hdr (hdr);
  401 + cnt = (hdr->ih_size + sizeof(image_header_t));
  402 + cnt += info.blksz - 1;
  403 + cnt /= info.blksz;
  404 + cnt -= 1;
  405 + } else {
  406 + printf("\n** Bad Magic Number **\n");
  407 + return 1;
  408 + }
  409 +
  410 + if (stor_dev->block_read (dev, info.start+1, cnt,
  411 + (ulong *)(addr+info.blksz)) != cnt) {
  412 + printf ("\n** Read error on %d:%d\n", dev, part);
  413 + return 1;
  414 + }
  415 + /* Loading ok, update default load address */
  416 + load_addr = addr;
  417 +
  418 + flush_cache (addr, (cnt+1)*info.blksz);
  419 +
  420 + /* Check if we should attempt an auto-start */
  421 + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
  422 + char *local_args[2];
  423 + extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
  424 + local_args[0] = argv[0];
  425 + local_args[1] = NULL;
  426 + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
  427 + rcode=do_bootm (cmdtp, 0, 1, local_args);
  428 + return rcode;
  429 + }
  430 + return 0;
  431 +}
  432 +#endif /* CONFIG_USB_STORAGE */
  433 +
  434 +
  435 +
  436 +/*********************************************************************************
  437 + * usb command intepreter
  438 + */
  439 +int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  440 +{
  441 +
  442 + int i;
  443 + struct usb_device *dev = NULL;
  444 + block_dev_desc_t *stor_dev;
  445 +
  446 + if ((strncmp(argv[1],"reset",5) == 0) ||
  447 + (strncmp(argv[1],"start",5) == 0)){
  448 + usb_stop();
  449 + printf("(Re)start USB...\n");
  450 + usb_init();
  451 + return 0;
  452 + }
  453 + if (strncmp(argv[1],"stop",4) == 0) {
  454 +#ifdef CONFIG_USB_KEYBOARD
  455 + if (argc==2) {
  456 + if (usb_kbd_deregister()!=0) {
  457 + printf("USB not stopped: usbkbd still using USB\n");
  458 + return 1;
  459 + }
  460 + }
  461 + else { /* forced stop, switch console in to serial */
  462 + console_assign(stdin,"serial");
  463 + usb_kbd_deregister();
  464 + }
  465 +#endif
  466 + printf("stopping USB..\n");
  467 + usb_stop();
  468 + return 0;
  469 + }
  470 + if (strncmp(argv[1],"tree",4) == 0) {
  471 + printf("\nDevice Tree:\n");
  472 + usb_show_tree(usb_get_dev_index(0));
  473 + return 0;
  474 + }
  475 + if (strncmp(argv[1],"inf",3) == 0) {
  476 + int d;
  477 + if (argc==2) {
  478 + for(d=0;d<USB_MAX_DEVICE;d++) {
  479 + dev=usb_get_dev_index(d);
  480 + if (dev==NULL)
  481 + break;
  482 + usb_display_desc(dev);
  483 + usb_display_config(dev);
  484 + }
  485 + return 0;
  486 + }
  487 + else {
  488 + int d;
  489 +
  490 + i=simple_strtoul(argv[2], NULL, 16);
  491 + printf("config for device %d\n",i);
  492 + for(d=0;d<USB_MAX_DEVICE;d++) {
  493 + dev=usb_get_dev_index(d);
  494 + if (dev==NULL)
  495 + break;
  496 + if (dev->devnum==i)
  497 + break;
  498 + }
  499 + if (dev==NULL) {
  500 + printf("*** NO Device avaiable ***\n");
  501 + return 0;
  502 + }
  503 + else {
  504 + usb_display_desc(dev);
  505 + usb_display_config(dev);
  506 + }
  507 + }
  508 + return 0;
  509 + }
  510 +#ifdef CONFIG_USB_STORAGE
  511 + if (strncmp(argv[1],"scan",4) == 0) {
  512 + printf("Scan for storage device:\n");
  513 + usb_stor_curr_dev=usb_stor_scan(1);
  514 + if (usb_stor_curr_dev==-1) {
  515 + printf("No device found. Not initialized?\n");
  516 + return 1;
  517 + }
  518 + return 0;
  519 + }
  520 + if (strncmp(argv[1],"part",4) == 0) {
  521 + int devno, ok;
  522 + for (ok=0, devno=0; devno<USB_MAX_STOR_DEV; ++devno) {
  523 + stor_dev=usb_stor_get_dev(devno);
  524 + if (stor_dev->type!=DEV_TYPE_UNKNOWN) {
  525 + ok++;
  526 + if (devno)
  527 + printf("\n");
  528 + printf("print_part of %x\n",devno);
  529 + print_part(stor_dev);
  530 + }
  531 + }
  532 + if (!ok) {
  533 + printf("\nno USB devices available\n");
  534 + return 1;
  535 + }
  536 + return 0;
  537 + }
  538 + if (strcmp(argv[1],"read") == 0) {
  539 + if (usb_stor_curr_dev<0) {
  540 + printf("no current device selected\n");
  541 + return 1;
  542 + }
  543 + if (argc==5) {
  544 + unsigned long addr = simple_strtoul(argv[2], NULL, 16);
  545 + unsigned long blk = simple_strtoul(argv[3], NULL, 16);
  546 + unsigned long cnt = simple_strtoul(argv[4], NULL, 16);
  547 + unsigned long n;
  548 + printf ("\nUSB read: device %d block # %ld, count %ld ... ",
  549 + usb_stor_curr_dev, blk, cnt);
  550 + stor_dev=usb_stor_get_dev(usb_stor_curr_dev);
  551 + n = stor_dev->block_read(usb_stor_curr_dev, blk, cnt, (ulong *)addr);
  552 + printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
  553 + if (n==cnt)
  554 + return 0;
  555 + return 1;
  556 + }
  557 + }
  558 + if (strcmp(argv[1],"dev") == 0) {
  559 + if (argc==3) {
  560 + int dev = (int)simple_strtoul(argv[2], NULL, 10);
  561 + printf ("\nUSB device %d: ", dev);
  562 + if (dev >= USB_MAX_STOR_DEV) {
  563 + printf("unknown device\n");
  564 + return 1;
  565 + }
  566 + printf ("\n Device %d: ", dev);
  567 + stor_dev=usb_stor_get_dev(dev);
  568 + dev_print(stor_dev);
  569 + if (stor_dev->type == DEV_TYPE_UNKNOWN) {
  570 + return 1;
  571 + }
  572 + usb_stor_curr_dev = dev;
  573 + printf("... is now current device\n");
  574 + return 0;
  575 + }
  576 + else {
  577 + printf ("\nUSB device %d: ", usb_stor_curr_dev);
  578 + stor_dev=usb_stor_get_dev(usb_stor_curr_dev);
  579 + dev_print(stor_dev);
  580 + if (stor_dev->type == DEV_TYPE_UNKNOWN) {
  581 + return 1;
  582 + }
  583 + return 0;
  584 + }
  585 + return 0;
  586 + }
  587 +#endif /* CONFIG_USB_STORAGE */
  588 + printf ("Usage:\n%s\n", cmdtp->usage);
  589 + return 1;
  590 +}
  591 +
  592 +
  593 +#endif /* (CONFIG_COMMANDS & CFG_CMD_USB) */