mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 70 participants
  • 19484 discussions
[PATCH kernel-4.19] ata: sata_zhaoxin: Add support for Zhaoxin Serial ATA
by LeoLiu-oc 26 Mar '21

26 Mar '21
Add Zhaoxin Serial ATA support for Zhaoxin CPUs. The patch is scheduled to be submitted to the kernel mainline in 2021. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/ata/Kconfig | 8 + drivers/ata/Makefile | 1 + drivers/ata/sata_zhaoxin.c | 395 +++++++++++++++++++++++++++++++++++++ 3 files changed, 404 insertions(+) create mode 100644 drivers/ata/sata_zhaoxin.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 99698d7fe585..20cec29cc4d3 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -478,6 +478,14 @@ config SATA_ULI If unsure, say N. +config SATA_ZHAOXIN + tristate "ZhaoXin SATA support" + depends on PCI + help + This option enables support for ZhaoXin Serial ATA. + + If unsure, say N. + config SATA_VIA tristate "VIA SATA support" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d21cdd83f7ab..2d9220311187 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_SATA_SIL) += sata_sil.o obj-$(CONFIG_SATA_SIS) += sata_sis.o obj-$(CONFIG_SATA_SVW) += sata_svw.o obj-$(CONFIG_SATA_ULI) += sata_uli.o +obj-$(CONFIG_SATA_ZHAOXIN) += sata_zhaoxin.o obj-$(CONFIG_SATA_VIA) += sata_via.o obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o diff --git a/drivers/ata/sata_zhaoxin.c b/drivers/ata/sata_zhaoxin.c new file mode 100644 index 000000000000..b0b16f6f364b --- /dev/null +++ b/drivers/ata/sata_zhaoxin.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * sata_zhaoxin.c - ZhaoXin Serial ATA controllers + * + * Maintained by: Tejun Heo <tj(a)kernel.org> + * Please ALWAYS copy linux-ide(a)vger.kernel.org + * on emails. + * + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * libata documentation is available via 'make {ps|pdf}docs', + * as Documentation/DocBook/libata.* + * + * Hardware documentation available under NDA. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> + +#define DRV_NAME "sata_zx" +#define DRV_VERSION "2.6.1" + +enum board_ids_enum { + cnd001, +}; + +enum { + SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ + SATA_INT_GATE = 0x41, /* SATA interrupt gating */ + SATA_NATIVE_MODE = 0x42, /* Native mode enable */ + PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ + PATA_PIO_TIMING = 0xAB, /* PATA timing register */ + + PORT0 = (1 << 1), + PORT1 = (1 << 0), + ALL_PORTS = PORT0 | PORT1, + + NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), + + SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */ +}; + +static int szx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +static int cnd001_scr_read(struct ata_link *link, unsigned int scr, u32 *val); +static int cnd001_scr_write(struct ata_link *link, unsigned int scr, u32 val); +static int szx_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); + +static void szx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); + +static const struct pci_device_id szx_pci_tbl[] = { + { PCI_VDEVICE(ZHAOXIN, 0x9002), cnd001 }, + { PCI_VDEVICE(ZHAOXIN, 0x9003), cnd001 }, + + { } /* terminate list */ +}; + +static struct pci_driver szx_pci_driver = { + .name = DRV_NAME, + .id_table = szx_pci_tbl, + .probe = szx_init_one, +#ifdef CONFIG_PM_SLEEP + .suspend = ata_pci_device_suspend, + .resume = ata_pci_device_resume, +#endif + .remove = ata_pci_remove_one, +}; + +static struct scsi_host_template szx_sht = { + ATA_BMDMA_SHT(DRV_NAME), +}; + +static struct ata_port_operations szx_base_ops = { + .inherits = &ata_bmdma_port_ops, + .sff_tf_load = szx_tf_load, +}; + +static struct ata_port_operations cnd001_ops = { + .inherits = &szx_base_ops, + .hardreset = szx_hardreset, + .scr_read = cnd001_scr_read, + .scr_write = cnd001_scr_write, +}; + +static struct ata_port_info cnd001_port_info = { + .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &cnd001_ops, +}; + + +MODULE_AUTHOR("Jeff Garzik"); +MODULE_DESCRIPTION("SCSI low-level driver for ZX SATA controllers"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, szx_pci_tbl); +MODULE_VERSION(DRV_VERSION); + +static int szx_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) +{ + int rc; + + rc = sata_std_hardreset(link, class, deadline); + if (!rc || rc == -EAGAIN) { + struct ata_port *ap = link->ap; + int pmp = link->pmp; + int tmprc; + + if (pmp) { + ap->ops->sff_dev_select(ap, pmp); + tmprc = ata_sff_wait_ready(&ap->link, deadline); + } else { + tmprc = ata_sff_wait_ready(link, deadline); + } + if (tmprc) { + ata_link_err(link, "COMRESET failed for wait (errno=%d)\n", rc); + } else { + ata_link_err(link, "wait for bsy success\n"); + } + ata_link_err(link, "COMRESET success (errno=%d) ap=%d link %d\n", rc, link->ap->port_no, link->pmp); + }else{ + ata_link_err(link, "COMRESET failed (errno=%d) ap=%d link %d\n", rc, link->ap->port_no, link->pmp); + } + return rc; +} + +static int cnd001_scr_read(struct ata_link *link, unsigned int scr, u32 *val) +{ + static const u8 ipm_tbl[] = { 1, 2, 6, 0 }; + struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); + int slot = 2 * link->ap->port_no + link->pmp; + u32 v = 0; + u8 raw; + + switch (scr) { + case SCR_STATUS: + pci_read_config_byte(pdev, 0xA0 + slot, &raw); + + /* read the DET field, bit0 and 1 of the config byte */ + v |= raw & 0x03; + + /* read the SPD field, bit4 of the configure byte */ + v |= raw & 0x30; + + /* read the IPM field, bit2 and 3 of the config byte */ + v |= ((ipm_tbl[(raw >> 2) & 0x3])<<8); + break; + + case SCR_ERROR: + /* devices other than 5287 uses 0xA8 as base */ + WARN_ON(pdev->device != 0x9002 && pdev->device != 0x9003); + pci_write_config_byte(pdev, 0x42, slot); + pci_read_config_dword(pdev, 0xA8, &v); + break; + + case SCR_CONTROL: + pci_read_config_byte(pdev, 0xA4 + slot, &raw); + + /* read the DET field, bit0 and bit1 */ + v |= ((raw & 0x02) << 1) | (raw & 0x01); + + /* read the IPM field, bit2 and bit3 */ + v |= ((raw >> 2) & 0x03) << 8; + + break; + + default: + return -EINVAL; + } + + *val = v; + return 0; +} + +static int cnd001_scr_write(struct ata_link *link, unsigned int scr, u32 val) +{ + struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); + int slot = 2 * link->ap->port_no + link->pmp; + u32 v = 0; + + WARN_ON(pdev == NULL); + + switch (scr) { + case SCR_ERROR: + /* devices 0x9002 uses 0xA8 as base */ + WARN_ON(pdev->device != 0x9002 && pdev->device != 0x9003); + pci_write_config_byte(pdev, 0x42, slot); + pci_write_config_dword(pdev, 0xA8, val); + return 0; + + case SCR_CONTROL: + /* set the DET field */ + v |= ((val & 0x4) >> 1) | (val & 0x1); + + /* set the IPM field */ + v |= ((val >> 8) & 0x3) << 2; + + + pci_write_config_byte(pdev, 0xA4 + slot, v); + + + return 0; + + default: + return -EINVAL; + } +} + + +/** + * szx_tf_load - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller. + * + * This is to fix the internal bug of zx chipsets, which will + * reset the device register after changing the IEN bit on ctl + * register. + */ +static void szx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) +{ + struct ata_taskfile ttf; + + if (tf->ctl != ap->last_ctl) { + ttf = *tf; + ttf.flags |= ATA_TFLAG_DEVICE; + tf = &ttf; + } + ata_sff_tf_load(ap, tf); +} + +static const unsigned int szx_bar_sizes[] = { + 8, 4, 8, 4, 16, 256 +}; + +static const unsigned int cnd001_bar_sizes0[] = { + 8, 4, 8, 4, 16, 0 +}; + +static const unsigned int cnd001_bar_sizes1[] = { + 8, 4, 0, 0, 16, 0 +}; + +static int cnd001_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) +{ + const struct ata_port_info *ppi0[] = { &cnd001_port_info, NULL }; + const struct ata_port_info *ppi1[] = { &cnd001_port_info, &ata_dummy_port_info}; + struct ata_host *host; + int i, rc; + + if (pdev->device == 0x9002) + rc = ata_pci_bmdma_prepare_host(pdev, ppi0, &host); + else if (pdev->device == 0x9003) + rc = ata_pci_bmdma_prepare_host(pdev, ppi1, &host); + else + rc = -EINVAL; + if (rc) + return rc; + *r_host = host; + + + /* cnd001 9002 hosts four sata ports as M/S of the two channels */ + /* cnd001 9003 hosts two sata ports as M/S of the one channel */ + for (i = 0; i < host->n_ports; i++) + ata_slave_link_init(host->ports[i]); + + return 0; +} + +static void szx_configure(struct pci_dev *pdev, int board_id) +{ + u8 tmp8; + + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8); + dev_info(&pdev->dev, "routed to hard irq line %d\n", + (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f); + + /* make sure SATA channels are enabled */ + pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8); + if ((tmp8 & ALL_PORTS) != ALL_PORTS) { + dev_dbg(&pdev->dev, "enabling SATA channels (0x%x)\n", + (int)tmp8); + tmp8 |= ALL_PORTS; + pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8); + } + + /* make sure interrupts for each channel sent to us */ + pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8); + if ((tmp8 & ALL_PORTS) != ALL_PORTS) { + dev_dbg(&pdev->dev, "enabling SATA channel interrupts (0x%x)\n", + (int) tmp8); + tmp8 |= ALL_PORTS; + pci_write_config_byte(pdev, SATA_INT_GATE, tmp8); + } + + /* make sure native mode is enabled */ + pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8); + if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) { + dev_dbg(&pdev->dev, + "enabling SATA channel native mode (0x%x)\n", + (int) tmp8); + tmp8 |= NATIVE_MODE_ALL; + pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); + } +} + +static int szx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + unsigned int i; + int rc; + struct ata_host *host = NULL; + int board_id = (int) ent->driver_data; + const unsigned * bar_sizes; + int legacy_mode = 0; + + ata_print_version_once(&pdev->dev, DRV_VERSION); + + if (pdev->device == 0x9002 || pdev->device == 0x9003) { + if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + u8 tmp8, mask; + + /* TODO: What if one channel is in native mode ... */ + pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); + mask = (1 << 2) | (1 << 0); + if ((tmp8 & mask) != mask) + legacy_mode = 1; + } + if (legacy_mode) + return -EINVAL; + } + + + rc = pcim_enable_device(pdev); + if (rc) + return rc; + + if (board_id == cnd001 && pdev->device == 0x9002) + bar_sizes = &cnd001_bar_sizes0[0]; + else if (board_id == cnd001 && pdev->device == 0x9003) + bar_sizes = &cnd001_bar_sizes1[0]; + else + bar_sizes = &szx_bar_sizes[0]; + + for (i = 0; i < ARRAY_SIZE(szx_bar_sizes); i++) + if ((pci_resource_start(pdev, i) == 0) || + (pci_resource_len(pdev, i) < bar_sizes[i])) { + if (bar_sizes[i] == 0) + continue; + dev_err(&pdev->dev, + "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n", + i, + (unsigned long long)pci_resource_start(pdev, i), + (unsigned long long)pci_resource_len(pdev, i)); + return -ENODEV; + } + + switch (board_id) { + case cnd001: + rc = cnd001_prepare_host(pdev, &host); + break; + default: + rc = -EINVAL; + } + if (rc) + return rc; + + szx_configure(pdev, board_id); + + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, + IRQF_SHARED, &szx_sht); +} + +module_pci_driver(szx_pci_driver); -- 2.20.1 Add Zhaoxin Serial ATA support for Zhaoxin CPUs. The patch is scheduled to be submitted to the kernel mainline in 2021. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/ata/Kconfig | 8 + drivers/ata/Makefile | 1 + drivers/ata/sata_zhaoxin.c | 395 +++++++++++++++++++++++++++++++++++++ 3 files changed, 404 insertions(+) create mode 100644 drivers/ata/sata_zhaoxin.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 99698d7fe585..20cec29cc4d3 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -478,6 +478,14 @@ config SATA_ULI If unsure, say N. +config SATA_ZHAOXIN + tristate "ZhaoXin SATA support" + depends on PCI + help + This option enables support for ZhaoXin Serial ATA. + + If unsure, say N. + config SATA_VIA tristate "VIA SATA support" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d21cdd83f7ab..2d9220311187 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_SATA_SIL) += sata_sil.o obj-$(CONFIG_SATA_SIS) += sata_sis.o obj-$(CONFIG_SATA_SVW) += sata_svw.o obj-$(CONFIG_SATA_ULI) += sata_uli.o +obj-$(CONFIG_SATA_ZHAOXIN) += sata_zhaoxin.o obj-$(CONFIG_SATA_VIA) += sata_via.o obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o diff --git a/drivers/ata/sata_zhaoxin.c b/drivers/ata/sata_zhaoxin.c new file mode 100644 index 000000000000..b0b16f6f364b --- /dev/null +++ b/drivers/ata/sata_zhaoxin.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * sata_zhaoxin.c - ZhaoXin Serial ATA controllers + * + * Maintained by: Tejun Heo <tj(a)kernel.org> + * Please ALWAYS copy linux-ide(a)vger.kernel.org + * on emails. + * + * Copyright 2003-2004 Red Hat, Inc. All rights reserved. + * Copyright 2003-2004 Jeff Garzik + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * libata documentation is available via 'make {ps|pdf}docs', + * as Documentation/DocBook/libata.* + * + * Hardware documentation available under NDA. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> +#include <linux/libata.h> + +#define DRV_NAME "sata_zx" +#define DRV_VERSION "2.6.1" + +enum board_ids_enum { + cnd001, +}; + +enum { + SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ + SATA_INT_GATE = 0x41, /* SATA interrupt gating */ + SATA_NATIVE_MODE = 0x42, /* Native mode enable */ + PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ + PATA_PIO_TIMING = 0xAB, /* PATA timing register */ + + PORT0 = (1 << 1), + PORT1 = (1 << 0), + ALL_PORTS = PORT0 | PORT1, + + NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), + + SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */ +}; + +static int szx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +static int cnd001_scr_read(struct ata_link *link, unsigned int scr, u32 *val); +static int cnd001_scr_write(struct ata_link *link, unsigned int scr, u32 val); +static int szx_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); + +static void szx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); + +static const struct pci_device_id szx_pci_tbl[] = { + { PCI_VDEVICE(ZHAOXIN, 0x9002), cnd001 }, + { PCI_VDEVICE(ZHAOXIN, 0x9003), cnd001 }, + + { } /* terminate list */ +}; + +static struct pci_driver szx_pci_driver = { + .name = DRV_NAME, + .id_table = szx_pci_tbl, + .probe = szx_init_one, +#ifdef CONFIG_PM_SLEEP + .suspend = ata_pci_device_suspend, + .resume = ata_pci_device_resume, +#endif + .remove = ata_pci_remove_one, +}; + +static struct scsi_host_template szx_sht = { + ATA_BMDMA_SHT(DRV_NAME), +}; + +static struct ata_port_operations szx_base_ops = { + .inherits = &ata_bmdma_port_ops, + .sff_tf_load = szx_tf_load, +}; + +static struct ata_port_operations cnd001_ops = { + .inherits = &szx_base_ops, + .hardreset = szx_hardreset, + .scr_read = cnd001_scr_read, + .scr_write = cnd001_scr_write, +}; + +static struct ata_port_info cnd001_port_info = { + .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &cnd001_ops, +}; + + +MODULE_AUTHOR("Jeff Garzik"); +MODULE_DESCRIPTION("SCSI low-level driver for ZX SATA controllers"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, szx_pci_tbl); +MODULE_VERSION(DRV_VERSION); + +static int szx_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) +{ + int rc; + + rc = sata_std_hardreset(link, class, deadline); + if (!rc || rc == -EAGAIN) { + struct ata_port *ap = link->ap; + int pmp = link->pmp; + int tmprc; + + if (pmp) { + ap->ops->sff_dev_select(ap, pmp); + tmprc = ata_sff_wait_ready(&ap->link, deadline); + } else { + tmprc = ata_sff_wait_ready(link, deadline); + } + if (tmprc) { + ata_link_err(link, "COMRESET failed for wait (errno=%d)\n", rc); + } else { + ata_link_err(link, "wait for bsy success\n"); + } + ata_link_err(link, "COMRESET success (errno=%d) ap=%d link %d\n", rc, link->ap->port_no, link->pmp); + }else{ + ata_link_err(link, "COMRESET failed (errno=%d) ap=%d link %d\n", rc, link->ap->port_no, link->pmp); + } + return rc; +} + +static int cnd001_scr_read(struct ata_link *link, unsigned int scr, u32 *val) +{ + static const u8 ipm_tbl[] = { 1, 2, 6, 0 }; + struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); + int slot = 2 * link->ap->port_no + link->pmp; + u32 v = 0; + u8 raw; + + switch (scr) { + case SCR_STATUS: + pci_read_config_byte(pdev, 0xA0 + slot, &raw); + + /* read the DET field, bit0 and 1 of the config byte */ + v |= raw & 0x03; + + /* read the SPD field, bit4 of the configure byte */ + v |= raw & 0x30; + + /* read the IPM field, bit2 and 3 of the config byte */ + v |= ((ipm_tbl[(raw >> 2) & 0x3])<<8); + break; + + case SCR_ERROR: + /* devices other than 5287 uses 0xA8 as base */ + WARN_ON(pdev->device != 0x9002 && pdev->device != 0x9003); + pci_write_config_byte(pdev, 0x42, slot); + pci_read_config_dword(pdev, 0xA8, &v); + break; + + case SCR_CONTROL: + pci_read_config_byte(pdev, 0xA4 + slot, &raw); + + /* read the DET field, bit0 and bit1 */ + v |= ((raw & 0x02) << 1) | (raw & 0x01); + + /* read the IPM field, bit2 and bit3 */ + v |= ((raw >> 2) & 0x03) << 8; + + break; + + default: + return -EINVAL; + } + + *val = v; + return 0; +} + +static int cnd001_scr_write(struct ata_link *link, unsigned int scr, u32 val) +{ + struct pci_dev *pdev = to_pci_dev(link->ap->host->dev); + int slot = 2 * link->ap->port_no + link->pmp; + u32 v = 0; + + WARN_ON(pdev == NULL); + + switch (scr) { + case SCR_ERROR: + /* devices 0x9002 uses 0xA8 as base */ + WARN_ON(pdev->device != 0x9002 && pdev->device != 0x9003); + pci_write_config_byte(pdev, 0x42, slot); + pci_write_config_dword(pdev, 0xA8, val); + return 0; + + case SCR_CONTROL: + /* set the DET field */ + v |= ((val & 0x4) >> 1) | (val & 0x1); + + /* set the IPM field */ + v |= ((val >> 8) & 0x3) << 2; + + + pci_write_config_byte(pdev, 0xA4 + slot, v); + + + return 0; + + default: + return -EINVAL; + } +} + + +/** + * szx_tf_load - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller. + * + * This is to fix the internal bug of zx chipsets, which will + * reset the device register after changing the IEN bit on ctl + * register. + */ +static void szx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) +{ + struct ata_taskfile ttf; + + if (tf->ctl != ap->last_ctl) { + ttf = *tf; + ttf.flags |= ATA_TFLAG_DEVICE; + tf = &ttf; + } + ata_sff_tf_load(ap, tf); +} + +static const unsigned int szx_bar_sizes[] = { + 8, 4, 8, 4, 16, 256 +}; + +static const unsigned int cnd001_bar_sizes0[] = { + 8, 4, 8, 4, 16, 0 +}; + +static const unsigned int cnd001_bar_sizes1[] = { + 8, 4, 0, 0, 16, 0 +}; + +static int cnd001_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) +{ + const struct ata_port_info *ppi0[] = { &cnd001_port_info, NULL }; + const struct ata_port_info *ppi1[] = { &cnd001_port_info, &ata_dummy_port_info}; + struct ata_host *host; + int i, rc; + + if (pdev->device == 0x9002) + rc = ata_pci_bmdma_prepare_host(pdev, ppi0, &host); + else if (pdev->device == 0x9003) + rc = ata_pci_bmdma_prepare_host(pdev, ppi1, &host); + else + rc = -EINVAL; + if (rc) + return rc; + *r_host = host; + + + /* cnd001 9002 hosts four sata ports as M/S of the two channels */ + /* cnd001 9003 hosts two sata ports as M/S of the one channel */ + for (i = 0; i < host->n_ports; i++) + ata_slave_link_init(host->ports[i]); + + return 0; +} + +static void szx_configure(struct pci_dev *pdev, int board_id) +{ + u8 tmp8; + + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8); + dev_info(&pdev->dev, "routed to hard irq line %d\n", + (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f); + + /* make sure SATA channels are enabled */ + pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8); + if ((tmp8 & ALL_PORTS) != ALL_PORTS) { + dev_dbg(&pdev->dev, "enabling SATA channels (0x%x)\n", + (int)tmp8); + tmp8 |= ALL_PORTS; + pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8); + } + + /* make sure interrupts for each channel sent to us */ + pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8); + if ((tmp8 & ALL_PORTS) != ALL_PORTS) { + dev_dbg(&pdev->dev, "enabling SATA channel interrupts (0x%x)\n", + (int) tmp8); + tmp8 |= ALL_PORTS; + pci_write_config_byte(pdev, SATA_INT_GATE, tmp8); + } + + /* make sure native mode is enabled */ + pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8); + if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) { + dev_dbg(&pdev->dev, + "enabling SATA channel native mode (0x%x)\n", + (int) tmp8); + tmp8 |= NATIVE_MODE_ALL; + pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); + } +} + +static int szx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + unsigned int i; + int rc; + struct ata_host *host = NULL; + int board_id = (int) ent->driver_data; + const unsigned * bar_sizes; + int legacy_mode = 0; + + ata_print_version_once(&pdev->dev, DRV_VERSION); + + if (pdev->device == 0x9002 || pdev->device == 0x9003) { + if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + u8 tmp8, mask; + + /* TODO: What if one channel is in native mode ... */ + pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); + mask = (1 << 2) | (1 << 0); + if ((tmp8 & mask) != mask) + legacy_mode = 1; + } + if (legacy_mode) + return -EINVAL; + } + + + rc = pcim_enable_device(pdev); + if (rc) + return rc; + + if (board_id == cnd001 && pdev->device == 0x9002) + bar_sizes = &cnd001_bar_sizes0[0]; + else if (board_id == cnd001 && pdev->device == 0x9003) + bar_sizes = &cnd001_bar_sizes1[0]; + else + bar_sizes = &szx_bar_sizes[0]; + + for (i = 0; i < ARRAY_SIZE(szx_bar_sizes); i++) + if ((pci_resource_start(pdev, i) == 0) || + (pci_resource_len(pdev, i) < bar_sizes[i])) { + if (bar_sizes[i] == 0) + continue; + dev_err(&pdev->dev, + "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n", + i, + (unsigned long long)pci_resource_start(pdev, i), + (unsigned long long)pci_resource_len(pdev, i)); + return -ENODEV; + } + + switch (board_id) { + case cnd001: + rc = cnd001_prepare_host(pdev, &host); + break; + default: + rc = -EINVAL; + } + if (rc) + return rc; + + szx_configure(pdev, board_id); + + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, + IRQF_SHARED, &szx_sht); +} + +module_pci_driver(szx_pci_driver); -- 2.20.1
2 1
0 0
[PATCH kernel-4.19 0/2] x86/bugs: Exclude Zhaoxin family 7 CPUs
by LeoLiu-oc 26 Mar '21

