Merge git://git.denx.de/u-boot-dm

This commit is contained in:
Tom Rini 2016-05-17 13:58:27 -04:00
commit 4b6e1fda10
136 changed files with 5426 additions and 2756 deletions

4
README
View file

@ -1066,7 +1066,7 @@ The following options need to be configured:
CONFIG_CMD_RUN run command in env variable
CONFIG_CMD_SANDBOX * sb command to access sandbox features
CONFIG_CMD_SAVES * save S record dump
CONFIG_CMD_SCSI * SCSI Support
CONFIG_SCSI * SCSI Support
CONFIG_CMD_SDRAM * print SDRAM configuration information
(requires CONFIG_CMD_I2C)
CONFIG_CMD_SETGETDCR Support for DCR Register access
@ -1254,7 +1254,7 @@ The following options need to be configured:
CONFIG_MTD_PARTITIONS Memory Technology Device partition table.
If IDE or SCSI support is enabled (CONFIG_CMD_IDE or
CONFIG_CMD_SCSI) you must configure support for at
CONFIG_SCSI) you must configure support for at
least one non-MTD partition type as well.
- IDE Reset method:

View file

@ -67,7 +67,7 @@ void dev_stor_init(void)
specs[ENUM_SATA].type = DEV_TYP_STOR | DT_STOR_SATA;
specs[ENUM_SATA].name = "sata";
#endif
#if defined(CONFIG_CMD_SCSI)
#if defined(CONFIG_SCSI)
specs[ENUM_SCSI].max_dev = CONFIG_SYS_SCSI_MAX_DEVICE;
specs[ENUM_SCSI].enum_started = 0;
specs[ENUM_SCSI].enum_ended = 0;

View file

@ -42,11 +42,11 @@
};
soft-spi {
compatible = "u-boot,soft-spi";
cs-gpio = <&gpy4 3 0>;
sclk-gpio = <&gpy3 1 0>;
mosi-gpio = <&gpy3 3 0>;
miso-gpio = <&gpy3 0 0>;
compatible = "spi-gpio";
cs-gpios = <&gpy4 3 0>;
gpio-sck = <&gpy3 1 0>;
gpio-mosi = <&gpy3 3 0>;
gpio-miso = <&gpy3 0 0>;
spi-delay-us = <1>;
#address-cells = <1>;
#size-cells = <0>;

View file

@ -40,10 +40,6 @@
nvidia,panel = <&lcd_panel>;
};
};
dc@54240000 {
status = "disabled";
};
};
/* This is not used in U-Boot, but is expected to be in kernel .dts */

View file

@ -82,7 +82,7 @@
/* SATA */
#define AHCI_BASE_ADDR (CONFIG_SYS_IMMR + 0x02200000)
#define CONFIG_BOARD_LATE_INIT
#define CONFIG_CMD_SCSI
#define CONFIG_SCSI
#define CONFIG_LIBATA
#define CONFIG_SCSI_AHCI
#define CONFIG_SCSI_AHCI_PLAT

View file

@ -372,14 +372,29 @@ _start:
move.l %d0, (%a1)
move.l %d0, (%a2)
/* set stackpointer to end of internal ram to get some stackspace for
the first c-code */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
move.l #__got_start, %a5 /* put relocation table address to a5 */
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
bsr board_init_f_alloc_reserve
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
bsr board_init_f_init_reserve
bsr cpu_init_f /* run low-level CPU init code (from flash) */
clr.l %sp@-
bsr board_init_f /* run low-level board init code (from flash) */
/* board_init_f() does not return */

View file

@ -134,17 +134,34 @@ _start:
move.l %d0, (%a1)
move.l %d0, (%a2)
/* set stackpointer to end of internal ram to get some stackspace for the
first c-code */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
move.l #__got_start, %a5 /* put relocation table address to a5 */
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
move.l #board_init_f_alloc_reserve, %a1
jsr (%a1)
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
move.l #board_init_f_init_reserve, %a1
jsr (%a1)
/* run low-level CPU init code (from flash) */
move.l #cpu_init_f, %a1
jsr (%a1)
/* run low-level board init code (from flash) */
clr.l %sp@-
move.l #board_init_f, %a1
jsr (%a1)

View file

@ -192,16 +192,34 @@ _after_flashbar_copy:
move.l %d0, (%a1)
move.l %d0, (%a2)
/* set stackpointer to end of internal ram to get some stackspace for the first c-code */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
move.l #__got_start, %a5 /* put relocation table address to a5 */
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
move.l #board_init_f_alloc_reserve, %a1
jsr (%a1)
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
move.l #board_init_f_init_reserve, %a1
jsr (%a1)
/* run low-level CPU init code (from flash) */
move.l #cpu_init_f, %a1
jsr (%a1)
/* run low-level board init code (from flash) */
clr.l %sp@-
move.l #board_init_f, %a1
jsr (%a1)

View file

@ -142,7 +142,7 @@ int cpu_init_r(void)
return 0;
}
void uart_port_conf(void)
void uart_port_conf(int port)
{
}

View file

@ -126,21 +126,32 @@ _start:
move.l %d0, (%a1)
move.l %d0, (%a2)
/*
* set stackpointer to internal sram end - 80
* (global data struct size + some bytes)
* get some stackspace for the first c-code,
*/
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
bsr board_init_f_alloc_reserve
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
bsr board_init_f_init_reserve
/* run low-level CPU init code (from flash) */
bsr cpu_init_f
/* run low-level board init code (from flash) */
clr.l %sp@-
bsr board_init_f
/* board_init_f() does not return */

View file

@ -148,17 +148,34 @@ _start:
move.l %d0, (%a1)
move.l %d0, (%a2)
/* set stackpointer to end of internal ram to get some stackspace for the
first c-code */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
move.l #__got_start, %a5 /* put relocation table address to a5 */
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
move.l #board_init_f_alloc_reserve, %a1
jsr (%a1)
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
move.l #board_init_f_init_reserve, %a1
jsr (%a1)
/* run low-level CPU init code (from flash) */
move.l #cpu_init_f, %a1
jsr (%a1)
/* run low-level board init code (from flash) */
clr.l %sp@-
move.l #board_init_f, %a1
jsr (%a1)

View file

@ -657,17 +657,34 @@ _start:
movec %d0, %RAMBAR1
#endif
/* set stackpointer to end of internal ram to get some stackspace for
the first c-code */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
move.l #__got_start, %a5 /* put relocation table address to a5 */
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
move.l #board_init_f_alloc_reserve, %a1
jsr (%a1)
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
move.l #board_init_f_init_reserve, %a1
jsr (%a1)
/* run low-level CPU init code (from flash) */
move.l #cpu_init_f, %a1
jsr (%a1)
/* run low-level board init code (from flash) */
clr.l %sp@-
move.l #board_init_f, %a1
jsr (%a1)

View file

@ -141,14 +141,29 @@ _start:
move.l %d0, (%a1)
move.l %d0, (%a2)
/* set stackpointer to end of internal ram to get some stackspace for the
first c-code */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
clr.l %sp@-
/* put relocation table address to a5 */
move.l #__got_start, %a5
move.l #__got_start, %a5 /* put relocation table address to a5 */
/* setup stack initially on top of internal static ram */
move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
/*
* if configured, malloc_f arena will be reserved first,
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
bsr board_init_f_alloc_reserve
/* update stack and frame-pointers */
move.l %d0, %sp
move.l %sp, %fp
/* initialize reserved area */
move.l %d0, -(%sp)
bsr board_init_f_init_reserve
jbsr cpu_init_f /* run low-level CPU init code (from flash) */
clr.l %sp@-
jbsr board_init_f /* run low-level board init code (from flash) */
/* board_init_f() does not return */

View file

@ -7,8 +7,6 @@
#ifndef _ASM_CONFIG_H_
#define _ASM_CONFIG_H_
#define CONFIG_SYS_GENERIC_GLOBAL_DATA
#define CONFIG_NEEDS_MANUAL_RELOC
#define CONFIG_LMB

View file

@ -56,6 +56,21 @@ void outl(unsigned int value, unsigned int addr);
void outw(unsigned int value, unsigned int addr);
void outb(unsigned int value, unsigned int addr);
static inline void _insw(volatile u16 *port, void *buf, int ns)
{
}
static inline void _outsw(volatile u16 *port, const void *buf, int ns)
{
}
#define insw(port, buf, ns) _insw((u16 *)port, buf, ns)
#define outsw(port, buf, ns) _outsw((u16 *)port, buf, ns)
/* For systemace.c */
#define out16(addr, val)
#define in16(addr) 0
#include <iotrace.h>
#include <asm/types.h>

View file

@ -47,6 +47,9 @@ source "arch/x86/cpu/queensbay/Kconfig"
# architecture-specific options below
config AHCI
default y
config SYS_MALLOC_F_LEN
default 0x800

View file

@ -261,7 +261,7 @@ static const struct udevice_id broadwell_ahci_ids[] = {
U_BOOT_DRIVER(ahci_broadwell_drv) = {
.name = "ahci_broadwell",
.id = UCLASS_DISK,
.id = UCLASS_AHCI,
.of_match = broadwell_ahci_ids,
.ofdata_to_platdata = broadwell_sata_ofdata_to_platdata,
.probe = broadwell_sata_probe,

View file

@ -58,7 +58,7 @@ int cpu_common_init(void)
return -ENODEV;
/* Cause the SATA device to do its early init */
uclass_first_device(UCLASS_DISK, &dev);
uclass_first_device(UCLASS_AHCI, &dev);
return 0;
}

View file

@ -162,7 +162,7 @@ static int bd82x6x_probe(struct udevice *dev)
return 0;
/* Cause the SATA device to do its init */
uclass_first_device(UCLASS_DISK, &dev);
uclass_first_device(UCLASS_AHCI, &dev);
ret = syscon_get_by_driver_data(X86_SYSCON_GMA, &gma_dev);
if (ret)

View file

@ -233,7 +233,7 @@ static const struct udevice_id bd82x6x_ahci_ids[] = {
U_BOOT_DRIVER(ahci_ivybridge_drv) = {
.name = "ahci_ivybridge",
.id = UCLASS_DISK,
.id = UCLASS_AHCI,
.of_match = bd82x6x_ahci_ids,
.probe = bd82x6x_sata_probe,
};

View file

@ -105,7 +105,7 @@ static int load_rescue_image(ulong addr)
/* Detect storage device */
for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
stor_dev = usb_stor_get_dev(devno);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
if (stor_dev->type != DEV_TYPE_UNKNOWN)
break;
}

View file

@ -32,8 +32,8 @@ Changed files:
- include/cmd_bsp.h added PIP405 commands definitions
- include/cmd_condefs.h added Floppy and SCSI support
- include/cmd_disk.h changed to work with block device description
- include/config_LANTEC.h excluded CONFIG_CMD_FDC and CONFIG_CMD_SCSI
- include/config_hymod.h excluded CONFIG_CMD_FDC and CONFIG_CMD_SCSI
- include/config_LANTEC.h excluded CONFIG_CMD_FDC and CONFIG_SCSI
- include/config_hymod.h excluded CONFIG_CMD_FDC and CONFIG_SCSI
- include/flash.h added INTEL_ID_28F320C3T 0x88C488C4
- include/i2c.h added "defined(CONFIG_PIP405)"
- include/image.h added IH_OS_U_BOOT, IH_TYPE_FIRMWARE
@ -86,7 +86,7 @@ section "Changes".
New Commands:
-------------
CONFIG_CMD_SCSI SCSI Support
CONFIG_SCSI SCSI Support
CONFIG_CMF_FDC Floppy disk support
IDE additions:

View file

@ -4,3 +4,10 @@ S: Maintained
F: board/sandbox/
F: include/configs/sandbox.h
F: configs/sandbox_defconfig
SANDBOX_NOBLK BOARD
M: Simon Glass <sjg@chromium.org>
S: Maintained
F: board/sandbox/
F: include/configs/sandbox.h
F: configs/sandbox_noblk_defconfig

View file

@ -112,7 +112,7 @@ obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
obj-$(CONFIG_SANDBOX) += host.o
obj-$(CONFIG_CMD_SATA) += sata.o
obj-$(CONFIG_CMD_SF) += sf.o
obj-$(CONFIG_CMD_SCSI) += scsi.o
obj-$(CONFIG_SCSI) += scsi.o
obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
obj-$(CONFIG_CMD_SOFTSWITCH) += softswitch.o
@ -155,12 +155,6 @@ obj-$(CONFIG_CMD_PMIC) += pmic.o
obj-$(CONFIG_CMD_REGULATOR) += regulator.o
endif # !CONFIG_SPL_BUILD
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_SPL_SATA_SUPPORT
obj-$(CONFIG_CMD_SCSI) += scsi.o
endif
endif # CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_BLOB) += blob.o
# core command

View file

@ -8,7 +8,7 @@
#include <command.h>
#include <part.h>
#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \
#if defined(CONFIG_CMD_IDE) || defined(CONFIG_SCSI) || \
defined(CONFIG_USB_STORAGE)
int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
char *const argv[])

1352
cmd/ide.c

File diff suppressed because it is too large Load diff

View file

@ -314,12 +314,14 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
}
/* Switch to the RPMB partition */
original_part = mmc->block_dev.hwpart;
if (mmc_select_hwpart(curr_device, MMC_PART_RPMB) != 0)
if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
0)
return CMD_RET_FAILURE;
ret = cp->cmd(cmdtp, flag, argc, argv);
/* Return to original partition */
if (mmc_select_hwpart(curr_device, original_part) != 0)
if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
0)
return CMD_RET_FAILURE;
return ret;
}
@ -346,7 +348,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
printf("\nMMC read: dev # %d, block # %d, count %d ... ",
curr_device, blk, cnt);
n = blk_dread(&mmc->block_dev, blk, cnt, addr);
n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
/* flush cache after read */
flush_cache((ulong)addr, cnt * 512); /* FIXME */
printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
@ -378,7 +380,7 @@ static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
printf("Error: card is write protected!\n");
return CMD_RET_FAILURE;
}
n = blk_dwrite(&mmc->block_dev, blk, cnt, addr);
n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
@ -406,7 +408,7 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
printf("Error: card is write protected!\n");
return CMD_RET_FAILURE;
}
n = blk_derase(&mmc->block_dev, blk, cnt);
n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt);
printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
@ -432,7 +434,7 @@ static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
if (!mmc)
return CMD_RET_FAILURE;
mmc_dev = mmc_get_dev(curr_device);
mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device);
if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
part_print(mmc_dev);
return CMD_RET_SUCCESS;
@ -467,7 +469,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
if (!mmc)
return CMD_RET_FAILURE;
ret = mmc_select_hwpart(dev, part);
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
printf("switch to partitions #%d, %s\n",
part, (!ret) ? "OK" : "ERROR");
if (ret)
@ -478,7 +480,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
printf("mmc%d is current device\n", curr_device);
else
printf("mmc%d(part %d) is current device\n",
curr_device, mmc->block_dev.hwpart);
curr_device, mmc_get_blk_desc(mmc)->hwpart);
return CMD_RET_SUCCESS;
}

View file

@ -16,70 +16,6 @@
#include <sata.h>
static int sata_curr_device = -1;
struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *dst)
{
return sata_read(block_dev->devnum, start, blkcnt, dst);
}
static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
return sata_write(block_dev->devnum, start, blkcnt, buffer);
}
int __sata_initialize(void)
{
int rc;
int i;
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
sata_dev_desc[i].if_type = IF_TYPE_SATA;
sata_dev_desc[i].devnum = i;
sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
sata_dev_desc[i].lba = 0;
sata_dev_desc[i].blksz = 512;
sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
sata_dev_desc[i].block_read = sata_bread;
sata_dev_desc[i].block_write = sata_bwrite;
rc = init_sata(i);
if (!rc) {
rc = scan_sata(i);
if (!rc && (sata_dev_desc[i].lba > 0) &&
(sata_dev_desc[i].blksz > 0))
part_init(&sata_dev_desc[i]);
}
}
sata_curr_device = 0;
return rc;
}
int sata_initialize(void) __attribute__((weak,alias("__sata_initialize")));
__weak int __sata_stop(void)
{
int i, err = 0;
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
err |= reset_sata(i);
if (err)
printf("Could not reset some SATA devices\n");
return err;
}
int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
#ifdef CONFIG_PARTITIONS
struct blk_desc *sata_get_dev(int dev)
{
return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
}
#endif
static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
@ -105,69 +41,40 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
case 1:
return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1],"inf", 3) == 0) {
int i;
putc('\n');
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; ++i) {
if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN)
continue;
printf ("SATA device %d: ", i);
dev_print(&sata_dev_desc[i]);
if (strncmp(argv[1], "inf", 3) == 0) {
blk_list_devices(IF_TYPE_SATA);
return 0;
} else if (strncmp(argv[1], "dev", 3) == 0) {
if (blk_print_device_num(IF_TYPE_SATA,
sata_curr_device)) {
printf("\nno SATA devices available\n");
return CMD_RET_FAILURE;
}
return 0;
} else if (strncmp(argv[1],"dev", 3) == 0) {
if ((sata_curr_device < 0) || (sata_curr_device >= CONFIG_SYS_SATA_MAX_DEVICE)) {
} else if (strncmp(argv[1], "part", 4) == 0) {
if (blk_list_part(IF_TYPE_SATA))
puts("\nno SATA devices available\n");
return 1;
}
printf("\nSATA device %d: ", sata_curr_device);
dev_print(&sata_dev_desc[sata_curr_device]);
return 0;
} else if (strncmp(argv[1],"part",4) == 0) {
int dev, ok;
for (ok = 0, dev = 0; dev < CONFIG_SYS_SATA_MAX_DEVICE; ++dev) {
if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
++ok;
if (dev)
putc ('\n');
part_print(&sata_dev_desc[dev]);
}
}
if (!ok) {
puts("\nno SATA devices available\n");
rc ++;
}
return rc;
}
return CMD_RET_USAGE;
case 3:
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
printf("\nSATA device %d: ", dev);
if (dev >= CONFIG_SYS_SATA_MAX_DEVICE) {
puts ("unknown device\n");
return 1;
if (!blk_show_device(IF_TYPE_SATA, dev)) {
sata_curr_device = dev;
printf("... is now current device\n");
} else {
return CMD_RET_FAILURE;
}
dev_print(&sata_dev_desc[dev]);
if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
return 1;
sata_curr_device = dev;
puts("... is now current device\n");
return 0;
} else if (strncmp(argv[1], "part", 4) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
part_print(&sata_dev_desc[dev]);
} else {
printf("\nSATA device %d not available\n", dev);
rc = 1;
if (blk_print_part_devnum(IF_TYPE_SATA, dev)) {
printf("\nSATA device %d not available\n",
dev);
return CMD_RET_FAILURE;
}
return rc;
}
@ -183,11 +90,8 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
printf("\nSATA read: device %d block # %ld, count %ld ... ",
sata_curr_device, blk, cnt);
n = blk_dread(&sata_dev_desc[sata_curr_device],
blk, cnt, (u32 *)addr);
/* flush cache after read */
flush_cache(addr, cnt * sata_dev_desc[sata_curr_device].blksz);
n = blk_read_devnum(IF_TYPE_SATA, sata_curr_device, blk,
cnt, (ulong *)addr);
printf("%ld blocks read: %s\n",
n, (n==cnt) ? "OK" : "ERROR");
@ -202,8 +106,8 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
printf("\nSATA write: device %d block # %ld, count %ld ... ",
sata_curr_device, blk, cnt);
n = blk_dwrite(&sata_dev_desc[sata_curr_device],
blk, cnt, (u32 *)addr);
n = blk_write_devnum(IF_TYPE_SATA, sata_curr_device,
blk, cnt, (ulong *)addr);
printf("%ld blocks written: %s\n",
n, (n == cnt) ? "OK" : "ERROR");

View file

