Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c10340ac authored by Jeff Garzik's avatar Jeff Garzik
Browse files

[libata] sata_svw: Disable ATAPI DMA on current boards (errata workaround)



Current Broadcom/Serverworks SATA boards (including Apple K2 SATA)
have problems with ATAPI DMA, so it is disabled.  ATAPI PIO, ATA PIO,
and ATA DMA continue to work just fine.

Acked-by: default avatarAnantha Subramanyam <ananth@broadcom.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent da02d2a1
Loading
Loading
Loading
Loading
+34 −7
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@
#define DRV_VERSION	"2.0"

enum {
	K2_FLAG_NO_ATAPI_DMA		= (1 << 29),

	/* Taskfile registers offsets */
	K2_SATA_TF_CMD_OFFSET		= 0x00,
	K2_SATA_TF_DATA_OFFSET		= 0x00,
@@ -83,11 +85,33 @@ enum {

	/* Port stride */
	K2_SATA_PORT_OFFSET		= 0x100,

	board_svw4			= 0,
	board_svw8			= 1,
};

static const struct k2_board_info {
	unsigned int		n_ports;
	unsigned long		port_flags;
} k2_board_info[] = {
	/* board_svw4 */
	{ 4, K2_FLAG_NO_ATAPI_DMA },

	/* board_svw8 */
	{ 8, K2_FLAG_NO_ATAPI_DMA },
};

static u8 k2_stat_check_status(struct ata_port *ap);


static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
{
	if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
		return -1;	/* ATAPI DMA not supported */

	return 0;
}

static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
	if (sc_reg > SCR_CONTROL)
@@ -313,6 +337,7 @@ static const struct ata_port_operations k2_sata_ops = {
	.check_status		= k2_stat_check_status,
	.exec_command		= ata_exec_command,
	.dev_select		= ata_std_dev_select,
	.check_atapi_dma	= k2_sata_check_atapi_dma,
	.bmdma_setup		= k2_bmdma_setup_mmio,
	.bmdma_start		= k2_bmdma_start_mmio,
	.bmdma_stop		= ata_bmdma_stop,
@@ -359,6 +384,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
	struct ata_probe_ent *probe_ent = NULL;
	unsigned long base;
	void __iomem *mmio_base;
	const struct k2_board_info *board_info =
			&k2_board_info[ent->driver_data];
	int pci_dev_busy = 0;
	int rc;
	int i;
@@ -424,7 +451,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e

	probe_ent->sht = &k2_sata_sht;
	probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
				ATA_FLAG_MMIO;
				ATA_FLAG_MMIO | board_info->port_flags;
	probe_ent->port_ops = &k2_sata_ops;
	probe_ent->n_ports = 4;
	probe_ent->irq = pdev->irq;
@@ -441,7 +468,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
	/* different controllers have different number of ports - currently 4 or 8 */
	/* All ports are on the same function. Multi-function device is no
	 * longer available. This should not be seen in any system. */
	for (i = 0; i < ent->driver_data; i++)
	for (i = 0; i < board_info->n_ports; i++)
		k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);

	pci_set_master(pdev);
@@ -469,11 +496,11 @@ err_out:
 * controller
 * */
static const struct pci_device_id k2_sata_pci_tbl[] = {
	{ PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
	{ PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
	{ PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
	{ PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },

	{ }
};