26 Mar '21
New Zhaoxin family 7 CPUs are not affected by SPECTRE_V2, SWAPGS. Extend cpu_vuln_whitelist flag with a NO_SPECTRE_V2 bit. And add these CPUs to the cpu vulnerability whitelist. LeoLiu-oc (2): x86/speculation/spectre_v2: Exclude Zhaoxin CPUs from SPECTRE_V2 Subject: [patch v1 2/2] x86/speculation/swapgs: Exclude Zhaoxin CPUs from SWAPGS vulnerability arch/x86/kernel/cpu/common.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) -- 2.20.1
2 1
0 0
[PATCH kernel-4.19 0/2] Disable WBINVD operation when entering C3 or above for Zhaoxin CPUs
by LeoLiu-oc 26 Mar '21

26 Mar '21
All Zhaoxin CPUs that support C3 share cache. And caches should not be flushed by software while entering C3 type state. And On all recent Zhaoxin platforms, ARB_DISABLE is a nop. So, set bm_control to zero to indicate that ARB_DISABLE is not required while entering C3 type state. LeoLiu-oc (2): x86/power: Optimize C3 entry on Centaur CPUs x86/acpi/cstate: Add Zhaoxin processors support for cache flush policy in C3 arch/x86/kernel/acpi/cstate.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) -- 2.20.1
2 1
0 0
[PATCH kernel-4.19] ACPI, x86: Add Zhaoxin processors support for NONSTOP TSC
by LeoLiu-oc 26 Mar '21