@ -10,361 +10,108 @@
*/
#include <common.h>
#include <command.h>
#include <inttypes.h>
#include <asm/processor.h>
#include <scsi.h>
#include <image.h>
#include <pci.h>
#ifdef CONFIG_SCSI_DEV_LIST
#define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
#else
#ifdef CONFIG_SCSI_SYM53C8XX
#define SCSI_VEND_ID 0x1000
#ifndef CONFIG_SCSI_DEV_ID
#define SCSI_DEV_ID 0x0001
#else
#define SCSI_DEV_ID CONFIG_SCSI_DEV_ID
#endif
#elif defined CONFIG_SATA_ULI5288
#define SCSI_VEND_ID 0x10b9
#define SCSI_DEV_ID 0x5288
#elif !defined(CONFIG_SCSI_AHCI_PLAT)
#error no scsi device defined
#endif
#define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
#endif
#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
#endif
static ccb tempccb; /* temporary scsi command buffer */
static unsigned char tempbuff[512]; /* temporary data buffer */
static int scsi_max_devs; /* number of highest available scsi device */
static int scsi_curr_dev; /* current device */
static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
/********************************************************************************
* forward declerations of some Setup Routines
*/
void scsi_setup_test_unit_ready(ccb * pccb);
void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks);
void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks);
void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks);
static void scsi_setup_write_ext(ccb *pccb, lbaint_t start,
unsigned short blocks);
void scsi_setup_inquiry(ccb * pccb);
void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
unsigned long *blksz);
static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
lbaint_t blkcnt, void *buffer);
static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
lbaint_t blkcnt, const void *buffer);
/*********************************************************************************
* (re)-scan the scsi bus and reports scsi device info
* to the user if mode = 1
*/
void scsi_scan(int mode)
{
unsigned char i,perq,modi,lun;
lbaint_t capacity;
unsigned long blksz;
ccb* pccb=(ccb *)&tempccb;
if(mode==1) {
printf("scanning bus for devices...\n");
}
for(i=0;i<CONFIG_SYS_SCSI_MAX_DEVICE;i++) {
scsi_dev_desc[i].target=0xff;
scsi_dev_desc[i].lun=0xff;
scsi_dev_desc[i].lba=0;
scsi_dev_desc[i].blksz=0;
scsi_dev_desc[i].log2blksz =
LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
scsi_dev_desc[i].vendor[0]=0;
scsi_dev_desc[i].product[0]=0;
scsi_dev_desc[i].revision[0]=0;
scsi_dev_desc[i].removable = false;
scsi_dev_desc[i].if_type=IF_TYPE_SCSI;
scsi_dev_desc[i].devnum = i;
scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
scsi_dev_desc[i].block_read=scsi_read;
scsi_dev_desc[i].block_write = scsi_write;
}
scsi_max_devs=0;
for(i=0;i<CONFIG_SYS_SCSI_MAX_SCSI_ID;i++) {
pccb->target=i;
for(lun=0;lun<CONFIG_SYS_SCSI_MAX_LUN;lun++) {
pccb->lun=lun;
pccb->pdata=(unsigned char *)&tempbuff;
pccb->datalen=512;
scsi_setup_inquiry(pccb);
if (scsi_exec(pccb) != true) {
if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
debug ("Selection timeout ID %d\n",pccb->target);
continue; /* selection timeout => assuming no device present */
}
scsi_print_error(pccb);
continue;
}
perq=tempbuff[0];
modi=tempbuff[1];
if((perq & 0x1f)==0x1f) {
continue; /* skip unknown devices */
}
if((modi&0x80)==0x80) /* drive is removable */
scsi_dev_desc[scsi_max_devs].removable=true;
/* get info for this device */
scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0],
&tempbuff[8], 8);
scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].product[0],
&tempbuff[16], 16);
scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].revision[0],
&tempbuff[32], 4);
scsi_dev_desc[scsi_max_devs].target=pccb->target;
scsi_dev_desc[scsi_max_devs].lun=pccb->lun;
pccb->datalen=0;
scsi_setup_test_unit_ready(pccb);
if (scsi_exec(pccb) != true) {
if (scsi_dev_desc[scsi_max_devs].removable == true) {
scsi_dev_desc[scsi_max_devs].type=perq;
goto removable;
}
scsi_print_error(pccb);
continue;
}
if (scsi_read_capacity(pccb, &capacity, &blksz)) {
scsi_print_error(pccb);
continue;
}
scsi_dev_desc[scsi_max_devs].lba=capacity;
scsi_dev_desc[scsi_max_devs].blksz=blksz;
scsi_dev_desc[scsi_max_devs].log2blksz =
LOG2(scsi_dev_desc[scsi_max_devs].blksz);
scsi_dev_desc[scsi_max_devs].type=perq;
part_init(&scsi_dev_desc[scsi_max_devs]);
removable:
if(mode==1) {
printf (" Device %d: ", scsi_max_devs);
dev_print(&scsi_dev_desc[scsi_max_devs]);
} /* if mode */
scsi_max_devs++;
} /* next LUN */
}
if(scsi_max_devs>0)
scsi_curr_dev=0;
else
scsi_curr_dev = -1;
printf("Found %d device(s).\n", scsi_max_devs);
#ifndef CONFIG_SPL_BUILD
setenv_ulong("scsidevs", scsi_max_devs);
#endif
}
int scsi_get_disk_count(void)
{
return scsi_max_devs;
}
#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
void scsi_init(void)
{
int busdevfunc = -1;
int i;
/*
* Find a device from the list, this driver will support a single
* controller.
*/
for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
/* get PCI Device ID */
#ifdef CONFIG_DM_PCI
struct udevice *dev;
int ret;
ret = dm_pci_find_device(scsi_device_list[i].vendor,
scsi_device_list[i].device, 0, &dev);
if (!ret) {
busdevfunc = dm_pci_get_bdf(dev);
break;
}
#else
busdevfunc = pci_find_device(scsi_device_list[i].vendor,
scsi_device_list[i].device,
0);
#endif
if (busdevfunc != -1)
break;
}
if (busdevfunc == -1) {
printf("Error: SCSI Controller(s) ");
for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
printf("%04X:%04X ",
scsi_device_list[i].vendor,
scsi_device_list[i].device);
}
printf("not found\n");
return;
}
#ifdef DEBUG
else {
printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
scsi_device_list[i].vendor,
scsi_device_list[i].device,
(busdevfunc >> 16) & 0xFF,
(busdevfunc >> 11) & 0x1F,
(busdevfunc >> 8) & 0x7);
}
#endif
bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
scsi_low_level_init(busdevfunc);
scsi_scan(1);
bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
}
#endif
#ifdef CONFIG_PARTITIONS
struct blk_desc *scsi_get_dev(int dev)
{
return (dev < CONFIG_SYS_SCSI_MAX_DEVICE) ? &scsi_dev_desc[dev] : NULL;
}
#endif
#ifndef CONFIG_SPL_BUILD
/******************************************************************************
/*
* scsi boot command intepreter. Derived from diskboot
*/
int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int do_scsiboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
return common_diskboot(cmdtp, "scsi", argc, argv);
}
/*********************************************************************************
/*
* scsi command intepreter
*/
int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
switch (argc) {
case 0:
case 1:
return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1],"res",3) == 0) {
printf("\nReset SCSI\n");
scsi_bus_reset();
scsi_scan(1);
return 0;
if (strncmp(argv[1], "res", 3) == 0) {
printf("\nReset SCSI\n");
scsi_bus_reset();
scsi_scan(1);
return 0;
}
if (strncmp(argv[1], "inf", 3) == 0) {
blk_list_devices(IF_TYPE_SCSI);
return 0;
}
if (strncmp(argv[1], "dev", 3) == 0) {
if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) {
printf("\nno SCSI devices available\n");
return CMD_RET_FAILURE;
}
if (strncmp(argv[1],"inf",3) == 0) {
int i;
for (i=0; i<CONFIG_SYS_SCSI_MAX_DEVICE; ++i) {
if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN)
continue; /* list only known devices */
printf ("SCSI dev. %d: ", i);
dev_print(&scsi_dev_desc[i]);
}
return 0;
}
if (strncmp(argv[1],"dev",3) == 0) {
if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CONFIG_SYS_SCSI_MAX_DEVICE)) {
printf("\nno SCSI devices available\n");
return 1;
}
printf ("\n Device %d: ", scsi_curr_dev);
dev_print(&scsi_dev_desc[scsi_curr_dev]);
return 0;
}
if (strncmp(argv[1],"scan",4) == 0) {
scsi_scan(1);
return 0;
}
if (strncmp(argv[1],"part",4) == 0) {
int dev, ok;
for (ok=0, dev=0; dev<CONFIG_SYS_SCSI_MAX_DEVICE; ++dev) {
if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) {
ok++;
if (dev)
printf("\n");
debug ("print_part of %x\n",dev);
part_print(&scsi_dev_desc[dev]);
}
}
if (!ok)
printf("\nno SCSI devices available\n");
return 1;
}
return CMD_RET_USAGE;
return 0;
}
if (strncmp(argv[1], "scan", 4) == 0) {
scsi_scan(1);
return 0;
}
if (strncmp(argv[1], "part", 4) == 0) {
if (blk_list_part(IF_TYPE_SCSI))
printf("\nno SCSI devices available\n");
return 0;
}
return CMD_RET_USAGE;
case 3:
if (strncmp(argv[1],"dev",3) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
printf ("\nSCSI device %d: ", dev);
if (dev >= CONFIG_SYS_SCSI_MAX_DEVICE) {
printf("unknown device\n");
return 1;
}
printf ("\n Device %d: ", dev);
dev_print(&scsi_dev_desc[dev]);
if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
return 1;
}
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
if (!blk_show_device(IF_TYPE_SCSI, dev)) {
scsi_curr_dev = dev;
printf("... is now current device\n");
return 0;
} else {
return CMD_RET_FAILURE;
}
if (strncmp(argv[1],"part",4) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) {
part_print(&scsi_dev_desc[dev]);
}
else {
printf ("\nSCSI device %d not available\n", dev);
}
return 1;
}
return CMD_RET_USAGE;
default:
/* at least 4 args */
if (strcmp(argv[1],"read") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong blk = simple_strtoul(argv[3], NULL, 16);
ulong cnt = simple_strtoul(argv[4], NULL, 16);
ulong n;
printf ("\nSCSI read: device %d block # %ld, count %ld ... ",
scsi_curr_dev, blk, cnt);
n = scsi_read(&scsi_dev_desc[scsi_curr_dev],
blk, cnt, (ulong *)addr);
printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
return 0;
} else if (strcmp(argv[1], "write") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong blk = simple_strtoul(argv[3], NULL, 16);
ulong cnt = simple_strtoul(argv[4], NULL, 16);
ulong n;
printf("\nSCSI write: device %d block # %ld, "
"count %ld ... ",
scsi_curr_dev, blk, cnt);
n = scsi_write(&scsi_dev_desc[scsi_curr_dev],
blk, cnt, (ulong *)addr);
printf("%ld blocks written: %s\n", n,
(n == cnt) ? "OK" : "ERROR");
return 0;
return 0;
}
if (strncmp(argv[1], "part", 4) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
if (blk_print_part_devnum(IF_TYPE_SCSI, dev)) {
printf("\nSCSI device %d not available\n",
dev);
return CMD_RET_FAILURE;
}
return 0;
}
return CMD_RET_USAGE;
default:
/* at least 4 args */
if (strcmp(argv[1], "read") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong blk = simple_strtoul(argv[3], NULL, 16);
ulong cnt = simple_strtoul(argv[4], NULL, 16);
ulong n;
printf("\nSCSI read: device %d block # %ld, count %ld ... ",
scsi_curr_dev, blk, cnt);
n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk,
cnt, (ulong *)addr);
printf("%ld blocks read: %s\n", n,
n == cnt ? "OK" : "ERROR");
return 0;
} else if (strcmp(argv[1], "write") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong blk = simple_strtoul(argv[3], NULL, 16);
ulong cnt = simple_strtoul(argv[4], NULL, 16);
ulong n;
printf("\nSCSI write: device %d block # %ld, count %ld ... ",
scsi_curr_dev, blk, cnt);
n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk,
cnt, (ulong *)addr);
printf("%ld blocks written: %s\n", n,
n == cnt ? "OK" : "ERROR");
return 0;
}
} /* switch */
return CMD_RET_USAGE;
}
@ -388,347 +135,3 @@ U_BOOT_CMD(
"boot from SCSI device",
"loadAddr dev:part"
);
#endif
/****************************************************************************************
* scsi_read
*/
/* almost the maximum amount of the scsi_ext command.. */
#define SCSI_MAX_READ_BLK 0xFFFF
#define SCSI_LBA48_READ 0xFFFFFFF
static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
lbaint_t blkcnt, void *buffer)
{
int device = block_dev->devnum;
lbaint_t start, blks;
uintptr_t buf_addr;
unsigned short smallblks = 0;
ccb* pccb=(ccb *)&tempccb;
device&=0xff;
/* Setup device
*/
pccb->target=scsi_dev_desc[device].target;
pccb->lun=scsi_dev_desc[device].lun;
buf_addr=(unsigned long)buffer;
start=blknr;
blks=blkcnt;
debug("\nscsi_read: dev %d startblk " LBAF
", blccnt " LBAF " buffer %lx\n",
device, start, blks, (unsigned long)buffer);
do {
pccb->pdata=(unsigned char *)buf_addr;
#ifdef CONFIG_SYS_64BIT_LBA
if (start > SCSI_LBA48_READ) {
unsigned long blocks;
blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
pccb->datalen = scsi_dev_desc[device].blksz * blocks;
scsi_setup_read16(pccb, start, blocks);
start += blocks;
blks -= blocks;
} else
#endif
if (blks > SCSI_MAX_READ_BLK) {
pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK;
smallblks=SCSI_MAX_READ_BLK;
scsi_setup_read_ext(pccb,start,smallblks);
start+=SCSI_MAX_READ_BLK;
blks-=SCSI_MAX_READ_BLK;
}
else {
pccb->datalen=scsi_dev_desc[device].blksz * blks;
smallblks=(unsigned short) blks;
scsi_setup_read_ext(pccb,start,smallblks);
start+=blks;
blks=0;
}
debug("scsi_read_ext: startblk " LBAF
", blccnt %x buffer %" PRIXPTR "\n",
start, smallblks, buf_addr);
if (scsi_exec(pccb) != true) {
scsi_print_error(pccb);
blkcnt-=blks;
break;
}
buf_addr+=pccb->datalen;
} while(blks!=0);
debug("scsi_read_ext: end startblk " LBAF
", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
return(blkcnt);
}
/*******************************************************************************
* scsi_write
*/
/* Almost the maximum amount of the scsi_ext command.. */
#define SCSI_MAX_WRITE_BLK 0xFFFF
static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
lbaint_t blkcnt, const void *buffer)
{
int device = block_dev->devnum;
lbaint_t start, blks;
uintptr_t buf_addr;
unsigned short smallblks;
ccb* pccb = (ccb *)&tempccb;
device &= 0xff;
/* Setup device
*/
pccb->target = scsi_dev_desc[device].target;
pccb->lun = scsi_dev_desc[device].lun;
buf_addr = (unsigned long)buffer;
start = blknr;
blks = blkcnt;
debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
__func__, device, start, blks, (unsigned long)buffer);
do {
pccb->pdata = (unsigned char *)buf_addr;
if (blks > SCSI_MAX_WRITE_BLK) {
pccb->datalen = (scsi_dev_desc[device].blksz *
SCSI_MAX_WRITE_BLK);
smallblks = SCSI_MAX_WRITE_BLK;
scsi_setup_write_ext(pccb, start, smallblks);
start += SCSI_MAX_WRITE_BLK;
blks -= SCSI_MAX_WRITE_BLK;
} else {
pccb->datalen = scsi_dev_desc[device].blksz * blks;
smallblks = (unsigned short)blks;
scsi_setup_write_ext(pccb, start, smallblks);
start += blks;
blks = 0;
}
debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
__func__, start, smallblks, buf_addr);
if (scsi_exec(pccb) != true) {
scsi_print_error(pccb);
blkcnt -= blks;
break;
}
buf_addr += pccb->datalen;
} while (blks != 0);
debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
__func__, start, smallblks, buf_addr);
return blkcnt;
}
/* copy src to dest, skipping leading and trailing blanks
* and null terminate the string
*/
void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
{
int start,end;
start=0;
while(start<len) {
if(src[start]!=' ')
break;
start++;
}
end=len-1;
while(end>start) {
if(src[end]!=' ')
break;
end--;
}
for( ; start<=end; start++) {
*dest++=src[start];
}
*dest='\0';
}
/* Trim trailing blanks, and NUL-terminate string
*/
void scsi_trim_trail (unsigned char *str, unsigned int len)
{
unsigned char *p = str + len - 1;
while (len-- > 0) {
*p-- = '\0';
if (*p != ' ') {
return;
}
}
}
int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
{
*capacity = 0;
memset(pccb->cmd, 0, sizeof(pccb->cmd));
pccb->cmd[0] = SCSI_RD_CAPAC10;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmdlen = 10;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
pccb->datalen = 8;
if (scsi_exec(pccb) != true)
return 1;
*capacity = ((lbaint_t)pccb->pdata[0] << 24) |
((lbaint_t)pccb->pdata[1] << 16) |
((lbaint_t)pccb->pdata[2] << 8) |
((lbaint_t)pccb->pdata[3]);
if (*capacity != 0xffffffff) {
/* Read capacity (10) was sufficient for this drive. */
*blksz = ((unsigned long)pccb->pdata[4] << 24) |
((unsigned long)pccb->pdata[5] << 16) |
((unsigned long)pccb->pdata[6] << 8) |
((unsigned long)pccb->pdata[7]);
return 0;
}
/* Read capacity (10) was insufficient. Use read capacity (16). */
memset(pccb->cmd, 0, sizeof(pccb->cmd));
pccb->cmd[0] = SCSI_RD_CAPAC16;
pccb->cmd[1] = 0x10;
pccb->cmdlen = 16;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
pccb->datalen = 16;
if (scsi_exec(pccb) != true)
return 1;
*capacity = ((uint64_t)pccb->pdata[0] << 56) |
((uint64_t)pccb->pdata[1] << 48) |
((uint64_t)pccb->pdata[2] << 40) |
((uint64_t)pccb->pdata[3] << 32) |
((uint64_t)pccb->pdata[4] << 24) |
((uint64_t)pccb->pdata[5] << 16) |
((uint64_t)pccb->pdata[6] << 8) |
((uint64_t)pccb->pdata[7]);
*blksz = ((uint64_t)pccb->pdata[8] << 56) |
((uint64_t)pccb->pdata[9] << 48) |
((uint64_t)pccb->pdata[10] << 40) |
((uint64_t)pccb->pdata[11] << 32) |
((uint64_t)pccb->pdata[12] << 24) |
((uint64_t)pccb->pdata[13] << 16) |
((uint64_t)pccb->pdata[14] << 8) |
((uint64_t)pccb->pdata[15]);
return 0;
}
/************************************************************************************
* Some setup (fill-in) routines
*/
void scsi_setup_test_unit_ready(ccb * pccb)
{
pccb->cmd[0]=SCSI_TST_U_RDY;
pccb->cmd[1]=pccb->lun<<5;
pccb->cmd[2]=0;
pccb->cmd[3]=0;
pccb->cmd[4]=0;
pccb->cmd[5]=0;
pccb->cmdlen=6;
pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
}
#ifdef CONFIG_SYS_64BIT_LBA
void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks)
{
pccb->cmd[0] = SCSI_READ16;
pccb->cmd[1] = pccb->lun<<5;
pccb->cmd[2] = ((unsigned char) (start >> 56)) & 0xff;
pccb->cmd[3] = ((unsigned char) (start >> 48)) & 0xff;
pccb->cmd[4] = ((unsigned char) (start >> 40)) & 0xff;
pccb->cmd[5] = ((unsigned char) (start >> 32)) & 0xff;
pccb->cmd[6] = ((unsigned char) (start >> 24)) & 0xff;
pccb->cmd[7] = ((unsigned char) (start >> 16)) & 0xff;
pccb->cmd[8] = ((unsigned char) (start >> 8)) & 0xff;
pccb->cmd[9] = ((unsigned char) (start)) & 0xff;
pccb->cmd[10] = 0;
pccb->cmd[11] = ((unsigned char) (blocks >> 24)) & 0xff;
pccb->cmd[12] = ((unsigned char) (blocks >> 16)) & 0xff;
pccb->cmd[13] = ((unsigned char) (blocks >> 8)) & 0xff;
pccb->cmd[14] = (unsigned char) blocks & 0xff;
pccb->cmd[15] = 0;
pccb->cmdlen = 16;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
debug ("scsi_setup_read16: cmd: %02X %02X "
"startblk %02X%02X%02X%02X%02X%02X%02X%02X "
"blccnt %02X%02X%02X%02X\n",
pccb->cmd[0], pccb->cmd[1],
pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
}
#endif
void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks)
{
pccb->cmd[0]=SCSI_READ10;
pccb->cmd[1]=pccb->lun<<5;
pccb->cmd[2]=((unsigned char) (start>>24))&0xff;
pccb->cmd[3]=((unsigned char) (start>>16))&0xff;
pccb->cmd[4]=((unsigned char) (start>>8))&0xff;
pccb->cmd[5]=((unsigned char) (start))&0xff;
pccb->cmd[6]=0;
pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
pccb->cmd[8]=(unsigned char) blocks & 0xff;
pccb->cmd[6]=0;
pccb->cmdlen=10;
pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
debug ("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
pccb->cmd[0],pccb->cmd[1],
pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
pccb->cmd[7],pccb->cmd[8]);
}
void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
{
pccb->cmd[0] = SCSI_WRITE10;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmd[2] = ((unsigned char) (start>>24)) & 0xff;
pccb->cmd[3] = ((unsigned char) (start>>16)) & 0xff;
pccb->cmd[4] = ((unsigned char) (start>>8)) & 0xff;
pccb->cmd[5] = ((unsigned char) (start)) & 0xff;
pccb->cmd[6] = 0;
pccb->cmd[7] = ((unsigned char) (blocks>>8)) & 0xff;
pccb->cmd[8] = (unsigned char)blocks & 0xff;
pccb->cmd[9] = 0;
pccb->cmdlen = 10;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
__func__,
pccb->cmd[0], pccb->cmd[1],
pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
pccb->cmd[7], pccb->cmd[8]);
}
void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks)
{
pccb->cmd[0]=SCSI_READ6;
pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f);
pccb->cmd[2]=((unsigned char) (start>>8))&0xff;
pccb->cmd[3]=((unsigned char) (start))&0xff;
pccb->cmd[4]=(unsigned char) blocks & 0xff;
pccb->cmd[5]=0;
pccb->cmdlen=6;
pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
debug ("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
pccb->cmd[0],pccb->cmd[1],
pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]);
}
void scsi_setup_inquiry(ccb * pccb)
{
pccb->cmd[0]=SCSI_INQUIRY;
pccb->cmd[1]=pccb->lun<<5;
pccb->cmd[2]=0;
pccb->cmd[3]=0;
if(pccb->datalen>255)
pccb->cmd[4]=255;
else
pccb->cmd[4]=(unsigned char)pccb->datalen;
pccb->cmd[5]=0;
pccb->cmdlen=6;
pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
}

View file

