Skip to content
Snippets Groups Projects
cmd_ide.c 50.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Wolfgang Denk's avatar
    Wolfgang Denk committed
    /*
     * atapi_read:
     * we transfer only one block per command, since the multiple DRQ per
     * command is not yet implemented
     */
    #define ATAPI_READ_MAX_BYTES	2048	/* we read max 2kbytes */
    #define ATAPI_READ_BLOCK_SIZE	2048	/* assuming CD part */
    
    #define ATAPI_READ_MAX_BLOCK	(ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    ulong atapi_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer)
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    	ulong n = 0;
    
    	unsigned char ccb[12];	/* Command descriptor block */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ulong cnt;
    
    
    	debug("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",
    	      device, blknr, blkcnt, (ulong) buffer);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	do {
    
    		if (blkcnt > ATAPI_READ_MAX_BLOCK)
    			cnt = ATAPI_READ_MAX_BLOCK;
    		else
    			cnt = blkcnt;
    
    		ccb[0] = ATAPI_CMD_READ_12;
    		ccb[1] = 0;	/* reserved */
    		ccb[2] = (unsigned char) (blknr >> 24) & 0xFF;	/* MSB Block */
    		ccb[3] = (unsigned char) (blknr >> 16) & 0xFF;	/*  */
    		ccb[4] = (unsigned char) (blknr >> 8) & 0xFF;
    		ccb[5] = (unsigned char) blknr & 0xFF;	/* LSB Block */
    		ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */
    		ccb[7] = (unsigned char) (cnt >> 16) & 0xFF;
    		ccb[8] = (unsigned char) (cnt >> 8) & 0xFF;
    		ccb[9] = (unsigned char) cnt & 0xFF;	/* LSB Block */
    		ccb[10] = 0;	/* reserved */
    		ccb[11] = 0;	/* reserved */
    
    		if (atapi_issue_autoreq(device, ccb, 12,
    					(unsigned char *) buffer,
    					cnt * ATAPI_READ_BLOCK_SIZE)
    		    == 0xFF) {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    			return (n);
    		}
    
    		n += cnt;
    		blkcnt -= cnt;
    		blknr += cnt;
    		buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	} while (blkcnt > 0);
    	return (n);
    }
    
    /* ------------------------------------------------------------------------- */
    
    #endif /* CONFIG_ATAPI */
    
    
    U_BOOT_CMD(ide, 5, 1, do_ide,
    	   "IDE sub-system",
    	   "reset - reset IDE controller\n"
    	   "ide info  - show available IDE devices\n"
    	   "ide device [dev] - show or set current device\n"
    	   "ide part [dev] - print partition table of one or all IDE devices\n"
    	   "ide read  addr blk# cnt\n"
    	   "ide write addr blk# cnt - read/write `cnt'"
    	   " blocks starting at block `blk#'\n"
    	   "    to/from memory address `addr'");
    
    U_BOOT_CMD(diskboot, 3, 1, do_diskboot,
    	   "boot from IDE device", "loadAddr dev:part");