26 Mar '21
mainline inclusion from mainline-5.3 commit 773b2f30a3fc026f3ed121a8b945b0ae19b64ec5 category: ACPI -------------------------------- Zhaoxin CPUs have NONSTOP TSC feature, so enable the ACPI driver support for it. Signed-off-by: Tony W Wang-oc <TonyWWang-oc(a)zhaoxin.com> Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de> Cc: "hpa(a)zytor.com" <hpa(a)zytor.com> Cc: "gregkh(a)linuxfoundation.org" <gregkh(a)linuxfoundation.org> Cc: "rjw(a)rjwysocki.net" <rjw(a)rjwysocki.net> Cc: "lenb(a)kernel.org" <lenb(a)kernel.org> Cc: David Wang <DavidWang(a)zhaoxin.com> Cc: "Cooper Yan(BJ-RD)" <CooperYan(a)zhaoxin.com> Cc: "Qiyuan Wang(BJ-RD)" <QiyuanWang(a)zhaoxin.com> Cc: "Herry Yang(BJ-RD)" <HerryYang(a)zhaoxin.com> Link: https://lkml.kernel.org/r/d1cfd937dabc44518d42038b55522c53@zhaoxin.com Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/acpi/acpi_pad.c | 1 + drivers/acpi/processor_idle.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index a47676a55b84..c06306e6ac92 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -73,6 +73,7 @@ static void power_saving_mwait_init(void) case X86_VENDOR_HYGON: case X86_VENDOR_AMD: case X86_VENDOR_INTEL: + case X86_VENDOR_ZHAOXIN: /* * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b2131c4ea124..6336f956a144 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -209,6 +209,7 @@ static void tsc_check_state(int state) case X86_VENDOR_AMD: case X86_VENDOR_INTEL: case X86_VENDOR_CENTAUR: + case X86_VENDOR_ZHAOXIN: /* * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. -- 2.20.1
2 1
0 0
[PATCH kernel-4.19 0/6] New Zhaoxin CPU vendor ID/FMS patch
by LeoLiu-oc 26 Mar '21