@ -723,7 +723,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int devno, ok = 0;
if (argc == 2) {
for (devno = 0; ; ++devno) {
stor_dev = usb_stor_get_dev(devno);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
devno);
if (stor_dev == NULL)
break;
if (stor_dev->type != DEV_TYPE_UNKNOWN) {
@ -736,7 +737,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
} else {
devno = simple_strtoul(argv[2], NULL, 16);
stor_dev = usb_stor_get_dev(devno);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
if (stor_dev != NULL &&
stor_dev->type != DEV_TYPE_UNKNOWN) {
ok++;
@ -762,7 +763,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
unsigned long n;
printf("\nUSB read: device %d block # %ld, count %ld"
" ... ", usb_stor_curr_dev, blk, cnt);
stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
usb_stor_curr_dev);
n = blk_dread(stor_dev, blk, cnt, (ulong *)addr);
printf("%ld blocks read: %s\n", n,
(n == cnt) ? "OK" : "ERROR");
@ -783,7 +785,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
unsigned long n;
printf("\nUSB write: device %d block # %ld, count %ld"
" ... ", usb_stor_curr_dev, blk, cnt);
stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
usb_stor_curr_dev);
n = blk_dwrite(stor_dev, blk, cnt, (ulong *)addr);
printf("%ld blocks write: %s\n", n,
(n == cnt) ? "OK" : "ERROR");
@ -796,7 +799,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc == 3) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
printf("\nUSB device %d: ", dev);
stor_dev = usb_stor_get_dev(dev);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, dev);
if (stor_dev == NULL) {
printf("unknown device\n");
return 1;
@ -810,7 +813,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 0;
} else {
printf("\nUSB device %d: ", usb_stor_curr_dev);
stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
usb_stor_curr_dev);
dev_print(stor_dev);
if (stor_dev->type == DEV_TYPE_UNKNOWN)
return 1;

View file

@ -84,6 +84,8 @@ obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o
obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_CMD_SATA) += sata.o
obj-$(CONFIG_SCSI) += scsi.o
obj-$(CONFIG_UPDATE_TFTP) += update.o
obj-$(CONFIG_DFU_TFTP) += update.o
obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
@ -112,6 +114,9 @@ obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
endif
ifdef CONFIG_SPL_SATA_SUPPORT
obj-$(CONFIG_SCSI) += scsi.o
endif
endif
#environment
obj-y += env_common.o
@ -130,6 +135,7 @@ obj-y += dlmalloc.o
ifdef CONFIG_SYS_MALLOC_F_LEN
obj-y += malloc_simple.o
endif
obj-$(CONFIG_CMD_IDE) += ide.o
obj-y += image.o
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += image-fdt.o

View file

@ -620,7 +620,7 @@ static int initr_ambapp_print(void)
}
#endif
#if defined(CONFIG_CMD_SCSI)
#if defined(CONFIG_SCSI)
static int initr_scsi(void)
{
puts("SCSI: ");
@ -923,7 +923,7 @@ init_fnc_t init_sequence_r[] = {
initr_ambapp_print,
#endif
#endif
#ifdef CONFIG_CMD_SCSI
#ifdef CONFIG_SCSI
INIT_FUNC_WATCHDOG_RESET
initr_scsi,
#endif

View file

@ -86,8 +86,8 @@ static int mmc_set_env_part(struct mmc *mmc)
dev = 0;
#endif
env_mmc_orig_hwpart = mmc->block_dev.hwpart;
ret = mmc_select_hwpart(dev, part);
env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
if (ret)
puts("MMC partition switch failed\n");
@ -119,7 +119,7 @@ static void fini_mmc_for_env(struct mmc *mmc)
#ifdef CONFIG_SPL_BUILD
dev = 0;
#endif
mmc_select_hwpart(dev, env_mmc_orig_hwpart);
blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart);
#endif
}

1231
common/ide.c Normal file

File diff suppressed because it is too large Load diff

115
common/sata.c Normal file
View file

@ -0,0 +1,115 @@
/*
* Copyright (C) 2000-2005, DENX Software Engineering
* Wolfgang Denk <wd@denx.de>
* Copyright (C) Procsys. All rights reserved.
* Mushtaq Khan <mushtaq_k@procsys.com>
* <mushtaqk_921@yahoo.co.in>
* Copyright (C) 2008 Freescale Semiconductor, Inc.
* Dave Liu <daveliu@freescale.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <sata.h>
struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
#ifdef CONFIG_PARTITIONS
struct blk_desc *sata_get_dev(int dev)
{
return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
}
#endif
#ifdef CONFIG_BLK
static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, void *dst)
{
return -ENOSYS;
}
static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
return -ENOSYS;
}
#else
static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *dst)
{
return sata_read(block_dev->devnum, start, blkcnt, dst);
}
static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
return sata_write(block_dev->devnum, start, blkcnt, buffer);
}
#endif
int __sata_initialize(void)
{
int rc;
int i;
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
sata_dev_desc[i].if_type = IF_TYPE_SATA;
sata_dev_desc[i].devnum = i;
sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
sata_dev_desc[i].lba = 0;
sata_dev_desc[i].blksz = 512;
sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
#ifndef CONFIG_BLK
sata_dev_desc[i].block_read = sata_bread;
sata_dev_desc[i].block_write = sata_bwrite;
#endif
rc = init_sata(i);
if (!rc) {
rc = scan_sata(i);
if (!rc && sata_dev_desc[i].lba > 0 &&
sata_dev_desc[i].blksz > 0)
part_init(&sata_dev_desc[i]);
}
}
return rc;
}
int sata_initialize(void) __attribute__((weak, alias("__sata_initialize")));
__weak int __sata_stop(void)
{
int i, err = 0;
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
err |= reset_sata(i);
if (err)
printf("Could not reset some SATA devices\n");
return err;
}
int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
#ifdef CONFIG_BLK
static const struct blk_ops sata_blk_ops = {
.read = sata_bread,
.write = sata_bwrite,
};
U_BOOT_DRIVER(sata_blk) = {
.name = "sata_blk",
.id = UCLASS_BLK,
.ops = &sata_blk_ops,
};
#else
U_BOOT_LEGACY_BLK(sata) = {
.if_typename = "sata",
.if_type = IF_TYPE_SATA,
.max_devs = CONFIG_SYS_SATA_MAX_DEVICE,
.desc = sata_dev_desc,
};
#endif

592
common/scsi.c Normal file
View file

@ -0,0 +1,592 @@
/*
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <inttypes.h>
#include <pci.h>
#include <scsi.h>
#ifdef CONFIG_SCSI_DEV_LIST
#define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
#else
#ifdef CONFIG_SCSI_SYM53C8XX
#define SCSI_VEND_ID 0x1000
#ifndef CONFIG_SCSI_DEV_ID
#define SCSI_DEV_ID 0x0001
#else
#define SCSI_DEV_ID CONFIG_SCSI_DEV_ID
#endif
#elif defined CONFIG_SATA_ULI5288
#define SCSI_VEND_ID 0x10b9
#define SCSI_DEV_ID 0x5288
#elif !defined(CONFIG_SCSI_AHCI_PLAT)
#error no scsi device defined
#endif
#define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
#endif
#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
#endif
static ccb tempccb; /* temporary scsi command buffer */
static unsigned char tempbuff[512]; /* temporary data buffer */
static int scsi_max_devs; /* number of highest available scsi device */
static int scsi_curr_dev; /* current device */
static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
/* almost the maximum amount of the scsi_ext command.. */
#define SCSI_MAX_READ_BLK 0xFFFF
#define SCSI_LBA48_READ 0xFFFFFFF
#ifdef CONFIG_SYS_64BIT_LBA
void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
{
pccb->cmd[0] = SCSI_READ16;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmd[2] = (unsigned char)(start >> 56) & 0xff;
pccb->cmd[3] = (unsigned char)(start >> 48) & 0xff;
pccb->cmd[4] = (unsigned char)(start >> 40) & 0xff;
pccb->cmd[5] = (unsigned char)(start >> 32) & 0xff;
pccb->cmd[6] = (unsigned char)(start >> 24) & 0xff;
pccb->cmd[7] = (unsigned char)(start >> 16) & 0xff;
pccb->cmd[8] = (unsigned char)(start >> 8) & 0xff;
pccb->cmd[9] = (unsigned char)start & 0xff;
pccb->cmd[10] = 0;
pccb->cmd[11] = (unsigned char)(blocks >> 24) & 0xff;
pccb->cmd[12] = (unsigned char)(blocks >> 16) & 0xff;
pccb->cmd[13] = (unsigned char)(blocks >> 8) & 0xff;
pccb->cmd[14] = (unsigned char)blocks & 0xff;
pccb->cmd[15] = 0;
pccb->cmdlen = 16;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
debug("scsi_setup_read16: cmd: %02X %02X startblk %02X%02X%02X%02X%02X%02X%02X%02X blccnt %02X%02X%02X%02X\n",
pccb->cmd[0], pccb->cmd[1],
pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
}
#endif
void scsi_setup_read_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
{
pccb->cmd[0] = SCSI_READ10;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
pccb->cmd[5] = (unsigned char)start & 0xff;
pccb->cmd[6] = 0;
pccb->cmd[7] = (unsigned char)(blocks >> 8) & 0xff;
pccb->cmd[8] = (unsigned char)blocks & 0xff;
pccb->cmd[6] = 0;
pccb->cmdlen = 10;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
debug("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
pccb->cmd[0], pccb->cmd[1],
pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
pccb->cmd[7], pccb->cmd[8]);
}
void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
{
pccb->cmd[0] = SCSI_WRITE10;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
pccb->cmd[5] = (unsigned char)start & 0xff;
pccb->cmd[6] = 0;
pccb->cmd[7] = ((unsigned char)(blocks >> 8)) & 0xff;
pccb->cmd[8] = (unsigned char)blocks & 0xff;
pccb->cmd[9] = 0;
pccb->cmdlen = 10;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
__func__,
pccb->cmd[0], pccb->cmd[1],
pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
pccb->cmd[7], pccb->cmd[8]);
}
void scsi_setup_read6(ccb *pccb, lbaint_t start, unsigned short blocks)
{
pccb->cmd[0] = SCSI_READ6;
pccb->cmd[1] = pccb->lun << 5 | ((unsigned char)(start >> 16) & 0x1f);
pccb->cmd[2] = (unsigned char)(start >> 8) & 0xff;
pccb->cmd[3] = (unsigned char)start & 0xff;
pccb->cmd[4] = (unsigned char)blocks & 0xff;
pccb->cmd[5] = 0;
pccb->cmdlen = 6;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
debug("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
pccb->cmd[0], pccb->cmd[1],
pccb->cmd[2], pccb->cmd[3], pccb->cmd[4]);
}
void scsi_setup_inquiry(ccb *pccb)
{
pccb->cmd[0] = SCSI_INQUIRY;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmd[2] = 0;
pccb->cmd[3] = 0;
if (pccb->datalen > 255)
pccb->cmd[4] = 255;
else
pccb->cmd[4] = (unsigned char)pccb->datalen;
pccb->cmd[5] = 0;
pccb->cmdlen = 6;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
}
#ifdef CONFIG_BLK
static ulong scsi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
void *buffer)
#else
static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
lbaint_t blkcnt, void *buffer)
#endif
{
#ifdef CONFIG_BLK
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
int device = block_dev->devnum;
lbaint_t start, blks;
uintptr_t buf_addr;
unsigned short smallblks = 0;
ccb *pccb = (ccb *)&tempccb;
device &= 0xff;
/* Setup device */
pccb->target = scsi_dev_desc[device].target;
pccb->lun = scsi_dev_desc[device].lun;
buf_addr = (unsigned long)buffer;
start = blknr;
blks = blkcnt;
debug("\nscsi_read: dev %d startblk " LBAF
", blccnt " LBAF " buffer %lx\n",
device, start, blks, (unsigned long)buffer);
do {
pccb->pdata = (unsigned char *)buf_addr;
#ifdef CONFIG_SYS_64BIT_LBA
if (start > SCSI_LBA48_READ) {
unsigned long blocks;
blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
pccb->datalen = scsi_dev_desc[device].blksz * blocks;
scsi_setup_read16(pccb, start, blocks);
start += blocks;
blks -= blocks;
} else
#endif
if (blks > SCSI_MAX_READ_BLK) {
pccb->datalen = scsi_dev_desc[device].blksz *
SCSI_MAX_READ_BLK;
smallblks = SCSI_MAX_READ_BLK;
scsi_setup_read_ext(pccb, start, smallblks);
start += SCSI_MAX_READ_BLK;
blks -= SCSI_MAX_READ_BLK;
} else {
pccb->datalen = scsi_dev_desc[device].blksz * blks;
smallblks = (unsigned short)blks;
scsi_setup_read_ext(pccb, start, smallblks);
start += blks;
blks = 0;
}
debug("scsi_read_ext: startblk " LBAF
", blccnt %x buffer %" PRIXPTR "\n",
start, smallblks, buf_addr);
if (scsi_exec(pccb) != true) {
scsi_print_error(pccb);
blkcnt -= blks;
break;
}
buf_addr += pccb->datalen;
} while (blks != 0);
debug("scsi_read_ext: end startblk " LBAF
", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
return blkcnt;
}
/*******************************************************************************
* scsi_write
*/
/* Almost the maximum amount of the scsi_ext command.. */
#define SCSI_MAX_WRITE_BLK 0xFFFF
#ifdef CONFIG_BLK
static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
const void *buffer)
#else
static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
lbaint_t blkcnt, const void *buffer)
#endif
{
#ifdef CONFIG_BLK
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
int device = block_dev->devnum;
lbaint_t start, blks;
uintptr_t buf_addr;
unsigned short smallblks;
ccb *pccb = (ccb *)&tempccb;
device &= 0xff;
/* Setup device */
pccb->target = scsi_dev_desc[device].target;
pccb->lun = scsi_dev_desc[device].lun;
buf_addr = (unsigned long)buffer;
start = blknr;
blks = blkcnt;
debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
__func__, device, start, blks, (unsigned long)buffer);
do {
pccb->pdata = (unsigned char *)buf_addr;
if (blks > SCSI_MAX_WRITE_BLK) {
pccb->datalen = (scsi_dev_desc[device].blksz *
SCSI_MAX_WRITE_BLK);
smallblks = SCSI_MAX_WRITE_BLK;
scsi_setup_write_ext(pccb, start, smallblks);
start += SCSI_MAX_WRITE_BLK;
blks -= SCSI_MAX_WRITE_BLK;
} else {
pccb->datalen = scsi_dev_desc[device].blksz * blks;
smallblks = (unsigned short)blks;
scsi_setup_write_ext(pccb, start, smallblks);
start += blks;
blks = 0;
}
debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
__func__, start, smallblks, buf_addr);
if (scsi_exec(pccb) != true) {
scsi_print_error(pccb);
blkcnt -= blks;
break;
}
buf_addr += pccb->datalen;
} while (blks != 0);
debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
__func__, start, smallblks, buf_addr);
return blkcnt;
}
int scsi_get_disk_count(void)
{
return scsi_max_devs;
}
#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
void scsi_init(void)
{
int busdevfunc = -1;
int i;
/*
* Find a device from the list, this driver will support a single
* controller.
*/
for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
/* get PCI Device ID */
#ifdef CONFIG_DM_PCI
struct udevice *dev;
int ret;
ret = dm_pci_find_device(scsi_device_list[i].vendor,
scsi_device_list[i].device, 0, &dev);
if (!ret) {
busdevfunc = dm_pci_get_bdf(dev);
break;
}
#else
busdevfunc = pci_find_device(scsi_device_list[i].vendor,
scsi_device_list[i].device,
0);
#endif
if (busdevfunc != -1)
break;
}
if (busdevfunc == -1) {
printf("Error: SCSI Controller(s) ");
for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
printf("%04X:%04X ",
scsi_device_list[i].vendor,
scsi_device_list[i].device);
}
printf("not found\n");
return;
}
#ifdef DEBUG
else {
printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
scsi_device_list[i].vendor,
scsi_device_list[i].device,
(busdevfunc >> 16) & 0xFF,
(busdevfunc >> 11) & 0x1F,
(busdevfunc >> 8) & 0x7);
}
#endif
bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
scsi_low_level_init(busdevfunc);
scsi_scan(1);
bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
}
#endif
/* copy src to dest, skipping leading and trailing blanks
* and null terminate the string
*/
void scsi_ident_cpy(unsigned char *dest, unsigned char *src, unsigned int len)
{
int start, end;
start = 0;
while (start < len) {
if (src[start] != ' ')
break;
start++;
}
end = len-1;
while (end > start) {
if (src[end] != ' ')
break;
end--;
}
for (; start <= end; start++)
*dest ++= src[start];
*dest = '\0';
}
/* Trim trailing blanks, and NUL-terminate string
*/
void scsi_trim_trail(unsigned char *str, unsigned int len)
{
unsigned char *p = str + len - 1;
while (len-- > 0) {
*p-- = '\0';
if (*p != ' ')
return;
}
}
int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
{
*capacity = 0;
memset(pccb->cmd, '\0', sizeof(pccb->cmd));
pccb->cmd[0] = SCSI_RD_CAPAC10;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmdlen = 10;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
pccb->datalen = 8;
if (scsi_exec(pccb) != true)
return 1;
*capacity = ((lbaint_t)pccb->pdata[0] << 24) |
((lbaint_t)pccb->pdata[1] << 16) |
((lbaint_t)pccb->pdata[2] << 8) |
((lbaint_t)pccb->pdata[3]);
if (*capacity != 0xffffffff) {
/* Read capacity (10) was sufficient for this drive. */
*blksz = ((unsigned long)pccb->pdata[4] << 24) |
((unsigned long)pccb->pdata[5] << 16) |
((unsigned long)pccb->pdata[6] << 8) |
((unsigned long)pccb->pdata[7]);
return 0;
}
/* Read capacity (10) was insufficient. Use read capacity (16). */
memset(pccb->cmd, '\0', sizeof(pccb->cmd));
pccb->cmd[0] = SCSI_RD_CAPAC16;
pccb->cmd[1] = 0x10;
pccb->cmdlen = 16;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
pccb->datalen = 16;
if (scsi_exec(pccb) != true)
return 1;
*capacity = ((uint64_t)pccb->pdata[0] << 56) |
((uint64_t)pccb->pdata[1] << 48) |
((uint64_t)pccb->pdata[2] << 40) |
((uint64_t)pccb->pdata[3] << 32) |
((uint64_t)pccb->pdata[4] << 24) |
((uint64_t)pccb->pdata[5] << 16) |
((uint64_t)pccb->pdata[6] << 8) |
((uint64_t)pccb->pdata[7]);
*blksz = ((uint64_t)pccb->pdata[8] << 56) |
((uint64_t)pccb->pdata[9] << 48) |
((uint64_t)pccb->pdata[10] << 40) |
((uint64_t)pccb->pdata[11] << 32) |
((uint64_t)pccb->pdata[12] << 24) |
((uint64_t)pccb->pdata[13] << 16) |
((uint64_t)pccb->pdata[14] << 8) |
((uint64_t)pccb->pdata[15]);
return 0;
}
/*
* Some setup (fill-in) routines
*/
void scsi_setup_test_unit_ready(ccb *pccb)
{
pccb->cmd[0] = SCSI_TST_U_RDY;
pccb->cmd[1] = pccb->lun << 5;
pccb->cmd[2] = 0;
pccb->cmd[3] = 0;
pccb->cmd[4] = 0;
pccb->cmd[5] = 0;
pccb->cmdlen = 6;
pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
}
/*
* (re)-scan the scsi bus and reports scsi device info
* to the user if mode = 1
*/
void scsi_scan(int mode)
{
unsigned char i, perq, modi, lun;
lbaint_t capacity;
unsigned long blksz;
ccb *pccb = (ccb *)&tempccb;
if (mode == 1)
printf("scanning bus for devices...\n");
for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; i++) {
scsi_dev_desc[i].target = 0xff;
scsi_dev_desc[i].lun = 0xff;
scsi_dev_desc[i].lba = 0;
scsi_dev_desc[i].blksz = 0;
scsi_dev_desc[i].log2blksz =
LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
scsi_dev_desc[i].type = DEV_TYPE_UNKNOWN;
scsi_dev_desc[i].vendor[0] = 0;
scsi_dev_desc[i].product[0] = 0;
scsi_dev_desc[i].revision[0] = 0;
scsi_dev_desc[i].removable = false;
scsi_dev_desc[i].if_type = IF_TYPE_SCSI;
scsi_dev_desc[i].devnum = i;
scsi_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
#ifndef CONFIG_BLK
scsi_dev_desc[i].block_read = scsi_read;
scsi_dev_desc[i].block_write = scsi_write;
#endif
}
scsi_max_devs = 0;
for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
pccb->target = i;
for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
pccb->lun = lun;
pccb->pdata = (unsigned char *)&tempbuff;
pccb->datalen = 512;
scsi_setup_inquiry(pccb);
if (scsi_exec(pccb) != true) {
if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
/*
* selection timeout => assuming no
* device present
*/
debug("Selection timeout ID %d\n",
pccb->target);
continue;
}
scsi_print_error(pccb);
continue;
}
perq = tempbuff[0];
modi = tempbuff[1];
if ((perq & 0x1f) == 0x1f)
continue; /* skip unknown devices */
if ((modi & 0x80) == 0x80) /* drive is removable */
scsi_dev_desc[scsi_max_devs].removable = true;
/* get info for this device */
scsi_ident_cpy((unsigned char *)&scsi_dev_desc
[scsi_max_devs].vendor[0],
&tempbuff[8], 8);
scsi_ident_cpy((unsigned char *)&scsi_dev_desc
[scsi_max_devs].product[0],
&tempbuff[16], 16);
scsi_ident_cpy((unsigned char *)&scsi_dev_desc
[scsi_max_devs].revision[0],
&tempbuff[32], 4);
scsi_dev_desc[scsi_max_devs].target = pccb->target;
scsi_dev_desc[scsi_max_devs].lun = pccb->lun;
pccb->datalen = 0;
scsi_setup_test_unit_ready(pccb);
if (scsi_exec(pccb) != true) {
if (scsi_dev_desc[scsi_max_devs].removable) {
scsi_dev_desc[scsi_max_devs].type =
perq;
goto removable;
}
scsi_print_error(pccb);
continue;
}
if (scsi_read_capacity(pccb, &capacity, &blksz)) {
scsi_print_error(pccb);
continue;
}
scsi_dev_desc[scsi_max_devs].lba = capacity;
scsi_dev_desc[scsi_max_devs].blksz = blksz;
scsi_dev_desc[scsi_max_devs].log2blksz =
LOG2(scsi_dev_desc[scsi_max_devs].blksz);
scsi_dev_desc[scsi_max_devs].type = perq;
part_init(&scsi_dev_desc[scsi_max_devs]);
removable:
if (mode == 1) {
printf(" Device %d: ", scsi_max_devs);
dev_print(&scsi_dev_desc[scsi_max_devs]);
} /* if mode */
scsi_max_devs++;
} /* next LUN */
}
if (scsi_max_devs > 0)
scsi_curr_dev = 0;
else
scsi_curr_dev = -1;
printf("Found %d device(s).\n", scsi_max_devs);
#ifndef CONFIG_SPL_BUILD
setenv_ulong("scsidevs", scsi_max_devs);
#endif
}
#ifdef CONFIG_BLK
static const struct blk_ops scsi_blk_ops = {
.read = scsi_read,
.write = scsi_write,
};
U_BOOT_DRIVER(scsi_blk) = {
.name = "scsi_blk",
.id = UCLASS_BLK,
.ops = &scsi_blk_ops,
};
#else
U_BOOT_LEGACY_BLK(scsi) = {
.if_typename = "sata",
.if_type = IF_TYPE_SCSI,
.max_devs = CONFIG_SYS_SCSI_MAX_DEVICE,
.desc = scsi_dev_desc,
};
#endif

