From fd382b8faeec5e9f8be6b480c99ddfc883a7b7b0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 17 Mar 2004 19:35:04 -0500 Subject: [libata] API cleanup Remove ->phy_config hook, everybody used pata_phy_config. Rename function to ata_set_mode, and directly call internally. --- include/linux/libata.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0d10e7df6771..f9022a25c6fa 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -362,7 +362,6 @@ struct ata_port_operations { u8 (*check_status)(struct ata_port *ap); void (*phy_reset) (struct ata_port *ap); - void (*phy_config) (struct ata_port *ap); void (*bmdma_start) (struct ata_queued_cmd *qc); void (*fill_sg) (struct ata_queued_cmd *qc); @@ -396,7 +395,6 @@ struct pci_bits { }; extern void ata_port_probe(struct ata_port *); -extern void pata_phy_config(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); extern void ata_port_disable(struct ata_port *); -- cgit v1.2.3 From 310d420ed0e68e187491c6b6712ae2db8c27e39a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 17 Mar 2004 20:27:36 -0500 Subject: [libata sata_sil] add post-set-mode hook to libata, use it Silicon Image has a register that indicates the data transfer mode (pio-old, pio-new, mdma or udma) that must be initialized after the SET FEATURES - XFER command has been issued. This requires a hook in libata core to set the register at the right time. Also, limit to UDMA5 due to scary comments in FreeBSD about chip errata. --- drivers/scsi/libata-core.c | 2 ++ drivers/scsi/sata_sil.c | 44 ++++++++++++++++++++++++++++++++++++++------ include/linux/libata.h | 1 + 3 files changed, 41 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 8db2b38ba580..14a30889b4e3 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1159,6 +1159,8 @@ static void ata_set_mode(struct ata_port *ap) return; } + if (ap->ops->post_set_mode) + ap->ops->post_set_mode(ap); } /** diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index aff03f16413b..9cc7c0b617c6 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -61,6 +61,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static void sil_post_set_mode (struct ata_port *ap); static struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, @@ -124,6 +125,7 @@ static struct ata_port_operations sil_ops = { .check_status = ata_check_status_mmio, .exec_command = ata_exec_command_mmio, .phy_reset = sata_phy_reset, + .post_set_mode = sil_post_set_mode, .bmdma_start = ata_bmdma_start_mmio, .fill_sg = ata_fill_sg, .eng_timeout = ata_eng_timeout, @@ -141,7 +143,7 @@ static struct ata_port_info sil_port_info[] = { .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | ATA_FLAG_MMIO, .pio_mask = 0x03, /* pio3-4 */ - .udma_mask = 0x7f, /* udma0-6; FIXME */ + .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, }, /* sil_3114 */ { @@ -149,7 +151,7 @@ static struct ata_port_info sil_port_info[] = { .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | ATA_FLAG_MMIO, .pio_mask = 0x03, /* pio3-4 */ - .udma_mask = 0x7f, /* udma0-6; FIXME */ + .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, }, }; @@ -162,11 +164,14 @@ static const struct { unsigned long bmdma; /* DMA register block */ unsigned long scr; /* SATA control register block */ unsigned long sien; /* SATA Interrupt Enable register */ + unsigned long xfer_mode;/* data transfer mode register */ } sil_port[] = { - { 0x80, 0x8A, 0x00, 0x100, 0x148 }, /* port 0 ... */ - { 0xC0, 0xCA, 0x08, 0x180, 0x1c8 }, - { 0x280, 0x28A, 0x200, 0x300, 0x348 }, - { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8 }, /* ... port 3 */ + /* port 0 ... */ + { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, + { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, + { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, + { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, + /* ... port 3 */ }; MODULE_AUTHOR("Jeff Garzik"); @@ -174,6 +179,33 @@ MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sil_pci_tbl); +static void sil_post_set_mode (struct ata_port *ap) +{ + struct ata_host_set *host_set = ap->host_set; + struct ata_device *dev; + void *addr = host_set->mmio_base + sil_port[ap->port_no].xfer_mode; + u32 tmp, dev_mode[2]; + unsigned int i; + + for (i = 0; i < 2; i++) { + dev = &ap->device[i]; + if (!ata_dev_present(dev)) + dev_mode[i] = 0; /* PIO0/1/2 */ + else if (dev->flags & ATA_DFLAG_PIO) + dev_mode[i] = 1; /* PIO3/4 */ + else + dev_mode[i] = 3; /* UDMA */ + /* value 2 indicates MDMA */ + } + + tmp = readl(addr); + tmp &= ~((1<<5) | (1<<4) | (1<<1) | (1<<0)); + tmp |= dev_mode[0]; + tmp |= (dev_mode[1] << 4); + writel(tmp, addr); + readl(addr); /* flush */ +} + static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_reg) { unsigned long offset = ap->ioaddr.scr_addr; diff --git a/include/linux/libata.h b/include/linux/libata.h index f9022a25c6fa..3a1cb04caec7 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -362,6 +362,7 @@ struct ata_port_operations { u8 (*check_status)(struct ata_port *ap); void (*phy_reset) (struct ata_port *ap); + void (*post_set_mode) (struct ata_port *ap); void (*bmdma_start) (struct ata_queued_cmd *qc); void (*fill_sg) (struct ata_queued_cmd *qc); -- cgit v1.2.3