26 Mar '21
This set of patches is to add support for Zhaoxin Family 7 CPUs. With these patches, the kernel can identify Zhaoxin CPUs features and Zhaoxin CPU topology information. LeoLiu-oc (6): x86/cpu: Create Zhaoxin processors architecture support file x86/cpu: Remove redundant cpu_detect_cache_sizes() call x86/cpu/centaur: Replace two-condition switch-case with an if statement x86/cpu/centaur: Add Centaur family >=7 CPUs initialization support x86/cpufeatures: Add Zhaoxin feature bits x86/cpu: Add detect extended topology for Zhaoxin CPUs MAINTAINERS | 6 + arch/x86/Kconfig.cpu | 13 +++ arch/x86/include/asm/cpufeatures.h | 21 ++++ arch/x86/include/asm/processor.h | 3 +- arch/x86/kernel/cpu/Makefile | 1 + arch/x86/kernel/cpu/centaur.c | 47 +++++--- arch/x86/kernel/cpu/zhaoxin.c | 170 +++++++++++++++++++++++++++++ 7 files changed, 243 insertions(+), 18 deletions(-) create mode 100644 arch/x86/kernel/cpu/zhaoxin.c -- 2.20.1
2 1
0 0
[PATCH openEuler-21.03] arm64/mpam: fix a possible deadlock in mpam_enable
by Zhang Ming 25 Mar '21