View file

@ -300,7 +300,7 @@ int spl_mmc_load_image(u32 boot_device)
if (part == 7)
part = 0;
err = mmc_switch_part(0, part);
err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
if (err) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts("spl: mmc partition switch failed\n");

View file

@ -34,7 +34,7 @@ int spl_sata_load_image(void)
} else {
/* try to recognize storage devices immediately */
scsi_scan(0);
stor_dev = scsi_get_dev(0);
stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0);
if (!stor_dev)
return -ENODEV;
}

View file

@ -39,7 +39,7 @@ int spl_usb_load_image(void)
#ifdef CONFIG_USB_STORAGE
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev);
if (!stor_dev)
return -ENODEV;
#endif

View file

@ -136,23 +136,6 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
#endif
void uhci_show_temp_int_td(void);
#ifdef CONFIG_PARTITIONS
struct blk_desc *usb_stor_get_dev(int index)
{
#ifdef CONFIG_BLK
struct udevice *dev;
int ret;
ret = blk_get_device(IF_TYPE_USB, index, &dev);
if (ret)
return NULL;
return dev_get_uclass_platdata(dev);
#else
return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
#endif
}
#endif
static void usb_show_progress(void)
{
debug(".");
@ -217,7 +200,6 @@ static int usb_stor_probe_device(struct usb_device *udev)
#ifdef CONFIG_BLK
struct us_data *data;
char dev_name[30], *str;
int ret;
#else
int start;
@ -240,14 +222,12 @@ static int usb_stor_probe_device(struct usb_device *udev)
for (lun = 0; lun <= max_lun; lun++) {
struct blk_desc *blkdev;
struct udevice *dev;
char str[10];
snprintf(dev_name, sizeof(dev_name), "%s.lun%d",
udev->dev->name, lun);
str = strdup(dev_name);
if (!str)
return -ENOMEM;
ret = blk_create_device(udev->dev, "usb_storage_blk", str,
IF_TYPE_USB, usb_max_devs, 512, 0, &dev);
snprintf(str, sizeof(str), "lun%d", lun);
ret = blk_create_devicef(udev->dev, "usb_storage_blk", str,
IF_TYPE_USB, usb_max_devs, 512, 0,
&dev);
if (ret) {
debug("Cannot bind driver\n");
return ret;
@ -1555,4 +1535,11 @@ U_BOOT_DRIVER(usb_storage_blk) = {
.id = UCLASS_BLK,
.ops = &usb_storage_ops,
};
#else
U_BOOT_LEGACY_BLK(usb) = {
.if_typename = "usb",
.if_type = IF_TYPE_USB,
.max_devs = USB_MAX_STOR_DEV,
.desc = usb_dev_desc,
};
#endif

View file

@ -1,4 +1,5 @@
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_MMC=y
CONFIG_PCI=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
CONFIG_I8042_KEYB=y
@ -97,6 +98,7 @@ CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
CONFIG_RESET=y
CONFIG_DM_MMC=y
CONFIG_SANDBOX_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y

View file

@ -0,0 +1,168 @@
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_PCI=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
CONFIG_I8042_KEYB=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_BOOTSTAGE=y
CONFIG_BOOTSTAGE_REPORT=y
CONFIG_BOOTSTAGE_USER_COUNT=0x20
CONFIG_BOOTSTAGE_FDT=y
CONFIG_BOOTSTAGE_STASH=y
CONFIG_BOOTSTAGE_STASH_ADDR=0x0
CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
CONFIG_HUSH_PARSER=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y
CONFIG_LOOPW=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_DEMO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y
CONFIG_CMD_RARP=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CDP=y
CONFIG_CMD_SNTP=y
CONFIG_CMD_DNS=y
CONFIG_CMD_LINK_LOCAL=y
CONFIG_CMD_TIME=y
CONFIG_CMD_TIMER=y
CONFIG_CMD_SOUND=y
CONFIG_CMD_BOOTSTAGE=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_TPM=y
CONFIG_CMD_TPM_TEST=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_OF_HOSTFILE=y
CONFIG_NETCONSOLE=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
CONFIG_SPL_SYSCON=y
CONFIG_DEVRES=y
CONFIG_DEBUG_DEVRES=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_CLK=y
CONFIG_CPU=y
CONFIG_DM_DEMO=y
CONFIG_DM_DEMO_SIMPLE=y
CONFIG_DM_DEMO_SHAPE=y
CONFIG_PM8916_GPIO=y
CONFIG_SANDBOX_GPIO=y
CONFIG_DM_I2C_COMPAT=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_I2C_CROS_EC_LDO=y
CONFIG_DM_I2C_GPIO=y
CONFIG_SYS_I2C_SANDBOX=y
CONFIG_I2C_MUX=y
CONFIG_SPL_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=y
CONFIG_CROS_EC_KEYB=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_CMD_CROS_EC=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_LPC=y
CONFIG_CROS_EC_SANDBOX=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
CONFIG_RESET=y
CONFIG_DM_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_SPI_FLASH_EON=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_SST=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_DM_ETH=y
CONFIG_DM_PCI=y
CONFIG_DM_PCI_COMPAT=y
CONFIG_PCI_SANDBOX=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_ROCKCHIP_PINCTRL=y
CONFIG_ROCKCHIP_3036_PINCTRL=y
CONFIG_PINCTRL_SANDBOX=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_ACT8846=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_PMIC_MAX77686=y
CONFIG_PMIC_PM8916=y
CONFIG_PMIC_RK808=y
CONFIG_PMIC_S2MPS11=y
CONFIG_DM_PMIC_SANDBOX=y
CONFIG_PMIC_S5M8767=y
CONFIG_PMIC_TPS65090=y
CONFIG_DM_REGULATOR=y
CONFIG_REGULATOR_ACT8846=y
CONFIG_DM_REGULATOR_PFUZE100=y
CONFIG_DM_REGULATOR_MAX77686=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK808=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_DM_REGULATOR_SANDBOX=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_RAM=y
CONFIG_REMOTEPROC_SANDBOX=y
CONFIG_DM_RTC=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y
CONFIG_SANDBOX_SPI=y
CONFIG_SPMI=y
CONFIG_SPMI_SANDBOX=y
CONFIG_TIMER=y
CONFIG_TIMER_EARLY=y
CONFIG_SANDBOX_TIMER=y
CONFIG_TPM_TIS_SANDBOX=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_EMUL=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_DM_VIDEO=y
CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_TPM=y
CONFIG_LZ4=y
CONFIG_ERRNO_STR=y
CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y

View file

@ -21,35 +21,6 @@
#define PRINTF(fmt,args...)
#endif
const struct block_drvr block_drvr[] = {
#if defined(CONFIG_CMD_IDE)
{ .name = "ide", .get_dev = ide_get_dev, },
#endif
#if defined(CONFIG_CMD_SATA)
{.name = "sata", .get_dev = sata_get_dev, },
#endif
#if defined(CONFIG_CMD_SCSI)
{ .name = "scsi", .get_dev = scsi_get_dev, },
#endif
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
{ .name = "usb", .get_dev = usb_stor_get_dev, },
#endif
#if defined(CONFIG_MMC)
{
.name = "mmc",
.get_dev = mmc_get_dev,
.select_hwpart = mmc_select_hwpart,
},
#endif
#if defined(CONFIG_SYSTEMACE)
{ .name = "ace", .get_dev = systemace_get_dev, },
#endif
#if defined(CONFIG_SANDBOX)
{ .name = "host", .get_dev = host_get_dev, },
#endif
{ },
};
DECLARE_GLOBAL_DATA_PTR;
#ifdef HAVE_BLOCK_DEVICE
@ -71,45 +42,23 @@ static struct part_driver *part_driver_lookup_type(int part_type)
static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
{
const struct block_drvr *drvr = block_drvr;
struct blk_desc* (*reloc_get_dev)(int dev);
int (*select_hwpart)(int dev_num, int hwpart);
char *name;
struct blk_desc *dev_desc;
int ret;
if (!ifname)
dev_desc = blk_get_devnum_by_typename(ifname, dev);
if (!dev_desc) {
debug("%s: No device for iface '%s', dev %d\n", __func__,
ifname, dev);
return NULL;
name = drvr->name;
#ifdef CONFIG_NEEDS_MANUAL_RELOC
name += gd->reloc_off;
#endif
while (drvr->name) {
name = drvr->name;
reloc_get_dev = drvr->get_dev;
select_hwpart = drvr->select_hwpart;
#ifdef CONFIG_NEEDS_MANUAL_RELOC
name += gd->reloc_off;
reloc_get_dev += gd->reloc_off;
if (select_hwpart)
select_hwpart += gd->reloc_off;
#endif
if (strncmp(ifname, name, strlen(name)) == 0) {
struct blk_desc *dev_desc = reloc_get_dev(dev);
if (!dev_desc)
return NULL;
if (hwpart == 0 && !select_hwpart)
return dev_desc;
if (!select_hwpart)
return NULL;
ret = select_hwpart(dev_desc->devnum, hwpart);
if (ret < 0)
return NULL;
return dev_desc;
}
drvr++;
}
return NULL;
ret = blk_dselect_hwpart(dev_desc, hwpart);
if (ret) {
debug("%s: Failed to select h/w partition: err-%d\n", __func__,
ret);
return NULL;
}
return dev_desc;
}
struct blk_desc *blk_get_dev(const char *ifname, int dev)
@ -401,7 +350,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
if (*ep) {
printf("** Bad device specification %s %s **\n",
ifname, dev_str);
dev = -1;
dev = -EINVAL;
goto cleanup;
}
@ -410,7 +359,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
if (*ep) {
printf("** Bad HW partition specification %s %s **\n",
ifname, hwpart_str);
dev = -1;
dev = -EINVAL;
goto cleanup;
}
}
@ -418,7 +367,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
*dev_desc = get_dev_hwpart(ifname, dev, hwpart);
if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
dev = -1;
dev = -ENOENT;
goto cleanup;
}

View file

@ -36,6 +36,8 @@ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/
obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/
obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/
obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += block/
obj-$(CONFIG_SPL_MMC_SUPPORT) += block/
else

View file

@ -9,10 +9,9 @@ config BLK
be partitioned into several areas, called 'partitions' in U-Boot.
A filesystem can be placed in each partition.
config DISK
bool "Support disk controllers with driver model"
config AHCI
bool "Support SATA controllers with driver model"
depends on DM
default y if DM
help
This enables a uclass for disk controllers in U-Boot. Various driver
types can use this, such as AHCI/SATA. It does not provide any standard

View file

@ -7,7 +7,11 @@
obj-$(CONFIG_BLK) += blk-uclass.o
obj-$(CONFIG_DISK) += disk-uclass.o
ifndef CONFIG_BLK
obj-y += blk_legacy.o
endif
obj-$(CONFIG_AHCI) += ahci-uclass.o
obj-$(CONFIG_SCSI_AHCI) += ahci.o
obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
obj-$(CONFIG_FSL_SATA) += fsl_sata.o
@ -22,7 +26,7 @@ obj-$(CONFIG_SATA_MV) += sata_mv.o
obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
obj-$(CONFIG_SATA_SIL) += sata_sil.o
obj-$(CONFIG_IDE_SIL680) += sil680.o
obj-$(CONFIG_SANDBOX) += sandbox.o
obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o sata_sandbox.o
obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
obj-$(CONFIG_SYSTEMACE) += systemace.o
obj-$(CONFIG_BLOCK_CACHE) += blkcache.o

View file

@ -8,7 +8,7 @@
#include <common.h>
#include <dm.h>
UCLASS_DRIVER(disk) = {
.id = UCLASS_DISK,
.name = "disk",
UCLASS_DRIVER(ahci) = {
.id = UCLASS_AHCI,
.name = "ahci",
};

View file

@ -11,6 +11,315 @@
#include <dm/device-internal.h>
#include <dm/lists.h>
static const char *if_typename_str[IF_TYPE_COUNT] = {
[IF_TYPE_IDE] = "ide",
[IF_TYPE_SCSI] = "scsi",
[IF_TYPE_ATAPI] = "atapi",
[IF_TYPE_USB] = "usb",
[IF_TYPE_DOC] = "doc",
[IF_TYPE_MMC] = "mmc",
[IF_TYPE_SD] = "sd",
[IF_TYPE_SATA] = "sata",
[IF_TYPE_HOST] = "host",
[IF_TYPE_SYSTEMACE] = "ace",
};
static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
[IF_TYPE_IDE] = UCLASS_INVALID,
[IF_TYPE_SCSI] = UCLASS_INVALID,
[IF_TYPE_ATAPI] = UCLASS_INVALID,
[IF_TYPE_USB] = UCLASS_MASS_STORAGE,
[IF_TYPE_DOC] = UCLASS_INVALID,
[IF_TYPE_MMC] = UCLASS_MMC,
[IF_TYPE_SD] = UCLASS_INVALID,
[IF_TYPE_SATA] = UCLASS_AHCI,
[IF_TYPE_HOST] = UCLASS_ROOT,
[IF_TYPE_SYSTEMACE] = UCLASS_INVALID,
};
static enum if_type if_typename_to_iftype(const char *if_typename)
{
int i;
for (i = 0; i < IF_TYPE_COUNT; i++) {
if (if_typename_str[i] &&
!strcmp(if_typename, if_typename_str[i]))
return i;
}
return IF_TYPE_UNKNOWN;
}
static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
{
return if_type_uclass_id[if_type];
}
struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
{
struct blk_desc *desc;
struct udevice *dev;
int ret;
ret = blk_get_device(if_type, devnum, &dev);
if (ret)
return NULL;
desc = dev_get_uclass_platdata(dev);
return desc;
}
/*
* This function is complicated with driver model. We look up the interface
* name in a local table. This gives us an interface type which we can match
* against the uclass of the block device's parent.
*/
struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
{
enum uclass_id uclass_id;
enum if_type if_type;
struct udevice *dev;
struct uclass *uc;
int ret;
if_type = if_typename_to_iftype(if_typename);
if (if_type == IF_TYPE_UNKNOWN) {
debug("%s: Unknown interface type '%s'\n", __func__,
if_typename);
return NULL;
}
uclass_id = if_type_to_uclass_id(if_type);
if (uclass_id == UCLASS_INVALID) {
debug("%s: Unknown uclass for interface type'\n",
if_typename_str[if_type]);
return NULL;
}
ret = uclass_get(UCLASS_BLK, &uc);
if (ret)
return NULL;
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_platdata(dev);
debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
if_type, devnum, dev->name, desc->if_type, desc->devnum);
if (desc->devnum != devnum)
continue;
/* Find out the parent device uclass */
if (device_get_uclass_id(dev->parent) != uclass_id) {
debug("%s: parent uclass %d, this dev %d\n", __func__,
device_get_uclass_id(dev->parent), uclass_id);
continue;
}
if (device_probe(dev))
return NULL;
debug("%s: Device desc %p\n", __func__, desc);
return desc;
}
debug("%s: No device found\n", __func__);
return NULL;
}
/**
* get_desc() - Get the block device descriptor for the given device number
*
* @if_type: Interface type
* @devnum: Device number (0 = first)
* @descp: Returns block device descriptor on success
* @return 0 on success, -ENODEV if there is no such device and no device
* with a higher device number, -ENOENT if there is no such device but there
* is one with a higher number, or other -ve on other error.
*/
static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
{
bool found_more = false;
struct udevice *dev;
struct uclass *uc;
int ret;
*descp = NULL;
ret = uclass_get(UCLASS_BLK, &uc);
if (ret)
return ret;
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_platdata(dev);
debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
if_type, devnum, dev->name, desc->if_type, desc->devnum);
if (desc->if_type == if_type) {
if (desc->devnum == devnum) {
ret = device_probe(dev);
if (ret)
return ret;
} else if (desc->devnum > devnum) {
found_more = true;
}
}
}
return found_more ? -ENOENT : -ENODEV;
}
int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
{
struct udevice *dev;
int ret;
ret = blk_get_device(if_type, devnum, &dev);
if (ret)
return ret;
return blk_select_hwpart(dev, hwpart);
}
int blk_list_part(enum if_type if_type)
{
struct blk_desc *desc;
int devnum, ok;
int ret;
for (ok = 0, devnum = 0;; ++devnum) {
ret = get_desc(if_type, devnum, &desc);
if (ret == -ENODEV)
break;
else if (ret)
continue;
if (desc->part_type != PART_TYPE_UNKNOWN) {
++ok;
if (devnum)
putc('\n');
part_print(desc);
}
}
if (!ok)
return -ENODEV;
return 0;
}
int blk_print_part_devnum(enum if_type if_type, int devnum)
{
struct blk_desc *desc;
int ret;
ret = get_desc(if_type, devnum, &desc);
if (ret)
return ret;
if (desc->type == DEV_TYPE_UNKNOWN)
return -ENOENT;
part_print(desc);
return 0;
}
void blk_list_devices(enum if_type if_type)
{
struct blk_desc *desc;
int ret;
int i;
for (i = 0;; ++i) {
ret = get_desc(if_type, i, &desc);
if (ret == -ENODEV)
break;
else if (ret)
continue;
if (desc->type == DEV_TYPE_UNKNOWN)
continue; /* list only known devices */
printf("Device %d: ", i);
dev_print(desc);
}
}
int blk_print_device_num(enum if_type if_type, int devnum)
{
struct blk_desc *desc;
int ret;
ret = get_desc(if_type, devnum, &desc);
if (ret)
return ret;
printf("\nIDE device %d: ", devnum);
dev_print(desc);
return 0;
}
int blk_show_device(enum if_type if_type, int devnum)
{
struct blk_desc *desc;
int ret;
printf("\nDevice %d: ", devnum);
ret = get_desc(if_type, devnum, &desc);
if (ret == -ENODEV || ret == -ENOENT) {
printf("unknown device\n");
return -ENODEV;
}
if (ret)
return ret;
dev_print(desc);
if (desc->type == DEV_TYPE_UNKNOWN)
return -ENOENT;
return 0;
}
ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
struct blk_desc *desc;
ulong n;
int ret;
ret = get_desc(if_type, devnum, &desc);
if (ret)
return ret;
n = blk_dread(desc, start, blkcnt, buffer);
if (IS_ERR_VALUE(n))
return n;
/* flush cache after read */
flush_cache((ulong)buffer, blkcnt * desc->blksz);
return n;
}
ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
struct blk_desc *desc;
int ret;
ret = get_desc(if_type, devnum, &desc);
if (ret)
return ret;
return blk_dwrite(desc, start, blkcnt, buffer);
}
int blk_select_hwpart(struct udevice *dev, int hwpart)
{
const struct blk_ops *ops = blk_get_ops(dev);
if (!ops)
return -ENOSYS;
if (!ops->select_hwpart)
return 0;
return ops->select_hwpart(dev, hwpart);
}
int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
{
return blk_select_hwpart(desc->bdev, hwpart);
}
int blk_first_device(int if_type, struct udevice **devp)
{
struct blk_desc *desc;
@ -131,6 +440,26 @@ int blk_prepare_device(struct udevice *dev)
return 0;
}
int blk_find_max_devnum(enum if_type if_type)
{
struct udevice *dev;
int max_devnum = -ENODEV;
struct uclass *uc;
int ret;
ret = uclass_get(UCLASS_BLK, &uc);
if (ret)
return ret;
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_platdata(dev);
if (desc->if_type == if_type && desc->devnum > max_devnum)
max_devnum = desc->devnum;
}
return max_devnum;
}
int blk_create_device(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
lbaint_t size, struct udevice **devp)
@ -139,6 +468,15 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
struct udevice *dev;
int ret;
if (devnum == -1) {
ret = blk_find_max_devnum(if_type);
if (ret == -ENODEV)
devnum = 0;
else if (ret < 0)
return ret;
else
devnum = ret + 1;
}
ret = device_bind_driver(parent, drv_name, name, &dev);
if (ret)
return ret;
@ -154,6 +492,29 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
return 0;
}
int blk_create_devicef(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
lbaint_t size, struct udevice **devp)
{
char dev_name[30], *str;
int ret;
snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
str = strdup(dev_name);
if (!str)
return -ENOMEM;
ret = blk_create_device(parent, drv_name, str, if_type, devnum,
blksz, size, devp);
if (ret) {
free(str);
return ret;
}
device_set_name_alloced(*devp);
return ret;
}
int blk_unbind_all(int if_type)
{
struct uclass *uc;

261
drivers/block/blk_legacy.c Normal file
View file

@ -0,0 +1,261 @@
/*
* Copyright (C) 2016 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <linux/err.h>
struct blk_driver *blk_driver_lookup_type(int if_type)
{
struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
struct blk_driver *entry;
for (entry = drv; entry != drv + n_ents; entry++) {
if (if_type == entry->if_type)
return entry;
}
/* Not found */
return NULL;
}
static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
{
struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
struct blk_driver *entry;
for (entry = drv; entry != drv + n_ents; entry++) {
if (!strcmp(if_typename, entry->if_typename))
return entry;
}
/* Not found */
return NULL;
}
/**
* get_desc() - Get the block device descriptor for the given device number
*
* @drv: Legacy block driver
* @devnum: Device number (0 = first)
* @descp: Returns block device descriptor on success
* @return 0 on success, -ENODEV if there is no such device, -ENOSYS if the
* driver does not provide a way to find a device, or other -ve on other
* error.
*/
static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp)
{
if (drv->desc) {
if (devnum < 0 || devnum >= drv->max_devs)
return -ENODEV;
*descp = &drv->desc[devnum];
return 0;
}
if (!drv->get_dev)
return -ENOSYS;
return drv->get_dev(devnum, descp);
}
#ifdef HAVE_BLOCK_DEVICE
int blk_list_part(enum if_type if_type)
{
struct blk_driver *drv;
struct blk_desc *desc;
int devnum, ok;
bool first = true;
drv = blk_driver_lookup_type(if_type);
if (!drv)
return -ENOSYS;
for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
if (get_desc(drv, devnum, &desc))
continue;
if (desc->part_type != PART_TYPE_UNKNOWN) {
++ok;
if (!first)
putc('\n');
part_print(desc);
first = false;
}
}
if (!ok)
return -ENODEV;
return 0;
}
int blk_print_part_devnum(enum if_type if_type, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
int ret;
if (!drv)
return -ENOSYS;
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
if (desc->type == DEV_TYPE_UNKNOWN)
return -ENOENT;
part_print(desc);
return 0;
}
void blk_list_devices(enum if_type if_type)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
int i;
if (!drv)
return;
for (i = 0; i < drv->max_devs; ++i) {
if (get_desc(drv, i, &desc))
continue;
if (desc->type == DEV_TYPE_UNKNOWN)
continue; /* list only known devices */
printf("Device %d: ", i);
dev_print(desc);
}
}
int blk_print_device_num(enum if_type if_type, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
int ret;
if (!drv)
return -ENOSYS;
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
printf("\n%s device %d: ", drv->if_typename, devnum);
dev_print(desc);
return 0;
}
int blk_show_device(enum if_type if_type, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
int ret;
if (!drv)
return -ENOSYS;
printf("\nDevice %d: ", devnum);
if (devnum >= drv->max_devs) {
puts("unknown device\n");
return -ENODEV;
}
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
dev_print(desc);
if (desc->type == DEV_TYPE_UNKNOWN)
return -ENOENT;
return 0;
}
#endif /* HAVE_BLOCK_DEVICE */
struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
if (!drv)
return NULL;
if (get_desc(drv, devnum, &desc))
return NULL;
return desc;
}
int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
{
struct blk_driver *drv = blk_driver_lookup_type(desc->if_type);
if (!drv)
return -ENOSYS;
if (drv->select_hwpart)
return drv->select_hwpart(desc, hwpart);
return 0;
}
struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_typename(if_typename);
struct blk_desc *desc;
if (!drv)
return NULL;
if (get_desc(drv, devnum, &desc))
return NULL;
return desc;
}
ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
ulong n;
int ret;
if (!drv)
return -ENOSYS;
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
n = desc->block_read(desc, start, blkcnt, buffer);
if (IS_ERR_VALUE(n))
return n;
/* flush cache after read */
flush_cache((ulong)buffer, blkcnt * desc->blksz);
return n;
}
ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
int ret;
if (!drv)
return -ENOSYS;
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
return desc->block_write(desc, start, blkcnt, buffer);
}
int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_desc *desc;
int ret;
if (!drv)
return -ENOSYS;
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
return drv->select_hwpart(desc, hwpart);
}

