Skip to content

Commit

Permalink
ahci: Marvell 88SE9215 controllers prefer DMA for ATAPI
Browse files Browse the repository at this point in the history
We use CD/DVD drives under Marvell 88SE9215 SATA controller on many
Loongson-based machines. We found its PIO doesn't work well, and on the
opposite its DMA seems work very well.

We don't know the detail of the 88SE9215 SATA controller, but we have
tested different CD/DVD drives and they all have problems under 88SE9215
(but they all work well under an Intel SATA controller). So, we consider
this problem is bound to 88SE9215 SATA controller rather than bound to
CD/DVD drives.

As a solution, we define a new dedicated AHCI board id which is named
board_ahci_yes_fbs_atapi_dma for 88SE9215, and for this id we set the
AHCI_HFLAG_ATAPI_DMA_QUIRK and ATA_QUIRK_ATAPI_MOD16_DMA flags on the
SATA controller in order to prefer ATAPI DMA.

Reported-by: Yuli Wang <wangyuli@uniontech.com>
Tested-by: Jie Fan <fanjie@uniontech.com>
Tested-by: Erpeng Xu <xuerpeng@uniontech.com>
Tested-by: Yuli Wang <wangyuli@uniontech.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Link: https://lore.kernel.org/r/20250318104314.2160526-1-chenhuacai@loongson.cn
Signed-off-by: Niklas Cassel <cassel@kernel.org>
  • Loading branch information
Huacai Chen authored and Niklas Cassel committed Mar 18, 2025
1 parent b500ee5 commit 0507c77
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
11 changes: 10 additions & 1 deletion drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ enum board_ids {
board_ahci_pcs_quirk_no_devslp,
board_ahci_pcs_quirk_no_sntf,
board_ahci_yes_fbs,
board_ahci_yes_fbs_atapi_dma,

/* board IDs for specific chipsets in alphabetical order */
board_ahci_al,
Expand Down Expand Up @@ -188,6 +189,14 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
[board_ahci_yes_fbs_atapi_dma] = {
AHCI_HFLAGS (AHCI_HFLAG_YES_FBS |
AHCI_HFLAG_ATAPI_DMA_QUIRK),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
/* by chipsets */
[board_ahci_al] = {
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_MSI),
Expand Down Expand Up @@ -590,7 +599,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
.driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9215),
.driver_data = board_ahci_yes_fbs },
.driver_data = board_ahci_yes_fbs_atapi_dma },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
.driver_data = board_ahci_yes_fbs },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9235),
Expand Down
1 change: 1 addition & 0 deletions drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ enum {
AHCI_HFLAG_NO_SXS = BIT(26), /* SXS not supported */
AHCI_HFLAG_43BIT_ONLY = BIT(27), /* 43bit DMA addr limit */
AHCI_HFLAG_INTEL_PCS_QUIRK = BIT(28), /* apply Intel PCS quirk */
AHCI_HFLAG_ATAPI_DMA_QUIRK = BIT(29), /* force ATAPI to use DMA */

/* ap->flags bits */

Expand Down
4 changes: 4 additions & 0 deletions drivers/ata/libahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,10 @@ static void ahci_dev_config(struct ata_device *dev)
{
struct ahci_host_priv *hpriv = dev->link->ap->host->private_data;

if ((dev->class == ATA_DEV_ATAPI) &&
(hpriv->flags & AHCI_HFLAG_ATAPI_DMA_QUIRK))
dev->quirks |= ATA_QUIRK_ATAPI_MOD16_DMA;

if (hpriv->flags & AHCI_HFLAG_SECT255) {
dev->max_sectors = 255;
ata_dev_info(dev,
Expand Down

0 comments on commit 0507c77

Please sign in to comment.