25 Mar '21
openEuler inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I3D58V CVE: NA ---------------------------------- No unlock operation is performed on the mpam_devices_lock before the return statement, which may lead to a deadlock. Signed-off-by: Zhang Ming <154842638(a)qq.com> Reported-by: Jian Cheng <cj.chengjian(a)huawei.com> Suggested-by: Jian Cheng <cj.chengjian(a)huawei.com> --- arch/arm64/kernel/mpam/mpam_device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index 1aca24f570d3..d8511527970a 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -560,8 +560,10 @@ static void __init mpam_enable(struct work_struct *work) mutex_lock(&mpam_devices_lock); mpam_enable_squash_features(); err = mpam_allocate_config(); - if (err) + if (err) { + mutex_unlock(&mpam_devices_lock); return; + } mutex_unlock(&mpam_devices_lock); mpam_enable_irqs(); -- 2.25.1
3 2
0 0
[PATCH kernel-4.19 2/2] x86/Kconfig: Drop vendor dependency for, X86_UMIP
by LeoLiu-oc 25 Mar '21

25 Mar '21
x86/Kconfig: Rename UMIP config parameter mainline inclusion from mainline-5.7 commit bdb04a1abbf92c998f1afb5f00a037f2edaec1f7 category: x86/Kconfig -------------------------------- Some Centaur family 7 CPUs and Zhaoxin family 7 CPUs support the UMIP feature too. The text size growth which UMIP adds is ~1K and distro kernels enable it anyway so remove the vendor dependency. [ bp: Rewrite commit message. ] Signed-off-by: Tony W Wang-oc <TonyWWang-oc(a)zhaoxin.com> Signed-off-by: Borislav Petkov <bp(a)suse.de> Link: https://lkml.kernel.org/r/1583733990-2587-1-git-send-email-TonyWWang-oc@zha… Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- arch/x86/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5e00e8900748..dd4dfb80ac6c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1869,7 +1869,6 @@ config X86_SMAP config X86_UMIP def_bool y - depends on CPU_SUP_INTEL || CPU_SUP_AMD prompt "User Mode Instruction Prevention" if EXPERT ---help--- User Mode Instruction Prevention (UMIP) is a security feature in -- 2.20.1
1 0
0 0
[PATCH kernel-4.19 1/2] x86/Kconfig: Rename UMIP config parameter
by LeoLiu-oc 25 Mar '21

