dm: Add support for scsi/sata based devices
All sata based drivers are bind and corresponding block device is created. Based on this find_scsi_device() is able to get back block device based on scsi_curr_dev pointer. intr_scsi() is commented now but it can be replaced by calling find_scsi_device() and scsi_scan(). scsi_dev_desc[] is commented out but common/scsi.c heavily depends on it. That's why CONFIG_SYS_SCSI_MAX_DEVICE is hardcoded to 1 and symbol is reassigned to a block description allocated by uclass. There is only one block description by device now but it doesn't need to be correct when more devices are present. scsi_bind() ensures corresponding block device creation. uclass post_probe (scsi_post_probe()) is doing low level init. SCSI/SATA DM based drivers requires to have 64bit base address as the first entry in platform data structure to setup mmio_base. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -19,6 +19,15 @@ config AHCI
|
||||
operations at present. The block device interface has not been converted
|
||||
to driver model.
|
||||
|
||||
config DM_SCSI
|
||||
bool "Support SCSI controllers with driver model"
|
||||
depends on BLK
|
||||
help
|
||||
This option enables the SCSI (Small Computer System Interface) uclass
|
||||
which supports SCSI and SATA HDDs. For every device configuration
|
||||
(IDs/LUNs) a block device is created with RAW read/write and
|
||||
filesystem support.
|
||||
|
||||
config BLOCK_CACHE
|
||||
bool "Use block device cache"
|
||||
default n
|
||||
@@ -27,3 +36,7 @@ config BLOCK_CACHE
|
||||
This is most useful when accessing filesystems under U-Boot since
|
||||
it will prevent repeated reads from directory structures and other
|
||||
filesystem data structures.
|
||||
|
||||
menu "SATA/SCSI device support"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -12,6 +12,7 @@ obj-y += blk_legacy.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_AHCI) += ahci-uclass.o
|
||||
obj-$(CONFIG_DM_SCSI) += scsi-uclass.o
|
||||
obj-$(CONFIG_SCSI_AHCI) += ahci.o
|
||||
obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
|
||||
obj-$(CONFIG_FSL_SATA) += fsl_sata.o
|
||||
|
||||
+22
-8
@@ -168,7 +168,7 @@ int ahci_reset(void __iomem *base)
|
||||
|
||||
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||
{
|
||||
#ifndef CONFIG_SCSI_AHCI_PLAT
|
||||
#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
|
||||
# ifdef CONFIG_DM_PCI
|
||||
struct udevice *dev = probe_ent->dev;
|
||||
struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
|
||||
@@ -198,7 +198,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||
writel(cap_save, mmio + HOST_CAP);
|
||||
writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
|
||||
|
||||
#ifndef CONFIG_SCSI_AHCI_PLAT
|
||||
#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
|
||||
# ifdef CONFIG_DM_PCI
|
||||
if (pplat->vendor == PCI_VENDOR_ID_INTEL) {
|
||||
u16 tmp16;
|
||||
@@ -327,6 +327,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||
writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
|
||||
tmp = readl(mmio + HOST_CTL);
|
||||
debug("HOST_CTL 0x%x\n", tmp);
|
||||
#if !defined(CONFIG_DM_SCSI)
|
||||
#ifndef CONFIG_SCSI_AHCI_PLAT
|
||||
# ifdef CONFIG_DM_PCI
|
||||
dm_pci_read_config16(dev, PCI_COMMAND, &tmp16);
|
||||
@@ -337,6 +338,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||
tmp |= PCI_COMMAND_MASTER;
|
||||
pci_write_config_word(pdev, PCI_COMMAND, tmp16);
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -344,8 +346,8 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||
|
||||
static void ahci_print_info(struct ahci_probe_ent *probe_ent)
|
||||
{
|
||||
#ifndef CONFIG_SCSI_AHCI_PLAT
|
||||
# ifdef CONFIG_DM_PCI
|
||||
#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
|
||||
# if defined(CONFIG_DM_PCI)
|
||||
struct udevice *dev = probe_ent->dev;
|
||||
# else
|
||||
pci_dev_t pdev = probe_ent->dev;
|
||||
@@ -372,7 +374,7 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
|
||||
else
|
||||
speed_s = "?";
|
||||
|
||||
#ifdef CONFIG_SCSI_AHCI_PLAT
|
||||
#if defined(CONFIG_SCSI_AHCI_PLAT) || defined(CONFIG_DM_SCSI)
|
||||
scc_s = "SATA";
|
||||
#else
|
||||
# ifdef CONFIG_DM_PCI
|
||||
@@ -424,13 +426,15 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SCSI_AHCI_PLAT
|
||||
# ifdef CONFIG_DM_PCI
|
||||
# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
|
||||
static int ahci_init_one(struct udevice *dev)
|
||||
# else
|
||||
static int ahci_init_one(pci_dev_t dev)
|
||||
# endif
|
||||
{
|
||||
#if !defined(CONFIG_DM_SCSI)
|
||||
u16 vendor;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
probe_ent = malloc(sizeof(struct ahci_probe_ent));
|
||||
@@ -450,6 +454,7 @@ static int ahci_init_one(pci_dev_t dev)
|
||||
probe_ent->pio_mask = 0x1f;
|
||||
probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
|
||||
|
||||
#if !defined(CONFIG_DM_SCSI)
|
||||
#ifdef CONFIG_DM_PCI
|
||||
probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
|
||||
PCI_REGION_MEM);
|
||||
@@ -473,6 +478,10 @@ static int ahci_init_one(pci_dev_t dev)
|
||||
if (vendor == 0x197b)
|
||||
pci_write_config_byte(dev, 0x41, 0xa1);
|
||||
#endif
|
||||
#else
|
||||
struct scsi_platdata *plat = dev_get_platdata(dev);
|
||||
probe_ent->mmio_base = (void *)plat->base;
|
||||
#endif
|
||||
|
||||
debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
|
||||
/* initialize adapter */
|
||||
@@ -954,14 +963,17 @@ int scsi_exec(ccb *pccb)
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_DM_SCSI)
|
||||
void scsi_low_level_init(int busdevfunc, struct udevice *dev)
|
||||
#else
|
||||
void scsi_low_level_init(int busdevfunc)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
u32 linkmap;
|
||||
|
||||
#ifndef CONFIG_SCSI_AHCI_PLAT
|
||||
# ifdef CONFIG_DM_PCI
|
||||
# if defined(CONFIG_DM_PCI)
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
@@ -969,6 +981,8 @@ void scsi_low_level_init(int busdevfunc)
|
||||
if (ret)
|
||||
return;
|
||||
ahci_init_one(dev);
|
||||
# elif defined(CONFIG_DM_SCSI)
|
||||
ahci_init_one(dev);
|
||||
# else
|
||||
ahci_init_one(busdevfunc);
|
||||
# endif
|
||||
|
||||
@@ -26,7 +26,7 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
|
||||
|
||||
static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
|
||||
[IF_TYPE_IDE] = UCLASS_INVALID,
|
||||
[IF_TYPE_SCSI] = UCLASS_INVALID,
|
||||
[IF_TYPE_SCSI] = UCLASS_SCSI,
|
||||
[IF_TYPE_ATAPI] = UCLASS_INVALID,
|
||||
[IF_TYPE_USB] = UCLASS_MASS_STORAGE,
|
||||
[IF_TYPE_DOC] = UCLASS_INVALID,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
* Copyright (c) 2016 Xilinx, Inc
|
||||
* Written by Michal Simek
|
||||
*
|
||||
* Based on ahci-uclass.c
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <scsi.h>
|
||||
|
||||
static int scsi_post_probe(struct udevice *dev)
|
||||
{
|
||||
debug("%s: device %p\n", __func__, dev);
|
||||
scsi_low_level_init(0, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(scsi) = {
|
||||
.id = UCLASS_SCSI,
|
||||
.name = "scsi",
|
||||
.post_probe = scsi_post_probe,
|
||||
};
|
||||
Reference in New Issue
Block a user