コード例 #1
0
ファイル: pata_sil680.c プロジェクト: jameshilliard/20-4-4
static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
	static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 };

	unsigned long tfaddr = sil680_selreg(ap, 0x02);
	unsigned long addr = sil680_seldev(ap, adev, 0x04);
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	int pio = adev->pio_mode - XFER_PIO_0;
	int lowest_pio = pio;
	u16 reg;

	struct ata_device *pair = ata_dev_pair(adev);

	if (pair != NULL && adev->pio_mode > pair->pio_mode)
		lowest_pio = pair->pio_mode - XFER_PIO_0;

	pci_write_config_word(pdev, addr, speed_p[pio]);
	pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]);

	pci_read_config_word(pdev, tfaddr-2, &reg);
	reg &= ~0x0200;			/* Clear IORDY */
	if (ata_pio_need_iordy(adev))
		reg |= 0x0200;		/* Enable IORDY */
	pci_write_config_word(pdev, tfaddr-2, reg);
}
コード例 #2
0
ファイル: pata_sil680.c プロジェクト: 0x000000FF/Linux4Edison
static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
	static const u8 ultra_table[2][7] = {
		{ 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF },	/* 100MHz */
		{ 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 },	/* 133Mhz */
	};
	static const u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };

	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	unsigned long ma = sil680_seldev(ap, adev, 0x08);
	unsigned long ua = sil680_seldev(ap, adev, 0x0C);
	unsigned long addr_mask = 0x80 + 4 * ap->port_no;
	int port_shift = adev->devno * 4;
	u8 scsc, mode;
	u16 multi, ultra;

	pci_read_config_byte(pdev, 0x8A, &scsc);
	pci_read_config_byte(pdev, addr_mask, &mode);
	pci_read_config_word(pdev, ma, &multi);
	pci_read_config_word(pdev, ua, &ultra);

	/* Mask timing bits */
	ultra &= ~0x3F;
	mode &= ~(0x03 << port_shift);

	/* Extract scsc */
	scsc = (scsc & 0x30) ? 1 : 0;

	if (adev->dma_mode >= XFER_UDMA_0) {
		multi = 0x10C1;
		ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0];
		mode |= (0x03 << port_shift);
	} else {
		multi = dma_table[adev->dma_mode - XFER_MW_DMA_0];
		mode |= (0x02 << port_shift);
	}
	pci_write_config_byte(pdev, addr_mask, mode);
	pci_write_config_word(pdev, ma, multi);
	pci_write_config_word(pdev, ua, ultra);
}
コード例 #3
0
ファイル: pata_sil680.c プロジェクト: 0x000000FF/Linux4Edison
static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	static const u16 speed_p[5] = {
		0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1
	};
	static const u16 speed_t[5] = {
		0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1
	};

	unsigned long tfaddr = sil680_selreg(ap, 0x02);
	unsigned long addr = sil680_seldev(ap, adev, 0x04);
	unsigned long addr_mask = 0x80 + 4 * ap->port_no;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	int pio = adev->pio_mode - XFER_PIO_0;
	int lowest_pio = pio;
	int port_shift = 4 * adev->devno;
	u16 reg;
	u8 mode;

	struct ata_device *pair = ata_dev_pair(adev);

	if (pair != NULL && adev->pio_mode > pair->pio_mode)
		lowest_pio = pair->pio_mode - XFER_PIO_0;

	pci_write_config_word(pdev, addr, speed_p[pio]);
	pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]);

	pci_read_config_word(pdev, tfaddr-2, &reg);
	pci_read_config_byte(pdev, addr_mask, &mode);

	reg &= ~0x0200;			/* Clear IORDY */
	mode &= ~(3 << port_shift);	/* Clear IORDY and DMA bits */

	if (ata_pio_need_iordy(adev)) {
		reg |= 0x0200;		/* Enable IORDY */
		mode |= 1 << port_shift;
	}
	pci_write_config_word(pdev, tfaddr-2, reg);
	pci_write_config_byte(pdev, addr_mask, mode);
}