View file

@ -17,6 +17,19 @@
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_BLK
static struct host_block_dev host_devices[CONFIG_HOST_MAX_DEVICES];
static struct host_block_dev *find_host_device(int dev)
{
if (dev >= 0 && dev < CONFIG_HOST_MAX_DEVICES)
return &host_devices[dev];
return NULL;
}
#endif
#ifdef CONFIG_BLK
static unsigned long host_block_read(struct udevice *dev,
unsigned long start, lbaint_t blkcnt,
void *buffer)
@ -24,6 +37,18 @@ static unsigned long host_block_read(struct udevice *dev,
struct host_block_dev *host_dev = dev_get_priv(dev);
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#else
static unsigned long host_block_read(struct blk_desc *block_dev,
unsigned long start, lbaint_t blkcnt,
void *buffer)
{
int dev = block_dev->devnum;
struct host_block_dev *host_dev = find_host_device(dev);
if (!host_dev)
return -1;
#endif
if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
-1) {
printf("ERROR: Invalid block %lx\n", start);
@ -35,12 +60,21 @@ static unsigned long host_block_read(struct udevice *dev,
return -1;
}
#ifdef CONFIG_BLK
static unsigned long host_block_write(struct udevice *dev,
unsigned long start, lbaint_t blkcnt,
const void *buffer)
{
struct host_block_dev *host_dev = dev_get_priv(dev);
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#else
static unsigned long host_block_write(struct blk_desc *block_dev,
unsigned long start, lbaint_t blkcnt,
const void *buffer)
{
int dev = block_dev->devnum;
struct host_block_dev *host_dev = find_host_device(dev);
#endif
if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
-1) {
@ -53,6 +87,7 @@ static unsigned long host_block_write(struct udevice *dev,
return -1;
}
#ifdef CONFIG_BLK
int host_dev_bind(int devnum, char *filename)
{
struct host_block_dev *host_dev;
@ -115,9 +150,51 @@ err:
free(str);
return ret;
}
#else
int host_dev_bind(int dev, char *filename)
{
struct host_block_dev *host_dev = find_host_device(dev);
if (!host_dev)
return -1;
if (host_dev->blk_dev.priv) {
os_close(host_dev->fd);
host_dev->blk_dev.priv = NULL;
}
if (host_dev->filename)
free(host_dev->filename);
if (filename && *filename) {
host_dev->filename = strdup(filename);
} else {
host_dev->filename = NULL;
return 0;
}
host_dev->fd = os_open(host_dev->filename, OS_O_RDWR);
if (host_dev->fd == -1) {
printf("Failed to access host backing file '%s'\n",
host_dev->filename);
return 1;
}
struct blk_desc *blk_dev = &host_dev->blk_dev;
blk_dev->if_type = IF_TYPE_HOST;
blk_dev->priv = host_dev;
blk_dev->blksz = 512;
blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz;
blk_dev->block_read = host_block_read;
blk_dev->block_write = host_block_write;
blk_dev->devnum = dev;
blk_dev->part_type = PART_TYPE_UNKNOWN;
part_init(blk_dev);
return 0;
}
#endif
int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
{
#ifdef CONFIG_BLK
struct udevice *dev;
int ret;
@ -125,20 +202,22 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
if (ret)
return ret;
*blk_devp = dev_get_uclass_platdata(dev);
#else
struct host_block_dev *host_dev = find_host_device(devnum);
if (!host_dev)
return -ENODEV;
if (!host_dev->blk_dev.priv)
return -ENOENT;
*blk_devp = &host_dev->blk_dev;
#endif
return 0;
}
struct blk_desc *host_get_dev(int dev)
{
struct blk_desc *blk_dev;
if (host_get_dev_err(dev, &blk_dev))
return NULL;
return blk_dev;
}
#ifdef CONFIG_BLK
static const struct blk_ops sandbox_host_blk_ops = {
.read = host_block_read,
.write = host_block_write,
@ -150,3 +229,11 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
.ops = &sandbox_host_blk_ops,
.priv_auto_alloc_size = sizeof(struct host_block_dev),
};
#else
U_BOOT_LEGACY_BLK(sandbox_host) = {
.if_typename = "host",
.if_type = IF_TYPE_HOST,
.max_devs = CONFIG_HOST_MAX_DEVICES,
.get_dev = host_get_dev_err,
};
#endif

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*
* This file contains dummy implementations of SCSI functions requried so
* that CONFIG_SCSI can be enabled for sandbox.
*/
#include <common.h>
#include <scsi.h>
void scsi_bus_reset(void)
{
}
void scsi_init(void)
{
}
int scsi_exec(ccb *pccb)
{
return 0;
}
void scsi_print_error(ccb *pccb)
{
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
int init_sata(int dev)
{
return 0;
}
int reset_sata(int dev)
{
return 0;
}
int scan_sata(int dev)
{
return 0;
}
ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
{
return 0;
}
ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
{
return 0;
}

View file

@ -33,7 +33,7 @@
#define PRINTF(fmt,args...)
#endif
#if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
#if defined(CONFIG_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
#undef SCSI_SINGLE_STEP
/*

View file

@ -27,7 +27,7 @@
#include <common.h>
#include <command.h>
#include <systemace.h>
#include <dm.h>
#include <part.h>
#include <asm/io.h>
@ -69,11 +69,9 @@ static u16 ace_readw(unsigned off)
return in16(base + off);
}
static unsigned long systemace_read(struct blk_desc *block_dev,
unsigned long start, lbaint_t blkcnt,
void *buffer);
#ifndef CONFIG_BLK
static struct blk_desc systemace_dev = { 0 };
#endif
static int get_cf_lock(void)
{
@ -104,42 +102,19 @@ static void release_cf_lock(void)
ace_writew((val & 0xffff), 0x18);
}
#ifdef CONFIG_PARTITIONS
struct blk_desc *systemace_get_dev(int dev)
{
/* The first time through this, the systemace_dev object is
not yet initialized. In that case, fill it in. */
if (systemace_dev.blksz == 0) {
systemace_dev.if_type = IF_TYPE_UNKNOWN;
systemace_dev.devnum = 0;
systemace_dev.part_type = PART_TYPE_UNKNOWN;
systemace_dev.type = DEV_TYPE_HARDDISK;
systemace_dev.blksz = 512;
systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
systemace_dev.removable = 1;
systemace_dev.block_read = systemace_read;
/*
* Ensure the correct bus mode (8/16 bits) gets enabled
*/
ace_writew(width == 8 ? 0 : 0x0001, 0);
part_init(&systemace_dev);
}
return &systemace_dev;
}
#endif
/*
* This function is called (by dereferencing the block_read pointer in
* the dev_desc) to read blocks of data. The return value is the
* number of blocks read. A zero return indicates an error.
*/
#ifdef CONFIG_BLK
static unsigned long systemace_read(struct udevice *dev, unsigned long start,
lbaint_t blkcnt, void *buffer)
#else
static unsigned long systemace_read(struct blk_desc *block_dev,
unsigned long start, lbaint_t blkcnt,
void *buffer)
#endif
{
int retry;
unsigned blk_countdown;
@ -257,3 +232,72 @@ static unsigned long systemace_read(struct blk_desc *block_dev,
return blkcnt;
}
#ifdef CONFIG_BLK
static int systemace_bind(struct udevice *dev)
{
struct blk_desc *bdesc;
struct udevice *bdev;
int ret;
ret = blk_create_devicef(dev, "systemace_blk", "blk", IF_TYPE_SYSTEMACE,
-1, 512, 0, &bdev);
if (ret) {
debug("Cannot create block device\n");
return ret;
}
bdesc = dev_get_uclass_platdata(bdev);
bdesc->removable = 1;
bdesc->part_type = PART_TYPE_UNKNOWN;
bdesc->log2blksz = LOG2(bdesc->blksz);
/* Ensure the correct bus mode (8/16 bits) gets enabled */
ace_writew(width == 8 ? 0 : 0x0001, 0);
return 0;
}
static const struct blk_ops systemace_blk_ops = {
.read = systemace_read,
};
U_BOOT_DRIVER(systemace_blk) = {
.name = "systemace_blk",
.id = UCLASS_BLK,
.ops = &systemace_blk_ops,
.bind = systemace_bind,
};
#else
static int systemace_get_dev(int dev, struct blk_desc **descp)
{
/* The first time through this, the systemace_dev object is
not yet initialized. In that case, fill it in. */
if (systemace_dev.blksz == 0) {
systemace_dev.if_type = IF_TYPE_UNKNOWN;
systemace_dev.devnum = 0;
systemace_dev.part_type = PART_TYPE_UNKNOWN;
systemace_dev.type = DEV_TYPE_HARDDISK;
systemace_dev.blksz = 512;
systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
systemace_dev.removable = 1;
systemace_dev.block_read = systemace_read;
/*
* Ensure the correct bus mode (8/16 bits) gets enabled
*/
ace_writew(width == 8 ? 0 : 0x0001, 0);
part_init(&systemace_dev);
}
*descp = &systemace_dev;
return 0;
}
U_BOOT_LEGACY_BLK(systemace) = {
.if_typename = "ace",
.if_type = IF_TYPE_SYSTEMACE,
.max_devs = 1,
.get_dev = systemace_get_dev,
};
#endif

View file

@ -112,6 +112,8 @@ int device_unbind(struct udevice *dev)
devres_release_all(dev);
if (dev->flags & DM_NAME_ALLOCED)
free((char *)dev->name);
free(dev);
return 0;

View file

@ -657,8 +657,8 @@ fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name)
#if CONFIG_IS_ENABLED(OF_CONTROL)
int index;
index = fdt_find_string(gd->fdt_blob, dev->parent->of_offset,
"reg-names", name);
index = fdt_find_string(gd->fdt_blob, dev->of_offset, "reg-names",
name);
if (index < 0)
return index;
@ -706,12 +706,18 @@ bool device_is_last_sibling(struct udevice *dev)
return list_is_last(&dev->sibling_node, &parent->child_head);
}
void device_set_name_alloced(struct udevice *dev)
{
dev->flags |= DM_NAME_ALLOCED;
}
int device_set_name(struct udevice *dev, const char *name)
{
name = strdup(name);
if (!name)
return -ENOMEM;
dev->name = name;
device_set_name_alloced(dev);
return 0;
}

View file

@ -171,6 +171,10 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
dm_dbg(" - found match at '%s'\n", entry->name);
ret = device_bind(parent, entry, name, NULL, offset, &dev);
if (ret == -ENODEV) {
dm_dbg("Driver '%s' refuses to bind\n", entry->name);
continue;
}
if (ret) {
dm_warn("Error binding driver '%s': %d\n", entry->name,
ret);

View file

@ -50,8 +50,9 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
if (dfu->data.mmc.hw_partition >= 0) {
part_num_bkp = mmc->block_dev.hwpart;
ret = mmc_select_hwpart(dfu->data.mmc.dev_num,
dfu->data.mmc.hw_partition);
ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
dfu->data.mmc.dev_num,
dfu->data.mmc.hw_partition);
if (ret)
return ret;
}
@ -75,12 +76,16 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
if (n != blk_count) {
error("MMC operation failed");
if (dfu->data.mmc.hw_partition >= 0)
mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
blk_select_hwpart_devnum(IF_TYPE_MMC,
dfu->data.mmc.dev_num,
part_num_bkp);
return -EIO;
}
if (dfu->data.mmc.hw_partition >= 0) {
ret = mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
dfu->data.mmc.dev_num,
part_num_bkp);
if (ret)
return ret;
}

193
drivers/gpio/74x164_gpio.c Normal file
View file

@ -0,0 +1,193 @@
/*
* Take drivers/gpio/gpio-74x164.c as reference.
*
* 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*
*/
#include <common.h>
#include <errno.h>
#include <dm.h>
#include <fdtdec.h>
#include <malloc.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dt-bindings/gpio/gpio.h>
#include <spi.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* struct gen_74x164_chip - Data for 74Hx164
*
* @oe: OE pin
* @nregs: number of registers
* @buffer: buffer for chained chips
*/
#define GEN_74X164_NUMBER_GPIOS 8
struct gen_74x164_priv {
struct gpio_desc oe;
u32 nregs;
/*
* Since the nregs are chained, every byte sent will make
* the previous byte shift to the next register in the
* chain. Thus, the first byte sent will end up in the last
* register at the end of the transfer. So, to have a logical
* numbering, store the bytes in reverse order.
*/
u8 *buffer;
};
static int gen_74x164_write_conf(struct udevice *dev)
{
struct gen_74x164_priv *priv = dev_get_priv(dev);
int ret;
ret = dm_spi_claim_bus(dev);
if (ret)
return ret;
ret = dm_spi_xfer(dev, priv->nregs * 8, priv->buffer, NULL,
SPI_XFER_BEGIN | SPI_XFER_END);
dm_spi_release_bus(dev);
return ret;
}
static int gen_74x164_get_value(struct udevice *dev, unsigned offset)
{
struct gen_74x164_priv *priv = dev_get_priv(dev);
uint bank = priv->nregs - 1 - offset / 8;
uint pin = offset % 8;
return (priv->buffer[bank] >> pin) & 0x1;
}
static int gen_74x164_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct gen_74x164_priv *priv = dev_get_priv(dev);
uint bank = priv->nregs - 1 - offset / 8;
uint pin = offset % 8;
int ret;
if (value)
priv->buffer[bank] |= 1 << pin;
else
priv->buffer[bank] &= ~(1 << pin);
ret = gen_74x164_write_conf(dev);
if (ret)
return ret;
return 0;
}
static int gen_74x164_direction_input(struct udevice *dev, unsigned offset)
{
return -ENOSYS;
}
static int gen_74x164_direction_output(struct udevice *dev, unsigned offset,
int value)
{
return gen_74x164_set_value(dev, offset, value);
}
static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
{
return GPIOF_OUTPUT;
}
static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static const struct dm_gpio_ops gen_74x164_ops = {
.direction_input = gen_74x164_direction_input,
.direction_output = gen_74x164_direction_output,
.get_value = gen_74x164_get_value,
.set_value = gen_74x164_set_value,
.get_function = gen_74x164_get_function,
.xlate = gen_74x164_xlate,
};
static int gen_74x164_probe(struct udevice *dev)
{
struct gen_74x164_priv *priv = dev_get_priv(dev);
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
char *str, name[32];
int ret;
const void *fdt = gd->fdt_blob;
int node = dev->of_offset;
snprintf(name, sizeof(name), "%s_", dev->name);
str = strdup(name);
if (!str)
return -ENOMEM;
/*
* See Linux kernel:
* Documentation/devicetree/bindings/gpio/gpio-74x164.txt
*/
priv->nregs = fdtdec_get_int(fdt, node, "registers-number", 1);
priv->buffer = calloc(priv->nregs, sizeof(u8));
if (!priv->buffer) {
ret = -ENOMEM;
goto free_str;
}
ret = fdtdec_get_byte_array(fdt, node, "registers-default",
priv->buffer, priv->nregs);
if (ret)
dev_dbg(dev, "No registers-default property\n");
ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret) {
dev_err(dev, "No oe-pins property\n");
goto free_buf;
}
uc_priv->bank_name = str;
uc_priv->gpio_count = priv->nregs * 8;
ret = gen_74x164_write_conf(dev);
if (ret)
goto free_buf;
dev_dbg(dev, "%s is ready\n", dev->name);
return 0;
free_buf:
free(priv->buffer);
free_str:
free(str);
return ret;
}
static const struct udevice_id gen_74x164_ids[] = {
{ .compatible = "fairchild,74hc595" },
{ }
};
U_BOOT_DRIVER(74x164) = {
.name = "74x164",
.id = UCLASS_GPIO,
.ops = &gen_74x164_ops,
.probe = gen_74x164_probe,
.priv_auto_alloc_size = sizeof(struct gen_74x164_priv),
.of_match = gen_74x164_ids,
};

View file

@ -143,4 +143,34 @@ config ZYNQ_GPIO
help
Supports GPIO access on Zynq SoC.
config DM_74X164
bool "74x164 serial-in/parallel-out 8-bits shift register"
depends on DM_GPIO
help
Driver for 74x164 compatible serial-in/parallel-out 8-outputs
shift registers, such as 74lv165, 74hc595.
This driver can be used to provide access to more gpio outputs.
config DM_PCA953X
bool "PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports"
depends on DM_GPIO
help
Say yes here to provide access to several register-oriented
SMBus I/O expanders, made mostly by NXP or TI. Compatible
models include:
4 bits: pca9536, pca9537
8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554,
pca9556, pca9557, pca9574, tca6408, xra1202
16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575,
tca6416
24 bits: tca6424
40 bits: pca9505, pca9698
Now, max 24 bits chips and PCA953X compatible chips are
supported
endmenu