25 Mar '21
mainline inclusion from mainline-5.5 commit b971880fe79f4042aaaf426744a5b19521bf77b3 category: x86/Kconfig -------------------------------- AMD 2nd generation EPYC processors support the UMIP (User-Mode Instruction Prevention) feature. So, rename X86_INTEL_UMIP to generic X86_UMIP and modify the text to cover both Intel and AMD. [ bp: take of the disabled-features.h copy in tools/ too. ] Signed-off-by: Babu Moger <babu.moger(a)amd.com> Signed-off-by: Borislav Petkov <bp(a)suse.de> Cc: Andy Lutomirski <luto(a)kernel.org> Cc: "H. Peter Anvin" <hpa(a)zytor.com> Cc: Ingo Molnar <mingo(a)redhat.com> Cc: Ricardo Neri <ricardo.neri-calderon(a)linux.intel.com> Cc: Thomas Gleixner <tglx(a)linutronix.de> Cc: "x86(a)kernel.org" <x86(a)kernel.org> Link: https://lkml.kernel.org/r/157298912544.17462.2018334793891409521.stgit@napl… Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- arch/x86/Kconfig | 16 ++++++++-------- arch/x86/include/asm/disabled-features.h | 2 +- arch/x86/include/asm/umip.h | 4 ++-- arch/x86/kernel/Makefile | 2 +- tools/arch/x86/include/asm/disabled-features.h | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2b0695630031..5e00e8900748 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1867,16 +1867,16 @@ config X86_SMAP If unsure, say Y. -config X86_INTEL_UMIP +config X86_UMIP def_bool y - depends on CPU_SUP_INTEL - prompt "Intel User Mode Instruction Prevention" if EXPERT + depends on CPU_SUP_INTEL || CPU_SUP_AMD + prompt "User Mode Instruction Prevention" if EXPERT ---help--- - The User Mode Instruction Prevention (UMIP) is a security - feature in newer Intel processors. If enabled, a general - protection fault is issued if the SGDT, SLDT, SIDT, SMSW - or STR instructions are executed in user mode. These instructions - unnecessarily expose information about the hardware state. + User Mode Instruction Prevention (UMIP) is a security feature in + some x86 processors. If enabled, a general protection fault is + issued if the SGDT, SLDT, SIDT, SMSW or STR instructions are + executed in user mode. These instructions unnecessarily expose + information about the hardware state. The vast majority of applications do not use these instructions. For the very few that do, software emulation is provided in diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index 33833d1909af..9d9da3487425 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -16,7 +16,7 @@ # define DISABLE_MPX (1<<(X86_FEATURE_MPX & 31)) #endif -#ifdef CONFIG_X86_INTEL_UMIP +#ifdef CONFIG_X86_UMIP # define DISABLE_UMIP 0 #else # define DISABLE_UMIP (1<<(X86_FEATURE_UMIP & 31)) diff --git a/arch/x86/include/asm/umip.h b/arch/x86/include/asm/umip.h index db43f2a0d92c..aeed98c3c9e1 100644 --- a/arch/x86/include/asm/umip.h +++ b/arch/x86/include/asm/umip.h @@ -4,9 +4,9 @@ #include <linux/types.h> #include <asm/ptrace.h> -#ifdef CONFIG_X86_INTEL_UMIP +#ifdef CONFIG_X86_UMIP bool fixup_umip_exception(struct pt_regs *regs); #else static inline bool fixup_umip_exception(struct pt_regs *regs) { return false; } -#endif /* CONFIG_X86_INTEL_UMIP */ +#endif /* CONFIG_X86_UMIP */ #endif /* _ASM_X86_UMIP_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index da0b6bc090f3..66835d9a6f72 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -134,7 +134,7 @@ obj-$(CONFIG_EFI) += sysfb_efi.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_TRACING) += tracepoint.o obj-$(CONFIG_SCHED_MC_PRIO) += itmt.o -obj-$(CONFIG_X86_INTEL_UMIP) += umip.o +obj-$(CONFIG_X86_UMIP) += umip.o obj-$(CONFIG_UNWINDER_ORC) += unwind_orc.o obj-$(CONFIG_UNWINDER_FRAME_POINTER) += unwind_frame.o diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h index 33833d1909af..9d9da3487425 100644 --- a/tools/arch/x86/include/asm/disabled-features.h +++ b/tools/arch/x86/include/asm/disabled-features.h @@ -16,7 +16,7 @@ # define DISABLE_MPX (1<<(X86_FEATURE_MPX & 31)) #endif -#ifdef CONFIG_X86_INTEL_UMIP +#ifdef CONFIG_X86_UMIP # define DISABLE_UMIP 0 #else # define DISABLE_UMIP (1<<(X86_FEATURE_UMIP & 31)) -- 2.20.1
1 0
0 0
[PATCH kernel-4.19 3/3] PCI: Add ACS quirk for Zhaoxin Root/Downstream Ports
by LeoLiu-oc 25 Mar '21

