rtt更新
This commit is contained in:
23
rt-thread/components/drivers/nvme/Kconfig
Normal file
23
rt-thread/components/drivers/nvme/Kconfig
Normal file
@@ -0,0 +1,23 @@
|
||||
menuconfig RT_USING_NVME
|
||||
bool "Using Non-Volatile Memory Express (NVME) device drivers"
|
||||
depends on RT_USING_DM
|
||||
depends on RT_USING_BLK
|
||||
depends on RT_USING_DMA
|
||||
default n
|
||||
|
||||
config RT_USING_NVME_IO_QUEUE
|
||||
int "Number of I/O Command queue"
|
||||
depends on RT_USING_NVME
|
||||
default 2 if RT_THREAD_PRIORITY_8
|
||||
default 4 if RT_THREAD_PRIORITY_32
|
||||
default 8 if RT_THREAD_PRIORITY_256
|
||||
|
||||
config RT_NVME_PCI
|
||||
bool "NVME support on PCI bus"
|
||||
depends on RT_USING_NVME
|
||||
depends on RT_USING_PCI
|
||||
default y
|
||||
|
||||
if RT_USING_NVME
|
||||
osource "$(SOC_DM_NVME_DIR)/Kconfig"
|
||||
endif
|
18
rt-thread/components/drivers/nvme/SConscript
Normal file
18
rt-thread/components/drivers/nvme/SConscript
Normal file
@@ -0,0 +1,18 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
|
||||
if not GetDepend(['RT_USING_NVME']):
|
||||
Return('group')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd + '/../include']
|
||||
|
||||
src = ['nvme.c']
|
||||
|
||||
if GetDepend(['RT_NVME_PCI']):
|
||||
src += ['nvme-pci.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
171
rt-thread/components/drivers/nvme/nvme-pci.c
Normal file
171
rt-thread/components/drivers/nvme/nvme-pci.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-02-25 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define NVME_REG_BAR 0
|
||||
|
||||
struct pci_nvme_quirk
|
||||
{
|
||||
const struct rt_nvme_ops *ops;
|
||||
};
|
||||
|
||||
struct pci_nvme_controller
|
||||
{
|
||||
struct rt_nvme_controller parent;
|
||||
const struct pci_nvme_quirk *quirk;
|
||||
|
||||
rt_bool_t is_msi;
|
||||
struct rt_pci_msix_entry msix_entries[RT_USING_NVME_QUEUE];
|
||||
};
|
||||
|
||||
static const struct rt_nvme_ops pci_nvme_std_ops =
|
||||
{
|
||||
.name = "PCI",
|
||||
};
|
||||
|
||||
static rt_err_t pci_nvme_probe(struct rt_pci_device *pdev)
|
||||
{
|
||||
rt_err_t err;
|
||||
rt_ssize_t msi_nr;
|
||||
struct rt_nvme_controller *nvme;
|
||||
struct pci_nvme_controller *pci_nvme = rt_calloc(1, sizeof(*pci_nvme));
|
||||
const struct pci_nvme_quirk *quirk = pdev->id->data;
|
||||
|
||||
if (!pci_nvme)
|
||||
{
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
pci_nvme->quirk = quirk;
|
||||
nvme = &pci_nvme->parent;
|
||||
nvme->dev = &pdev->parent;
|
||||
nvme->regs = rt_pci_iomap(pdev, NVME_REG_BAR);
|
||||
|
||||
if (!nvme->regs)
|
||||
{
|
||||
err = -RT_EIO;
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
nvme->ops = quirk && quirk->ops ? quirk->ops : &pci_nvme_std_ops;
|
||||
|
||||
if ((msi_nr = rt_pci_msix_vector_count(pdev)) <= 0)
|
||||
{
|
||||
msi_nr = rt_pci_msi_vector_count(pdev);
|
||||
}
|
||||
if (msi_nr > 0)
|
||||
{
|
||||
nvme->irqs_nr = RT_ARRAY_SIZE(pci_nvme->msix_entries);
|
||||
nvme->irqs_nr = rt_min_t(rt_size_t, msi_nr, nvme->irqs_nr);
|
||||
}
|
||||
|
||||
if (nvme->irqs_nr > 0)
|
||||
{
|
||||
rt_pci_msix_entry_index_linear(pci_nvme->msix_entries, nvme->irqs_nr);
|
||||
|
||||
if (rt_pci_msix_enable(pdev, pci_nvme->msix_entries, nvme->irqs_nr) > 0)
|
||||
{
|
||||
pci_nvme->is_msi = RT_TRUE;
|
||||
|
||||
for (int i = 0; i < nvme->irqs_nr; ++i)
|
||||
{
|
||||
nvme->irqs[i] = pci_nvme->msix_entries[i].irq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pci_nvme->is_msi)
|
||||
{
|
||||
nvme->irqs_nr = 1;
|
||||
nvme->irqs[0] = pdev->irq;
|
||||
rt_pci_irq_unmask(pdev);
|
||||
}
|
||||
|
||||
rt_pci_set_master(pdev);
|
||||
|
||||
if ((err = rt_nvme_controller_register(nvme)))
|
||||
{
|
||||
goto _disable;
|
||||
}
|
||||
|
||||
pdev->parent.user_data = pci_nvme;
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
_disable:
|
||||
if (pci_nvme->is_msi)
|
||||
{
|
||||
rt_pci_msix_disable(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pci_irq_mask(pdev);
|
||||
}
|
||||
rt_pci_clear_master(pdev);
|
||||
rt_iounmap(nvme->regs);
|
||||
|
||||
_fail:
|
||||
rt_free(pci_nvme);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static rt_err_t pci_nvme_remove(struct rt_pci_device *pdev)
|
||||
{
|
||||
struct rt_nvme_controller *nvme;
|
||||
struct pci_nvme_controller *pci_nvme = pdev->parent.user_data;
|
||||
|
||||
nvme = &pci_nvme->parent;
|
||||
|
||||
rt_nvme_controller_unregister(nvme);
|
||||
|
||||
if (pci_nvme->is_msi)
|
||||
{
|
||||
rt_pci_msix_disable(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* INTx is shared, don't mask all */
|
||||
rt_hw_interrupt_umask(pdev->irq);
|
||||
rt_pci_irq_mask(pdev);
|
||||
}
|
||||
|
||||
rt_pci_clear_master(pdev);
|
||||
|
||||
rt_iounmap(nvme->regs);
|
||||
rt_free(pci_nvme);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t pci_nvme_shutdown(struct rt_pci_device *pdev)
|
||||
{
|
||||
return pci_nvme_remove(pdev);
|
||||
}
|
||||
|
||||
static const struct rt_pci_device_id pci_nvme_ids[] =
|
||||
{
|
||||
{ RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0010) },
|
||||
{ RT_PCI_DEVICE_CLASS(PCIS_STORAGE_EXPRESS, ~0) },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct rt_pci_driver pci_nvme_driver =
|
||||
{
|
||||
.name = "nvme-pci",
|
||||
|
||||
.ids = pci_nvme_ids,
|
||||
.probe = pci_nvme_probe,
|
||||
.remove = pci_nvme_remove,
|
||||
.shutdown = pci_nvme_shutdown,
|
||||
};
|
||||
RT_PCI_DRIVER_EXPORT(pci_nvme_driver);
|
1302
rt-thread/components/drivers/nvme/nvme.c
Normal file
1302
rt-thread/components/drivers/nvme/nvme.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user