View file

@ -11,6 +11,9 @@ obj-$(CONFIG_AXP_GPIO) += axp_gpio.o
endif
obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
obj-$(CONFIG_DM_PCA953X) += pca953x_gpio.o
obj-$(CONFIG_DM_74X164) += 74x164_gpio.o
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o

View file

@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
#include <dt-bindings/gpio/gpio.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
@ -113,19 +114,33 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
return 0;
}
int gpio_xlate_offs_flags(struct udevice *dev,
struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
if (args->args_count < 1)
return -EINVAL;
desc->offset = args->args[0];
if (args->args_count < 2)
return 0;
if (args->args[1] & GPIO_ACTIVE_LOW)
desc->flags = GPIOD_ACTIVE_LOW;
return 0;
}
static int gpio_find_and_xlate(struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
/* Use the first argument as the offset by default */
if (args->args_count > 0)
desc->offset = args->args[0];
if (ops->xlate)
return ops->xlate(desc->dev, desc, args);
else
desc->offset = -1;
desc->flags = 0;
return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
return gpio_xlate_offs_flags(desc->dev, desc, args);
}
int dm_gpio_request(struct gpio_desc *desc, const char *label)
@ -605,6 +620,7 @@ static int _gpio_request_by_name_nodev(const void *blob, int node,
desc->dev = NULL;
desc->offset = 0;
desc->flags = 0;
ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
"#gpio-cells", 0, index, &args);
if (ret) {

View file

@ -162,15 +162,6 @@ static int broadwell_gpio_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static int broadwell_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static const struct dm_gpio_ops gpio_broadwell_ops = {
.request = broadwell_gpio_request,
.direction_input = broadwell_gpio_direction_input,
@ -178,7 +169,6 @@ static const struct dm_gpio_ops gpio_broadwell_ops = {
.get_value = broadwell_gpio_get_value,
.set_value = broadwell_gpio_set_value,
.get_function = broadwell_gpio_get_function,
.xlate = broadwell_gpio_xlate,
};
static const struct udevice_id intel_broadwell_gpio_ids[] = {

View file

@ -25,7 +25,6 @@
#include <asm/io.h>
#include <asm/errno.h>
#include <malloc.h>
#include <dt-bindings/gpio/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@ -277,22 +276,12 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
static int omap_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static const struct dm_gpio_ops gpio_omap_ops = {
.direction_input = omap_gpio_direction_input,
.direction_output = omap_gpio_direction_output,
.get_value = omap_gpio_get_value,
.set_value = omap_gpio_set_value,
.get_function = omap_gpio_get_function,
.xlate = omap_gpio_xlate,
};
static int omap_gpio_probe(struct udevice *dev)

351
drivers/gpio/pca953x_gpio.c Normal file
View file

@ -0,0 +1,351 @@
/*
* Take linux kernel driver drivers/gpio/gpio-pca953x.c for reference.
*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*
*/
/*
* Note:
* The driver's compatible table is borrowed from Linux Kernel,
* but now max supported gpio pins is 24 and only PCA953X_TYPE
* is supported. PCA957X_TYPE is not supported now.
* Also the Polarity Inversion feature is not supported now.
*
* TODO:
* 1. Support PCA957X_TYPE
* 2. Support max 40 gpio pins
* 3. Support Plolarity Inversion
*/
#include <common.h>
#include <errno.h>
#include <dm.h>
#include <fdtdec.h>
#include <i2c.h>
#include <malloc.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dt-bindings/gpio/gpio.h>
#define PCA953X_INPUT 0
#define PCA953X_OUTPUT 1
#define PCA953X_INVERT 2
#define PCA953X_DIRECTION 3
#define PCA_GPIO_MASK 0x00FF
#define PCA_INT 0x0100
#define PCA953X_TYPE 0x1000
#define PCA957X_TYPE 0x2000
#define PCA_TYPE_MASK 0xF000
#define PCA_CHIP_TYPE(x) ((x) & PCA_TYPE_MASK)
enum {
PCA953X_DIRECTION_IN,
PCA953X_DIRECTION_OUT,
};
#define MAX_BANK 3
#define BANK_SZ 8
DECLARE_GLOBAL_DATA_PTR;
/*
* struct pca953x_info - Data for pca953x
*
* @dev: udevice structure for the device
* @addr: i2c slave address
* @invert: Polarity inversion or not
* @gpio_count: the number of gpio pins that the device supports
* @chip_type: indicate the chip type,PCA953X or PCA957X
* @bank_count: the number of banks that the device supports
* @reg_output: array to hold the value of output registers
* @reg_direction: array to hold the value of direction registers
*/
struct pca953x_info {
struct udevice *dev;
int addr;
int invert;
int gpio_count;
int chip_type;
int bank_count;
u8 reg_output[MAX_BANK];
u8 reg_direction[MAX_BANK];
};
static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
int offset)
{
struct pca953x_info *info = dev_get_platdata(dev);
int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
int off = offset / BANK_SZ;
int ret = 0;
ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1);
if (ret) {
dev_err(dev, "%s error\n", __func__);
return ret;
}
return 0;
}
static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
int offset)
{
struct pca953x_info *info = dev_get_platdata(dev);
int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
int off = offset / BANK_SZ;
int ret;
u8 byte;
ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1);
if (ret) {
dev_err(dev, "%s error\n", __func__);
return ret;
}
*val = byte;
return 0;
}
static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
{
struct pca953x_info *info = dev_get_platdata(dev);
int ret = 0;
if (info->gpio_count <= 8) {
ret = dm_i2c_read(dev, reg, val, 1);
} else if (info->gpio_count <= 16) {
ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
} else {
dev_err(dev, "Unsupported now\n");
return -EINVAL;
}
return ret;
}
static int pca953x_is_output(struct udevice *dev, int offset)
{
struct pca953x_info *info = dev_get_platdata(dev);
int bank = offset / BANK_SZ;
int off = offset % BANK_SZ;
/*0: output; 1: input */
return !(info->reg_direction[bank] & (1 << off));
}
static int pca953x_get_value(struct udevice *dev, unsigned offset)
{
int ret;
u8 val = 0;
ret = pca953x_read_single(dev, PCA953X_INPUT, &val, offset);
if (ret)
return ret;
return (val >> offset) & 0x1;
}
static int pca953x_set_value(struct udevice *dev, unsigned offset,
int value)
{
struct pca953x_info *info = dev_get_platdata(dev);
int bank = offset / BANK_SZ;
int off = offset % BANK_SZ;
u8 val;
int ret;
if (value)
val = info->reg_output[bank] | (1 << off);
else
val = info->reg_output[bank] & ~(1 << off);
ret = pca953x_write_single(dev, PCA953X_OUTPUT, val, offset);
if (ret)
return ret;
info->reg_output[bank] = val;
return 0;
}
static int pca953x_set_direction(struct udevice *dev, unsigned offset, int dir)
{
struct pca953x_info *info = dev_get_platdata(dev);
int bank = offset / BANK_SZ;
int off = offset % BANK_SZ;
u8 val;
int ret;
if (dir == PCA953X_DIRECTION_IN)
val = info->reg_direction[bank] | (1 << off);
else
val = info->reg_direction[bank] & ~(1 << off);
ret = pca953x_write_single(dev, PCA953X_DIRECTION, val, offset);
if (ret)
return ret;
info->reg_direction[bank] = val;
return 0;
}
static int pca953x_direction_input(struct udevice *dev, unsigned offset)
{
return pca953x_set_direction(dev, offset, PCA953X_DIRECTION_IN);
}
static int pca953x_direction_output(struct udevice *dev, unsigned offset,
int value)
{
/* Configure output value. */
pca953x_set_value(dev, offset, value);
/* Configure direction as output. */
pca953x_set_direction(dev, offset, PCA953X_DIRECTION_OUT);
return 0;
}
static int pca953x_get_function(struct udevice *dev, unsigned offset)
{
if (pca953x_is_output(dev, offset))
return GPIOF_OUTPUT;
else
return GPIOF_INPUT;
}
static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static const struct dm_gpio_ops pca953x_ops = {
.direction_input = pca953x_direction_input,
.direction_output = pca953x_direction_output,
.get_value = pca953x_get_value,
.set_value = pca953x_set_value,
.get_function = pca953x_get_function,
.xlate = pca953x_xlate,
};
static int pca953x_probe(struct udevice *dev)
{
struct pca953x_info *info = dev_get_platdata(dev);
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
char name[32], *str;
int addr;
ulong driver_data;
int ret;
if (!info) {
dev_err(dev, "platdata not ready\n");
return -ENOMEM;
}
if (!chip) {
dev_err(dev, "i2c not ready\n");
return -ENODEV;
}
addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
if (addr == 0)
return -ENODEV;
info->addr = addr;
driver_data = dev_get_driver_data(dev);
info->gpio_count = driver_data & PCA_GPIO_MASK;
if (info->gpio_count > MAX_BANK * BANK_SZ) {
dev_err(dev, "Max support %d pins now\n", MAX_BANK * BANK_SZ);
return -EINVAL;
}
info->chip_type = PCA_CHIP_TYPE(driver_data);
if (info->chip_type != PCA953X_TYPE) {
dev_err(dev, "Only support PCA953X chip type now.\n");
return -EINVAL;
}
info->bank_count = DIV_ROUND_UP(info->gpio_count, BANK_SZ);
ret = pca953x_read_regs(dev, PCA953X_OUTPUT, info->reg_output);
if (ret) {
dev_err(dev, "Error reading output register\n");
return ret;
}
ret = pca953x_read_regs(dev, PCA953X_DIRECTION, info->reg_direction);
if (ret) {
dev_err(dev, "Error reading direction register\n");
return ret;
}
snprintf(name, sizeof(name), "gpio@%x_", info->addr);
str = strdup(name);
if (!str)
return -ENOMEM;
uc_priv->bank_name = str;
uc_priv->gpio_count = info->gpio_count;
dev_dbg(dev, "%s is ready\n", str);
return 0;
}
#define OF_953X(__nrgpio, __int) (ulong)(__nrgpio | PCA953X_TYPE | __int)
#define OF_957X(__nrgpio, __int) (ulong)(__nrgpio | PCA957X_TYPE | __int)
static const struct udevice_id pca953x_ids[] = {
{ .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
{ .compatible = "nxp,pca9534", .data = OF_953X(8, PCA_INT), },
{ .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
{ .compatible = "nxp,pca9536", .data = OF_953X(4, 0), },
{ .compatible = "nxp,pca9537", .data = OF_953X(4, PCA_INT), },
{ .compatible = "nxp,pca9538", .data = OF_953X(8, PCA_INT), },
{ .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), },
{ .compatible = "nxp,pca9554", .data = OF_953X(8, PCA_INT), },
{ .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), },
{ .compatible = "nxp,pca9556", .data = OF_953X(8, 0), },
{ .compatible = "nxp,pca9557", .data = OF_953X(8, 0), },
{ .compatible = "nxp,pca9574", .data = OF_957X(8, PCA_INT), },
{ .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
{ .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
{ .compatible = "maxim,max7310", .data = OF_953X(8, 0), },
{ .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
{ .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
{ .compatible = "maxim,max7315", .data = OF_953X(8, PCA_INT), },
{ .compatible = "ti,pca6107", .data = OF_953X(8, PCA_INT), },
{ .compatible = "ti,tca6408", .data = OF_953X(8, PCA_INT), },
{ .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
{ .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
{ .compatible = "onsemi,pca9654", .data = OF_953X(8, PCA_INT), },
{ .compatible = "exar,xra1202", .data = OF_953X(8, 0), },
{ }
};
U_BOOT_DRIVER(pca953x) = {
.name = "pca953x",
.id = UCLASS_GPIO,
.ops = &pca953x_ops,
.probe = pca953x_probe,
.platdata_auto_alloc_size = sizeof(struct pca953x_info),
.of_match = pca953x_ids,
};

View file

@ -12,7 +12,6 @@
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/compat.h>
#include <dt-bindings/gpio/gpio.h>
#include <mach/pic32.h>
DECLARE_GLOBAL_DATA_PTR;
@ -99,14 +98,6 @@ static int pic32_gpio_direction_output(struct udevice *dev,
return 0;
}
static int pic32_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static int pic32_gpio_get_function(struct udevice *dev, unsigned offset)
{
int ret = GPIOF_UNUSED;
@ -131,7 +122,6 @@ static const struct dm_gpio_ops gpio_pic32_ops = {
.get_value = pic32_gpio_get_value,
.set_value = pic32_gpio_set_value,
.get_function = pic32_gpio_get_function,
.xlate = pic32_gpio_xlate,
};
static int pic32_gpio_probe(struct udevice *dev)

View file

@ -16,7 +16,6 @@
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <dm/pinctrl.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/clock/rk3288-cru.h>
enum {
@ -98,15 +97,6 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
#endif
}
static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static int rockchip_gpio_probe(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
@ -135,7 +125,6 @@ static const struct dm_gpio_ops gpio_rockchip_ops = {
.get_value = rockchip_gpio_get_value,
.set_value = rockchip_gpio_set_value,
.get_function = rockchip_gpio_get_function,
.xlate = rockchip_gpio_xlate,
};
static const struct udevice_id rockchip_gpio_ids[] = {

View file

@ -13,7 +13,6 @@
#include <asm/io.h>
#include <asm/gpio.h>
#include <dm/device-internal.h>
#include <dt-bindings/gpio/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@ -276,22 +275,12 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_FUNC;
}
static int exynos_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
return 0;
}
static const struct dm_gpio_ops gpio_exynos_ops = {
.direction_input = exynos_gpio_direction_input,
.direction_output = exynos_gpio_direction_output,
.get_value = exynos_gpio_get_value,
.set_value = exynos_gpio_set_value,
.get_function = exynos_gpio_get_function,
.xlate = exynos_gpio_xlate,
};
static int gpio_exynos_probe(struct udevice *dev)

View file

@ -2,7 +2,7 @@ menu "MMC Host controller Support"
config MMC
bool "Enable MMC support"
depends on ARCH_SUNXI
depends on ARCH_SUNXI || SANDBOX
help
TODO: Move all architectures to use this option
@ -58,4 +58,13 @@ config MMC_UNIPHIER
help
This selects support for the SD/MMC Host Controller on UniPhier SoCs.
config SANDBOX_MMC
bool "Sandbox MMC support"
depends on MMC && SANDBOX
help
This select a dummy sandbox MMC driver. At present this does nothing
other than allow sandbox to be build with MMC support. This
improves build coverage for sandbox and makes it easier to detect
MMC build errors with sandbox.
endmenu

View file

@ -5,7 +5,13 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_DM_MMC) += mmc-uclass.o
ifdef CONFIG_DM_MMC
obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
endif
ifndef CONFIG_BLK
obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
endif
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
@ -34,7 +40,11 @@ obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
ifdef CONFIG_BLK
ifdef CONFIG_GENERIC_MMC
obj-$(CONFIG_SANDBOX) += sandbox_mmc.o
endif
endif
obj-$(CONFIG_SDHCI) += sdhci.o
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o

View file

@ -21,6 +21,112 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev)
return upriv->mmc;
}
#ifdef CONFIG_BLK
struct mmc *find_mmc_device(int dev_num)
{
struct udevice *dev, *mmc_dev;
int ret;
ret = blk_get_device(IF_TYPE_MMC, dev_num, &dev);
if (ret) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("MMC Device %d not found\n", dev_num);
#endif
return NULL;
}
mmc_dev = dev_get_parent(dev);
return mmc_get_mmc_dev(mmc_dev);
}
int get_mmc_num(void)
{
return max(blk_find_max_devnum(IF_TYPE_MMC), 0);
}
int mmc_get_next_devnum(void)
{
int ret;
ret = get_mmc_num();
if (ret < 0)
return ret;
return ret + 1;
}
struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
{
struct blk_desc *desc;
struct udevice *dev;
device_find_first_child(mmc->dev, &dev);
if (!dev)
return NULL;
desc = dev_get_uclass_platdata(dev);
return desc;
}
void mmc_do_preinit(void)
{
struct udevice *dev;
struct uclass *uc;
int ret;
ret = uclass_get(UCLASS_MMC, &uc);
if (ret)
return;
uclass_foreach_dev(dev, uc) {
struct mmc *m = mmc_get_mmc_dev(dev);
if (!m)
continue;
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
mmc_set_preinit(m, 1);
#endif
if (m->preinit)
mmc_start_init(m);
}
}
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
void print_mmc_devices(char separator)
{
struct udevice *dev;
char *mmc_type;
bool first = true;
for (uclass_first_device(UCLASS_MMC, &dev);
dev;
uclass_next_device(&dev)) {
struct mmc *m = mmc_get_mmc_dev(dev);
if (!first) {
printf("%c", separator);
if (separator != '\n')
puts(" ");
}
if (m->has_init)
mmc_type = IS_SD(m) ? "SD" : "eMMC";
else
mmc_type = NULL;
printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum);
if (mmc_type)
printf(" (%s)", mmc_type);
}
printf("\n");
}
#else
void print_mmc_devices(char separator) { }
#endif
#endif /* CONFIG_BLK */
U_BOOT_DRIVER(mmc) = {
.name = "mmc",
.id = UCLASS_MMC,

View file

@ -21,9 +21,6 @@
#include <div64.h>
#include "mmc_private.h"
static struct list_head mmc_devices;
static int cur_dev_num = -1;
__weak int board_mmc_getwp(struct mmc *mmc)
{
return -1;
@ -178,25 +175,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
return mmc_send_cmd(mmc, &cmd, NULL);
}
struct mmc *find_mmc_device(int dev_num)
{
struct mmc *m;
struct list_head *entry;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
if (m->block_dev.devnum == dev_num)
return m;
}
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("MMC Device %d not found\n", dev_num);
#endif
return NULL;
}
static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
lbaint_t blkcnt)
{
@ -238,9 +216,17 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
return blkcnt;
}
#ifdef CONFIG_BLK
static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
void *dst)
#else
static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *dst)
#endif
{
#ifdef CONFIG_BLK
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
int dev_num = block_dev->devnum;
int err;
lbaint_t cur, blocks_todo = blkcnt;
@ -252,14 +238,14 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
if (!mmc)
return 0;
err = mmc_select_hwpart(dev_num, block_dev->hwpart);
err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
if (err < 0)
return 0;
if ((start + blkcnt) > mmc->block_dev.lba) {
if ((start + blkcnt) > block_dev->lba) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
start + blkcnt, mmc->block_dev.lba);
start + blkcnt, block_dev->lba);
#endif
return 0;
}
@ -577,43 +563,15 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
return -1;
}
mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
return 0;
}
int mmc_select_hwpart(int dev_num, int hwpart)
static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
{
struct mmc *mmc = find_mmc_device(dev_num);
int ret;
if (!mmc)
return -ENODEV;
if (mmc->block_dev.hwpart == hwpart)
return 0;
if (mmc->part_config == MMCPART_NOAVAILABLE) {
printf("Card doesn't support part_switch\n");
return -EMEDIUMTYPE;
}
ret = mmc_switch_part(dev_num, hwpart);
if (ret)
return ret;
return 0;
}
int mmc_switch_part(int dev_num, unsigned int part_num)
{
struct mmc *mmc = find_mmc_device(dev_num);
int ret;
if (!mmc)
return -1;
ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
(mmc->part_config & ~PART_ACCESS_MASK)
| (part_num & PART_ACCESS_MASK));
@ -624,12 +582,55 @@ int mmc_switch_part(int dev_num, unsigned int part_num)
*/
if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
ret = mmc_set_capacity(mmc, part_num);
mmc->block_dev.hwpart = part_num;
mmc_get_blk_desc(mmc)->hwpart = part_num;
}
return ret;
}
#ifdef CONFIG_BLK
static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
{
struct udevice *mmc_dev = dev_get_parent(bdev);
struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
struct blk_desc *desc = dev_get_uclass_platdata(bdev);
int ret;
if (desc->hwpart == hwpart)
return 0;
if (mmc->part_config == MMCPART_NOAVAILABLE)
return -EMEDIUMTYPE;
ret = mmc_switch_part(mmc, hwpart);
if (ret)
return ret;
return 0;
}
#else
static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
{
struct mmc *mmc = find_mmc_device(desc->devnum);
int ret;
if (!mmc)
return -ENODEV;
if (mmc->block_dev.hwpart == hwpart)
return 0;
if (mmc->part_config == MMCPART_NOAVAILABLE)
return -EMEDIUMTYPE;
ret = mmc_switch_part(mmc, hwpart);
if (ret)
return ret;
return 0;
}
#endif
int mmc_hwpart_config(struct mmc *mmc,
const struct mmc_hwpart_conf *conf,
enum mmc_hwpart_conf_mode mode)
@ -1039,6 +1040,7 @@ static int mmc_startup(struct mmc *mmc)
int timeout = 1000;
bool has_parts = false;
bool part_completed;
struct blk_desc *bdesc;
#ifdef CONFIG_MMC_SPI_CRC_ON
if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
@ -1335,7 +1337,7 @@ static int mmc_startup(struct mmc *mmc)
mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
}
err = mmc_set_capacity(mmc, mmc->block_dev.hwpart);
err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
if (err)
return err;
@ -1475,31 +1477,32 @@ static int mmc_startup(struct mmc *mmc)
}
/* fill in device description */
mmc->block_dev.lun = 0;
mmc->block_dev.hwpart = 0;
mmc->block_dev.type = 0;
mmc->block_dev.blksz = mmc->read_bl_len;
mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
bdesc = mmc_get_blk_desc(mmc);
bdesc->lun = 0;
bdesc->hwpart = 0;
bdesc->type = 0;
bdesc->blksz = mmc->read_bl_len;
bdesc->log2blksz = LOG2(bdesc->blksz);
bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
#if !defined(CONFIG_SPL_BUILD) || \
(defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
!defined(CONFIG_USE_TINY_PRINTF))
sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
(mmc->cid[3] >> 16) & 0xffff);
sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
(mmc->cid[2] >> 24) & 0xff);
sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
(mmc->cid[2] >> 16) & 0xf);
#else
mmc->block_dev.vendor[0] = 0;
mmc->block_dev.product[0] = 0;
mmc->block_dev.revision[0] = 0;
bdesc->vendor[0] = 0;
bdesc->product[0] = 0;
bdesc->revision[0] = 0;
#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
part_init(&mmc->block_dev);
part_init(bdesc);
#endif
return 0;
@ -1537,8 +1540,55 @@ int __deprecated mmc_register(struct mmc *mmc)
return -1;
}
#ifdef CONFIG_BLK
int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
{
struct blk_desc *bdesc;
struct udevice *bdev;
int ret;
ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512,
0, &bdev);
if (ret) {
debug("Cannot create block device\n");
return ret;
}
bdesc = dev_get_uclass_platdata(bdev);
mmc->cfg = cfg;
mmc->priv = dev;
/* the following chunk was from mmc_register() */
/* Setup dsr related values */
mmc->dsr_imp = 0;
mmc->dsr = 0xffffffff;
/* Setup the universal parts of the block interface just once */
bdesc->removable = 1;
/* setup initial part type */
bdesc->part_type = mmc->cfg->part_type;
mmc->dev = dev;
return 0;
}
int mmc_unbind(struct udevice *dev)
{
struct udevice *bdev;
device_find_first_child(dev, &bdev);
if (bdev) {
device_remove(bdev);
device_unbind(bdev);
}
return 0;
}
#else
struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
{
struct blk_desc *bdesc;
struct mmc *mmc;
/* quick validation */
@ -1559,19 +1609,17 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
mmc->dsr_imp = 0;
mmc->dsr = 0xffffffff;
/* Setup the universal parts of the block interface just once */
mmc->block_dev.if_type = IF_TYPE_MMC;
mmc->block_dev.devnum = cur_dev_num++;
mmc->block_dev.removable = 1;
mmc->block_dev.block_read = mmc_bread;
mmc->block_dev.block_write = mmc_bwrite;
mmc->block_dev.block_erase = mmc_berase;
bdesc = mmc_get_blk_desc(mmc);
bdesc->if_type = IF_TYPE_MMC;
bdesc->removable = 1;
bdesc->devnum = mmc_get_next_devnum();
bdesc->block_read = mmc_bread;
bdesc->block_write = mmc_bwrite;
bdesc->block_erase = mmc_berase;
/* setup initial part type */
mmc->block_dev.part_type = mmc->cfg->part_type;
INIT_LIST_HEAD(&mmc->link);
list_add_tail(&mmc->link, &mmc_devices);
bdesc->part_type = mmc->cfg->part_type;
mmc_list_add(mmc);
return mmc;
}
@ -1581,15 +1629,23 @@ void mmc_destroy(struct mmc *mmc)
/* only freeing memory for now */
free(mmc);
}
#endif
#ifdef CONFIG_PARTITIONS
struct blk_desc *mmc_get_dev(int dev)
#ifndef CONFIG_BLK
static int mmc_get_dev(int dev, struct blk_desc **descp)
{
struct mmc *mmc = find_mmc_device(dev);
if (!mmc || mmc_init(mmc))
return NULL;
int ret;
return &mmc->block_dev;
if (!mmc)
return -ENODEV;
ret = mmc_init(mmc);
if (ret)
return ret;
*descp = &mmc->block_dev;
return 0;
}
#endif
@ -1636,7 +1692,7 @@ int mmc_start_init(struct mmc *mmc)
return err;
/* The internal partition reset to user partition(0) at every CMD0*/
mmc->block_dev.hwpart = 0;
mmc_get_blk_desc(mmc)->hwpart = 0;
/* Test for SD version 2 */
err = mmc_send_if_cond(mmc);
@ -1683,7 +1739,11 @@ int mmc_init(struct mmc *mmc)
{
int err = 0;
unsigned start;
#ifdef CONFIG_DM_MMC
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
upriv->mmc = mmc;
#endif
if (mmc->has_init)
return 0;
@ -1716,66 +1776,11 @@ __weak int board_mmc_init(bd_t *bis)
return -1;
}
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
void print_mmc_devices(char separator)
{
struct mmc *m;
struct list_head *entry;
char *mmc_type;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
if (m->has_init)
mmc_type = IS_SD(m) ? "SD" : "eMMC";
else
mmc_type = NULL;
printf("%s: %d", m->cfg->name, m->block_dev.devnum);
if (mmc_type)
printf(" (%s)", mmc_type);
if (entry->next != &mmc_devices) {
printf("%c", separator);
if (separator != '\n')
puts (" ");
}
}
printf("\n");
}
#else
void print_mmc_devices(char separator) { }
#endif
int get_mmc_num(void)
{
return cur_dev_num;
}
void mmc_set_preinit(struct mmc *mmc, int preinit)
{
mmc->preinit = preinit;
}
static void do_preinit(void)
{
struct mmc *m;
struct list_head *entry;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
mmc_set_preinit(m, 1);
#endif
if (m->preinit)
mmc_start_init(m);
}
}
#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
static int mmc_probe(bd_t *bis)
{
@ -1828,9 +1833,9 @@ int mmc_initialize(bd_t *bis)
return 0;
initialized = 1;
INIT_LIST_HEAD (&mmc_devices);
cur_dev_num = 0;
#ifndef CONFIG_BLK
mmc_list_init();
#endif
ret = mmc_probe(bis);
if (ret)
return ret;
@ -1839,7 +1844,7 @@ int mmc_initialize(bd_t *bis)
print_mmc_devices(',');
#endif
do_preinit();
mmc_do_preinit();
return 0;
}
@ -1965,3 +1970,25 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
enable);
}
#endif
#ifdef CONFIG_BLK
static const struct blk_ops mmc_blk_ops = {
.read = mmc_bread,
.write = mmc_bwrite,
.select_hwpart = mmc_select_hwpart,
};
U_BOOT_DRIVER(mmc_blk) = {
.name = "mmc_blk",
.id = UCLASS_BLK,
.ops = &mmc_blk_ops,
};
#else
U_BOOT_LEGACY_BLK(mmc) = {
.if_typename = "mmc",
.if_type = IF_TYPE_MMC,
.max_devs = -1,
.get_dev = mmc_get_dev,
.select_hwpart = mmc_select_hwpartp,
};
#endif