25 Mar '21
mainline inclusion from mainline-5.6.9 commit 299bd044a6f332b4a6c8f708575c27cad70a35c1 category: PCI Adapt to current kernel code -------------------------------- Many Zhaoxin Root Ports and Switch Downstream Ports do provide ACS-like capability but have no ACS Capability Structure. Peer-to-Peer transactions could be blocked between these ports, so add quirk so devices behind them could be assigned to different IOMMU group. Link: https://lore.kernel.org/r/20200327091148.5190-4-RaymondPang-oc@zhaoxin.com Signed-off-by: Raymond Pang <RaymondPang-oc(a)zhaoxin.com> Signed-off-by: Bjorn Helgaas <bhelgaas(a)google.com> Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/pci/quirks.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 8f072a511fdd..5bfe2457aea9 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4281,6 +4281,31 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0d, PCI_CLASS_NOT_DEFINED DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, 0x2f0e, PCI_CLASS_NOT_DEFINED, 8, quirk_relaxedordering_disable); + /* + * Many Zhaoxin Root Ports and Switch Downstream Ports have no ACS capability. + * But the implementation could block peer-to-peer transactions between them + * and provide ACS-like functionality. + */ +static int pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags) +{ + u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV); + int ret = acs_flags & ~flags ? 0 : 1; + + if (!pci_is_pcie(dev) || + ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) && + (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) + return -ENOTTY; + + switch (dev->device) { + case 0x0710 ... 0x071e: + case 0x0721: + case 0x0723 ... 0x0732: + return ret; + } + + return false; +} + /* * The AMD ARM A1100 (aka "SEATTLE") SoC has a bug in its PCIe Root Complex * where Upstream Transaction Layer Packets with the Relaxed Ordering @@ -4771,6 +4796,8 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_ZHAOXIN, 0x3038, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_ZHAOXIN, 0x3104, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs }, + /* Zhaoxin Root/Downstream Ports */ + { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, { 0 } }; -- 2.20.1
1 0
0 0
[PATCH kernel-4.19 2/3] PCI: Add ACS quirk for Zhaoxin multi-function devices
by LeoLiu-oc 25 Mar '21

25 Mar '21
mainline inclusion from mainline-5.6.9 commit 0325837c51cb7c9a5bd3e354ac0c0cda0667d50e category: PCI -------------------------------- Some Zhaoxin endpoints are implemented as multi-function devices without an ACS capability, but they actually don't support peer-to-peer transactions. Add ACS quirks to declare DMA isolation. Link: https://lore.kernel.org/r/20200327091148.5190-3-RaymondPang-oc@zhaoxin.com Signed-off-by: Raymond Pang <RaymondPang-oc(a)zhaoxin.com> Signed-off-by: Bjorn Helgaas <bhelgaas(a)google.com> Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/pci/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index edb6138a9e7f..8f072a511fdd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4767,6 +4767,10 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_AMPERE, 0xE00B, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs }, + /* Zhaoxin multi-function devices */ + { PCI_VENDOR_ID_ZHAOXIN, 0x3038, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_ZHAOXIN, 0x3104, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs }, { 0 } }; -- 2.20.1
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 1882
  • 1883
  • 1884
  • 1885
  • 1886
  • 1887
  • 1888
  • ...
  • 1949
  • Older →

HyperKitty Powered by HyperKitty