108
drivers/mmc/mmc_legacy.c Normal file
View file

@ -0,0 +1,108 @@
/*
* Copyright (C) 2016 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <mmc.h>
static struct list_head mmc_devices;
static int cur_dev_num = -1;
struct mmc *find_mmc_device(int dev_num)
{
struct mmc *m;
struct list_head *entry;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
if (m->block_dev.devnum == dev_num)
return m;
}
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("MMC Device %d not found\n", dev_num);
#endif
return NULL;
}
int mmc_get_next_devnum(void)
{
return cur_dev_num++;
}
struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
{
return &mmc->block_dev;
}
int get_mmc_num(void)
{
return cur_dev_num;
}
void mmc_do_preinit(void)
{
struct mmc *m;
struct list_head *entry;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
mmc_set_preinit(m, 1);
#endif
if (m->preinit)
mmc_start_init(m);
}
}
void mmc_list_init(void)
{
INIT_LIST_HEAD(&mmc_devices);
cur_dev_num = 0;
}
void mmc_list_add(struct mmc *mmc)
{
INIT_LIST_HEAD(&mmc->link);
list_add_tail(&mmc->link, &mmc_devices);
}
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
void print_mmc_devices(char separator)
{
struct mmc *m;
struct list_head *entry;
char *mmc_type;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
if (m->has_init)
mmc_type = IS_SD(m) ? "SD" : "eMMC";
else
mmc_type = NULL;
printf("%s: %d", m->cfg->name, m->block_dev.devnum);
if (mmc_type)
printf(" (%s)", mmc_type);
if (entry->next != &mmc_devices) {
printf("%c", separator);
if (separator != '\n')
puts(" ");
}
}
printf("\n");
}
#else
void print_mmc_devices(char separator) { }
#endif

View file

@ -25,8 +25,13 @@ void mmc_adapter_card_type_ident(void);
unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt);
unsigned long mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *src);
#ifdef CONFIG_BLK
ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
const void *src);
#else
ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
const void *src);
#endif
#else /* CONFIG_SPL_BUILD */
@ -46,4 +51,28 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
#endif /* CONFIG_SPL_BUILD */
/**
* mmc_get_next_devnum() - Get the next available MMC device number
*
* @return next available device number (0 = first), or -ve on error
*/
int mmc_get_next_devnum(void);
/**
* mmc_do_preinit() - Get an MMC device ready for use
*/
void mmc_do_preinit(void);
/**
* mmc_list_init() - Set up the list of MMC devices
*/
void mmc_list_init(void);
/**
* mmc_list_add() - Add a new MMC device to the list of devices
*
* @mmc: Device to add
*/
void mmc_list_add(struct mmc *mmc);
#endif /* _MMC_PRIVATE_H_ */

View file

@ -9,6 +9,7 @@
#include <config.h>
#include <common.h>
#include <dm.h>
#include <part.h>
#include <div64.h>
#include <linux/math64.h>
@ -78,7 +79,8 @@ unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
if (!mmc)
return -1;
err = mmc_select_hwpart(dev_num, block_dev->hwpart);
err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num,
block_dev->hwpart);
if (err < 0)
return -1;
@ -121,9 +123,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
struct mmc_data data;
int timeout = 1000;
if ((start + blkcnt) > mmc->block_dev.lba) {
if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) {
printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
start + blkcnt, mmc->block_dev.lba);
start + blkcnt, mmc_get_blk_desc(mmc)->lba);
return 0;
}
@ -171,9 +173,17 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
return blkcnt;
}
#ifdef CONFIG_BLK
ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
const void *src)
#else
ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
const void *src)
#endif
{
#ifdef CONFIG_BLK
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
int dev_num = block_dev->devnum;
lbaint_t cur, blocks_todo = blkcnt;
int err;
@ -182,7 +192,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
if (!mmc)
return 0;
err = mmc_select_hwpart(dev_num, block_dev->hwpart);
err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart);
if (err < 0)
return 0;

View file

@ -825,6 +825,7 @@ static int omap_hsmmc_probe(struct udevice *dev)
gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN);
#endif
mmc->dev = dev;
upriv->mmc = mmc;
return 0;

View file

@ -41,7 +41,12 @@ static int pic32_sdhci_probe(struct udevice *dev)
return ret;
}
return add_sdhci(host, f_min_max[1], f_min_max[0]);
ret = add_sdhci(host, f_min_max[1], f_min_max[0]);
if (ret)
return ret;
host->mmc->dev = dev;
return 0;
}
static const struct udevice_id pic32_sdhci_ids[] = {

View file

@ -104,6 +104,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
if (ret)
return ret;
host->mmc->dev = dev;
upriv->mmc = host->mmc;
return 0;

View file

@ -8,18 +8,150 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <mmc.h>
#include <asm/test.h>
DECLARE_GLOBAL_DATA_PTR;
struct sandbox_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
};
/**
* sandbox_mmc_send_cmd() - Emulate SD commands
*
* This emulate an SD card version 2. Single-block reads result in zero data.
* Multiple-block reads return a test string.
*/
static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
switch (cmd->cmdidx) {
case MMC_CMD_ALL_SEND_CID:
break;
case SD_CMD_SEND_RELATIVE_ADDR:
cmd->response[0] = 0 << 16; /* mmc->rca */
case MMC_CMD_GO_IDLE_STATE:
break;
case SD_CMD_SEND_IF_COND:
cmd->response[0] = 0xaa;
break;
case MMC_CMD_SEND_STATUS:
cmd->response[0] = MMC_STATUS_RDY_FOR_DATA;
break;
case MMC_CMD_SELECT_CARD:
break;
case MMC_CMD_SEND_CSD:
cmd->response[0] = 0;
cmd->response[1] = 10 << 16; /* 1 << block_len */
break;
case SD_CMD_SWITCH_FUNC: {
u32 *resp = (u32 *)data->dest;
resp[7] = cpu_to_be32(SD_HIGHSPEED_BUSY);
break;
}
case MMC_CMD_READ_SINGLE_BLOCK:
memset(data->dest, '\0', data->blocksize);
break;
case MMC_CMD_READ_MULTIPLE_BLOCK:
strcpy(data->dest, "this is a test");
break;
case MMC_CMD_STOP_TRANSMISSION:
break;
case SD_CMD_APP_SEND_OP_COND:
cmd->response[0] = OCR_BUSY | OCR_HCS;
cmd->response[1] = 0;
cmd->response[2] = 0;
break;
case MMC_CMD_APP_CMD:
break;
case MMC_CMD_SET_BLOCKLEN:
debug("block len %d\n", cmd->cmdarg);
break;
case SD_CMD_APP_SEND_SCR: {
u32 *scr = (u32 *)data->dest;
scr[0] = cpu_to_be32(2 << 24 | 1 << 15); /* SD version 3 */
break;
}
default:
debug("%s: Unknown command %d\n", __func__, cmd->cmdidx);
break;
}
return 0;
}
static void sandbox_mmc_set_ios(struct mmc *mmc)
{
}
static int sandbox_mmc_init(struct mmc *mmc)
{
return 0;
}
static int sandbox_mmc_getcd(struct mmc *mmc)
{
return 1;
}
static const struct mmc_ops sandbox_mmc_ops = {
.send_cmd = sandbox_mmc_send_cmd,
.set_ios = sandbox_mmc_set_ios,
.init = sandbox_mmc_init,
.getcd = sandbox_mmc_getcd,
};
int sandbox_mmc_probe(struct udevice *dev)
{
struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
return mmc_init(&plat->mmc);
}
int sandbox_mmc_bind(struct udevice *dev)
{
struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
struct mmc_config *cfg = &plat->cfg;
int ret;
cfg->name = dev->name;
cfg->ops = &sandbox_mmc_ops;
cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_8BIT;
cfg->voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->f_min = 1000000;
cfg->f_max = 52000000;
cfg->b_max = U32_MAX;
ret = mmc_bind(dev, &plat->mmc, cfg);
if (ret)
return ret;
return 0;
}
int sandbox_mmc_unbind(struct udevice *dev)
{
mmc_unbind(dev);
return 0;
}
static const struct udevice_id sandbox_mmc_ids[] = {
{ .compatible = "sandbox,mmc" },
{ }
};
U_BOOT_DRIVER(warm_mmc_sandbox) = {
U_BOOT_DRIVER(mmc_sandbox) = {
.name = "mmc_sandbox",
.id = UCLASS_MMC,
.of_match = sandbox_mmc_ids,
.bind = sandbox_mmc_bind,
.unbind = sandbox_mmc_unbind,
.probe = sandbox_mmc_probe,
.platdata_auto_alloc_size = sizeof(struct sandbox_mmc_plat),
};

View file

@ -108,6 +108,7 @@ static int socfpga_dwmmc_probe(struct udevice *dev)
return ret;
upriv->mmc = host->mmc;
host->mmc->dev = dev;
return 0;
}

View file

@ -725,6 +725,7 @@ int uniphier_sd_probe(struct udevice *dev)
return -EIO;
upriv->mmc = priv->mmc;
priv->mmc->dev = dev;
return 0;
}

View file

@ -35,6 +35,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
CONFIG_ZYNQ_SDHCI_MIN_FREQ);
upriv->mmc = host->mmc;
host->mmc->dev = dev;
return 0;
}

View file

@ -175,11 +175,7 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
int bus;
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
#else
for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
#endif
bdf = pci_hose_find_devices(hose, bus, ids, &index);
if (bdf != -1)
return bdf;

View file

@ -2,6 +2,9 @@
* (C) Copyright 2004-2007 Freescale Semiconductor, Inc.
* TsiChung Liew, Tsi-Chung.Liew@freescale.com.
*
* Modified to add device model (DM) support
* (C) Copyright 2015 Angelo Dureghello <angelo@sysam.it>
*
* SPDX-License-Identifier: GPL-2.0+
*/
@ -11,9 +14,10 @@
*/
#include <common.h>
#include <dm.h>
#include <dm/platform_data/serial_coldfire.h>
#include <serial.h>
#include <linux/compiler.h>
#include <asm/immap.h>
#include <asm/uart.h>
@ -21,91 +25,110 @@ DECLARE_GLOBAL_DATA_PTR;
extern void uart_port_conf(int port);
static int mcf_serial_init(void)
static int mcf_serial_init_common(uart_t *uart, int port_idx, int baudrate)
{
volatile uart_t *uart;
u32 counter;
uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
uart_port_conf(CONFIG_SYS_UART_PORT);
uart_port_conf(port_idx);
/* write to SICR: SIM2 = uart mode,dcd does not affect rx */
uart->ucr = UART_UCR_RESET_RX;
uart->ucr = UART_UCR_RESET_TX;
uart->ucr = UART_UCR_RESET_ERROR;
uart->ucr = UART_UCR_RESET_MR;
writeb(UART_UCR_RESET_RX, &uart->ucr);
writeb(UART_UCR_RESET_TX, &uart->ucr);
writeb(UART_UCR_RESET_ERROR, &uart->ucr);
writeb(UART_UCR_RESET_MR, &uart->ucr);
__asm__("nop");
uart->uimr = 0;
writeb(0, &uart->uimr);
/* write to CSR: RX/TX baud rate from timers */
uart->ucsr = (UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK);
writeb(UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK, &uart->ucsr);
uart->umr = (UART_UMR_BC_8 | UART_UMR_PM_NONE);
uart->umr = UART_UMR_SB_STOP_BITS_1;
writeb(UART_UMR_BC_8 | UART_UMR_PM_NONE, &uart->umr);
writeb(UART_UMR_SB_STOP_BITS_1, &uart->umr);
/* Setting up BaudRate */
counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
counter = counter / gd->baudrate;
counter = (u32) ((gd->bus_clk / 32) + (baudrate / 2));
counter = counter / baudrate;
/* write to CTUR: divide counter upper byte */
uart->ubg1 = (u8) ((counter & 0xff00) >> 8);
writeb((u8)((counter & 0xff00) >> 8), &uart->ubg1);
/* write to CTLR: divide counter lower byte */
uart->ubg2 = (u8) (counter & 0x00ff);
writeb((u8)(counter & 0x00ff), &uart->ubg2);
uart->ucr = (UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED);
writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
return (0);
}
static void mcf_serial_setbrg_common(uart_t *uart, int baudrate)
{
u32 counter;
/* Setting up BaudRate */
counter = (u32) ((gd->bus_clk / 32) + (baudrate / 2));
counter = counter / baudrate;
/* write to CTUR: divide counter upper byte */
writeb(((counter & 0xff00) >> 8), &uart->ubg1);
/* write to CTLR: divide counter lower byte */
writeb((counter & 0x00ff), &uart->ubg2);
writeb(UART_UCR_RESET_RX, &uart->ucr);
writeb(UART_UCR_RESET_TX, &uart->ucr);
writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
}
#ifndef CONFIG_DM_SERIAL
static int mcf_serial_init(void)
{
uart_t *uart_base;
int port_idx;
uart_base = (uart_t *)CONFIG_SYS_UART_BASE;
port_idx = CONFIG_SYS_UART_PORT;
return mcf_serial_init_common(uart_base, port_idx, gd->baudrate);
}
static void mcf_serial_putc(const char c)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
if (c == '\n')
serial_putc('\r');
/* Wait for last character to go. */
while (!(uart->usr & UART_USR_TXRDY)) ;
while (!(readb(&uart->usr) & UART_USR_TXRDY))
;
uart->utb = c;
writeb(c, &uart->utb);
}
static int mcf_serial_getc(void)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
/* Wait for a character to arrive. */
while (!(uart->usr & UART_USR_RXRDY)) ;
return uart->urb;
}
while (!(readb(&uart->usr) & UART_USR_RXRDY))
;
static int mcf_serial_tstc(void)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
return (uart->usr & UART_USR_RXRDY);
return readb(&uart->urb);
}
static void mcf_serial_setbrg(void)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
u32 counter;
uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
/* Setting up BaudRate */
counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
counter = counter / gd->baudrate;
mcf_serial_setbrg_common(uart, gd->baudrate);
}
/* write to CTUR: divide counter upper byte */
uart->ubg1 = ((counter & 0xff00) >> 8);
/* write to CTLR: divide counter lower byte */
uart->ubg2 = (counter & 0x00ff);
static int mcf_serial_tstc(void)
{
uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
uart->ucr = UART_UCR_RESET_RX;
uart->ucr = UART_UCR_RESET_TX;
uart->ucr = UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED;
return readb(&uart->usr) & UART_USR_RXRDY;
}
static struct serial_device mcf_serial_drv = {
@ -128,3 +151,80 @@ __weak struct serial_device *default_serial_console(void)
{
return &mcf_serial_drv;
}
#endif
#ifdef CONFIG_DM_SERIAL
static int coldfire_serial_probe(struct udevice *dev)
{
struct coldfire_serial_platdata *plat = dev->platdata;
return mcf_serial_init_common((uart_t *)plat->base,
plat->port, plat->baudrate);
}
static int coldfire_serial_putc(struct udevice *dev, const char ch)
{
struct coldfire_serial_platdata *plat = dev->platdata;
uart_t *uart = (uart_t *)plat->base;
/* Wait for last character to go. */
if (!(readb(&uart->usr) & UART_USR_TXRDY))
return -EAGAIN;
writeb(ch, &uart->utb);
return 0;
}
static int coldfire_serial_getc(struct udevice *dev)
{
struct coldfire_serial_platdata *plat = dev->platdata;
uart_t *uart = (uart_t *)(plat->base);
/* Wait for a character to arrive. */
if (!(readb(&uart->usr) & UART_USR_RXRDY))
return -EAGAIN;
return readb(&uart->urb);
}
int coldfire_serial_setbrg(struct udevice *dev, int baudrate)
{
struct coldfire_serial_platdata *plat = dev->platdata;
uart_t *uart = (uart_t *)(plat->base);
mcf_serial_setbrg_common(uart, baudrate);
return 0;
}
static int coldfire_serial_pending(struct udevice *dev, bool input)
{
struct coldfire_serial_platdata *plat = dev->platdata;
uart_t *uart = (uart_t *)(plat->base);
if (input)
return readb(&uart->usr) & UART_USR_RXRDY ? 1 : 0;
else
return readb(&uart->usr) & UART_USR_TXRDY ? 0 : 1;
return 0;
}
static const struct dm_serial_ops coldfire_serial_ops = {
.putc = coldfire_serial_putc,
.pending = coldfire_serial_pending,
.getc = coldfire_serial_getc,
.setbrg = coldfire_serial_setbrg,
};
U_BOOT_DRIVER(serial_coldfire) = {
.name = "serial_coldfire",
.id = UCLASS_SERIAL,
.probe = coldfire_serial_probe,
.ops = &coldfire_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
#endif

View file

@ -26,15 +26,20 @@ struct soft_spi_platdata {
struct gpio_desc mosi;
struct gpio_desc miso;
int spi_delay_us;
int flags;
};
#define SPI_MASTER_NO_RX BIT(0)
#define SPI_MASTER_NO_TX BIT(1)
struct soft_spi_priv {
unsigned int mode;
};
static int soft_spi_scl(struct udevice *dev, int bit)
{
struct soft_spi_platdata *plat = dev->platdata;
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->sclk, bit);
@ -43,7 +48,8 @@ static int soft_spi_scl(struct udevice *dev, int bit)
static int soft_spi_sda(struct udevice *dev, int bit)
{
struct soft_spi_platdata *plat = dev->platdata;
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->mosi, bit);
@ -52,7 +58,8 @@ static int soft_spi_sda(struct udevice *dev, int bit)
static int soft_spi_cs_activate(struct udevice *dev)
{
struct soft_spi_platdata *plat = dev->platdata;
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->cs, 0);
dm_gpio_set_value(&plat->sclk, 0);
@ -63,7 +70,8 @@ static int soft_spi_cs_activate(struct udevice *dev)
static int soft_spi_cs_deactivate(struct udevice *dev)
{
struct soft_spi_platdata *plat = dev->platdata;
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_platdata *plat = dev_get_platdata(bus);
dm_gpio_set_value(&plat->cs, 0);
@ -100,8 +108,9 @@ static int soft_spi_release_bus(struct udevice *dev)
static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
struct soft_spi_priv *priv = dev_get_priv(dev);
struct soft_spi_platdata *plat = dev->platdata;
struct udevice *bus = dev_get_parent(dev);
struct soft_spi_priv *priv = dev_get_priv(bus);
struct soft_spi_platdata *plat = dev_get_platdata(bus);
uchar tmpdin = 0;
uchar tmpdout = 0;
const u8 *txd = dout;
@ -134,14 +143,16 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
if (!cpha)
soft_spi_scl(dev, 0);
soft_spi_sda(dev, tmpdout & 0x80);
if ((plat->flags & SPI_MASTER_NO_TX) == 0)
soft_spi_sda(dev, !!(tmpdout & 0x80));
udelay(plat->spi_delay_us);
if (cpha)
soft_spi_scl(dev, 0);
else
soft_spi_scl(dev, 1);
tmpdin <<= 1;
tmpdin |= dm_gpio_get_value(&plat->miso);
if ((plat->flags & SPI_MASTER_NO_RX) == 0)
tmpdin |= dm_gpio_get_value(&plat->miso);
tmpdout <<= 1;
udelay(plat->spi_delay_us);
if (cpha)
@ -203,24 +214,36 @@ static int soft_spi_probe(struct udevice *dev)
struct spi_slave *slave = dev_get_parent_priv(dev);
struct soft_spi_platdata *plat = dev->platdata;
int cs_flags, clk_flags;
int ret;
cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs,
if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
GPIOD_IS_OUT | cs_flags) ||
gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk,
GPIOD_IS_OUT | clk_flags) ||
gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) ||
gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso,
GPIOD_IS_IN))
gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
GPIOD_IS_OUT | clk_flags))
return -EINVAL;
ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret)
plat->flags |= SPI_MASTER_NO_TX;
ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
GPIOD_IS_IN);
if (ret)
plat->flags |= SPI_MASTER_NO_RX;
if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
(SPI_MASTER_NO_RX | SPI_MASTER_NO_TX))
return -EINVAL;
return 0;
}
static const struct udevice_id soft_spi_ids[] = {
{ .compatible = "u-boot,soft-spi" },
{ .compatible = "spi-gpio" },
{ }
};

View file

@ -45,12 +45,12 @@ static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
return 0;
}
int spi_claim_bus(struct spi_slave *slave)
int dm_spi_claim_bus(struct udevice *dev)
{
struct udevice *dev = slave->dev;
struct udevice *bus = dev->parent;
struct dm_spi_ops *ops = spi_get_ops(bus);
struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
struct spi_slave *slave = dev_get_parent_priv(dev);
int speed;
int ret;
@ -73,9 +73,8 @@ int spi_claim_bus(struct spi_slave *slave)
return ops->claim_bus ? ops->claim_bus(dev) : 0;
}
void spi_release_bus(struct spi_slave *slave)
void dm_spi_release_bus(struct udevice *dev)
{
struct udevice *dev = slave->dev;
struct udevice *bus = dev->parent;
struct dm_spi_ops *ops = spi_get_ops(bus);
@ -83,10 +82,9 @@ void spi_release_bus(struct spi_slave *slave)
ops->release_bus(dev);
}
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
struct udevice *dev = slave->dev;
struct udevice *bus = dev->parent;
if (bus->uclass->uc_drv->id != UCLASS_SPI)
@ -95,6 +93,22 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
}
int spi_claim_bus(struct spi_slave *slave)
{
return dm_spi_claim_bus(slave->dev);
}
void spi_release_bus(struct spi_slave *slave)
{
dm_spi_release_bus(slave->dev);
}
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
}
static int spi_post_bind(struct udevice *dev)
{
/* Scan the bus for devices */

View file

@ -3,5 +3,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_DM_USB) += common.o
obj-$(CONFIG_USB_EHCI_FSL) += fsl-dt-fixup.o
obj-$(CONFIG_USB_XHCI_FSL) += fsl-dt-fixup.o

View file

@ -0,0 +1,40 @@
/*
* Provides code common for host and device side USB.
*
* (C) Copyright 2016
* Texas Instruments Incorporated, <www.ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <libfdt.h>
#include <linux/usb/otg.h>
DECLARE_GLOBAL_DATA_PTR;
static const char *const usb_dr_modes[] = {
[USB_DR_MODE_UNKNOWN] = "",
[USB_DR_MODE_HOST] = "host",
[USB_DR_MODE_PERIPHERAL] = "peripheral",
[USB_DR_MODE_OTG] = "otg",
};
enum usb_dr_mode usb_get_dr_mode(int node)
{
const void *fdt = gd->fdt_blob;
const char *dr_mode;
int i;
dr_mode = fdt_getprop(fdt, node, "dr_mode", NULL);
if (!dr_mode) {
error("usb dr_mode not found\n");
return USB_DR_MODE_UNKNOWN;
}
for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
if (!strcmp(dr_mode, usb_dr_modes[i]))
return i;
return USB_DR_MODE_UNKNOWN;
}

View file

@ -620,6 +620,13 @@ static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
static int tegra_lcd_bind(struct udevice *dev)
{
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
const void *blob = gd->fdt_blob;
int node = dev->of_offset;
int rgb;
rgb = fdt_subnode_offset(blob, node, "rgb");
if ((rgb < 0) || !fdtdec_get_is_enabled(blob, rgb))
return -ENODEV;
plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
(1 << LCD_MAX_LOG2_BPP) / 8;

View file

@ -1254,7 +1254,7 @@ int file_fat_detectfs(void)
#if defined(CONFIG_CMD_IDE) || \
defined(CONFIG_CMD_SATA) || \
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC)
printf("Interface: ");

View file

@ -206,6 +206,16 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
struct fdtdec_phandle_args;
/**
* gpio_xlate_offs_flags() - implementation for common use of dm_gpio_ops.xlate
*
* This routine sets the offset field to args[0] and the flags field to
* GPIOD_ACTIVE_LOW if the GPIO_ACTIVE_LOW flag is present in args[1].
*
*/
int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
struct fdtdec_phandle_args *args);
/**
* struct struct dm_gpio_ops - Driver model GPIO operations
*
@ -258,12 +268,11 @@ struct dm_gpio_ops {
*
* @desc->dev to @dev
* @desc->flags to 0
* @desc->offset to the value of the first argument in args, if any,
* otherwise -1 (which is invalid)
* @desc->offset to 0
*
* This method is optional so if the above defaults suit it can be
* omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag
* in desc->flags.
* This method is optional and defaults to gpio_xlate_offs_flags,
* which will parse offset and the GPIO_ACTIVE_LOW flag in the first
* two arguments.
*
* Note that @dev is passed in as a parameter to follow driver model
* uclass conventions, even though it is already available as

View file

@ -30,6 +30,7 @@ enum if_type {
IF_TYPE_SD,
IF_TYPE_SATA,
IF_TYPE_HOST,
IF_TYPE_SYSTEMACE,
IF_TYPE_COUNT, /* Number of interface types */
};
@ -62,6 +63,11 @@ struct blk_desc {
char product[20+1]; /* IDE Serial no, SCSI product */
char revision[8+1]; /* firmware revision */
#ifdef CONFIG_BLK
/*
* For now we have a few functions which take struct blk_desc as a
* parameter. This field allows them to look up the associated
* device. Once these functions are removed we can drop this field.
*/
struct udevice *bdev;
#else
unsigned long (*block_read)(struct blk_desc *block_dev,
@ -210,6 +216,25 @@ struct blk_ops {
*/
unsigned long (*erase)(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt);
/**
* select_hwpart() - select a particular hardware partition
*
* Some devices (e.g. MMC) can support partitioning at the hardware
* level. This is quite separate from the normal idea of
* software-based partitions. MMC hardware partitions must be
* explicitly selected. Once selected only the region of the device
* covered by that partition is accessible.
*
* The MMC standard provides for two boot partitions (numbered 1 and 2),
* rpmb (3), and up to 4 addition general-purpose partitions (4-7).
*
* @desc: Block device to update
* @hwpart: Hardware partition number to select. 0 means the raw
* device, 1 is the first partition, 2 is the second, etc.
* @return 0 if OK, -ve on error
*/
int (*select_hwpart)(struct udevice *dev, int hwpart);
};
#define blk_get_ops(dev) ((struct blk_ops *)(dev)->driver->ops)
@ -269,7 +294,8 @@ int blk_next_device(struct udevice **devp);
* @drv_name: Driver name to use for the block device
* @name: Name for the device
* @if_type: Interface type (enum if_type_t)
* @devnum: Device number, specific to the interface type
* @devnum: Device number, specific to the interface type, or -1 to
* allocate the next available number
* @blksz: Block size of the device in bytes (typically 512)
* @size: Total size of the device in bytes
* @devp: the new device (which has not been probed)
@ -278,6 +304,23 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
lbaint_t size, struct udevice **devp);
/**
* blk_create_devicef() - Create a new named block device
*
* @parent: Parent of the new device
* @drv_name: Driver name to use for the block device
* @name: Name for the device (parent name is prepended)
* @if_type: Interface type (enum if_type_t)
* @devnum: Device number, specific to the interface type, or -1 to
* allocate the next available number
* @blksz: Block size of the device in bytes (typically 512)
* @size: Total size of the device in bytes
* @devp: the new device (which has not been probed)
*/
int blk_create_devicef(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
lbaint_t size, struct udevice **devp);
/**
* blk_prepare_device() - Prepare a block device for use
*
@ -298,6 +341,29 @@ int blk_prepare_device(struct udevice *dev);
*/
int blk_unbind_all(int if_type);
/**
* blk_find_max_devnum() - find the maximum device number for an interface type
*
* Finds the last allocated device number for an interface type @if_type. The
* next number is safe to use for a newly allocated device.
*
* @if_type: Interface type to scan
* @return maximum device number found, or -ENODEV if none, or other -ve on
* error
*/
int blk_find_max_devnum(enum if_type if_type);
/**
* blk_select_hwpart() - select a hardware partition
*
* Select a hardware partition if the device supports it (typically MMC does)
*
* @dev: Device to update
* @hwpart: Partition number to select
* @return 0 if OK, -ve on error
*/
int blk_select_hwpart(struct udevice *dev, int hwpart);
#else
#include <errno.h>
/*
@ -340,6 +406,201 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
blkcache_invalidate(block_dev->if_type, block_dev->devnum);
return block_dev->block_erase(block_dev, start, blkcnt);
}
/**
* struct blk_driver - Driver for block interface types
*
* This provides access to the block devices for each interface type. One
* driver should be provided using U_BOOT_LEGACY_BLK() for each interface
* type that is to be supported.
*
* @if_typename: Interface type name
* @if_type: Interface type
* @max_devs: Maximum number of devices supported
* @desc: Pointer to list of devices for this interface type,
* or NULL to use @get_dev() instead
*/
struct blk_driver {
const char *if_typename;
enum if_type if_type;
int max_devs;
struct blk_desc *desc;
/**
* get_dev() - get a pointer to a block device given its number
*
* Each interface allocates its own devices and typically
* struct blk_desc is contained with the interface's data structure.
* There is no global numbering for block devices. This method allows
* the device for an interface type to be obtained when @desc is NULL.
*
* @devnum: Device number (0 for first device on that interface,
* 1 for second, etc.
* @descp: Returns pointer to the block device on success
* @return 0 if OK, -ve on error
*/
int (*get_dev)(int devnum, struct blk_desc **descp);
/**
* select_hwpart() - Select a hardware partition
*
* Some devices (e.g. MMC) can support partitioning at the hardware
* level. This is quite separate from the normal idea of
* software-based partitions. MMC hardware partitions must be
* explicitly selected. Once selected only the region of the device
* covered by that partition is accessible.
*
* The MMC standard provides for two boot partitions (numbered 1 and 2),
* rpmb (3), and up to 4 addition general-purpose partitions (4-7).
* Partition 0 is the main user-data partition.
*
* @desc: Block device descriptor
* @hwpart: Hardware partition number to select. 0 means the main
* user-data partition, 1 is the first partition, 2 is
* the second, etc.
* @return 0 if OK, other value for an error
*/
int (*select_hwpart)(struct blk_desc *desc, int hwpart);
};
/*
* Declare a new U-Boot legacy block driver. New drivers should use driver
* model (UCLASS_BLK).
*/
#define U_BOOT_LEGACY_BLK(__name) \
ll_entry_declare(struct blk_driver, __name, blk_driver)
struct blk_driver *blk_driver_lookup_type(int if_type);
#endif /* !CONFIG_BLK */
/**
* blk_get_devnum_by_typename() - Get a block device by type and number
*
* This looks through the available block devices of the given type, returning
* the one with the given @devnum.
*
* @if_type: Block device type
* @devnum: Device number
* @return point to block device descriptor, or NULL if not found
*/
struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum);
/**
* blk_get_devnum_by_type() - Get a block device by type name, and number
*
* This looks up the block device type based on @if_typename, then calls
* blk_get_devnum_by_type().
*
* @if_typename: Block device type name
* @devnum: Device number
* @return point to block device descriptor, or NULL if not found
*/
struct blk_desc *blk_get_devnum_by_typename(const char *if_typename,
int devnum);
/**
* blk_dselect_hwpart() - select a hardware partition
*
* This selects a hardware partition (such as is supported by MMC). The block
* device size may change as this effectively points the block device to a
* partition at the hardware level. See the select_hwpart() method above.
*
* @desc: Block device descriptor for the device to select
* @hwpart: Partition number to select
* @return 0 if OK, -ve on error
*/
int blk_dselect_hwpart(struct blk_desc *desc, int hwpart);
/**
* blk_list_part() - list the partitions for block devices of a given type
*
* This looks up the partition type for each block device of type @if_type,
* then displays a list of partitions.
*
* @if_type: Block device type
* @return 0 if OK, -ENODEV if there is none of that type
*/
int blk_list_part(enum if_type if_type);
/**
* blk_list_devices() - list the block devices of a given type
*
* This lists each block device of the type @if_type, showing the capacity
* as well as type-specific information.
*
* @if_type: Block device type
*/
void blk_list_devices(enum if_type if_type);
/**
* blk_show_device() - show information about a given block device
*
* This shows the block device capacity as well as type-specific information.
*
* @if_type: Block device type
* @devnum: Device number
* @return 0 if OK, -ENODEV for invalid device number
*/
int blk_show_device(enum if_type if_type, int devnum);
/**
* blk_print_device_num() - show information about a given block device
*
* This is similar to blk_show_device() but returns an error if the block
* device type is unknown.
*
* @if_type: Block device type
* @devnum: Device number
* @return 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
* device is not connected
*/
int blk_print_device_num(enum if_type if_type, int devnum);
/**
* blk_print_part_devnum() - print the partition information for a device
*
* @if_type: Block device type
* @devnum: Device number
* @return 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
* the interface type is not supported, other -ve on other error
*/
int blk_print_part_devnum(enum if_type if_type, int devnum);
/**
* blk_read_devnum() - read blocks from a device
*
* @if_type: Block device type
* @devnum: Device number
* @blkcnt: Number of blocks to read
* @buffer: Address to write data to
* @return number of blocks read, or -ve error number on error
*/
ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
lbaint_t blkcnt, void *buffer);
/**
* blk_write_devnum() - write blocks to a device
*
* @if_type: Block device type
* @devnum: Device number
* @blkcnt: Number of blocks to write
* @buffer: Address to read data from
* @return number of blocks written, or -ve error number on error
*/
ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
lbaint_t blkcnt, const void *buffer);
/**
* blk_select_hwpart_devnum() - select a hardware partition
*
* This is similar to blk_dselect_hwpart() but it looks up the interface and
* device number.
*
* @if_type: Block device type
* @devnum: Device number
* @hwpart: Partition number to select
* @return 0 if OK, -ve on error
*/
int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
#endif

View file

@ -45,7 +45,7 @@
#define CONFIG_CMD_READ /* Read data from partition */
#define CONFIG_CMD_SANDBOX /* sb command to access sandbox features */
#define CONFIG_CMD_SAVES /* save S record dump */
#define CONFIG_CMD_SCSI /* SCSI Support */
#define CONFIG_SCSI /* SCSI Support */
#define CONFIG_CMD_SDRAM /* SDRAM DIMM SPD info printout */
#define CONFIG_CMD_TERMINAL /* built-in Serial Terminal */
#define CONFIG_CMD_UBI /* UBI Support */

View file

@ -165,7 +165,7 @@
BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
#endif
#ifdef CONFIG_CMD_SCSI
#ifdef CONFIG_SCSI
#define BOOTENV_RUN_SCSI_INIT "run scsi_init; "
#define BOOTENV_SET_SCSI_NEED_INIT "setenv scsi_need_init; "
#define BOOTENV_SHARED_SCSI \
@ -185,9 +185,9 @@
#define BOOTENV_SET_SCSI_NEED_INIT
#define BOOTENV_SHARED_SCSI
#define BOOTENV_DEV_SCSI \
BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI
#define BOOTENV_DEV_NAME_SCSI \
BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI
#endif
#ifdef CONFIG_CMD_IDE

View file

@ -45,7 +45,7 @@
/* Rather than repeat this expression each time, add a define for it */
#if defined(CONFIG_CMD_IDE) || \
defined(CONFIG_CMD_SATA) || \
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_CMD_PART) || \
defined(CONFIG_CMD_GPT) || \

View file

@ -373,7 +373,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
#if defined(CONFIG_PCI)
#define CONFIG_CMD_PCI
#define CONFIG_CMD_SCSI
#define CONFIG_SCSI
#endif
/*

View file

@ -576,7 +576,7 @@
#if defined(CONFIG_PCI)
#define CONFIG_CMD_PCI
#define CONFIG_CMD_SCSI
#define CONFIG_SCSI
#endif
/*

View file

@ -449,7 +449,7 @@
#if defined(CONFIG_PCI)
#define CONFIG_CMD_PCI
#define CONFIG_CMD_SCSI
#define CONFIG_SCSI
#endif
#define CONFIG_WATCHDOG /* watchdog enabled */

View file

@ -354,8 +354,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
#define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */
#undef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
#define CONFIG_PCI_PNP /* do pci plug-and-play */
#undef CONFIG_EEPRO100
@ -612,7 +610,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
#if defined(CONFIG_PCI)
#define CONFIG_CMD_PCI
#define CONFIG_CMD_SCSI
#define CONFIG_SCSI
#endif
#undef CONFIG_WATCHDOG /* watchdog disabled */

View file

@ -43,7 +43,7 @@
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_FDC
#define CONFIG_CMD_SCSI
#define CONFIG_SCSI
#define CONFIG_CMD_DATE
#define CONFIG_CMD_SDRAM
#define CONFIG_CMD_SAVES

Some files were not shown because too many files have changed in this diff Show more