Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev: (86 commits) SPIN_LOCK_UNLOCKED cleanup in drivers/ata/pata_winbond.c drivers/ata/pata_cmd640.c: fix build with CONFIG_PM=n pata_hpt37x: Further small fixes pata_hpt3x2n: Add HPT371N support and other bits ata: printk warning fixes libata: separate ATA_EHI_DID_RESET into DID_SOFTRESET and DID_HARDRESET ahci: consolidate common port flags ata_timing: ensure t->cycle is always correct libata: add missing call to ->cable_detect() in new EH path pata_amd: remove contamination added during cable_detect conversion libata: Handle drives that require a spin-up command before first access libata: HPA support libata: kill probe_ent and related helpers libata: convert the remaining PATA drivers to new init model libata: convert the remaining SATA drivers to new init model libata: convert ata_pci_init_native_mode() users to new init model libata: convert drivers with combined SATA/PATA ports to new init model libata: add init helpers including ata_pci_prepare_native_host() libata: convert native PCI host handling to new init model libata: convert legacy PCI host handling to new init model ...
This commit is contained in:
commit
f73b0a08ea
|
@ -692,7 +692,6 @@ CONFIG_SATA_SIL=y
|
|||
CONFIG_SATA_VIA=y
|
||||
# CONFIG_SATA_VITESSE is not set
|
||||
# CONFIG_SATA_INIC162X is not set
|
||||
CONFIG_SATA_INTEL_COMBINED=y
|
||||
CONFIG_SATA_ACPI=y
|
||||
# CONFIG_PATA_ALI is not set
|
||||
# CONFIG_PATA_AMD is not set
|
||||
|
|
|
@ -435,7 +435,6 @@ CONFIG_SCSI_SATA_SIL=m
|
|||
# CONFIG_SCSI_SATA_ULI is not set
|
||||
CONFIG_SCSI_SATA_VIA=m
|
||||
# CONFIG_SCSI_SATA_VITESSE is not set
|
||||
CONFIG_SCSI_SATA_INTEL_COMBINED=y
|
||||
# CONFIG_SCSI_DMX3191D is not set
|
||||
# CONFIG_SCSI_FUTURE_DOMAIN is not set
|
||||
# CONFIG_SCSI_IPS is not set
|
||||
|
|
|
@ -631,7 +631,6 @@ CONFIG_SATA_SIL=y
|
|||
CONFIG_SATA_VIA=y
|
||||
# CONFIG_SATA_VITESSE is not set
|
||||
# CONFIG_SATA_INIC162X is not set
|
||||
CONFIG_SATA_INTEL_COMBINED=y
|
||||
CONFIG_SATA_ACPI=y
|
||||
# CONFIG_PATA_ALI is not set
|
||||
# CONFIG_PATA_AMD is not set
|
||||
|
|
|
@ -156,11 +156,6 @@ config SATA_INIC162X
|
|||
help
|
||||
This option enables support for Initio 162x Serial ATA.
|
||||
|
||||
config SATA_INTEL_COMBINED
|
||||
bool
|
||||
depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
|
||||
default y
|
||||
|
||||
config SATA_ACPI
|
||||
bool
|
||||
depends on ACPI && PCI
|
||||
|
@ -184,7 +179,7 @@ config PATA_ALI
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_AMD
|
||||
tristate "AMD/NVidia PATA support (Experimental)"
|
||||
tristate "AMD/NVidia PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the AMD and NVidia PATA
|
||||
|
@ -209,6 +204,16 @@ config PATA_ATIIXP
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_CMD640_PCI
|
||||
tristate "CMD640 PCI PATA support (Very Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the CMD640 PCI IDE
|
||||
interface chip. Only the primary channel is currently
|
||||
supported.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_CMD64X
|
||||
tristate "CMD64x PATA support (Very Experimental)"
|
||||
depends on PCI&& EXPERIMENTAL
|
||||
|
@ -273,7 +278,7 @@ config ATA_GENERIC
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_HPT366
|
||||
tristate "HPT 366/368 PATA support (Very Experimental)"
|
||||
tristate "HPT 366/368 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the HPT 366 and 368
|
||||
|
@ -282,7 +287,7 @@ config PATA_HPT366
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_HPT37X
|
||||
tristate "HPT 370/370A/371/372/374/302 PATA support (Very Experimental)"
|
||||
tristate "HPT 370/370A/371/372/374/302 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the majority of the later HPT
|
||||
|
@ -309,7 +314,7 @@ config PATA_HPT3X3
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_ISAPNP
|
||||
tristate "ISA Plug and Play PATA support (Very Experimental)"
|
||||
tristate "ISA Plug and Play PATA support (Experimental)"
|
||||
depends on EXPERIMENTAL && ISAPNP
|
||||
help
|
||||
This option enables support for ISA plug & play ATA
|
||||
|
@ -318,8 +323,8 @@ config PATA_ISAPNP
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_IT821X
|
||||
tristate "IT8211/2 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
tristate "IT8211/2 PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the ITE 8211 and 8212
|
||||
PATA controllers via the new ATA layer, including RAID
|
||||
|
@ -390,10 +395,10 @@ config PATA_MPIIX
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_OLDPIIX
|
||||
tristate "Intel PATA old PIIX support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
tristate "Intel PATA old PIIX support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for old(?) PIIX PATA support.
|
||||
This option enables support for early PIIX PATA support.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
|
@ -444,7 +449,7 @@ config PATA_PCMCIA
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_PDC_OLD
|
||||
tristate "Older Promise PATA controller support (Very Experimental)"
|
||||
tristate "Older Promise PATA controller support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the Promise 20246, 20262, 20263,
|
||||
|
@ -459,7 +464,7 @@ config PATA_QDI
|
|||
Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
|
||||
|
||||
config PATA_RADISYS
|
||||
tristate "RADISYS 82600 PATA support (Very experimental)"
|
||||
tristate "RADISYS 82600 PATA support (Very Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the RADISYS 82600
|
||||
|
@ -477,7 +482,7 @@ config PATA_RZ1000
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_SC1200
|
||||
tristate "SC1200 PATA support (Raving Lunatic)"
|
||||
tristate "SC1200 PATA support (Very Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
help
|
||||
This option enables support for the NatSemi/AMD SC1200 SoC
|
||||
|
@ -486,8 +491,8 @@ config PATA_SC1200
|
|||
If unsure, say N.
|
||||
|
||||
config PATA_SERVERWORKS
|
||||
tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support (Experimental)"
|
||||
depends on PCI && EXPERIMENTAL
|
||||
tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the Serverworks OSB4/CSB5/CSB6 and
|
||||
HT1000 PATA controllers, via the new ATA layer.
|
||||
|
|
|
@ -22,6 +22,7 @@ obj-$(CONFIG_PATA_ALI) += pata_ali.o
|
|||
obj-$(CONFIG_PATA_AMD) += pata_amd.o
|
||||
obj-$(CONFIG_PATA_ARTOP) += pata_artop.o
|
||||
obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o
|
||||
obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o
|
||||
obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
|
||||
obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o
|
||||
obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
|
||||
|
|
|
@ -170,6 +170,10 @@ enum {
|
|||
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
|
||||
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
|
||||
AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
|
||||
|
||||
AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY,
|
||||
};
|
||||
|
||||
struct ahci_cmd_hdr {
|
||||
|
@ -188,8 +192,10 @@ struct ahci_sg {
|
|||
};
|
||||
|
||||
struct ahci_host_priv {
|
||||
u32 cap; /* cache of HOST_CAP register */
|
||||
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
|
||||
u32 cap; /* cap to use */
|
||||
u32 port_map; /* port map to use */
|
||||
u32 saved_cap; /* saved initial cap */
|
||||
u32 saved_port_map; /* saved initial port_map */
|
||||
};
|
||||
|
||||
struct ahci_port_priv {
|
||||
|
@ -209,7 +215,6 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
|
|||
static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||
static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
|
||||
static irqreturn_t ahci_interrupt (int irq, void *dev_instance);
|
||||
static void ahci_irq_clear(struct ata_port *ap);
|
||||
static int ahci_port_start(struct ata_port *ap);
|
||||
static void ahci_port_stop(struct ata_port *ap);
|
||||
|
@ -263,7 +268,6 @@ static const struct ata_port_operations ahci_ops = {
|
|||
.qc_prep = ahci_qc_prep,
|
||||
.qc_issue = ahci_qc_issue,
|
||||
|
||||
.irq_handler = ahci_interrupt,
|
||||
.irq_clear = ahci_irq_clear,
|
||||
.irq_on = ata_dummy_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
@ -298,7 +302,6 @@ static const struct ata_port_operations ahci_vt8251_ops = {
|
|||
.qc_prep = ahci_qc_prep,
|
||||
.qc_issue = ahci_qc_issue,
|
||||
|
||||
.irq_handler = ahci_interrupt,
|
||||
.irq_clear = ahci_irq_clear,
|
||||
.irq_on = ata_dummy_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
@ -324,58 +327,41 @@ static const struct ata_port_operations ahci_vt8251_ops = {
|
|||
static const struct ata_port_info ahci_port_info[] = {
|
||||
/* board_ahci */
|
||||
{
|
||||
.sht = &ahci_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY,
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_pi */
|
||||
{
|
||||
.sht = &ahci_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
|
||||
.flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_vt8251 */
|
||||
{
|
||||
.sht = &ahci_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY |
|
||||
ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
|
||||
.flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
|
||||
AHCI_FLAG_NO_NCQ,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &ahci_vt8251_ops,
|
||||
},
|
||||
/* board_ahci_ign_iferr */
|
||||
{
|
||||
.sht = &ahci_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY |
|
||||
AHCI_FLAG_IGN_IRQ_IF_ERR,
|
||||
.flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_sb600 */
|
||||
{
|
||||
.sht = &ahci_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
|
||||
ATA_FLAG_SKIP_D2H_BSY |
|
||||
.flags = AHCI_FLAG_COMMON |
|
||||
AHCI_FLAG_IGN_SERR_INTERNAL,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
|
@ -413,11 +399,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
|
||||
|
||||
/* ATI */
|
||||
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
|
||||
{ PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
|
||||
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
|
||||
|
||||
/* VIA */
|
||||
{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
|
||||
{ PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */
|
||||
|
||||
/* NVIDIA */
|
||||
{ PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */
|
||||
|
@ -471,10 +457,100 @@ static inline int ahci_nr_ports(u32 cap)
|
|||
return (cap & 0x1f) + 1;
|
||||
}
|
||||
|
||||
static inline void __iomem *ahci_port_base(void __iomem *base,
|
||||
unsigned int port)
|
||||
static inline void __iomem *ahci_port_base(struct ata_port *ap)
|
||||
{
|
||||
return base + 0x100 + (port * 0x80);
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
|
||||
return mmio + 0x100 + (ap->port_no * 0x80);
|
||||
}
|
||||
|
||||
/**
|
||||
* ahci_save_initial_config - Save and fixup initial config values
|
||||
* @pdev: target PCI device
|
||||
* @pi: associated ATA port info
|
||||
* @hpriv: host private area to store config values
|
||||
*
|
||||
* Some registers containing configuration info might be setup by
|
||||
* BIOS and might be cleared on reset. This function saves the
|
||||
* initial values of those registers into @hpriv such that they
|
||||
* can be restored after controller reset.
|
||||
*
|
||||
* If inconsistent, config values are fixed up by this function.
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*/
|
||||
static void ahci_save_initial_config(struct pci_dev *pdev,
|
||||
const struct ata_port_info *pi,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
|
||||
u32 cap, port_map;
|
||||
int i;
|
||||
|
||||
/* Values prefixed with saved_ are written back to host after
|
||||
* reset. Values without are used for driver operation.
|
||||
*/
|
||||
hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
|
||||
hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
|
||||
|
||||
/* fixup zero port_map */
|
||||
if (!port_map) {
|
||||
port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1;
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"PORTS_IMPL is zero, forcing 0x%x\n", port_map);
|
||||
|
||||
/* write the fixed up value to the PI register */
|
||||
hpriv->saved_port_map = port_map;
|
||||
}
|
||||
|
||||
/* cross check port_map and cap.n_ports */
|
||||
if (pi->flags & AHCI_FLAG_HONOR_PI) {
|
||||
u32 tmp_port_map = port_map;
|
||||
int n_ports = ahci_nr_ports(cap);
|
||||
|
||||
for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
|
||||
if (tmp_port_map & (1 << i)) {
|
||||
n_ports--;
|
||||
tmp_port_map &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Whine if inconsistent. No need to update cap.
|
||||
* port_map is used to determine number of ports.
|
||||
*/
|
||||
if (n_ports || tmp_port_map)
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"nr_ports (%u) and implemented port map "
|
||||
"(0x%x) don't match\n",
|
||||
ahci_nr_ports(cap), port_map);
|
||||
} else {
|
||||
/* fabricate port_map from cap.nr_ports */
|
||||
port_map = (1 << ahci_nr_ports(cap)) - 1;
|
||||
}
|
||||
|
||||
/* record values to use during operation */
|
||||
hpriv->cap = cap;
|
||||
hpriv->port_map = port_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* ahci_restore_initial_config - Restore initial config
|
||||
* @host: target ATA host
|
||||
*
|
||||
* Restore initial config stored by ahci_save_initial_config().
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*/
|
||||
static void ahci_restore_initial_config(struct ata_host *host)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
|
||||
writel(hpriv->saved_cap, mmio + HOST_CAP);
|
||||
writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
|
||||
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
|
||||
}
|
||||
|
||||
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
|
||||
|
@ -511,8 +587,9 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
|
|||
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
}
|
||||
|
||||
static void ahci_start_engine(void __iomem *port_mmio)
|
||||
static void ahci_start_engine(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 tmp;
|
||||
|
||||
/* start DMA */
|
||||
|
@ -522,8 +599,9 @@ static void ahci_start_engine(void __iomem *port_mmio)
|
|||
readl(port_mmio + PORT_CMD); /* flush */
|
||||
}
|
||||
|
||||
static int ahci_stop_engine(void __iomem *port_mmio)
|
||||
static int ahci_stop_engine(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(port_mmio + PORT_CMD);
|
||||
|
@ -545,19 +623,23 @@ static int ahci_stop_engine(void __iomem *port_mmio)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
|
||||
dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
|
||||
static void ahci_start_fis_rx(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u32 tmp;
|
||||
|
||||
/* set FIS registers */
|
||||
if (cap & HOST_CAP_64)
|
||||
writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
|
||||
writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
|
||||
if (hpriv->cap & HOST_CAP_64)
|
||||
writel((pp->cmd_slot_dma >> 16) >> 16,
|
||||
port_mmio + PORT_LST_ADDR_HI);
|
||||
writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
|
||||
|
||||
if (cap & HOST_CAP_64)
|
||||
writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
|
||||
writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
|
||||
if (hpriv->cap & HOST_CAP_64)
|
||||
writel((pp->rx_fis_dma >> 16) >> 16,
|
||||
port_mmio + PORT_FIS_ADDR_HI);
|
||||
writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
|
||||
|
||||
/* enable FIS reception */
|
||||
tmp = readl(port_mmio + PORT_CMD);
|
||||
|
@ -568,8 +650,9 @@ static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
|
|||
readl(port_mmio + PORT_CMD);
|
||||
}
|
||||
|
||||
static int ahci_stop_fis_rx(void __iomem *port_mmio)
|
||||
static int ahci_stop_fis_rx(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 tmp;
|
||||
|
||||
/* disable FIS reception */
|
||||
|
@ -586,14 +669,16 @@ static int ahci_stop_fis_rx(void __iomem *port_mmio)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ahci_power_up(void __iomem *port_mmio, u32 cap)
|
||||
static void ahci_power_up(struct ata_port *ap)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 cmd;
|
||||
|
||||
cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
|
||||
|
||||
/* spin up device */
|
||||
if (cap & HOST_CAP_SSS) {
|
||||
if (hpriv->cap & HOST_CAP_SSS) {
|
||||
cmd |= PORT_CMD_SPIN_UP;
|
||||
writel(cmd, port_mmio + PORT_CMD);
|
||||
}
|
||||
|
@ -603,11 +688,13 @@ static void ahci_power_up(void __iomem *port_mmio, u32 cap)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static void ahci_power_down(void __iomem *port_mmio, u32 cap)
|
||||
static void ahci_power_down(struct ata_port *ap)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 cmd, scontrol;
|
||||
|
||||
if (!(cap & HOST_CAP_SSS))
|
||||
if (!(hpriv->cap & HOST_CAP_SSS))
|
||||
return;
|
||||
|
||||
/* put device into listen mode, first set PxSCTL.DET to 0 */
|
||||
|
@ -622,29 +709,28 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void ahci_init_port(void __iomem *port_mmio, u32 cap,
|
||||
dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
|
||||
static void ahci_init_port(struct ata_port *ap)
|
||||
{
|
||||
/* enable FIS reception */
|
||||
ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
|
||||
ahci_start_fis_rx(ap);
|
||||
|
||||
/* enable DMA */
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_start_engine(ap);
|
||||
}
|
||||
|
||||
static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
|
||||
static int ahci_deinit_port(struct ata_port *ap, const char **emsg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* disable DMA */
|
||||
rc = ahci_stop_engine(port_mmio);
|
||||
rc = ahci_stop_engine(ap);
|
||||
if (rc) {
|
||||
*emsg = "failed to stop engine";
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* disable FIS reception */
|
||||
rc = ahci_stop_fis_rx(port_mmio);
|
||||
rc = ahci_stop_fis_rx(ap);
|
||||
if (rc) {
|
||||
*emsg = "failed stop FIS RX";
|
||||
return rc;
|
||||
|
@ -653,12 +739,11 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
||||
static int ahci_reset_controller(struct ata_host *host)
|
||||
{
|
||||
u32 cap_save, impl_save, tmp;
|
||||
|
||||
cap_save = readl(mmio + HOST_CAP);
|
||||
impl_save = readl(mmio + HOST_PORTS_IMPL);
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
u32 tmp;
|
||||
|
||||
/* global controller reset */
|
||||
tmp = readl(mmio + HOST_CTL);
|
||||
|
@ -674,7 +759,7 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
|||
|
||||
tmp = readl(mmio + HOST_CTL);
|
||||
if (tmp & HOST_RESET) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
dev_printk(KERN_ERR, host->dev,
|
||||
"controller reset failed (0x%x)\n", tmp);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -683,18 +768,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
|||
writel(HOST_AHCI_EN, mmio + HOST_CTL);
|
||||
(void) readl(mmio + HOST_CTL); /* flush */
|
||||
|
||||
/* These write-once registers are normally cleared on reset.
|
||||
* Restore BIOS values... which we HOPE were present before
|
||||
* reset.
|
||||
*/
|
||||
if (!impl_save) {
|
||||
impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
|
||||
}
|
||||
writel(cap_save, mmio + HOST_CAP);
|
||||
writel(impl_save, mmio + HOST_PORTS_IMPL);
|
||||
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
|
||||
/* some registers might be cleared on reset. restore initial values */
|
||||
ahci_restore_initial_config(host);
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
|
||||
u16 tmp16;
|
||||
|
@ -708,23 +783,23 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
|
||||
int n_ports, unsigned int port_flags,
|
||||
struct ahci_host_priv *hpriv)
|
||||
static void ahci_init_controller(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
int i, rc;
|
||||
u32 tmp;
|
||||
|
||||
for (i = 0; i < n_ports; i++) {
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, i);
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
const char *emsg = NULL;
|
||||
|
||||
if ((port_flags & AHCI_FLAG_HONOR_PI) &&
|
||||
!(hpriv->port_map & (1 << i)))
|
||||
if (ata_port_is_dummy(ap))
|
||||
continue;
|
||||
|
||||
/* make sure port is not active */
|
||||
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
|
||||
rc = ahci_deinit_port(ap, &emsg);
|
||||
if (rc)
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"%s (%d)\n", emsg, rc);
|
||||
|
@ -752,7 +827,7 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
|
|||
|
||||
static unsigned int ahci_dev_classify(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
struct ata_taskfile tf;
|
||||
u32 tmp;
|
||||
|
||||
|
@ -802,8 +877,7 @@ static int ahci_clo(struct ata_port *ap)
|
|||
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
const u32 cmd_fis_len = 5; /* five dwords */
|
||||
const char *reason = NULL;
|
||||
struct ata_taskfile tf;
|
||||
|
@ -820,7 +894,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
|||
}
|
||||
|
||||
/* prepare for SRST (AHCI-1.1 10.4.1) */
|
||||
rc = ahci_stop_engine(port_mmio);
|
||||
rc = ahci_stop_engine(ap);
|
||||
if (rc) {
|
||||
reason = "failed to stop engine";
|
||||
goto fail_restart;
|
||||
|
@ -840,7 +914,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
|||
}
|
||||
|
||||
/* restart engine */
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_start_engine(ap);
|
||||
|
||||
ata_tf_init(ap->device, &tf);
|
||||
fis = pp->cmd_tbl;
|
||||
|
@ -899,7 +973,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
|||
return 0;
|
||||
|
||||
fail_restart:
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_start_engine(ap);
|
||||
fail:
|
||||
ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
|
||||
return rc;
|
||||
|
@ -910,13 +984,11 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
|
||||
struct ata_taskfile tf;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
ahci_stop_engine(port_mmio);
|
||||
ahci_stop_engine(ap);
|
||||
|
||||
/* clear D2H reception area to properly wait for D2H FIS */
|
||||
ata_tf_init(ap->device, &tf);
|
||||
|
@ -925,7 +997,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
|
||||
rc = sata_std_hardreset(ap, class);
|
||||
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_start_engine(ap);
|
||||
|
||||
if (rc == 0 && ata_port_online(ap))
|
||||
*class = ahci_dev_classify(ap);
|
||||
|
@ -938,20 +1010,18 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
|
||||
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
ahci_stop_engine(port_mmio);
|
||||
ahci_stop_engine(ap);
|
||||
|
||||
rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
|
||||
|
||||
/* vt8251 needs SError cleared for the port to operate */
|
||||
ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
|
||||
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_start_engine(ap);
|
||||
|
||||
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
|
||||
|
||||
|
@ -963,7 +1033,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
|
||||
static void ahci_postreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 new_tmp, tmp;
|
||||
|
||||
ata_std_postreset(ap, class);
|
||||
|
@ -1131,8 +1201,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
|
|||
|
||||
static void ahci_host_intr(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u32 status, qc_active;
|
||||
|
@ -1283,7 +1352,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
|
|||
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
|
||||
if (qc->tf.protocol == ATA_PROT_NCQ)
|
||||
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
|
||||
|
@ -1295,8 +1364,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
|
|||
|
||||
static void ahci_freeze(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
|
||||
/* turn IRQ off */
|
||||
writel(0, port_mmio + PORT_IRQ_MASK);
|
||||
|
@ -1305,7 +1373,7 @@ static void ahci_freeze(struct ata_port *ap)
|
|||
static void ahci_thaw(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
u32 tmp;
|
||||
|
||||
/* clear IRQ */
|
||||
|
@ -1319,13 +1387,10 @@ static void ahci_thaw(struct ata_port *ap)
|
|||
|
||||
static void ahci_error_handler(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
|
||||
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
/* restart engine */
|
||||
ahci_stop_engine(port_mmio);
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_stop_engine(ap);
|
||||
ahci_start_engine(ap);
|
||||
}
|
||||
|
||||
/* perform recovery */
|
||||
|
@ -1335,13 +1400,10 @@ static void ahci_error_handler(struct ata_port *ap)
|
|||
|
||||
static void ahci_vt8251_error_handler(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
|
||||
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
/* restart engine */
|
||||
ahci_stop_engine(port_mmio);
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_stop_engine(ap);
|
||||
ahci_start_engine(ap);
|
||||
}
|
||||
|
||||
/* perform recovery */
|
||||
|
@ -1352,36 +1414,26 @@ static void ahci_vt8251_error_handler(struct ata_port *ap)
|
|||
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
qc->err_mask |= AC_ERR_OTHER;
|
||||
|
||||
if (qc->err_mask) {
|
||||
if (qc->flags & ATA_QCFLAG_FAILED) {
|
||||
/* make DMA engine forget about the failed command */
|
||||
ahci_stop_engine(port_mmio);
|
||||
ahci_start_engine(port_mmio);
|
||||
ahci_stop_engine(ap);
|
||||
ahci_start_engine(ap);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
const char *emsg = NULL;
|
||||
int rc;
|
||||
|
||||
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
|
||||
rc = ahci_deinit_port(ap, &emsg);
|
||||
if (rc == 0)
|
||||
ahci_power_down(port_mmio, hpriv->cap);
|
||||
ahci_power_down(ap);
|
||||
else {
|
||||
ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
|
||||
ahci_init_port(port_mmio, hpriv->cap,
|
||||
pp->cmd_slot_dma, pp->rx_fis_dma);
|
||||
ahci_init_port(ap);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -1389,13 +1441,8 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
|
|||
|
||||
static int ahci_port_resume(struct ata_port *ap)
|
||||
{
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
|
||||
ahci_power_up(port_mmio, hpriv->cap);
|
||||
ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
|
||||
ahci_power_up(ap);
|
||||
ahci_init_port(ap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1423,8 +1470,6 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
|
|||
static int ahci_pci_device_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(&pdev->dev);
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
int rc;
|
||||
|
||||
rc = ata_pci_device_do_resume(pdev);
|
||||
|
@ -1432,12 +1477,11 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
|
|||
return rc;
|
||||
|
||||
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
|
||||
rc = ahci_reset_controller(mmio, pdev);
|
||||
rc = ahci_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
ahci_init_controller(mmio, pdev, host->n_ports,
|
||||
host->ports[0]->flags, hpriv);
|
||||
ahci_init_controller(host);
|
||||
}
|
||||
|
||||
ata_host_resume(host);
|
||||
|
@ -1449,10 +1493,7 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
|
|||
static int ahci_port_start(struct ata_port *ap)
|
||||
{
|
||||
struct device *dev = ap->host->dev;
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
struct ahci_port_priv *pp;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
void *mem;
|
||||
dma_addr_t mem_dma;
|
||||
int rc;
|
||||
|
@ -1500,85 +1541,29 @@ static int ahci_port_start(struct ata_port *ap)
|
|||
ap->private_data = pp;
|
||||
|
||||
/* power up port */
|
||||
ahci_power_up(port_mmio, hpriv->cap);
|
||||
ahci_power_up(ap);
|
||||
|
||||
/* initialize port */
|
||||
ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
|
||||
ahci_init_port(ap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ahci_port_stop(struct ata_port *ap)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = ap->host->private_data;
|
||||
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
const char *emsg = NULL;
|
||||
int rc;
|
||||
|
||||
/* de-initialize port */
|
||||
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
|
||||
rc = ahci_deinit_port(ap, &emsg);
|
||||
if (rc)
|
||||
ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
|
||||
}
|
||||
|
||||
static void ahci_setup_port(struct ata_ioports *port, void __iomem *base,
|
||||
unsigned int port_idx)
|
||||
static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
|
||||
{
|
||||
VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
|
||||
base = ahci_port_base(base, port_idx);
|
||||
VPRINTK("base now==0x%lx\n", base);
|
||||
|
||||
port->cmd_addr = base;
|
||||
port->scr_addr = base + PORT_SCR;
|
||||
|
||||
VPRINTK("EXIT\n");
|
||||
}
|
||||
|
||||
static int ahci_host_init(struct ata_probe_ent *probe_ent)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = probe_ent->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
|
||||
void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
|
||||
unsigned int i, cap_n_ports, using_dac;
|
||||
int rc;
|
||||
|
||||
rc = ahci_reset_controller(mmio, pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
hpriv->cap = readl(mmio + HOST_CAP);
|
||||
hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
|
||||
cap_n_ports = ahci_nr_ports(hpriv->cap);
|
||||
|
||||
VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
|
||||
hpriv->cap, hpriv->port_map, cap_n_ports);
|
||||
|
||||
if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
|
||||
unsigned int n_ports = cap_n_ports;
|
||||
u32 port_map = hpriv->port_map;
|
||||
int max_port = 0;
|
||||
|
||||
for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
|
||||
if (port_map & (1 << i)) {
|
||||
n_ports--;
|
||||
port_map &= ~(1 << i);
|
||||
max_port = i;
|
||||
} else
|
||||
probe_ent->dummy_port_mask |= 1 << i;
|
||||
}
|
||||
|
||||
if (n_ports || port_map)
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"nr_ports (%u) and implemented port map "
|
||||
"(0x%x) don't match\n",
|
||||
cap_n_ports, hpriv->port_map);
|
||||
|
||||
probe_ent->n_ports = max_port + 1;
|
||||
} else
|
||||
probe_ent->n_ports = cap_n_ports;
|
||||
|
||||
using_dac = hpriv->cap & HOST_CAP_64;
|
||||
if (using_dac &&
|
||||
!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
|
||||
rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
|
||||
|
@ -1604,23 +1589,14 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
|
|||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < probe_ent->n_ports; i++)
|
||||
ahci_setup_port(&probe_ent->port[i], mmio, i);
|
||||
|
||||
ahci_init_controller(mmio, pdev, probe_ent->n_ports,
|
||||
probe_ent->port_flags, hpriv);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ahci_print_info(struct ata_probe_ent *probe_ent)
|
||||
static void ahci_print_info(struct ata_host *host)
|
||||
{
|
||||
struct ahci_host_priv *hpriv = probe_ent->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
|
||||
void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
|
||||
u32 vers, cap, impl, speed;
|
||||
const char *speed_s;
|
||||
u16 cc;
|
||||
|
@ -1690,11 +1666,12 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
|
|||
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
struct ata_port_info pi = ahci_port_info[ent->driver_data];
|
||||
const struct ata_port_info *ppi[] = { &pi, NULL };
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct ahci_host_priv *hpriv;
|
||||
int rc;
|
||||
struct ata_host *host;
|
||||
int i, rc;
|
||||
|
||||
VPRINTK("ENTER\n");
|
||||
|
||||
|
@ -1703,6 +1680,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* acquire resources */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -1716,44 +1694,49 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (pci_enable_msi(pdev))
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->sht = ahci_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = ahci_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = ahci_port_info[board_idx].pio_mask;
|
||||
probe_ent->udma_mask = ahci_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = ahci_port_info[board_idx].port_ops;
|
||||
/* save initial config */
|
||||
ahci_save_initial_config(pdev, &pi, hpriv);
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
probe_ent->private_data = hpriv;
|
||||
/* prepare host */
|
||||
if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ))
|
||||
pi.flags |= ATA_FLAG_NCQ;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
host->private_data = hpriv;
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
if (hpriv->port_map & (1 << i)) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
|
||||
ap->ioaddr.cmd_addr = port_mmio;
|
||||
ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
|
||||
} else
|
||||
host->ports[i]->ops = &ata_dummy_port_ops;
|
||||
}
|
||||
|
||||
/* initialize adapter */
|
||||
rc = ahci_host_init(probe_ent);
|
||||
rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) &&
|
||||
(hpriv->cap & HOST_CAP_NCQ))
|
||||
probe_ent->port_flags |= ATA_FLAG_NCQ;
|
||||
rc = ahci_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
ahci_print_info(probe_ent);
|
||||
ahci_init_controller(host);
|
||||
ahci_print_info(host);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
|
||||
&ahci_sht);
|
||||
}
|
||||
|
||||
static int __init ahci_init(void)
|
||||
|
|
|
@ -32,35 +32,6 @@
|
|||
* A generic parallel ATA driver using libata
|
||||
*/
|
||||
|
||||
/**
|
||||
* generic_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int generic_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generic_error_handler - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
* @classes:
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
|
||||
static void generic_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, generic_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* generic_set_mode - mode setting
|
||||
* @ap: interface to set up
|
||||
|
@ -144,8 +115,9 @@ static struct ata_port_operations generic_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = generic_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "ata_piix"
|
||||
#define DRV_VERSION "2.10ac1"
|
||||
#define DRV_VERSION "2.11"
|
||||
|
||||
enum {
|
||||
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
|
||||
|
@ -155,11 +155,11 @@ struct piix_host_priv {
|
|||
static int piix_init_one (struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent);
|
||||
static void piix_pata_error_handler(struct ata_port *ap);
|
||||
static void ich_pata_error_handler(struct ata_port *ap);
|
||||
static void piix_sata_error_handler(struct ata_port *ap);
|
||||
static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
|
||||
static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
|
||||
static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
|
||||
static int ich_pata_cable_detect(struct ata_port *ap);
|
||||
|
||||
static unsigned int in_module_init = 1;
|
||||
|
||||
|
@ -305,6 +305,7 @@ static const struct ata_port_operations piix_pata_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = piix_pata_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
|
@ -336,8 +337,9 @@ static const struct ata_port_operations ich_pata_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ich_pata_error_handler,
|
||||
.error_handler = piix_pata_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ich_pata_cable_detect,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
|
@ -580,12 +582,13 @@ static const struct ich_laptop ich_laptop[] = {
|
|||
/* devid, subvendor, subdev */
|
||||
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
|
||||
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
|
||||
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
|
||||
/* end marker */
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
/**
|
||||
* piix_pata_cbl_detect - Probe host controller cable detect info
|
||||
* ich_pata_cable_detect - Probe host controller cable detect info
|
||||
* @ap: Port for which cable detect info is desired
|
||||
*
|
||||
* Read 80c cable indicator from ATA PCI device's PCI config
|
||||
|
@ -595,23 +598,18 @@ static const struct ich_laptop ich_laptop[] = {
|
|||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void ich_pata_cbl_detect(struct ata_port *ap)
|
||||
static int ich_pata_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
const struct ich_laptop *lap = &ich_laptop[0];
|
||||
u8 tmp, mask;
|
||||
|
||||
/* no 80c support in host controller? */
|
||||
if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
|
||||
goto cbl40;
|
||||
|
||||
/* Check for specials - Acer Aspire 5602WLMi */
|
||||
while (lap->device) {
|
||||
if (lap->device == pdev->device &&
|
||||
lap->subvendor == pdev->subsystem_vendor &&
|
||||
lap->subdevice == pdev->subsystem_device) {
|
||||
ap->cbl = ATA_CBL_PATA40_SHORT;
|
||||
return;
|
||||
return ATA_CBL_PATA40_SHORT;
|
||||
}
|
||||
lap++;
|
||||
}
|
||||
|
@ -620,20 +618,14 @@ static void ich_pata_cbl_detect(struct ata_port *ap)
|
|||
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
|
||||
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
|
||||
if ((tmp & mask) == 0)
|
||||
goto cbl40;
|
||||
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return;
|
||||
|
||||
cbl40:
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
* piix_pata_prereset - prereset for PATA host controller
|
||||
* @ap: Target port
|
||||
*
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
@ -643,8 +635,6 @@ static int piix_pata_prereset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -655,30 +645,6 @@ static void piix_pata_error_handler(struct ata_port *ap)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* ich_pata_prereset - prereset for PATA host controller
|
||||
* @ap: Target port
|
||||
*
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
static int ich_pata_prereset(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
ich_pata_cbl_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void ich_pata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, ich_pata_prereset, ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
static void piix_sata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1056,7 +1056,7 @@ static void ata_eh_analyze_serror(struct ata_port *ap)
|
|||
}
|
||||
if (serror & SERR_INTERNAL) {
|
||||
err_mask |= AC_ERR_SYSTEM;
|
||||
action |= ATA_EH_SOFTRESET;
|
||||
action |= ATA_EH_HARDRESET;
|
||||
}
|
||||
if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG))
|
||||
ata_ehi_hotplugged(&ehc->i);
|
||||
|
@ -1151,7 +1151,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
|
|||
return ATA_EH_SOFTRESET;
|
||||
}
|
||||
|
||||
if (!(qc->err_mask & AC_ERR_DEV))
|
||||
if (stat & (ATA_ERR | ATA_DF))
|
||||
qc->err_mask |= AC_ERR_DEV;
|
||||
else
|
||||
return 0;
|
||||
|
||||
switch (qc->dev->class) {
|
||||
|
@ -1669,7 +1671,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
reset == softreset ? "soft" : "hard");
|
||||
|
||||
/* mark that this EH session started with reset */
|
||||
ehc->i.flags |= ATA_EHI_DID_RESET;
|
||||
if (reset == hardreset)
|
||||
ehc->i.flags |= ATA_EHI_DID_HARDRESET;
|
||||
else
|
||||
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
||||
|
||||
rc = ata_do_reset(ap, reset, classes);
|
||||
|
||||
|
@ -1808,6 +1813,10 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
|
|||
}
|
||||
}
|
||||
|
||||
/* PDIAG- should have been released, ask cable type if post-reset */
|
||||
if ((ehc->i.flags & ATA_EHI_DID_RESET) && ap->ops->cable_detect)
|
||||
ap->cbl = ap->ops->cable_detect(ap);
|
||||
|
||||
/* Configure new devices forward such that user doesn't see
|
||||
* device detection messages backwards.
|
||||
*/
|
||||
|
|
|
@ -104,7 +104,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
|
|||
* libata transport template. libata doesn't do real transport stuff.
|
||||
* It just needs the eh_timed_out hook.
|
||||
*/
|
||||
struct scsi_transport_template ata_scsi_transport_template = {
|
||||
static struct scsi_transport_template ata_scsi_transport_template = {
|
||||
.eh_strategy_handler = ata_scsi_error,
|
||||
.eh_timed_out = ata_scsi_timed_out,
|
||||
.user_scan = ata_scsi_user_scan,
|
||||
|
@ -2678,6 +2678,18 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
|||
tf->device = qc->dev->devno ?
|
||||
tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
|
||||
|
||||
/* READ/WRITE LONG use a non-standard sect_size */
|
||||
qc->sect_size = ATA_SECT_SIZE;
|
||||
switch (tf->command) {
|
||||
case ATA_CMD_READ_LONG:
|
||||
case ATA_CMD_READ_LONG_ONCE:
|
||||
case ATA_CMD_WRITE_LONG:
|
||||
case ATA_CMD_WRITE_LONG_ONCE:
|
||||
if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
|
||||
goto invalid_fld;
|
||||
qc->sect_size = scmd->request_bufflen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter SET_FEATURES - XFER MODE command -- otherwise,
|
||||
* SET_FEATURES - XFER MODE must be preceded/succeeded
|
||||
|
@ -2792,8 +2804,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
|
|||
{
|
||||
int rc = 0;
|
||||
|
||||
if (unlikely(!scmd->cmd_len)) {
|
||||
ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
|
||||
if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) {
|
||||
DPRINTK("bad CDB len=%u, max=%u\n",
|
||||
scmd->cmd_len, dev->cdb_len);
|
||||
scmd->result = DID_ERROR << 16;
|
||||
done(scmd);
|
||||
return 0;
|
||||
|
@ -2948,6 +2961,48 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
|||
}
|
||||
}
|
||||
|
||||
int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
struct Scsi_Host *shost;
|
||||
|
||||
rc = -ENOMEM;
|
||||
shost = scsi_host_alloc(sht, sizeof(struct ata_port *));
|
||||
if (!shost)
|
||||
goto err_alloc;
|
||||
|
||||
*(struct ata_port **)&shost->hostdata[0] = ap;
|
||||
ap->scsi_host = shost;
|
||||
|
||||
shost->transportt = &ata_scsi_transport_template;
|
||||
shost->unique_id = ap->print_id;
|
||||
shost->max_id = 16;
|
||||
shost->max_lun = 1;
|
||||
shost->max_channel = 1;
|
||||
shost->max_cmd_len = 16;
|
||||
|
||||
rc = scsi_add_host(ap->scsi_host, ap->host->dev);
|
||||
if (rc)
|
||||
goto err_add;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_add:
|
||||
scsi_host_put(host->ports[i]->scsi_host);
|
||||
err_alloc:
|
||||
while (--i >= 0) {
|
||||
struct Scsi_Host *shost = host->ports[i]->scsi_host;
|
||||
|
||||
scsi_remove_host(shost);
|
||||
scsi_host_put(shost);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ata_scsi_scan_host(struct ata_port *ap)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -3224,21 +3279,21 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host,
|
|||
struct ata_port_info *port_info,
|
||||
struct Scsi_Host *shost)
|
||||
{
|
||||
struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL);
|
||||
struct ata_probe_ent *ent;
|
||||
struct ata_port *ap;
|
||||
|
||||
ap = ata_port_alloc(host);
|
||||
if (!ap)
|
||||
return NULL;
|
||||
|
||||
ent = ata_probe_ent_alloc(host->dev, port_info);
|
||||
if (!ent) {
|
||||
kfree(ap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ata_port_init(ap, host, ent, 0);
|
||||
ap->port_no = 0;
|
||||
ap->lock = shost->host_lock;
|
||||
devm_kfree(host->dev, ent);
|
||||
ap->pio_mask = port_info->pio_mask;
|
||||
ap->mwdma_mask = port_info->mwdma_mask;
|
||||
ap->udma_mask = port_info->udma_mask;
|
||||
ap->flags |= port_info->flags;
|
||||
ap->ops = port_info->port_ops;
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
|
||||
return ap;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
|
||||
|
@ -3294,8 +3349,10 @@ int ata_sas_port_init(struct ata_port *ap)
|
|||
{
|
||||
int rc = ap->ops->port_start(ap);
|
||||
|
||||
if (!rc)
|
||||
if (!rc) {
|
||||
ap->print_id = ata_print_id++;
|
||||
rc = ata_bus_probe(ap);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -526,169 +526,400 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
|
|||
port = port * 2;
|
||||
for (i = 0; i < 2; i ++) {
|
||||
if (pci_resource_start(pdev, port + i) == 0 ||
|
||||
pci_resource_len(pdev, port + i) == 0)
|
||||
return 0;
|
||||
pci_resource_len(pdev, port + i) == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_pci_init_native_mode - Initialize native-mode driver
|
||||
* @pdev: pci device to be initialized
|
||||
* @port: array[2] of pointers to port info structures.
|
||||
* @ports: bitmap of ports present
|
||||
* ata_pci_init_bmdma - acquire PCI BMDMA resources and init ATA host
|
||||
* @host: target ATA host
|
||||
*
|
||||
* Utility function which allocates and initializes an
|
||||
* ata_probe_ent structure for a standard dual-port
|
||||
* PIO-based IDE controller. The returned ata_probe_ent
|
||||
* structure can be passed to ata_device_add(). The returned
|
||||
* ata_probe_ent structure should then be freed with kfree().
|
||||
* Acquire PCI BMDMA resources and initialize @host accordingly.
|
||||
*
|
||||
* The caller need only pass the address of the primary port, the
|
||||
* secondary will be deduced automatically. If the device has non
|
||||
* standard secondary port mappings this function can be called twice,
|
||||
* once for each interface.
|
||||
* LOCKING:
|
||||
* Inherited from calling layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
|
||||
struct ata_probe_ent *
|
||||
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
|
||||
static int ata_pci_init_bmdma(struct ata_host *host)
|
||||
{
|
||||
struct ata_probe_ent *probe_ent;
|
||||
int i, p = 0;
|
||||
void __iomem * const *iomap;
|
||||
struct device *gdev = host->dev;
|
||||
struct pci_dev *pdev = to_pci_dev(gdev);
|
||||
int i, rc;
|
||||
|
||||
/* iomap BARs */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (pcim_iomap(pdev, i, 0) == NULL) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"failed to iomap PCI BAR %d\n", i);
|
||||
return NULL;
|
||||
}
|
||||
/* TODO: If we get no DMA mask we should fall back to PIO */
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* request and iomap DMA region */
|
||||
rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
void __iomem *bmdma = host->iomap[4] + 8 * i;
|
||||
|
||||
if (ata_port_is_dummy(ap))
|
||||
continue;
|
||||
|
||||
ap->ioaddr.bmdma_addr = bmdma;
|
||||
if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||
(ioread8(bmdma + 2) & 0x80))
|
||||
host->flags |= ATA_HOST_SIMPLEX;
|
||||
}
|
||||
|
||||
pcim_iomap(pdev, 4, 0); /* may fail */
|
||||
iomap = pcim_iomap_table(pdev);
|
||||
|
||||
/* alloc and init probe_ent */
|
||||
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
|
||||
if (!probe_ent)
|
||||
return NULL;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
|
||||
/* Discard disabled ports. Some controllers show their
|
||||
unused channels this way */
|
||||
if (ata_resources_present(pdev, 0) == 0)
|
||||
ports &= ~ATA_PORT_PRIMARY;
|
||||
if (ata_resources_present(pdev, 1) == 0)
|
||||
ports &= ~ATA_PORT_SECONDARY;
|
||||
|
||||
if (ports & ATA_PORT_PRIMARY) {
|
||||
probe_ent->port[p].cmd_addr = iomap[0];
|
||||
probe_ent->port[p].altstatus_addr =
|
||||
probe_ent->port[p].ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[1] | ATA_PCI_CTL_OFS);
|
||||
if (iomap[4]) {
|
||||
if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||
(ioread8(iomap[4] + 2) & 0x80))
|
||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||
probe_ent->port[p].bmdma_addr = iomap[4];
|
||||
}
|
||||
ata_std_ports(&probe_ent->port[p]);
|
||||
p++;
|
||||
}
|
||||
|
||||
if (ports & ATA_PORT_SECONDARY) {
|
||||
probe_ent->port[p].cmd_addr = iomap[2];
|
||||
probe_ent->port[p].altstatus_addr =
|
||||
probe_ent->port[p].ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[3] | ATA_PCI_CTL_OFS);
|
||||
if (iomap[4]) {
|
||||
if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||
(ioread8(iomap[4] + 10) & 0x80))
|
||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||
probe_ent->port[p].bmdma_addr = iomap[4] + 8;
|
||||
}
|
||||
ata_std_ports(&probe_ent->port[p]);
|
||||
probe_ent->pinfo2 = port[1];
|
||||
p++;
|
||||
}
|
||||
|
||||
probe_ent->n_ports = p;
|
||||
return probe_ent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
|
||||
struct ata_port_info **port, int port_mask)
|
||||
/**
|
||||
* ata_pci_init_native_host - acquire native ATA resources and init host
|
||||
* @host: target ATA host
|
||||
* @port_mask: ports to consider
|
||||
*
|
||||
* Acquire native PCI ATA resources for @host and initialize
|
||||
* @host accordoingly.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from calling layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
|
||||
{
|
||||
struct ata_probe_ent *probe_ent;
|
||||
void __iomem *iomap[5] = { }, *bmdma;
|
||||
struct device *gdev = host->dev;
|
||||
struct pci_dev *pdev = to_pci_dev(gdev);
|
||||
int i, rc;
|
||||
|
||||
if (port_mask & ATA_PORT_PRIMARY) {
|
||||
iomap[0] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CMD, 8);
|
||||
iomap[1] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CTL, 1);
|
||||
if (!iomap[0] || !iomap[1])
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (port_mask & ATA_PORT_SECONDARY) {
|
||||
iomap[2] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CMD, 8);
|
||||
iomap[3] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CTL, 1);
|
||||
if (!iomap[2] || !iomap[3])
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bmdma = pcim_iomap(pdev, 4, 16); /* may fail */
|
||||
|
||||
/* alloc and init probe_ent */
|
||||
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
|
||||
if (!probe_ent)
|
||||
return NULL;
|
||||
|
||||
probe_ent->n_ports = 2;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
|
||||
if (port_mask & ATA_PORT_PRIMARY) {
|
||||
probe_ent->irq = ATA_PRIMARY_IRQ(pdev);
|
||||
probe_ent->port[0].cmd_addr = iomap[0];
|
||||
probe_ent->port[0].altstatus_addr =
|
||||
probe_ent->port[0].ctl_addr = iomap[1];
|
||||
if (bmdma) {
|
||||
probe_ent->port[0].bmdma_addr = bmdma;
|
||||
if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||
(ioread8(bmdma + 2) & 0x80))
|
||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||
/* Discard disabled ports. Some controllers show their unused
|
||||
* channels this way. Disabled ports are made dummy.
|
||||
*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
|
||||
host->ports[i]->ops = &ata_dummy_port_ops;
|
||||
port_mask &= ~(1 << i);
|
||||
}
|
||||
ata_std_ports(&probe_ent->port[0]);
|
||||
} else
|
||||
probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY;
|
||||
}
|
||||
|
||||
if (port_mask & ATA_PORT_SECONDARY) {
|
||||
if (probe_ent->irq)
|
||||
probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev);
|
||||
if (!port_mask) {
|
||||
dev_printk(KERN_ERR, gdev, "no available port\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* request, iomap BARs and init port addresses accordingly */
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
int base = i * 2;
|
||||
void __iomem * const *iomap;
|
||||
|
||||
if (!(port_mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, gdev, "failed to request/iomap "
|
||||
"BARs for port %d (errno=%d)\n", i, rc);
|
||||
if (rc == -EBUSY)
|
||||
pcim_pin_device(pdev);
|
||||
return rc;
|
||||
}
|
||||
host->iomap = iomap = pcim_iomap_table(pdev);
|
||||
|
||||
ap->ioaddr.cmd_addr = iomap[base];
|
||||
ap->ioaddr.altstatus_addr =
|
||||
ap->ioaddr.ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_pci_prepare_native_host - helper to prepare native PCI ATA host
|
||||
* @pdev: target PCI device
|
||||
* @ppi: array of port_info
|
||||
* @n_ports: number of ports to allocate
|
||||
* @r_host: out argument for the initialized ATA host
|
||||
*
|
||||
* Helper to allocate ATA host for @pdev, acquire all native PCI
|
||||
* resources and initialize it accordingly in one go.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from calling layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_pci_prepare_native_host(struct pci_dev *pdev,
|
||||
const struct ata_port_info * const * ppi,
|
||||
int n_ports, struct ata_host **r_host)
|
||||
{
|
||||
struct ata_host *host;
|
||||
unsigned int port_mask;
|
||||
int rc;
|
||||
|
||||
if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
|
||||
if (!host) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"failed to allocate ATA host\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
port_mask = ATA_PORT_PRIMARY;
|
||||
if (n_ports > 1)
|
||||
port_mask |= ATA_PORT_SECONDARY;
|
||||
|
||||
rc = ata_pci_init_native_host(host, port_mask);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
/* init DMA related stuff */
|
||||
rc = ata_pci_init_bmdma(host);
|
||||
if (rc)
|
||||
goto err_bmdma;
|
||||
|
||||
devres_remove_group(&pdev->dev, NULL);
|
||||
*r_host = host;
|
||||
return 0;
|
||||
|
||||
err_bmdma:
|
||||
/* This is necessary because PCI and iomap resources are
|
||||
* merged and releasing the top group won't release the
|
||||
* acquired resources if some of those have been acquired
|
||||
* before entering this function.
|
||||
*/
|
||||
pcim_iounmap_regions(pdev, 0xf);
|
||||
err_out:
|
||||
devres_release_group(&pdev->dev, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct ata_legacy_devres {
|
||||
unsigned int mask;
|
||||
unsigned long cmd_port[2];
|
||||
void __iomem * cmd_addr[2];
|
||||
void __iomem * ctl_addr[2];
|
||||
unsigned int irq[2];
|
||||
void * irq_dev_id[2];
|
||||
};
|
||||
|
||||
static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!legacy_dr->irq[i])
|
||||
continue;
|
||||
|
||||
free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
|
||||
legacy_dr->irq[i] = 0;
|
||||
legacy_dr->irq_dev_id[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ata_legacy_release(struct device *gdev, void *res)
|
||||
{
|
||||
struct ata_legacy_devres *this = res;
|
||||
int i;
|
||||
|
||||
ata_legacy_free_irqs(this);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (this->cmd_addr[i])
|
||||
ioport_unmap(this->cmd_addr[i]);
|
||||
if (this->ctl_addr[i])
|
||||
ioport_unmap(this->ctl_addr[i]);
|
||||
if (this->cmd_port[i])
|
||||
release_region(this->cmd_port[i], 8);
|
||||
}
|
||||
}
|
||||
|
||||
static int ata_init_legacy_port(struct ata_port *ap,
|
||||
struct ata_legacy_devres *legacy_dr)
|
||||
{
|
||||
struct ata_host *host = ap->host;
|
||||
int port_no = ap->port_no;
|
||||
unsigned long cmd_port, ctl_port;
|
||||
|
||||
if (port_no == 0) {
|
||||
cmd_port = ATA_PRIMARY_CMD;
|
||||
ctl_port = ATA_PRIMARY_CTL;
|
||||
} else {
|
||||
cmd_port = ATA_SECONDARY_CMD;
|
||||
ctl_port = ATA_SECONDARY_CTL;
|
||||
}
|
||||
|
||||
/* request cmd_port */
|
||||
if (request_region(cmd_port, 8, "libata"))
|
||||
legacy_dr->cmd_port[port_no] = cmd_port;
|
||||
else {
|
||||
dev_printk(KERN_WARNING, host->dev,
|
||||
"0x%0lX IDE port busy\n", cmd_port);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* iomap cmd and ctl ports */
|
||||
legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
|
||||
legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
|
||||
if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no])
|
||||
return -ENOMEM;
|
||||
|
||||
/* init IO addresses */
|
||||
ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
|
||||
ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
|
||||
ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_init_legacy_host - acquire legacy ATA resources and init ATA host
|
||||
* @host: target ATA host
|
||||
* @legacy_mask: out parameter, mask indicating ports is in legacy mode
|
||||
* @was_busy: out parameter, indicates whether any port was busy
|
||||
*
|
||||
* Acquire legacy ATA resources for ports.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from calling layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int ata_init_legacy_host(struct ata_host *host,
|
||||
unsigned int *legacy_mask, int *was_busy)
|
||||
{
|
||||
struct device *gdev = host->dev;
|
||||
struct ata_legacy_devres *legacy_dr;
|
||||
int i, rc;
|
||||
|
||||
if (!devres_open_group(gdev, NULL, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
|
||||
rc = -ENOMEM;
|
||||
legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
|
||||
GFP_KERNEL);
|
||||
if (!legacy_dr)
|
||||
goto err_out;
|
||||
devres_add(gdev, legacy_dr);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
*legacy_mask &= ~(1 << i);
|
||||
rc = ata_init_legacy_port(host->ports[i], legacy_dr);
|
||||
if (rc == 0)
|
||||
legacy_dr->mask |= 1 << i;
|
||||
else if (rc == -EBUSY)
|
||||
(*was_busy)++;
|
||||
}
|
||||
|
||||
if (!legacy_dr->mask)
|
||||
return -EBUSY;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
if (!(legacy_dr->mask & (1 << i)))
|
||||
host->ports[i]->ops = &ata_dummy_port_ops;
|
||||
|
||||
*legacy_mask |= legacy_dr->mask;
|
||||
|
||||
devres_remove_group(gdev, NULL);
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
devres_release_group(gdev, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_request_legacy_irqs - request legacy ATA IRQs
|
||||
* @host: target ATA host
|
||||
* @handler: array of IRQ handlers
|
||||
* @irq_flags: array of IRQ flags
|
||||
* @dev_id: array of IRQ dev_ids
|
||||
*
|
||||
* Request legacy IRQs for non-dummy legacy ports in @host. All
|
||||
* IRQ parameters are passed as array to allow ports to have
|
||||
* separate IRQ handlers.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from calling layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int ata_request_legacy_irqs(struct ata_host *host,
|
||||
irq_handler_t const *handler,
|
||||
const unsigned int *irq_flags,
|
||||
void * const *dev_id)
|
||||
{
|
||||
struct device *gdev = host->dev;
|
||||
struct ata_legacy_devres *legacy_dr;
|
||||
int i, rc;
|
||||
|
||||
legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
|
||||
BUG_ON(!legacy_dr);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
unsigned int irq;
|
||||
|
||||
/* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
|
||||
if (i == 0)
|
||||
irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
|
||||
else
|
||||
probe_ent->irq = ATA_SECONDARY_IRQ(pdev);
|
||||
probe_ent->port[1].cmd_addr = iomap[2];
|
||||
probe_ent->port[1].altstatus_addr =
|
||||
probe_ent->port[1].ctl_addr = iomap[3];
|
||||
if (bmdma) {
|
||||
probe_ent->port[1].bmdma_addr = bmdma + 8;
|
||||
if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
|
||||
(ioread8(bmdma + 10) & 0x80))
|
||||
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
|
||||
irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
|
||||
|
||||
if (!(legacy_dr->mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
if (!handler[i]) {
|
||||
dev_printk(KERN_ERR, gdev,
|
||||
"NULL handler specified for port %d\n", i);
|
||||
rc = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
ata_std_ports(&probe_ent->port[1]);
|
||||
|
||||
/* FIXME: could be pointing to stack area; must copy */
|
||||
probe_ent->pinfo2 = port[1];
|
||||
} else
|
||||
probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
|
||||
rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
|
||||
dev_id[i]);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, gdev,
|
||||
"irq %u request failed (errno=%d)\n", irq, rc);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return probe_ent;
|
||||
/* record irq allocation in legacy_dr */
|
||||
legacy_dr->irq[i] = irq;
|
||||
legacy_dr->irq_dev_id[i] = dev_id[i];
|
||||
|
||||
/* only used to print info */
|
||||
if (i == 0)
|
||||
host->irq = irq;
|
||||
else
|
||||
host->irq2 = irq;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
ata_legacy_free_irqs(legacy_dr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_pci_init_one - Initialize/register PCI IDE host controller
|
||||
* @pdev: Controller to be initialized
|
||||
|
@ -718,8 +949,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
|
|||
unsigned int n_ports)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_probe_ent *probe_ent = NULL;
|
||||
struct ata_port_info *port[2];
|
||||
struct ata_host *host = NULL;
|
||||
const struct ata_port_info *port[2];
|
||||
u8 mask;
|
||||
unsigned int legacy_mode = 0;
|
||||
int rc;
|
||||
|
@ -743,7 +974,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
|
|||
|
||||
Checking dev->is_enabled is insufficient as this is not set at
|
||||
boot for the primary video which is BIOS enabled
|
||||
*/
|
||||
*/
|
||||
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
|
@ -769,96 +1000,68 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
|
|||
#endif
|
||||
}
|
||||
|
||||
if (!legacy_mode) {
|
||||
rc = pci_request_regions(pdev, DRV_NAME);
|
||||
if (rc) {
|
||||
pcim_pin_device(pdev);
|
||||
goto err_out;
|
||||
}
|
||||
} else {
|
||||
/* Deal with combined mode hack. This side of the logic all
|
||||
goes away once the combined mode hack is killed in 2.6.21 */
|
||||
if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) {
|
||||
struct resource *conflict, res;
|
||||
res.start = ATA_PRIMARY_CMD;
|
||||
res.end = ATA_PRIMARY_CMD + 8 - 1;
|
||||
conflict = ____request_resource(&ioport_resource, &res);
|
||||
while (conflict->child)
|
||||
conflict = ____request_resource(conflict, &res);
|
||||
if (!strcmp(conflict->name, "libata"))
|
||||
legacy_mode |= ATA_PORT_PRIMARY;
|
||||
else {
|
||||
pcim_pin_device(pdev);
|
||||
printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \
|
||||
"ata: conflict with %s\n",
|
||||
ATA_PRIMARY_CMD,
|
||||
conflict->name);
|
||||
}
|
||||
} else
|
||||
legacy_mode |= ATA_PORT_PRIMARY;
|
||||
|
||||
if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) {
|
||||
struct resource *conflict, res;
|
||||
res.start = ATA_SECONDARY_CMD;
|
||||
res.end = ATA_SECONDARY_CMD + 8 - 1;
|
||||
conflict = ____request_resource(&ioport_resource, &res);
|
||||
while (conflict->child)
|
||||
conflict = ____request_resource(conflict, &res);
|
||||
if (!strcmp(conflict->name, "libata"))
|
||||
legacy_mode |= ATA_PORT_SECONDARY;
|
||||
else {
|
||||
pcim_pin_device(pdev);
|
||||
printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \
|
||||
"ata: conflict with %s\n",
|
||||
ATA_SECONDARY_CMD,
|
||||
conflict->name);
|
||||
}
|
||||
} else
|
||||
legacy_mode |= ATA_PORT_SECONDARY;
|
||||
|
||||
if (legacy_mode & ATA_PORT_PRIMARY)
|
||||
pci_request_region(pdev, 1, DRV_NAME);
|
||||
if (legacy_mode & ATA_PORT_SECONDARY)
|
||||
pci_request_region(pdev, 3, DRV_NAME);
|
||||
/* If there is a DMA resource, allocate it */
|
||||
pci_request_region(pdev, 4, DRV_NAME);
|
||||
}
|
||||
|
||||
/* we have legacy mode, but all ports are unavailable */
|
||||
if (legacy_mode == (1 << 3)) {
|
||||
rc = -EBUSY;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* TODO: If we get no DMA mask we should fall back to PIO */
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
if (legacy_mode) {
|
||||
probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
|
||||
} else {
|
||||
if (n_ports == 2)
|
||||
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
else
|
||||
probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
|
||||
}
|
||||
if (!probe_ent) {
|
||||
/* alloc and init host */
|
||||
host = ata_host_alloc_pinfo(dev, port, 2);
|
||||
if (!host) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"failed to allocate ATA host\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
if (!legacy_mode) {
|
||||
unsigned int port_mask;
|
||||
|
||||
if (!ata_device_add(probe_ent)) {
|
||||
rc = -ENODEV;
|
||||
goto err_out;
|
||||
port_mask = ATA_PORT_PRIMARY;
|
||||
if (n_ports > 1)
|
||||
port_mask |= ATA_PORT_SECONDARY;
|
||||
|
||||
rc = ata_pci_init_native_host(host, port_mask);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
} else {
|
||||
int was_busy = 0;
|
||||
|
||||
rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
|
||||
if (was_busy)
|
||||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
/* request respective PCI regions, may fail */
|
||||
rc = pci_request_region(pdev, 1, DRV_NAME);
|
||||
rc = pci_request_region(pdev, 3, DRV_NAME);
|
||||
}
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
/* init BMDMA, may fail */
|
||||
ata_pci_init_bmdma(host);
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* start host and request IRQ */
|
||||
rc = ata_host_start(host);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
if (!legacy_mode)
|
||||
rc = devm_request_irq(dev, pdev->irq,
|
||||
port_info[0]->port_ops->irq_handler,
|
||||
IRQF_SHARED, DRV_NAME, host);
|
||||
else {
|
||||
irq_handler_t handler[2] = { host->ops->irq_handler,
|
||||
host->ops->irq_handler };
|
||||
unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
|
||||
void *dev_id[2] = { host, host };
|
||||
|
||||
rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
|
||||
}
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
/* register */
|
||||
rc = ata_host_register(host, port_info[0]->sht);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
devres_remove_group(dev, NULL);
|
||||
return 0;
|
||||
|
||||
|
@ -893,12 +1096,12 @@ int ata_pci_clear_simplex(struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask)
|
||||
unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer_mask)
|
||||
{
|
||||
/* Filter out DMA modes if the device has been configured by
|
||||
the BIOS as PIO only */
|
||||
|
||||
if (ap->ioaddr.bmdma_addr == 0)
|
||||
if (adev->ap->ioaddr.bmdma_addr == 0)
|
||||
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
|
||||
return xfer_mask;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ enum {
|
|||
ATA_DNXFER_QUIET = (1 << 31),
|
||||
};
|
||||
|
||||
extern unsigned int ata_print_id;
|
||||
extern struct workqueue_struct *ata_aux_wq;
|
||||
extern int atapi_enabled;
|
||||
extern int atapi_dmadir;
|
||||
|
@ -92,10 +93,7 @@ extern int ata_flush_cache(struct ata_device *dev);
|
|||
extern void ata_dev_init(struct ata_device *dev);
|
||||
extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
|
||||
extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
|
||||
extern void ata_port_init(struct ata_port *ap, struct ata_host *host,
|
||||
const struct ata_probe_ent *ent, unsigned int port_no);
|
||||
extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
|
||||
const struct ata_port_info *port);
|
||||
extern struct ata_port *ata_port_alloc(struct ata_host *host);
|
||||
|
||||
/* libata-acpi.c */
|
||||
#ifdef CONFIG_SATA_ACPI
|
||||
|
@ -113,8 +111,8 @@ static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
|
|||
#endif
|
||||
|
||||
/* libata-scsi.c */
|
||||
extern struct scsi_transport_template ata_scsi_transport_template;
|
||||
|
||||
extern int ata_scsi_add_hosts(struct ata_host *host,
|
||||
struct scsi_host_template *sht);
|
||||
extern void ata_scsi_scan_host(struct ata_port *ap);
|
||||
extern int ata_scsi_offline_dev(struct ata_device *dev);
|
||||
extern void ata_scsi_hotplug(struct work_struct *work);
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <linux/dmi.h>
|
||||
|
||||
#define DRV_NAME "pata_ali"
|
||||
#define DRV_VERSION "0.7.3"
|
||||
#define DRV_VERSION "0.7.4"
|
||||
|
||||
/*
|
||||
* Cable special cases
|
||||
|
@ -89,59 +89,6 @@ static int ali_c2_cable_detect(struct ata_port *ap)
|
|||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
* ali_early_error_handler - reset for eary chip
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Handle the reset callback for the later chips with cable detect
|
||||
*/
|
||||
|
||||
static int ali_c2_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ali_c2_cable_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void ali_c2_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, ali_c2_pre_reset,
|
||||
ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* ali_early_cable_detect - cable detection
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Perform cable detection for older chipsets. This turns out to be
|
||||
* rather easy to implement
|
||||
*/
|
||||
|
||||
static int ali_early_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
* ali_early_probe_init - reset for early chip
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Handle the reset callback for the early (pre cable detect) chips.
|
||||
*/
|
||||
|
||||
static int ali_early_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ali_early_cable_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void ali_early_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, ali_early_pre_reset,
|
||||
ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* ali_20_filter - filter for earlier ALI DMA
|
||||
* @ap: ALi ATA port
|
||||
|
@ -151,7 +98,7 @@ static void ali_early_error_handler(struct ata_port *ap)
|
|||
* fix that later on. Also ensure we do not do UDMA on WDC drives
|
||||
*/
|
||||
|
||||
static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
|
||||
static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
char model_num[ATA_ID_PROD_LEN + 1];
|
||||
/* No DMA on anything but a disk for now */
|
||||
|
@ -160,7 +107,7 @@ static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device
|
|||
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
|
||||
if (strstr(model_num, "WDC"))
|
||||
return mask &= ~ATA_MASK_UDMA;
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,7 +261,6 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
/**
|
||||
* ali_lock_sectors - Keep older devices to 255 sector mode
|
||||
* @ap: ATA port
|
||||
* @adev: Device
|
||||
*
|
||||
* Called during the bus probe for each device that is found. We use
|
||||
|
@ -324,7 +270,7 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
* slower PIO methods
|
||||
*/
|
||||
|
||||
static void ali_lock_sectors(struct ata_port *ap, struct ata_device *adev)
|
||||
static void ali_lock_sectors(struct ata_device *adev)
|
||||
{
|
||||
adev->max_sectors = 255;
|
||||
}
|
||||
|
@ -366,8 +312,9 @@ static struct ata_port_operations ali_early_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ali_early_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
@ -402,8 +349,9 @@ static struct ata_port_operations ali_20_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ali_early_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -440,8 +388,9 @@ static struct ata_port_operations ali_c2_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ali_c2_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ali_c2_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -477,8 +426,9 @@ static struct ata_port_operations ali_c5_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ali_c2_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ali_c2_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_amd"
|
||||
#define DRV_VERSION "0.2.8"
|
||||
#define DRV_VERSION "0.3.8"
|
||||
|
||||
/**
|
||||
* timing_setup - shared timing computation and load
|
||||
|
@ -119,32 +119,25 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
|
|||
}
|
||||
|
||||
/**
|
||||
* amd_probe_init - cable detection
|
||||
* amd_probe_init - perform reset handling
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Perform cable detection. The BIOS stores this in PCI config
|
||||
* space for us.
|
||||
* Reset sequence checking enable bits to see which ports are
|
||||
* active.
|
||||
*/
|
||||
|
||||
static int amd_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
static const u32 bitmask[2] = {0x03, 0x0C};
|
||||
static const struct pci_bits amd_enable_bits[] = {
|
||||
{ 0x40, 1, 0x02, 0x02 },
|
||||
{ 0x40, 1, 0x01, 0x01 }
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 ata66;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x42, &ata66);
|
||||
if (ata66 & bitmask[ap->port_no])
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
}
|
||||
|
@ -156,28 +149,16 @@ static void amd_error_handler(struct ata_port *ap)
|
|||
ata_std_postreset);
|
||||
}
|
||||
|
||||
static int amd_early_pre_reset(struct ata_port *ap)
|
||||
static int amd_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
static const u32 bitmask[2] = {0x03, 0x0C};
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static struct pci_bits amd_enable_bits[] = {
|
||||
{ 0x40, 1, 0x02, 0x02 },
|
||||
{ 0x40, 1, 0x01, 0x01 }
|
||||
};
|
||||
u8 ata66;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
/* No host side cable detection */
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
}
|
||||
|
||||
static void amd_early_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, amd_early_pre_reset,
|
||||
ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
pci_read_config_byte(pdev, 0x42, &ata66);
|
||||
if (ata66 & bitmask[ap->port_no])
|
||||
return ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,31 +228,16 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
*/
|
||||
|
||||
static int nv_pre_reset(struct ata_port *ap) {
|
||||
static const u8 bitmask[2] = {0x03, 0x0C};
|
||||
static const struct pci_bits nv_enable_bits[] = {
|
||||
{ 0x50, 1, 0x02, 0x02 },
|
||||
{ 0x50, 1, 0x01, 0x01 }
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 ata66;
|
||||
u16 udma;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x52, &ata66);
|
||||
if (ata66 & bitmask[ap->port_no])
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
|
||||
/* We now have to double check because the Nvidia boxes BIOS
|
||||
doesn't always set the cable bits but does set mode bits */
|
||||
|
||||
pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
|
||||
if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -281,6 +247,29 @@ static void nv_error_handler(struct ata_port *ap)
|
|||
ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
static int nv_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
static const u8 bitmask[2] = {0x03, 0x0C};
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 ata66;
|
||||
u16 udma;
|
||||
int cbl;
|
||||
|
||||
pci_read_config_byte(pdev, 0x52, &ata66);
|
||||
if (ata66 & bitmask[ap->port_no])
|
||||
cbl = ATA_CBL_PATA80;
|
||||
else
|
||||
cbl = ATA_CBL_PATA40;
|
||||
|
||||
/* We now have to double check because the Nvidia boxes BIOS
|
||||
doesn't always set the cable bits but does set mode bits */
|
||||
pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
|
||||
if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
|
||||
cbl = ATA_CBL_PATA80;
|
||||
return cbl;
|
||||
}
|
||||
|
||||
/**
|
||||
* nv100_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
|
@ -353,8 +342,9 @@ static struct ata_port_operations amd33_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = amd_early_error_handler,
|
||||
.error_handler = amd_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -387,8 +377,9 @@ static struct ata_port_operations amd66_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = amd_early_error_handler,
|
||||
.error_handler = amd_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -423,6 +414,7 @@ static struct ata_port_operations amd100_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = amd_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -457,6 +449,7 @@ static struct ata_port_operations amd133_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = amd_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = amd_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -491,6 +484,7 @@ static struct ata_port_operations nv100_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = nv_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = nv_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -525,6 +519,7 @@ static struct ata_port_operations nv133_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = nv_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = nv_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -49,8 +49,6 @@ static int artop6210_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -85,18 +83,28 @@ static int artop6260_pre_reset(struct ata_port *ap)
|
|||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
/* Odd numbered device ids are the units with enable bits (the -R cards) */
|
||||
if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* artop6260_cable_detect - identify cable type
|
||||
* @ap: Port
|
||||
*
|
||||
* Identify the cable type for the ARTOp interface in question
|
||||
*/
|
||||
|
||||
static int artop6260_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
pci_read_config_byte(pdev, 0x49, &tmp);
|
||||
if (tmp & (1 << ap->port_no))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,7 +233,7 @@ static void artop6260_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
/**
|
||||
* artop6210_set_dmamode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: um
|
||||
* @adev: Device whose timings we are configuring
|
||||
*
|
||||
* Set DMA mode for device, in host controller PCI config space.
|
||||
*
|
||||
|
@ -333,6 +341,7 @@ static const struct ata_port_operations artop6210_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = artop6210_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -366,6 +375,7 @@ static const struct ata_port_operations artop6260_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = artop6260_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = artop6260_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_atiixp"
|
||||
#define DRV_VERSION "0.4.4"
|
||||
#define DRV_VERSION "0.4.5"
|
||||
|
||||
enum {
|
||||
ATIIXP_IDE_PIO_TIMING = 0x40,
|
||||
|
@ -35,23 +35,15 @@ enum {
|
|||
|
||||
static int atiixp_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits atiixp_enable_bits[] = {
|
||||
{ 0x48, 1, 0x01, 0x00 },
|
||||
{ 0x48, 1, 0x08, 0x00 }
|
||||
};
|
||||
u8 udma;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
/* Hack from drivers/ide/pci. Really we want to know how to do the
|
||||
raw detection not play follow the bios mode guess */
|
||||
pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
|
||||
if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -60,6 +52,19 @@ static void atiixp_error_handler(struct ata_port *ap)
|
|||
ata_bmdma_drive_eh(ap, atiixp_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static int atiixp_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 udma;
|
||||
|
||||
/* Hack from drivers/ide/pci. Really we want to know how to do the
|
||||
raw detection not play follow the bios mode guess */
|
||||
pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
|
||||
if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
|
||||
return ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
* atiixp_set_pio_timing - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
|
@ -245,6 +250,7 @@ static struct ata_port_operations atiixp_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = atiixp_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = atiixp_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = atiixp_bmdma_start,
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* pata_cmd640.c - CMD640 PCI PATA for new ATA layer
|
||||
* (C) 2007 Red Hat Inc
|
||||
* Alan Cox <alan@redhat.com>
|
||||
*
|
||||
* Based upon
|
||||
* linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996
|
||||
*
|
||||
* Copyright (C) 1995-1996 Linus Torvalds & authors (see driver)
|
||||
*
|
||||
* This drives only the PCI version of the controller. If you have a
|
||||
* VLB one then we have enough docs to support it but you can write
|
||||
* your own code.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_cmd640"
|
||||
#define DRV_VERSION "0.0.5"
|
||||
|
||||
struct cmd640_reg {
|
||||
int last;
|
||||
u8 reg58[ATA_MAX_DEVICES];
|
||||
};
|
||||
|
||||
enum {
|
||||
CFR = 0x50,
|
||||
CNTRL = 0x51,
|
||||
CMDTIM = 0x52,
|
||||
ARTIM0 = 0x53,
|
||||
DRWTIM0 = 0x54,
|
||||
ARTIM23 = 0x57,
|
||||
DRWTIM23 = 0x58,
|
||||
BRST = 0x59
|
||||
};
|
||||
|
||||
/**
|
||||
* cmd640_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA port
|
||||
* @adev: ATA device
|
||||
*
|
||||
* Called to do the PIO mode setup.
|
||||
*/
|
||||
|
||||
static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct cmd640_reg *timing = ap->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct ata_timing t;
|
||||
const unsigned long T = 1000000 / 33;
|
||||
const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };
|
||||
u8 reg;
|
||||
int arttim = ARTIM0 + 2 * adev->devno;
|
||||
struct ata_device *pair = ata_dev_pair(adev);
|
||||
|
||||
if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) {
|
||||
printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* The second channel has shared timings and the setup timing is
|
||||
messy to switch to merge it for worst case */
|
||||
if (ap->port_no && pair) {
|
||||
struct ata_timing p;
|
||||
ata_timing_compute(pair, pair->pio_mode, &p, T, 1);
|
||||
ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP);
|
||||
}
|
||||
|
||||
/* Make the timings fit */
|
||||
if (t.recover > 16) {
|
||||
t.active += t.recover - 16;
|
||||
t.recover = 16;
|
||||
}
|
||||
if (t.active > 16)
|
||||
t.active = 16;
|
||||
|
||||
/* Now convert the clocks into values we can actually stuff into
|
||||
the chip */
|
||||
|
||||
if (t.recover > 1)
|
||||
t.recover--; /* 640B only */
|
||||
else
|
||||
t.recover = 15;
|
||||
|
||||
if (t.setup > 4)
|
||||
t.setup = 0xC0;
|
||||
else
|
||||
t.setup = setup_data[t.setup];
|
||||
|
||||
if (ap->port_no == 0) {
|
||||
t.active &= 0x0F; /* 0 = 16 */
|
||||
|
||||
/* Load setup timing */
|
||||
pci_read_config_byte(pdev, arttim, ®);
|
||||
reg &= 0x3F;
|
||||
reg |= t.setup;
|
||||
pci_write_config_byte(pdev, arttim, reg);
|
||||
|
||||
/* Load active/recovery */
|
||||
pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover);
|
||||
} else {
|
||||
/* Save the shared timings for channel, they will be loaded
|
||||
by qc_issue_prot. Reloading the setup time is expensive
|
||||
so we keep a merged one loaded */
|
||||
pci_read_config_byte(pdev, ARTIM23, ®);
|
||||
reg &= 0x3F;
|
||||
reg |= t.setup;
|
||||
pci_write_config_byte(pdev, ARTIM23, reg);
|
||||
timing->reg58[adev->devno] = (t.active << 4) | t.recover;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* cmd640_qc_issue_prot - command preparation hook
|
||||
* @qc: Command to be issued
|
||||
*
|
||||
* Channel 1 has shared timings. We must reprogram the
|
||||
* clock each drive 2/3 switch we do.
|
||||
*/
|
||||
|
||||
static unsigned int cmd640_qc_issue_prot(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct ata_device *adev = qc->dev;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct cmd640_reg *timing = ap->private_data;
|
||||
|
||||
if (ap->port_no != 0 && adev->devno != timing->last) {
|
||||
pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]);
|
||||
timing->last = adev->devno;
|
||||
}
|
||||
return ata_qc_issue_prot(qc);
|
||||
}
|
||||
|
||||
/**
|
||||
* cmd640_port_start - port setup
|
||||
* @ap: ATA port being set up
|
||||
*
|
||||
* The CMD640 needs to maintain private data structures so we
|
||||
* allocate space here.
|
||||
*/
|
||||
|
||||
static int cmd640_port_start(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct cmd640_reg *timing;
|
||||
|
||||
int ret = ata_port_start(ap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
|
||||
if (timing == NULL)
|
||||
return -ENOMEM;
|
||||
timing->last = -1; /* Force a load */
|
||||
ap->private_data = timing;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct scsi_host_template cmd640_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
.proc_name = DRV_NAME,
|
||||
.dma_boundary = ATA_DMA_BOUNDARY,
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
#ifdef CONFIG_PM
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct ata_port_operations cmd640_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = cmd640_set_piomode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
.bmdma_stop = ata_bmdma_stop,
|
||||
.bmdma_status = ata_bmdma_status,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = cmd640_qc_issue_prot,
|
||||
|
||||
/* In theory this is not needed once we kill the prefetcher */
|
||||
.data_xfer = ata_data_xfer_noirq,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = cmd640_port_start,
|
||||
};
|
||||
|
||||
static void cmd640_hardware_init(struct pci_dev *pdev)
|
||||
{
|
||||
u8 r;
|
||||
u8 ctrl;
|
||||
|
||||
/* CMD640 detected, commiserations */
|
||||
pci_write_config_byte(pdev, 0x5B, 0x00);
|
||||
/* Get version info */
|
||||
pci_read_config_byte(pdev, CFR, &r);
|
||||
/* PIO0 command cycles */
|
||||
pci_write_config_byte(pdev, CMDTIM, 0);
|
||||
/* 512 byte bursts (sector) */
|
||||
pci_write_config_byte(pdev, BRST, 0x40);
|
||||
/*
|
||||
* A reporter a long time ago
|
||||
* Had problems with the data fifo
|
||||
* So don't run the risk
|
||||
* Of putting crap on the disk
|
||||
* For its better just to go slow
|
||||
*/
|
||||
/* Do channel 0 */
|
||||
pci_read_config_byte(pdev, CNTRL, &ctrl);
|
||||
pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0);
|
||||
/* Ditto for channel 1 */
|
||||
pci_read_config_byte(pdev, ARTIM23, &ctrl);
|
||||
ctrl |= 0x0C;
|
||||
pci_write_config_byte(pdev, ARTIM23, ctrl);
|
||||
}
|
||||
|
||||
static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static struct ata_port_info info = {
|
||||
.sht = &cmd640_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.port_ops = &cmd640_port_ops
|
||||
};
|
||||
|
||||
static struct ata_port_info *port_info[2] = { &info, &info };
|
||||
|
||||
cmd640_hardware_init(pdev);
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int cmd640_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
cmd640_hardware_init(pdev);
|
||||
#ifdef CONFIG_PM
|
||||
return ata_pci_device_resume(pdev);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct pci_device_id cmd640[] = {
|
||||
{ PCI_VDEVICE(CMD, 0x640), 0 },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct pci_driver cmd640_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = cmd640,
|
||||
.probe = cmd640_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ata_pci_device_suspend,
|
||||
#endif
|
||||
.resume = cmd640_reinit_one,
|
||||
};
|
||||
|
||||
static int __init cmd640_init(void)
|
||||
{
|
||||
return pci_register_driver(&cmd640_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit cmd640_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&cmd640_pci_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("low-level driver for CMD640 PATA controllers");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, cmd640);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
module_init(cmd640_init);
|
||||
module_exit(cmd640_exit);
|
|
@ -75,13 +75,7 @@ enum {
|
|||
DTPR1 = 0x7C
|
||||
};
|
||||
|
||||
static int cmd64x_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static int cmd648_pre_reset(struct ata_port *ap)
|
||||
static int cmd648_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 r;
|
||||
|
@ -89,21 +83,8 @@ static int cmd648_pre_reset(struct ata_port *ap)
|
|||
/* Check cable detect bits */
|
||||
pci_read_config_byte(pdev, BMIDECSR, &r);
|
||||
if (r & (1 << ap->port_no))
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void cmd64x_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, cmd64x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static void cmd648_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, cmd648_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
return ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,8 +285,9 @@ static struct ata_port_operations cmd64x_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cmd64x_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -338,8 +320,9 @@ static struct ata_port_operations cmd646r1_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cmd64x_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -372,8 +355,9 @@ static struct ata_port_operations cmd648_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cmd648_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = cmd648_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -139,18 +139,6 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
cs5520_set_timings(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
|
||||
static int cs5520_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void cs5520_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, cs5520_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static struct scsi_host_template cs5520_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
|
@ -186,8 +174,9 @@ static struct ata_port_operations cs5520_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cs5520_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -197,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = {
|
|||
.qc_issue = ata_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -205,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = {
|
|||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct ata_port_info pi = {
|
||||
.flags = ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f,
|
||||
.port_ops = &cs5520_port_ops,
|
||||
};
|
||||
const struct ata_port_info *ppi[2];
|
||||
u8 pcicfg;
|
||||
void __iomem *iomap[5];
|
||||
static struct ata_probe_ent probe[2];
|
||||
int ports = 0;
|
||||
void *iomap[5];
|
||||
struct ata_host *host;
|
||||
struct ata_ioports *ioaddr;
|
||||
int i, rc;
|
||||
|
||||
/* IDE port enable bits */
|
||||
pci_read_config_byte(dev, 0x60, &pcicfg);
|
||||
pci_read_config_byte(pdev, 0x60, &pcicfg);
|
||||
|
||||
/* Check if the ATA ports are enabled */
|
||||
if ((pcicfg & 3) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
ppi[0] = ppi[1] = &ata_dummy_port_info;
|
||||
if (pcicfg & 1)
|
||||
ppi[0] = π
|
||||
if (pcicfg & 2)
|
||||
ppi[1] = π
|
||||
|
||||
if ((pcicfg & 0x40) == 0) {
|
||||
printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n");
|
||||
pci_write_config_byte(dev, 0x60, pcicfg | 0x40);
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"DMA mode disabled. Enabling.\n");
|
||||
pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
|
||||
}
|
||||
|
||||
pi.mwdma_mask = id->driver_data;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Perform set up for DMA */
|
||||
if (pci_enable_device_bars(dev, 1<<2)) {
|
||||
if (pci_enable_device_bars(pdev, 1<<2)) {
|
||||
printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
pci_set_master(dev);
|
||||
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
|
||||
|
||||
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
|
||||
if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
|
||||
printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Map IO ports */
|
||||
iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8);
|
||||
iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1);
|
||||
iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8);
|
||||
iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1);
|
||||
iomap[4] = pcim_iomap(dev, 2, 0);
|
||||
/* Map IO ports and initialize host accordingly */
|
||||
iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8);
|
||||
iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1);
|
||||
iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8);
|
||||
iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1);
|
||||
iomap[4] = pcim_iomap(pdev, 2, 0);
|
||||
|
||||
if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
|
||||
return -ENOMEM;
|
||||
|
||||
/* We have to do our own plumbing as the PCI setup for this
|
||||
chipset is non-standard so we can't punt to the libata code */
|
||||
ioaddr = &host->ports[0]->ioaddr;
|
||||
ioaddr->cmd_addr = iomap[0];
|
||||
ioaddr->ctl_addr = iomap[1];
|
||||
ioaddr->altstatus_addr = iomap[1];
|
||||
ioaddr->bmdma_addr = iomap[4];
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
INIT_LIST_HEAD(&probe[0].node);
|
||||
probe[0].dev = pci_dev_to_dev(dev);
|
||||
probe[0].port_ops = &cs5520_port_ops;
|
||||
probe[0].sht = &cs5520_sht;
|
||||
probe[0].pio_mask = 0x1F;
|
||||
probe[0].mwdma_mask = id->driver_data;
|
||||
probe[0].irq = 14;
|
||||
probe[0].irq_flags = 0;
|
||||
probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
|
||||
probe[0].n_ports = 1;
|
||||
probe[0].port[0].cmd_addr = iomap[0];
|
||||
probe[0].port[0].ctl_addr = iomap[1];
|
||||
probe[0].port[0].altstatus_addr = iomap[1];
|
||||
probe[0].port[0].bmdma_addr = iomap[4];
|
||||
ioaddr = &host->ports[1]->ioaddr;
|
||||
ioaddr->cmd_addr = iomap[2];
|
||||
ioaddr->ctl_addr = iomap[3];
|
||||
ioaddr->altstatus_addr = iomap[3];
|
||||
ioaddr->bmdma_addr = iomap[4] + 8;
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
/* The secondary lurks at different addresses but is otherwise
|
||||
the same beastie */
|
||||
/* activate the host */
|
||||
pci_set_master(pdev);
|
||||
rc = ata_host_start(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe[1] = probe[0];
|
||||
INIT_LIST_HEAD(&probe[1].node);
|
||||
probe[1].irq = 15;
|
||||
probe[1].port[0].cmd_addr = iomap[2];
|
||||
probe[1].port[0].ctl_addr = iomap[3];
|
||||
probe[1].port[0].altstatus_addr = iomap[3];
|
||||
probe[1].port[0].bmdma_addr = iomap[4] + 8;
|
||||
for (i = 0; i < 2; i++) {
|
||||
static const int irq[] = { 14, 15 };
|
||||
struct ata_port *ap = host->ports[0];
|
||||
|
||||
/* Let libata fill in the port details */
|
||||
ata_std_ports(&probe[0].port[0]);
|
||||
ata_std_ports(&probe[1].port[0]);
|
||||
if (ata_port_is_dummy(ap))
|
||||
continue;
|
||||
|
||||
/* Now add the ports that are active */
|
||||
if (pcicfg & 1)
|
||||
ports += ata_device_add(&probe[0]);
|
||||
if (pcicfg & 2)
|
||||
ports += ata_device_add(&probe[1]);
|
||||
if (ports)
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
|
||||
ata_interrupt, 0, DRV_NAME, host);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return ata_host_register(host, &cs5520_sht);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -160,18 +160,6 @@ static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc)
|
|||
return ata_qc_issue_prot(qc);
|
||||
}
|
||||
|
||||
static int cs5530_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void cs5530_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, cs5530_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
|
||||
static struct scsi_host_template cs5530_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
|
@ -213,8 +201,9 @@ static struct ata_port_operations cs5530_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cs5530_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = cs5530_qc_issue_prot,
|
||||
|
|
|
@ -70,36 +70,23 @@
|
|||
#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 )
|
||||
|
||||
/**
|
||||
* cs5535_pre_reset - detect cable type
|
||||
* cs5535_cable_detect - detect cable type
|
||||
* @ap: Port to detect on
|
||||
*
|
||||
* Perform cable detection for ATA66 capable cable. Return a libata
|
||||
* cable type.
|
||||
*/
|
||||
|
||||
static int cs5535_pre_reset(struct ata_port *ap)
|
||||
static int cs5535_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
u8 cable;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable);
|
||||
if (cable & 1)
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA80;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* cs5535_error_handler - reset/probe
|
||||
* @ap: Port to reset
|
||||
*
|
||||
* Reset and configure a port
|
||||
*/
|
||||
|
||||
static void cs5535_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, cs5535_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -205,8 +192,9 @@ static struct ata_port_operations cs5535_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cs5535_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = cs5535_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -41,17 +41,6 @@ enum {
|
|||
CY82_INDEX_TIMEOUT = 0x32
|
||||
};
|
||||
|
||||
static int cy82c693_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void cy82c693_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, cy82c693_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* cy82c693_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
|
@ -156,8 +145,9 @@ static struct ata_port_operations cy82c693_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = cy82c693_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_efar"
|
||||
#define DRV_VERSION "0.4.3"
|
||||
#define DRV_VERSION "0.4.4"
|
||||
|
||||
/**
|
||||
* efar_pre_reset - check for 40/80 pin
|
||||
* efar_pre_reset - Enable bits
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection for the EFAR ATA interface. This is
|
||||
|
@ -38,18 +38,11 @@ static int efar_pre_reset(struct ata_port *ap)
|
|||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
{ 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x47, &tmp);
|
||||
if (tmp & (2 >> ap->port_no))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -66,6 +59,25 @@ static void efar_error_handler(struct ata_port *ap)
|
|||
ata_bmdma_drive_eh(ap, efar_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* efar_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection for the EFAR ATA interface. This is
|
||||
* different to the PIIX arrangement
|
||||
*/
|
||||
|
||||
static int efar_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
pci_read_config_byte(pdev, 0x47, &tmp);
|
||||
if (tmp & (2 >> ap->port_no))
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
* efar_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
|
@ -256,6 +268,7 @@ static const struct ata_port_operations efar_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = efar_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = efar_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt366"
|
||||
#define DRV_VERSION "0.6.0"
|
||||
#define DRV_VERSION "0.6.1"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_speed;
|
||||
|
@ -169,13 +169,12 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons
|
|||
|
||||
/**
|
||||
* hpt366_filter - mode selection filter
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*
|
||||
* Block UDMA on devices that cause trouble with this controller.
|
||||
*/
|
||||
|
||||
static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
|
||||
static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
if (adev->class == ATA_DEV_ATA) {
|
||||
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
|
||||
|
@ -185,7 +184,7 @@ static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device
|
|||
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
|
||||
mask &= ~(0x0F << ATA_SHIFT_UDMA);
|
||||
}
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,24 +209,28 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
|
|||
return 0xffffffffU; /* silence compiler warning */
|
||||
}
|
||||
|
||||
static int hpt36x_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
u8 ata66;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
pci_read_config_byte(pdev, 0x5A, &ata66);
|
||||
if (ata66 & (1 << ap->port_no))
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
static int hpt36x_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
static const struct pci_bits hpt36x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
{ 0x54, 1, 0x04, 0x04 }
|
||||
};
|
||||
|
||||
u8 ata66;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x5A, &ata66);
|
||||
if (ata66 & (1 << ap->port_no))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -354,6 +357,7 @@ static struct ata_port_operations hpt366_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = hpt36x_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = hpt36x_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
|
||||
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
|
||||
* Portions Copyright (C) 2003 Red Hat Inc
|
||||
* Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
|
||||
*
|
||||
* TODO
|
||||
* PLL mode
|
||||
|
@ -25,7 +26,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt37x"
|
||||
#define DRV_VERSION "0.6.0"
|
||||
#define DRV_VERSION "0.6.5"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_speed;
|
||||
|
@ -61,201 +62,75 @@ struct hpt_chip {
|
|||
* 31 FIFO enable.
|
||||
*/
|
||||
|
||||
/* from highpoint documentation. these are old values */
|
||||
static const struct hpt_clock hpt370_timings_33[] = {
|
||||
/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */
|
||||
{ XFER_UDMA_5, 0x16454e31 },
|
||||
{ XFER_UDMA_4, 0x16454e31 },
|
||||
{ XFER_UDMA_3, 0x166d4e31 },
|
||||
{ XFER_UDMA_2, 0x16494e31 },
|
||||
{ XFER_UDMA_1, 0x164d4e31 },
|
||||
{ XFER_UDMA_0, 0x16514e31 },
|
||||
static struct hpt_clock hpt37x_timings_33[] = {
|
||||
{ XFER_UDMA_6, 0x12446231 }, /* 0x12646231 ?? */
|
||||
{ XFER_UDMA_5, 0x12446231 },
|
||||
{ XFER_UDMA_4, 0x12446231 },
|
||||
{ XFER_UDMA_3, 0x126c6231 },
|
||||
{ XFER_UDMA_2, 0x12486231 },
|
||||
{ XFER_UDMA_1, 0x124c6233 },
|
||||
{ XFER_UDMA_0, 0x12506297 },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x26514e21 },
|
||||
{ XFER_MW_DMA_1, 0x26514e33 },
|
||||
{ XFER_MW_DMA_0, 0x26514e97 },
|
||||
{ XFER_MW_DMA_2, 0x22406c31 },
|
||||
{ XFER_MW_DMA_1, 0x22406c33 },
|
||||
{ XFER_MW_DMA_0, 0x22406c97 },
|
||||
|
||||
{ XFER_PIO_4, 0x06514e21 },
|
||||
{ XFER_PIO_3, 0x06514e22 },
|
||||
{ XFER_PIO_2, 0x06514e33 },
|
||||
{ XFER_PIO_1, 0x06914e43 },
|
||||
{ XFER_PIO_0, 0x06914e57 },
|
||||
{ 0, 0x06514e57 }
|
||||
{ XFER_PIO_4, 0x06414e31 },
|
||||
{ XFER_PIO_3, 0x06414e42 },
|
||||
{ XFER_PIO_2, 0x06414e53 },
|
||||
{ XFER_PIO_1, 0x06814e93 },
|
||||
{ XFER_PIO_0, 0x06814ea7 }
|
||||
};
|
||||
|
||||
static const struct hpt_clock hpt370_timings_66[] = {
|
||||
{ XFER_UDMA_5, 0x14846231 },
|
||||
{ XFER_UDMA_4, 0x14886231 },
|
||||
{ XFER_UDMA_3, 0x148c6231 },
|
||||
{ XFER_UDMA_2, 0x148c6231 },
|
||||
{ XFER_UDMA_1, 0x14906231 },
|
||||
{ XFER_UDMA_0, 0x14986231 },
|
||||
static struct hpt_clock hpt37x_timings_50[] = {
|
||||
{ XFER_UDMA_6, 0x12848242 },
|
||||
{ XFER_UDMA_5, 0x12848242 },
|
||||
{ XFER_UDMA_4, 0x12ac8242 },
|
||||
{ XFER_UDMA_3, 0x128c8242 },
|
||||
{ XFER_UDMA_2, 0x120c8242 },
|
||||
{ XFER_UDMA_1, 0x12148254 },
|
||||
{ XFER_UDMA_0, 0x121882ea },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x26514e21 },
|
||||
{ XFER_MW_DMA_1, 0x26514e33 },
|
||||
{ XFER_MW_DMA_0, 0x26514e97 },
|
||||
{ XFER_MW_DMA_2, 0x22808242 },
|
||||
{ XFER_MW_DMA_1, 0x22808254 },
|
||||
{ XFER_MW_DMA_0, 0x228082ea },
|
||||
|
||||
{ XFER_PIO_4, 0x06514e21 },
|
||||
{ XFER_PIO_3, 0x06514e22 },
|
||||
{ XFER_PIO_2, 0x06514e33 },
|
||||
{ XFER_PIO_1, 0x06914e43 },
|
||||
{ XFER_PIO_0, 0x06914e57 },
|
||||
{ 0, 0x06514e57 }
|
||||
{ XFER_PIO_4, 0x0a81f442 },
|
||||
{ XFER_PIO_3, 0x0a81f443 },
|
||||
{ XFER_PIO_2, 0x0a81f454 },
|
||||
{ XFER_PIO_1, 0x0ac1f465 },
|
||||
{ XFER_PIO_0, 0x0ac1f48a }
|
||||
};
|
||||
|
||||
/* these are the current (4 sep 2001) timings from highpoint */
|
||||
static const struct hpt_clock hpt370a_timings_33[] = {
|
||||
{ XFER_UDMA_5, 0x12446231 },
|
||||
{ XFER_UDMA_4, 0x12446231 },
|
||||
{ XFER_UDMA_3, 0x126c6231 },
|
||||
{ XFER_UDMA_2, 0x12486231 },
|
||||
{ XFER_UDMA_1, 0x124c6233 },
|
||||
{ XFER_UDMA_0, 0x12506297 },
|
||||
static struct hpt_clock hpt37x_timings_66[] = {
|
||||
{ XFER_UDMA_6, 0x1c869c62 },
|
||||
{ XFER_UDMA_5, 0x1cae9c62 }, /* 0x1c8a9c62 */
|
||||
{ XFER_UDMA_4, 0x1c8a9c62 },
|
||||
{ XFER_UDMA_3, 0x1c8e9c62 },
|
||||
{ XFER_UDMA_2, 0x1c929c62 },
|
||||
{ XFER_UDMA_1, 0x1c9a9c62 },
|
||||
{ XFER_UDMA_0, 0x1c829c62 },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x22406c31 },
|
||||
{ XFER_MW_DMA_1, 0x22406c33 },
|
||||
{ XFER_MW_DMA_0, 0x22406c97 },
|
||||
{ XFER_MW_DMA_2, 0x2c829c62 },
|
||||
{ XFER_MW_DMA_1, 0x2c829c66 },
|
||||
{ XFER_MW_DMA_0, 0x2c829d2e },
|
||||
|
||||
{ XFER_PIO_4, 0x06414e31 },
|
||||
{ XFER_PIO_3, 0x06414e42 },
|
||||
{ XFER_PIO_2, 0x06414e53 },
|
||||
{ XFER_PIO_1, 0x06814e93 },
|
||||
{ XFER_PIO_0, 0x06814ea7 },
|
||||
{ 0, 0x06814ea7 }
|
||||
{ XFER_PIO_4, 0x0c829c62 },
|
||||
{ XFER_PIO_3, 0x0c829c84 },
|
||||
{ XFER_PIO_2, 0x0c829ca6 },
|
||||
{ XFER_PIO_1, 0x0d029d26 },
|
||||
{ XFER_PIO_0, 0x0d029d5e }
|
||||
};
|
||||
|
||||
/* 2x 33MHz timings */
|
||||
static const struct hpt_clock hpt370a_timings_66[] = {
|
||||
{ XFER_UDMA_5, 0x1488e673 },
|
||||
{ XFER_UDMA_4, 0x1488e673 },
|
||||
{ XFER_UDMA_3, 0x1498e673 },
|
||||
{ XFER_UDMA_2, 0x1490e673 },
|
||||
{ XFER_UDMA_1, 0x1498e677 },
|
||||
{ XFER_UDMA_0, 0x14a0e73f },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x2480fa73 },
|
||||
{ XFER_MW_DMA_1, 0x2480fa77 },
|
||||
{ XFER_MW_DMA_0, 0x2480fb3f },
|
||||
|
||||
{ XFER_PIO_4, 0x0c82be73 },
|
||||
{ XFER_PIO_3, 0x0c82be95 },
|
||||
{ XFER_PIO_2, 0x0c82beb7 },
|
||||
{ XFER_PIO_1, 0x0d02bf37 },
|
||||
{ XFER_PIO_0, 0x0d02bf5f },
|
||||
{ 0, 0x0d02bf5f }
|
||||
};
|
||||
|
||||
static const struct hpt_clock hpt370a_timings_50[] = {
|
||||
{ XFER_UDMA_5, 0x12848242 },
|
||||
{ XFER_UDMA_4, 0x12ac8242 },
|
||||
{ XFER_UDMA_3, 0x128c8242 },
|
||||
{ XFER_UDMA_2, 0x120c8242 },
|
||||
{ XFER_UDMA_1, 0x12148254 },
|
||||
{ XFER_UDMA_0, 0x121882ea },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x22808242 },
|
||||
{ XFER_MW_DMA_1, 0x22808254 },
|
||||
{ XFER_MW_DMA_0, 0x228082ea },
|
||||
|
||||
{ XFER_PIO_4, 0x0a81f442 },
|
||||
{ XFER_PIO_3, 0x0a81f443 },
|
||||
{ XFER_PIO_2, 0x0a81f454 },
|
||||
{ XFER_PIO_1, 0x0ac1f465 },
|
||||
{ XFER_PIO_0, 0x0ac1f48a },
|
||||
{ 0, 0x0ac1f48a }
|
||||
};
|
||||
|
||||
static const struct hpt_clock hpt372_timings_33[] = {
|
||||
{ XFER_UDMA_6, 0x1c81dc62 },
|
||||
{ XFER_UDMA_5, 0x1c6ddc62 },
|
||||
{ XFER_UDMA_4, 0x1c8ddc62 },
|
||||
{ XFER_UDMA_3, 0x1c8edc62 }, /* checkme */
|
||||
{ XFER_UDMA_2, 0x1c91dc62 },
|
||||
{ XFER_UDMA_1, 0x1c9adc62 }, /* checkme */
|
||||
{ XFER_UDMA_0, 0x1c82dc62 }, /* checkme */
|
||||
|
||||
{ XFER_MW_DMA_2, 0x2c829262 },
|
||||
{ XFER_MW_DMA_1, 0x2c829266 }, /* checkme */
|
||||
{ XFER_MW_DMA_0, 0x2c82922e }, /* checkme */
|
||||
|
||||
{ XFER_PIO_4, 0x0c829c62 },
|
||||
{ XFER_PIO_3, 0x0c829c84 },
|
||||
{ XFER_PIO_2, 0x0c829ca6 },
|
||||
{ XFER_PIO_1, 0x0d029d26 },
|
||||
{ XFER_PIO_0, 0x0d029d5e },
|
||||
{ 0, 0x0d029d5e }
|
||||
};
|
||||
|
||||
static const struct hpt_clock hpt372_timings_50[] = {
|
||||
{ XFER_UDMA_5, 0x12848242 },
|
||||
{ XFER_UDMA_4, 0x12ac8242 },
|
||||
{ XFER_UDMA_3, 0x128c8242 },
|
||||
{ XFER_UDMA_2, 0x120c8242 },
|
||||
{ XFER_UDMA_1, 0x12148254 },
|
||||
{ XFER_UDMA_0, 0x121882ea },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x22808242 },
|
||||
{ XFER_MW_DMA_1, 0x22808254 },
|
||||
{ XFER_MW_DMA_0, 0x228082ea },
|
||||
|
||||
{ XFER_PIO_4, 0x0a81f442 },
|
||||
{ XFER_PIO_3, 0x0a81f443 },
|
||||
{ XFER_PIO_2, 0x0a81f454 },
|
||||
{ XFER_PIO_1, 0x0ac1f465 },
|
||||
{ XFER_PIO_0, 0x0ac1f48a },
|
||||
{ 0, 0x0a81f443 }
|
||||
};
|
||||
|
||||
static const struct hpt_clock hpt372_timings_66[] = {
|
||||
{ XFER_UDMA_6, 0x1c869c62 },
|
||||
{ XFER_UDMA_5, 0x1cae9c62 },
|
||||
{ XFER_UDMA_4, 0x1c8a9c62 },
|
||||
{ XFER_UDMA_3, 0x1c8e9c62 },
|
||||
{ XFER_UDMA_2, 0x1c929c62 },
|
||||
{ XFER_UDMA_1, 0x1c9a9c62 },
|
||||
{ XFER_UDMA_0, 0x1c829c62 },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x2c829c62 },
|
||||
{ XFER_MW_DMA_1, 0x2c829c66 },
|
||||
{ XFER_MW_DMA_0, 0x2c829d2e },
|
||||
|
||||
{ XFER_PIO_4, 0x0c829c62 },
|
||||
{ XFER_PIO_3, 0x0c829c84 },
|
||||
{ XFER_PIO_2, 0x0c829ca6 },
|
||||
{ XFER_PIO_1, 0x0d029d26 },
|
||||
{ XFER_PIO_0, 0x0d029d5e },
|
||||
{ 0, 0x0d029d26 }
|
||||
};
|
||||
|
||||
static const struct hpt_clock hpt374_timings_33[] = {
|
||||
{ XFER_UDMA_6, 0x12808242 },
|
||||
{ XFER_UDMA_5, 0x12848242 },
|
||||
{ XFER_UDMA_4, 0x12ac8242 },
|
||||
{ XFER_UDMA_3, 0x128c8242 },
|
||||
{ XFER_UDMA_2, 0x120c8242 },
|
||||
{ XFER_UDMA_1, 0x12148254 },
|
||||
{ XFER_UDMA_0, 0x121882ea },
|
||||
|
||||
{ XFER_MW_DMA_2, 0x22808242 },
|
||||
{ XFER_MW_DMA_1, 0x22808254 },
|
||||
{ XFER_MW_DMA_0, 0x228082ea },
|
||||
|
||||
{ XFER_PIO_4, 0x0a81f442 },
|
||||
{ XFER_PIO_3, 0x0a81f443 },
|
||||
{ XFER_PIO_2, 0x0a81f454 },
|
||||
{ XFER_PIO_1, 0x0ac1f465 },
|
||||
{ XFER_PIO_0, 0x0ac1f48a },
|
||||
{ 0, 0x06814e93 }
|
||||
};
|
||||
|
||||
static const struct hpt_chip hpt370 = {
|
||||
"HPT370",
|
||||
48,
|
||||
{
|
||||
hpt370_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
NULL,
|
||||
hpt370_timings_66
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -263,10 +138,10 @@ static const struct hpt_chip hpt370a = {
|
|||
"HPT370A",
|
||||
48,
|
||||
{
|
||||
hpt370a_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
hpt370a_timings_50,
|
||||
hpt370a_timings_66
|
||||
hpt37x_timings_50,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -274,10 +149,10 @@ static const struct hpt_chip hpt372 = {
|
|||
"HPT372",
|
||||
55,
|
||||
{
|
||||
hpt372_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
hpt372_timings_50,
|
||||
hpt372_timings_66
|
||||
hpt37x_timings_50,
|
||||
hpt37x_timings_66
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -285,10 +160,10 @@ static const struct hpt_chip hpt302 = {
|
|||
"HPT302",
|
||||
66,
|
||||
{
|
||||
hpt372_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
hpt372_timings_50,
|
||||
hpt372_timings_66
|
||||
hpt37x_timings_50,
|
||||
hpt37x_timings_66
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -296,10 +171,10 @@ static const struct hpt_chip hpt371 = {
|
|||
"HPT371",
|
||||
66,
|
||||
{
|
||||
hpt372_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
hpt372_timings_50,
|
||||
hpt372_timings_66
|
||||
hpt37x_timings_50,
|
||||
hpt37x_timings_66
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -307,10 +182,10 @@ static const struct hpt_chip hpt372a = {
|
|||
"HPT372A",
|
||||
66,
|
||||
{
|
||||
hpt372_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
hpt372_timings_50,
|
||||
hpt372_timings_66
|
||||
hpt37x_timings_50,
|
||||
hpt37x_timings_66
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -318,7 +193,7 @@ static const struct hpt_chip hpt374 = {
|
|||
"HPT374",
|
||||
48,
|
||||
{
|
||||
hpt374_timings_33,
|
||||
hpt37x_timings_33,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
|
@ -397,13 +272,12 @@ static const char *bad_ata100_5[] = {
|
|||
|
||||
/**
|
||||
* hpt370_filter - mode selection filter
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*
|
||||
* Block UDMA on devices that cause trouble with this controller.
|
||||
*/
|
||||
|
||||
static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
|
||||
static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
if (adev->class == ATA_DEV_ATA) {
|
||||
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
|
||||
|
@ -411,24 +285,23 @@ static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device
|
|||
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
|
||||
mask &= ~(0x1F << ATA_SHIFT_UDMA);
|
||||
}
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt370a_filter - mode selection filter
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*
|
||||
* Block UDMA on devices that cause trouble with this controller.
|
||||
*/
|
||||
|
||||
static unsigned long hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
|
||||
static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
if (adev->class != ATA_DEV_ATA) {
|
||||
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
|
||||
mask &= ~ (0x1F << ATA_SHIFT_UDMA);
|
||||
}
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -462,8 +335,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
|
|||
ap->cbl = ATA_CBL_PATA80;
|
||||
|
||||
/* Reset the state machine */
|
||||
pci_write_config_byte(pdev, 0x50, 0x37);
|
||||
pci_write_config_byte(pdev, 0x54, 0x37);
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
|
@ -513,8 +385,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
|
|||
ap->cbl = ATA_CBL_PATA80;
|
||||
|
||||
/* Reset the state machine */
|
||||
pci_write_config_byte(pdev, 0x50, 0x37);
|
||||
pci_write_config_byte(pdev, 0x54, 0x37);
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
|
@ -1032,6 +903,24 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
.udma_mask = 0x3f,
|
||||
.port_ops = &hpt370a_port_ops
|
||||
};
|
||||
/* HPT370 - UDMA100 */
|
||||
static struct ata_port_info info_hpt370_33 = {
|
||||
.sht = &hpt37x_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x0f,
|
||||
.port_ops = &hpt370_port_ops
|
||||
};
|
||||
/* HPT370A - UDMA100 */
|
||||
static struct ata_port_info info_hpt370a_33 = {
|
||||
.sht = &hpt37x_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x0f,
|
||||
.port_ops = &hpt370a_port_ops
|
||||
};
|
||||
/* HPT371, 372 and friends - UDMA133 */
|
||||
static struct ata_port_info info_hpt372 = {
|
||||
.sht = &hpt37x_sht,
|
||||
|
@ -1067,7 +956,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
|
||||
u8 irqmask;
|
||||
u32 class_rev;
|
||||
u8 mcr1;
|
||||
u32 freq;
|
||||
int prefer_dpll = 1;
|
||||
|
||||
unsigned long iobase = pci_resource_start(dev, 4);
|
||||
|
||||
const struct hpt_chip *chip_table;
|
||||
int clock_slot;
|
||||
|
@ -1088,10 +981,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
case 3:
|
||||
port = &info_hpt370;
|
||||
chip_table = &hpt370;
|
||||
prefer_dpll = 0;
|
||||
break;
|
||||
case 4:
|
||||
port = &info_hpt370a;
|
||||
chip_table = &hpt370a;
|
||||
prefer_dpll = 0;
|
||||
break;
|
||||
case 5:
|
||||
port = &info_hpt372;
|
||||
|
@ -1119,8 +1014,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
chip_table = &hpt302;
|
||||
break;
|
||||
case PCI_DEVICE_ID_TTI_HPT371:
|
||||
if (class_rev > 1)
|
||||
return -ENODEV;
|
||||
port = &info_hpt372;
|
||||
chip_table = &hpt371;
|
||||
/* Single channel device, master is not present
|
||||
but the BIOS (or us for non x86) must mark it
|
||||
absent */
|
||||
pci_read_config_byte(dev, 0x50, &mcr1);
|
||||
mcr1 &= ~0x04;
|
||||
pci_write_config_byte(dev, 0x50, mcr1);
|
||||
break;
|
||||
case PCI_DEVICE_ID_TTI_HPT374:
|
||||
chip_table = &hpt374;
|
||||
|
@ -1150,8 +1053,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
*/
|
||||
|
||||
pci_write_config_byte(dev, 0x5b, 0x23);
|
||||
|
||||
/*
|
||||
* HighPoint does this for HPT372A.
|
||||
* NOTE: This register is only writeable via I/O space.
|
||||
*/
|
||||
if (chip_table == &hpt372a)
|
||||
outb(0x0e, iobase + 0x9c);
|
||||
|
||||
pci_read_config_dword(dev, 0x70, &freq);
|
||||
/* Some devices do not let this value be accessed via PCI space
|
||||
according to the old driver */
|
||||
|
||||
freq = inl(iobase + 0x90);
|
||||
if ((freq >> 12) != 0xABCDE) {
|
||||
int i;
|
||||
u8 sr;
|
||||
|
@ -1162,7 +1075,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
/* This is the process the HPT371 BIOS is reported to use */
|
||||
for(i = 0; i < 128; i++) {
|
||||
pci_read_config_byte(dev, 0x78, &sr);
|
||||
total += sr;
|
||||
total += sr & 0x1FF;
|
||||
udelay(15);
|
||||
}
|
||||
freq = total / 128;
|
||||
|
@ -1173,15 +1086,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
* Turn the frequency check into a band and then find a timing
|
||||
* table to match it.
|
||||
*/
|
||||
|
||||
|
||||
clock_slot = hpt37x_clock_slot(freq, chip_table->base);
|
||||
if (chip_table->clocks[clock_slot] == NULL) {
|
||||
if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
|
||||
/*
|
||||
* We need to try PLL mode instead
|
||||
*
|
||||
* For non UDMA133 capable devices we should
|
||||
* use a 50MHz DPLL by choice
|
||||
*/
|
||||
unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192;
|
||||
unsigned int f_high = f_low + 2;
|
||||
unsigned int f_low, f_high;
|
||||
int adjust;
|
||||
|
||||
clock_slot = 2;
|
||||
if (port->udma_mask & 0xE0)
|
||||
clock_slot = 3;
|
||||
|
||||
f_low = (MHz[clock_slot] * chip_table->base) / 192;
|
||||
f_high = f_low + 2;
|
||||
|
||||
/* Select the DPLL clock. */
|
||||
pci_write_config_byte(dev, 0x5b, 0x21);
|
||||
|
||||
for(adjust = 0; adjust < 8; adjust++) {
|
||||
if (hpt37x_calibrate_dpll(dev))
|
||||
|
@ -1197,25 +1122,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
/* Check if this works for all cases */
|
||||
port->private_data = (void *)hpt370_timings_66;
|
||||
if (clock_slot == 3)
|
||||
port->private_data = (void *)hpt37x_timings_66;
|
||||
else
|
||||
port->private_data = (void *)hpt37x_timings_50;
|
||||
|
||||
printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
|
||||
} else {
|
||||
port->private_data = (void *)chip_table->clocks[clock_slot];
|
||||
/*
|
||||
* Perform a final fixup. The 371 and 372 clock determines
|
||||
* if UDMA133 is available.
|
||||
*/
|
||||
* Perform a final fixup. Note that we will have used the
|
||||
* DPLL on the HPT372 which means we don't have to worry
|
||||
* about lack of UDMA133 support on lower clocks
|
||||
*/
|
||||
|
||||
if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */
|
||||
printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n");
|
||||
if (port == &info_hpt372)
|
||||
port = &info_hpt372_50;
|
||||
else BUG();
|
||||
}
|
||||
if (clock_slot < 2 && port == &info_hpt370)
|
||||
port = &info_hpt370_33;
|
||||
if (clock_slot < 2 && port == &info_hpt370a)
|
||||
port = &info_hpt370a_33;
|
||||
printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
|
||||
}
|
||||
|
||||
port_info[0] = port_info[1] = port;
|
||||
/* Now kick off ATA set up */
|
||||
return ata_pci_init_one(dev, port_info, 2);
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
|
||||
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
|
||||
* Portions Copyright (C) 2003 Red Hat Inc
|
||||
* Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
|
||||
*
|
||||
*
|
||||
* TODO
|
||||
* 371N
|
||||
* Work out best PLL policy
|
||||
*/
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt3x2n"
|
||||
#define DRV_VERSION "0.3.2"
|
||||
#define DRV_VERSION "0.3.3"
|
||||
|
||||
enum {
|
||||
HPT_PCI_FAST = (1 << 31),
|
||||
|
@ -115,14 +115,13 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed)
|
|||
}
|
||||
|
||||
/**
|
||||
* hpt3x2n_pre_reset - reset the hpt3x2n bus
|
||||
* @ap: ATA port to reset
|
||||
* hpt3x2n_cable_detect - Detect the cable type
|
||||
* @ap: ATA port to detect on
|
||||
*
|
||||
* Perform the initial reset handling for the 3x2n series controllers.
|
||||
* Reset the hardware and state machine, obtain the cable type.
|
||||
* Return the cable type attached to this port
|
||||
*/
|
||||
|
||||
static int hpt3xn_pre_reset(struct ata_port *ap)
|
||||
static int hpt3x2n_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
u8 scr2, ata66;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
@ -135,15 +134,26 @@ static int hpt3xn_pre_reset(struct ata_port *ap)
|
|||
pci_write_config_byte(pdev, 0x5B, scr2);
|
||||
|
||||
if (ata66 & (1 << ap->port_no))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt3x2n_pre_reset - reset the hpt3x2n bus
|
||||
* @ap: ATA port to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the initial reset handling for the 3x2n series controllers.
|
||||
* Reset the hardware and state machine,
|
||||
*/
|
||||
|
||||
static int hpt3xn_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
/* Reset the state machine */
|
||||
pci_write_config_byte(pdev, 0x50, 0x37);
|
||||
pci_write_config_byte(pdev, 0x54, 0x37);
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -364,6 +374,7 @@ static struct ata_port_operations hpt3x2n_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = hpt3x2n_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = hpt3x2n_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -422,8 +433,9 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
|
|||
{
|
||||
unsigned long freq;
|
||||
u32 fcnt;
|
||||
unsigned long iobase = pci_resource_start(pdev, 4);
|
||||
|
||||
pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt);
|
||||
fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */
|
||||
if ((fcnt >> 12) != 0xABCDE) {
|
||||
printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n");
|
||||
return 33; /* Not BIOS set */
|
||||
|
@ -492,6 +504,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
unsigned int pci_mhz;
|
||||
unsigned int f_low, f_high;
|
||||
int adjust;
|
||||
unsigned long iobase = pci_resource_start(dev, 4);
|
||||
|
||||
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
|
||||
class_rev &= 0xFF;
|
||||
|
@ -501,6 +514,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
if (class_rev < 6)
|
||||
return -ENODEV;
|
||||
break;
|
||||
case PCI_DEVICE_ID_TTI_HPT371:
|
||||
if (class_rev < 2)
|
||||
return -ENODEV;
|
||||
/* 371N if rev > 1 */
|
||||
break;
|
||||
case PCI_DEVICE_ID_TTI_HPT372:
|
||||
/* 372N if rev >= 1*/
|
||||
if (class_rev == 0)
|
||||
|
@ -528,6 +546,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
irqmask &= ~0x10;
|
||||
pci_write_config_byte(dev, 0x5a, irqmask);
|
||||
|
||||
/*
|
||||
* HPT371 chips physically have only one channel, the secondary one,
|
||||
* but the primary channel registers do exist! Go figure...
|
||||
* So, we manually disable the non-existing channel here
|
||||
* (if the BIOS hasn't done this already).
|
||||
*/
|
||||
if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
|
||||
u8 mcr1;
|
||||
pci_read_config_byte(dev, 0x50, &mcr1);
|
||||
mcr1 &= ~0x04;
|
||||
pci_write_config_byte(dev, 0x50, mcr1);
|
||||
}
|
||||
|
||||
/* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or
|
||||
50 for UDMA100. Right now we always use 66 */
|
||||
|
||||
|
@ -546,14 +577,24 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
break;
|
||||
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
|
||||
}
|
||||
if (adjust == 8)
|
||||
printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n");
|
||||
if (adjust == 8) {
|
||||
printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Set our private data up. We only need a few flags so we use
|
||||
it directly */
|
||||
port->private_data = NULL;
|
||||
if (pci_mhz > 60)
|
||||
if (pci_mhz > 60) {
|
||||
port->private_data = (void *)PCI66;
|
||||
/*
|
||||
* On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
|
||||
* the MISC. register to stretch the UltraDMA Tss timing.
|
||||
* NOTE: This register is only writeable via I/O space.
|
||||
*/
|
||||
if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
|
||||
outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
|
||||
}
|
||||
|
||||
/* Now kick off ATA set up */
|
||||
port_info[0] = port_info[1] = port;
|
||||
|
@ -562,6 +603,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
|
||||
static const struct pci_device_id hpt3x2n[] = {
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },
|
||||
|
|
|
@ -25,25 +25,6 @@
|
|||
#define DRV_NAME "pata_hpt3x3"
|
||||
#define DRV_VERSION "0.4.2"
|
||||
|
||||
static int hpt3x3_probe_init(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt3x3_probe_reset - reset the hpt3x3 bus
|
||||
* @ap: ATA port to reset
|
||||
*
|
||||
* Perform the housekeeping when doing an ATA bus reeset. We just
|
||||
* need to force the cable type.
|
||||
*/
|
||||
|
||||
static void hpt3x3_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, hpt3x3_probe_init, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt3x3_set_piomode - PIO setup
|
||||
* @ap: ATA interface
|
||||
|
@ -139,8 +120,9 @@ static struct ata_port_operations hpt3x3_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = hpt3x3_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -49,13 +49,13 @@ static struct ata_port_operations isapnp_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -74,8 +74,10 @@ static struct ata_port_operations isapnp_port_ops = {
|
|||
|
||||
static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
|
||||
{
|
||||
struct ata_probe_ent ae;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
void __iomem *cmd_addr, *ctl_addr;
|
||||
int rc;
|
||||
|
||||
if (pnp_port_valid(idev, 0) == 0)
|
||||
return -ENODEV;
|
||||
|
@ -84,34 +86,36 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
|
|||
if (pnp_irq_valid(idev, 0) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* allocate host */
|
||||
host = ata_host_alloc(&idev->dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
|
||||
if (!cmd_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &idev->dev;
|
||||
ae.port_ops = &isapnp_port_ops;
|
||||
ae.sht = &isapnp_sht;
|
||||
ae.n_ports = 1;
|
||||
ae.pio_mask = 1; /* ISA so PIO 0 cycles */
|
||||
ae.irq = pnp_irq(idev, 0);
|
||||
ae.irq_flags = 0;
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS;
|
||||
ae.port[0].cmd_addr = cmd_addr;
|
||||
ap = host->ports[0];
|
||||
|
||||
ap->ops = &isapnp_port_ops;
|
||||
ap->pio_mask = 1;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
|
||||
ap->ioaddr.cmd_addr = cmd_addr;
|
||||
|
||||
if (pnp_port_valid(idev, 1) == 0) {
|
||||
ctl_addr = devm_ioport_map(&idev->dev,
|
||||
pnp_port_start(idev, 1), 1);
|
||||
ae.port[0].altstatus_addr = ctl_addr;
|
||||
ae.port[0].ctl_addr = ctl_addr;
|
||||
ae.port_flags |= ATA_FLAG_SRST;
|
||||
ap->ioaddr.altstatus_addr = ctl_addr;
|
||||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
}
|
||||
ata_std_ports(&ae.port[0]);
|
||||
|
||||
if (ata_device_add(&ae) == 0)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
/* activate */
|
||||
return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0,
|
||||
&isapnp_sht);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
* it8213_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection for the 8213 ATA interface. This is
|
||||
* different to the PIIX arrangement
|
||||
* Filter out ports by the enable bits before doing the normal reset
|
||||
* and probe.
|
||||
*/
|
||||
|
||||
static int it8213_pre_reset(struct ata_port *ap)
|
||||
|
@ -34,23 +34,14 @@ static int it8213_pre_reset(struct ata_port *ap)
|
|||
static const struct pci_bits it8213_enable_bits[] = {
|
||||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
pci_read_config_byte(pdev, 0x42, &tmp);
|
||||
if (tmp & 2) /* The initial docs are incorrect */
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* it8213_probe_reset - Probe specified port on PATA host controller
|
||||
* it8213_error_handler - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
*
|
||||
* LOCKING:
|
||||
|
@ -62,10 +53,28 @@ static void it8213_error_handler(struct ata_port *ap)
|
|||
ata_bmdma_drive_eh(ap, it8213_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* it8213_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection for the 8213 ATA interface. This is
|
||||
* different to the PIIX arrangement
|
||||
*/
|
||||
|
||||
static int it8213_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
pci_read_config_byte(pdev, 0x42, &tmp);
|
||||
if (tmp & 2) /* The initial docs are incorrect */
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
* it8213_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: um
|
||||
* @adev: Device whose timings we are configuring
|
||||
*
|
||||
* Set PIO mode for device, in host controller PCI config space.
|
||||
*
|
||||
|
@ -268,6 +277,7 @@ static const struct ata_port_operations it8213_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = it8213_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = it8213_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
|
||||
|
||||
#define DRV_NAME "pata_it821x"
|
||||
#define DRV_VERSION "0.3.4"
|
||||
#define DRV_VERSION "0.3.6"
|
||||
|
||||
struct it821x_dev
|
||||
{
|
||||
|
@ -112,31 +112,6 @@ struct it821x_dev
|
|||
|
||||
static int it8212_noraid;
|
||||
|
||||
/**
|
||||
* it821x_pre_reset - probe
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set the cable type
|
||||
*/
|
||||
|
||||
static int it821x_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_error_handler - probe/reset
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set the cable type and trigger a probe
|
||||
*/
|
||||
|
||||
static void it821x_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, it821x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* it821x_program - program the PIO/MWDMA registers
|
||||
* @ap: ATA port
|
||||
|
@ -520,7 +495,6 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
|
|||
|
||||
/**
|
||||
* it821x_dev_config - Called each device identify
|
||||
* @ap: ATA port
|
||||
* @adev: Device that has just been identified
|
||||
*
|
||||
* Perform the initial setup needed for each device that is chip
|
||||
|
@ -531,7 +505,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
|
|||
* basically we need to filter commands for this chip.
|
||||
*/
|
||||
|
||||
static void it821x_dev_config(struct ata_port *ap, struct ata_device *adev)
|
||||
static void it821x_dev_config(struct ata_device *adev)
|
||||
{
|
||||
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||
|
||||
|
@ -667,8 +641,9 @@ static struct ata_port_operations it821x_smart_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = it821x_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -703,8 +678,9 @@ static struct ata_port_operations it821x_passthru_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = it821x_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = it821x_passthru_bmdma_start,
|
||||
|
|
|
@ -129,8 +129,8 @@ static struct ata_port_operations ixp4xx_port_ops = {
|
|||
.qc_issue = ata_qc_issue_prot,
|
||||
.eng_timeout = ata_eng_timeout,
|
||||
.data_xfer = ixp4xx_mmio_data_xfer,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ixp4xx_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -173,12 +173,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
|
|||
|
||||
static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
unsigned int irq;
|
||||
struct resource *cs0, *cs1;
|
||||
struct ata_probe_ent ae;
|
||||
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
struct ixp4xx_pata_data *data = pdev->dev.platform_data;
|
||||
int rc;
|
||||
|
||||
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
|
@ -186,6 +186,12 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
|
|||
if (!cs0 || !cs1)
|
||||
return -EINVAL;
|
||||
|
||||
/* allocate host */
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
|
||||
|
||||
data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
|
||||
|
@ -199,32 +205,22 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
|
|||
*data->cs0_cfg = data->cs0_bits;
|
||||
*data->cs1_cfg = data->cs1_bits;
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ap = host->ports[0];
|
||||
|
||||
ae.dev = &pdev->dev;
|
||||
ae.port_ops = &ixp4xx_port_ops;
|
||||
ae.sht = &ixp4xx_sht;
|
||||
ae.n_ports = 1;
|
||||
ae.pio_mask = 0x1f; /* PIO4 */
|
||||
ae.irq = irq;
|
||||
ae.irq_flags = 0;
|
||||
ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
|
||||
| ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
|
||||
ap->ops = &ixp4xx_port_ops;
|
||||
ap->pio_mask = 0x1f; /* PIO4 */
|
||||
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
|
||||
|
||||
/* run in polling mode if no irq has been assigned */
|
||||
if (!irq)
|
||||
ae.port_flags |= ATA_FLAG_PIO_POLLING;
|
||||
ap->flags |= ATA_FLAG_PIO_POLLING;
|
||||
|
||||
ixp4xx_setup_port(&ae.port[0], data);
|
||||
ixp4xx_setup_port(&ap->ioaddr, data);
|
||||
|
||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
ret = ata_device_add(&ae);
|
||||
if (ret == 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
/* activate host */
|
||||
return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
|
||||
}
|
||||
|
||||
static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
|
||||
|
|
|
@ -162,6 +162,7 @@ static struct ata_port_operations simple_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
@ -185,6 +186,7 @@ static struct ata_port_operations legacy_port_ops = {
|
|||
.check_status = ata_check_status,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
|
@ -305,6 +307,7 @@ static struct ata_port_operations pdc20230_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
@ -360,6 +363,7 @@ static struct ata_port_operations ht6560a_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
@ -426,6 +430,7 @@ static struct ata_port_operations ht6560b_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
@ -547,6 +552,7 @@ static struct ata_port_operations opti82c611a_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
@ -680,6 +686,7 @@ static struct ata_port_operations opti82c46x_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = opti82c46x_qc_issue_prot,
|
||||
|
@ -709,7 +716,8 @@ static struct ata_port_operations opti82c46x_port_ops = {
|
|||
static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq)
|
||||
{
|
||||
struct legacy_data *ld = &legacy_data[nr_legacy_host];
|
||||
struct ata_probe_ent ae;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
struct platform_device *pdev;
|
||||
struct ata_port_operations *ops = &legacy_port_ops;
|
||||
void __iomem *io_addr, *ctrl_addr;
|
||||
|
@ -791,24 +799,23 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
|
|||
if (ops == &legacy_port_ops && (autospeed & mask))
|
||||
ops = &simple_port_ops;
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &pdev->dev;
|
||||
ae.port_ops = ops;
|
||||
ae.sht = &legacy_sht;
|
||||
ae.n_ports = 1;
|
||||
ae.pio_mask = pio_modes;
|
||||
ae.irq = irq;
|
||||
ae.irq_flags = 0;
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy;
|
||||
ae.port[0].cmd_addr = io_addr;
|
||||
ae.port[0].altstatus_addr = ctrl_addr;
|
||||
ae.port[0].ctl_addr = ctrl_addr;
|
||||
ata_std_ports(&ae.port[0]);
|
||||
ae.private_data = ld;
|
||||
ret = -ENOMEM;
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
goto fail;
|
||||
ap = host->ports[0];
|
||||
|
||||
ret = -ENODEV;
|
||||
if (!ata_device_add(&ae))
|
||||
ap->ops = ops;
|
||||
ap->pio_mask = pio_modes;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
|
||||
ap->ioaddr.cmd_addr = io_addr;
|
||||
ap->ioaddr.altstatus_addr = ctrl_addr;
|
||||
ap->ioaddr.ctl_addr = ctrl_addr;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
ap->private_data = ld;
|
||||
|
||||
ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_marvell"
|
||||
#define DRV_VERSION "0.1.1"
|
||||
#define DRV_VERSION "0.1.4"
|
||||
|
||||
/**
|
||||
* marvell_pre_reset - check for 40/80 pin
|
||||
|
@ -52,22 +52,23 @@ static int marvell_pre_reset(struct ata_port *ap)
|
|||
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
|
||||
(!(devices & 0x10))) /* PATA enable ? */
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static int marvell_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
/* Cable type */
|
||||
switch(ap->port_no)
|
||||
{
|
||||
case 0:
|
||||
if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1)
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
break;
|
||||
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
case 1: /* Legacy SATA port */
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
break;
|
||||
return ATA_CBL_SATA;
|
||||
}
|
||||
return ata_std_prereset(ap);
|
||||
BUG();
|
||||
return 0; /* Our BUG macro needs the right markup */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,6 +124,7 @@ static const struct ata_port_operations marvell_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = marvell_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = marvell_cable_detect,
|
||||
|
||||
/* BMDMA handling is PCI ATA format, use helpers */
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
|
||||
#define DRV_NAME "mpc52xx_ata"
|
||||
#define DRV_VERSION "0.1.0"
|
||||
#define DRV_VERSION "0.1.0ac2"
|
||||
|
||||
|
||||
/* Private structures used by the driver */
|
||||
|
@ -297,38 +297,37 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
|
|||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = mpc52xx_ata_error_handler,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static struct ata_probe_ent mpc52xx_ata_probe_ent = {
|
||||
.port_ops = &mpc52xx_ata_port_ops,
|
||||
.sht = &mpc52xx_ata_sht,
|
||||
.n_ports = 1,
|
||||
.pio_mask = 0x1f, /* Up to PIO4 */
|
||||
.mwdma_mask = 0x00, /* No MWDMA */
|
||||
.udma_mask = 0x00, /* No UDMA */
|
||||
.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.irq_flags = 0,
|
||||
};
|
||||
|
||||
static int __devinit
|
||||
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
|
||||
{
|
||||
struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent;
|
||||
struct ata_ioports *aio = &ae->port[0];
|
||||
int rv;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
struct ata_ioports *aio;
|
||||
int rc;
|
||||
|
||||
INIT_LIST_HEAD(&ae->node);
|
||||
ae->dev = dev;
|
||||
ae->irq = priv->ata_irq;
|
||||
host = ata_host_alloc(dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
ap = host->ports[0];
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
ap->pio_mask = 0x1f; /* Up to PIO4 */
|
||||
ap->mwdma_mask = 0x00; /* No MWDMA */
|
||||
ap->udma_mask = 0x00; /* No UDMA */
|
||||
ap->ops = &mpc52xx_ata_port_ops;
|
||||
host->private_data = priv;
|
||||
|
||||
aio = &ap->ioaddr;
|
||||
aio->cmd_addr = NULL; /* Don't have a classic reg block */
|
||||
aio->altstatus_addr = &priv->ata_regs->tf_control;
|
||||
aio->ctl_addr = &priv->ata_regs->tf_control;
|
||||
|
@ -343,11 +342,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
|
|||
aio->status_addr = &priv->ata_regs->tf_command;
|
||||
aio->command_addr = &priv->ata_regs->tf_command;
|
||||
|
||||
ae->private_data = priv;
|
||||
|
||||
rv = ata_device_add(ae);
|
||||
|
||||
return rv ? 0 : -EINVAL;
|
||||
/* activate host */
|
||||
return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
|
||||
&mpc52xx_ata_sht);
|
||||
}
|
||||
|
||||
static struct mpc52xx_ata_priv *
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_mpiix"
|
||||
#define DRV_VERSION "0.7.5"
|
||||
#define DRV_VERSION "0.7.6"
|
||||
|
||||
enum {
|
||||
IDETIM = 0x6C, /* IDE control register */
|
||||
|
@ -53,7 +53,6 @@ static int mpiix_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
|
||||
return -ENOENT;
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -185,12 +184,12 @@ static struct ata_port_operations mpiix_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = mpiix_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = mpiix_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -201,8 +200,9 @@ static struct ata_port_operations mpiix_port_ops = {
|
|||
static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
/* Single threaded by the PCI probe logic */
|
||||
static struct ata_probe_ent probe;
|
||||
static int printed_version;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
void __iomem *cmd_addr, *ctl_addr;
|
||||
u16 idetim;
|
||||
int irq;
|
||||
|
@ -210,6 +210,10 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
host = ata_host_alloc(&dev->dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* MPIIX has many functions which can be turned on or off according
|
||||
to other devices present. Make sure IDE is enabled before we try
|
||||
and use it */
|
||||
|
@ -238,27 +242,21 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
without BARs set fools the setup. #2 If you pci_disable_device
|
||||
the MPIIX your box goes castors up */
|
||||
|
||||
INIT_LIST_HEAD(&probe.node);
|
||||
probe.dev = pci_dev_to_dev(dev);
|
||||
probe.port_ops = &mpiix_port_ops;
|
||||
probe.sht = &mpiix_sht;
|
||||
probe.pio_mask = 0x1F;
|
||||
probe.irq_flags = IRQF_SHARED;
|
||||
probe.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
|
||||
probe.n_ports = 1;
|
||||
ap = host->ports[0];
|
||||
ap->ops = &mpiix_port_ops;
|
||||
ap->pio_mask = 0x1F;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
|
||||
probe.irq = irq;
|
||||
probe.port[0].cmd_addr = cmd_addr;
|
||||
probe.port[0].ctl_addr = ctl_addr;
|
||||
probe.port[0].altstatus_addr = ctl_addr;
|
||||
ap->ioaddr.cmd_addr = cmd_addr;
|
||||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
ap->ioaddr.altstatus_addr = ctl_addr;
|
||||
|
||||
/* Let libata fill in the port details */
|
||||
ata_std_ports(&probe.port[0]);
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
/* Now add the port that is active */
|
||||
if (ata_device_add(&probe))
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
/* activate host */
|
||||
return ata_host_activate(host, irq, ata_interrupt, IRQF_SHARED,
|
||||
&mpiix_sht);
|
||||
}
|
||||
|
||||
static const struct pci_device_id mpiix[] = {
|
||||
|
|
|
@ -16,33 +16,7 @@
|
|||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_netcell"
|
||||
#define DRV_VERSION "0.1.6"
|
||||
|
||||
/**
|
||||
* netcell_probe_init - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Cables are handled by the RAID controller. Report 80 pin.
|
||||
*/
|
||||
|
||||
static int netcell_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* netcell_probe_reset - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void netcell_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, netcell_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
#define DRV_VERSION "0.1.7"
|
||||
|
||||
/* No PIO or DMA methods needed for this device */
|
||||
|
||||
|
@ -81,8 +55,9 @@ static const struct ata_port_operations netcell_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = netcell_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_80wire,
|
||||
|
||||
/* BMDMA handling is PCI ATA format, use helpers */
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_ns87410"
|
||||
#define DRV_VERSION "0.4.3"
|
||||
#define DRV_VERSION "0.4.6"
|
||||
|
||||
/**
|
||||
* ns87410_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
* Check enabled ports
|
||||
*/
|
||||
|
||||
static int ns87410_pre_reset(struct ata_port *ap)
|
||||
|
@ -47,7 +47,6 @@ static int ns87410_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -177,6 +176,7 @@ static struct ata_port_operations ns87410_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ns87410_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ns87410_qc_issue_prot,
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_oldpiix"
|
||||
#define DRV_VERSION "0.5.4"
|
||||
#define DRV_VERSION "0.5.5"
|
||||
|
||||
/**
|
||||
* oldpiix_pre_reset - probe begin
|
||||
|
@ -44,7 +44,6 @@ static int oldpiix_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -65,7 +64,7 @@ static void oldpiix_pata_error_handler(struct ata_port *ap)
|
|||
/**
|
||||
* oldpiix_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: um
|
||||
* @adev: Device whose timings we are configuring
|
||||
*
|
||||
* Set PIO mode for device, in host controller PCI config space.
|
||||
*
|
||||
|
@ -255,6 +254,7 @@ static const struct ata_port_operations oldpiix_pata_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = oldpiix_pata_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_opti"
|
||||
#define DRV_VERSION "0.2.8"
|
||||
#define DRV_VERSION "0.2.9"
|
||||
|
||||
enum {
|
||||
READ_REG = 0, /* index of Read cycle timing register */
|
||||
|
@ -61,8 +61,6 @@ static int opti_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -198,6 +196,7 @@ static struct ata_port_operations opti_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = opti_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_optidma"
|
||||
#define DRV_VERSION "0.2.4"
|
||||
#define DRV_VERSION "0.3.2"
|
||||
|
||||
enum {
|
||||
READ_REG = 0, /* index of Read cycle timing register */
|
||||
|
@ -62,7 +62,6 @@ static int optidma_pre_reset(struct ata_port *ap)
|
|||
if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
|
||||
return -ENOENT;
|
||||
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,7 @@ static void optidma_lock(struct ata_port *ap)
|
|||
}
|
||||
|
||||
/**
|
||||
* optidma_set_mode - set mode data
|
||||
* optidma_mode_setup - set mode data
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
* @mode: Mode to set
|
||||
|
@ -128,7 +127,7 @@ static void optidma_lock(struct ata_port *ap)
|
|||
* IRQ here we depend on the host set locking to avoid catastrophe.
|
||||
*/
|
||||
|
||||
static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
|
||||
static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode)
|
||||
{
|
||||
struct ata_device *pair = ata_dev_pair(adev);
|
||||
int pio = adev->pio_mode - XFER_PIO_0;
|
||||
|
@ -202,7 +201,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
|
|||
}
|
||||
|
||||
/**
|
||||
* optiplus_set_mode - DMA setup for Firestar Plus
|
||||
* optiplus_mode_setup - DMA setup for Firestar Plus
|
||||
* @ap: ATA port
|
||||
* @adev: device
|
||||
* @mode: desired mode
|
||||
|
@ -213,7 +212,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
|
|||
* one
|
||||
*/
|
||||
|
||||
static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
|
||||
static void optiplus_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 udcfg;
|
||||
|
@ -225,7 +224,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m
|
|||
pci_read_config_byte(pdev, 0x44, &udcfg);
|
||||
if (mode <= XFER_UDMA_0) {
|
||||
udcfg &= ~(1 << unit);
|
||||
optidma_set_mode(ap, adev, adev->dma_mode);
|
||||
optidma_mode_setup(ap, adev, adev->dma_mode);
|
||||
} else {
|
||||
udcfg |= (1 << unit);
|
||||
if (ap->port_no) {
|
||||
|
@ -253,7 +252,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m
|
|||
|
||||
static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
optidma_set_mode(ap, adev, adev->pio_mode);
|
||||
optidma_mode_setup(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +267,7 @@ static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
optidma_set_mode(ap, adev, adev->dma_mode);
|
||||
optidma_mode_setup(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,7 +282,7 @@ static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
optiplus_set_mode(ap, adev, adev->pio_mode);
|
||||
optiplus_mode_setup(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,7 +297,7 @@ static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
static void optiplus_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
optiplus_set_mode(ap, adev, adev->dma_mode);
|
||||
optiplus_mode_setup(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,26 +321,29 @@ static u8 optidma_make_bits43(struct ata_device *adev)
|
|||
}
|
||||
|
||||
/**
|
||||
* optidma_post_set_mode - finalize PCI setup
|
||||
* optidma_set_mode - mode setup
|
||||
* @ap: port to set up
|
||||
*
|
||||
* Finalise the configuration by writing the nibble of extra bits
|
||||
* of data into the chip.
|
||||
* Use the standard setup to tune the chipset and then finalise the
|
||||
* configuration by writing the nibble of extra bits of data into
|
||||
* the chip.
|
||||
*/
|
||||
|
||||
static void optidma_post_set_mode(struct ata_port *ap)
|
||||
static int optidma_set_mode(struct ata_port *ap, struct ata_device **r_failed)
|
||||
{
|
||||
u8 r;
|
||||
int nybble = 4 * ap->port_no;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int rc = ata_do_set_mode(ap, r_failed);
|
||||
if (rc == 0) {
|
||||
pci_read_config_byte(pdev, 0x43, &r);
|
||||
|
||||
pci_read_config_byte(pdev, 0x43, &r);
|
||||
|
||||
r &= (0x0F << nybble);
|
||||
r |= (optidma_make_bits43(&ap->device[0]) +
|
||||
(optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
|
||||
|
||||
pci_write_config_byte(pdev, 0x43, r);
|
||||
r &= (0x0F << nybble);
|
||||
r |= (optidma_make_bits43(&ap->device[0]) +
|
||||
(optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
|
||||
pci_write_config_byte(pdev, 0x43, r);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct scsi_host_template optidma_sht = {
|
||||
|
@ -381,7 +383,8 @@ static struct ata_port_operations optidma_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.error_handler = optidma_error_handler,
|
||||
.post_set_mode = optidma_post_set_mode,
|
||||
.set_mode = optidma_set_mode,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -416,7 +419,8 @@ static struct ata_port_operations optiplus_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.error_handler = optidma_error_handler,
|
||||
.post_set_mode = optidma_post_set_mode,
|
||||
.set_mode = optidma_set_mode,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
|
||||
#define DRV_NAME "pata_pcmcia"
|
||||
#define DRV_VERSION "0.3.0"
|
||||
#define DRV_VERSION "0.3.1"
|
||||
|
||||
/*
|
||||
* Private data structure to glue stuff together
|
||||
|
@ -54,6 +54,39 @@ struct ata_pcmcia_info {
|
|||
dev_node_t node;
|
||||
};
|
||||
|
||||
/**
|
||||
* pcmcia_set_mode - PCMCIA specific mode setup
|
||||
* @ap: Port
|
||||
* @r_failed_dev: Return pointer for failed device
|
||||
*
|
||||
* Perform the tuning and setup of the devices and timings, which
|
||||
* for PCMCIA is the same as any other controller. We wrap it however
|
||||
* as we need to spot hardware with incorrect or missing master/slave
|
||||
* decode, which alas is embarrassingly common in the PC world
|
||||
*/
|
||||
|
||||
static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
|
||||
{
|
||||
struct ata_device *master = &ap->device[0];
|
||||
struct ata_device *slave = &ap->device[1];
|
||||
|
||||
if (!ata_dev_enabled(master) || !ata_dev_enabled(slave))
|
||||
return ata_do_set_mode(ap, r_failed_dev);
|
||||
|
||||
if (memcmp(master->id + ATA_ID_FW_REV, slave->id + ATA_ID_FW_REV,
|
||||
ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0)
|
||||
{
|
||||
/* Suspicious match, but could be two cards from
|
||||
the same vendor - check serial */
|
||||
if (memcmp(master->id + ATA_ID_SERNO, slave->id + ATA_ID_SERNO,
|
||||
ATA_ID_SERNO_LEN) == 0 && master->id[ATA_ID_SERNO] >> 8) {
|
||||
ata_dev_printk(slave, KERN_WARNING, "is a ghost device, ignoring.\n");
|
||||
ata_dev_disable(slave);
|
||||
}
|
||||
}
|
||||
return ata_do_set_mode(ap, r_failed_dev);
|
||||
}
|
||||
|
||||
static struct scsi_host_template pcmcia_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
|
@ -73,6 +106,7 @@ static struct scsi_host_template pcmcia_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations pcmcia_port_ops = {
|
||||
.set_mode = pcmcia_set_mode,
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -84,13 +118,13 @@ static struct ata_port_operations pcmcia_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
||||
.data_xfer = ata_data_xfer_noirq,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -111,7 +145,8 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|||
|
||||
static int pcmcia_init_one(struct pcmcia_device *pdev)
|
||||
{
|
||||
struct ata_probe_ent ae;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
struct ata_pcmcia_info *info;
|
||||
tuple_t tuple;
|
||||
struct {
|
||||
|
@ -255,24 +290,24 @@ next_entry:
|
|||
* Having done the PCMCIA plumbing the ATA side is relatively
|
||||
* sane.
|
||||
*/
|
||||
ret = -ENOMEM;
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
goto failed;
|
||||
ap = host->ports[0];
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &pdev->dev;
|
||||
ae.port_ops = &pcmcia_port_ops;
|
||||
ae.sht = &pcmcia_sht;
|
||||
ae.n_ports = 1;
|
||||
ae.pio_mask = 1; /* ISA so PIO 0 cycles */
|
||||
ae.irq = pdev->irq.AssignedIRQ;
|
||||
ae.irq_flags = IRQF_SHARED;
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
|
||||
ae.port[0].cmd_addr = io_addr;
|
||||
ae.port[0].altstatus_addr = ctl_addr;
|
||||
ae.port[0].ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ae.port[0]);
|
||||
ap->ops = &pcmcia_port_ops;
|
||||
ap->pio_mask = 1; /* ISA so PIO 0 cycles */
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
ap->ioaddr.cmd_addr = io_addr;
|
||||
ap->ioaddr.altstatus_addr = ctl_addr;
|
||||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
ret = -ENODEV;
|
||||
if (ata_device_add(&ae) == 0)
|
||||
/* activate */
|
||||
ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt,
|
||||
IRQF_SHARED, &pcmcia_sht);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
info->ndev = 1;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_pdc2027x"
|
||||
#define DRV_VERSION "0.8"
|
||||
#define DRV_VERSION "0.9"
|
||||
#undef PDC_DEBUG
|
||||
|
||||
#ifdef PDC_DEBUG
|
||||
|
@ -66,8 +66,10 @@ static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *e
|
|||
static void pdc2027x_error_handler(struct ata_port *ap);
|
||||
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
|
||||
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
|
||||
static void pdc2027x_post_set_mode(struct ata_port *ap);
|
||||
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask);
|
||||
static int pdc2027x_cable_detect(struct ata_port *ap);
|
||||
static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed);
|
||||
|
||||
/*
|
||||
* ATA Timing Tables based on 133MHz controller clock.
|
||||
|
@ -146,6 +148,7 @@ static struct scsi_host_template pdc2027x_sht = {
|
|||
|
||||
static struct ata_port_operations pdc2027x_pata100_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -166,8 +169,8 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = pdc2027x_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = pdc2027x_cable_detect,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -179,7 +182,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
|
|||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pdc2027x_set_piomode,
|
||||
.set_dmamode = pdc2027x_set_dmamode,
|
||||
.post_set_mode = pdc2027x_post_set_mode,
|
||||
.set_mode = pdc2027x_set_mode,
|
||||
.mode_filter = pdc2027x_mode_filter,
|
||||
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
|
@ -200,8 +204,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = pdc2027x_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = pdc2027x_cable_detect,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -212,7 +216,6 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
|
|||
static struct ata_port_info pdc2027x_port_info[] = {
|
||||
/* PDC_UDMA_100 */
|
||||
{
|
||||
.sht = &pdc2027x_sht,
|
||||
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
|
||||
ATA_FLAG_MMIO,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
|
@ -222,7 +225,6 @@ static struct ata_port_info pdc2027x_port_info[] = {
|
|||
},
|
||||
/* PDC_UDMA_133 */
|
||||
{
|
||||
.sht = &pdc2027x_sht,
|
||||
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
|
||||
ATA_FLAG_MMIO,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
|
@ -261,7 +263,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
|
|||
}
|
||||
|
||||
/**
|
||||
* pdc2027x_pata_cbl_detect - Probe host controller cable detect info
|
||||
* pdc2027x_pata_cable_detect - Probe host controller cable detect info
|
||||
* @ap: Port for which cable detect info is desired
|
||||
*
|
||||
* Read 80c cable indicator from Promise extended register.
|
||||
|
@ -270,7 +272,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
|
|||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
static void pdc2027x_cbl_detect(struct ata_port *ap)
|
||||
static int pdc2027x_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
u32 cgcr;
|
||||
|
||||
|
@ -281,13 +283,10 @@ static void pdc2027x_cbl_detect(struct ata_port *ap)
|
|||
|
||||
PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no);
|
||||
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return;
|
||||
|
||||
return ATA_CBL_PATA80;
|
||||
cbl40:
|
||||
printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no);
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
ap->udma_mask &= ATA_UDMA_MASK_40C;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,7 +313,6 @@ static int pdc2027x_prereset(struct ata_port *ap)
|
|||
/* Check whether port enabled */
|
||||
if (!pdc2027x_port_enabled(ap))
|
||||
return -ENOENT;
|
||||
pdc2027x_cbl_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -333,6 +331,32 @@ static void pdc2027x_error_handler(struct ata_port *ap)
|
|||
ata_bmdma_drive_eh(ap, pdc2027x_prereset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc2720x_mode_filter - mode selection filter
|
||||
* @adev: ATA device
|
||||
* @mask: list of modes proposed
|
||||
*
|
||||
* Block UDMA on devices that cause trouble with this controller.
|
||||
*/
|
||||
|
||||
static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||
struct ata_device *pair = ata_dev_pair(adev);
|
||||
|
||||
if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
|
||||
/* Check for slave of a Maxtor at UDMA6 */
|
||||
ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
|
||||
ATA_ID_PROD_LEN + 1);
|
||||
/* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
|
||||
if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6)
|
||||
mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
|
||||
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc2027x_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port to configure
|
||||
|
@ -444,17 +468,22 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
}
|
||||
|
||||
/**
|
||||
* pdc2027x_post_set_mode - Set the timing registers back to correct values.
|
||||
* pdc2027x_set_mode - Set the timing registers back to correct values.
|
||||
* @ap: Port to configure
|
||||
* @r_failed: Returned device for failure
|
||||
*
|
||||
* The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
|
||||
* automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
|
||||
* This function overwrites the possibly incorrect values set by the hardware to be correct.
|
||||
*/
|
||||
static void pdc2027x_post_set_mode(struct ata_port *ap)
|
||||
static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = ata_do_set_mode(ap, r_failed);
|
||||
if (i < 0)
|
||||
return i;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
|
||||
|
@ -476,6 +505,7 @@ static void pdc2027x_post_set_mode(struct ata_port *ap)
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -521,12 +551,12 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
|
|||
|
||||
/**
|
||||
* pdc_read_counter - Read the ctr counter
|
||||
* @probe_ent: for the port address
|
||||
* @host: target ATA host
|
||||
*/
|
||||
|
||||
static long pdc_read_counter(struct ata_probe_ent *probe_ent)
|
||||
static long pdc_read_counter(struct ata_host *host)
|
||||
{
|
||||
void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
|
||||
long counter;
|
||||
int retry = 1;
|
||||
u32 bccrl, bccrh, bccrlv, bccrhv;
|
||||
|
@ -564,12 +594,12 @@ retry:
|
|||
* adjust_pll - Adjust the PLL input clock in Hz.
|
||||
*
|
||||
* @pdc_controller: controller specific information
|
||||
* @probe_ent: For the port address
|
||||
* @host: target ATA host
|
||||
* @pll_clock: The input of PLL in HZ
|
||||
*/
|
||||
static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx)
|
||||
static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int board_idx)
|
||||
{
|
||||
void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
|
||||
u16 pll_ctl;
|
||||
long pll_clock_khz = pll_clock / 1000;
|
||||
long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ;
|
||||
|
@ -649,19 +679,19 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
|
|||
|
||||
/**
|
||||
* detect_pll_input_clock - Detect the PLL input clock in Hz.
|
||||
* @probe_ent: for the port address
|
||||
* @host: target ATA host
|
||||
* Ex. 16949000 on 33MHz PCI bus for pdc20275.
|
||||
* Half of the PCI clock.
|
||||
*/
|
||||
static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
|
||||
static long pdc_detect_pll_input_clock(struct ata_host *host)
|
||||
{
|
||||
void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
|
||||
u32 scr;
|
||||
long start_count, end_count;
|
||||
long pll_clock;
|
||||
|
||||
/* Read current counter value */
|
||||
start_count = pdc_read_counter(probe_ent);
|
||||
start_count = pdc_read_counter(host);
|
||||
|
||||
/* Start the test mode */
|
||||
scr = readl(mmio_base + PDC_SYS_CTL);
|
||||
|
@ -673,7 +703,7 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
|
|||
mdelay(100);
|
||||
|
||||
/* Read the counter values again */
|
||||
end_count = pdc_read_counter(probe_ent);
|
||||
end_count = pdc_read_counter(host);
|
||||
|
||||
/* Stop the test mode */
|
||||
scr = readl(mmio_base + PDC_SYS_CTL);
|
||||
|
@ -692,11 +722,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
|
|||
|
||||
/**
|
||||
* pdc_hardware_init - Initialize the hardware.
|
||||
* @pdev: instance of pci_dev found
|
||||
* @pdc_controller: controller specific information
|
||||
* @pe: for the port address
|
||||
* @host: target ATA host
|
||||
* @board_idx: board identifier
|
||||
*/
|
||||
static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx)
|
||||
static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx)
|
||||
{
|
||||
long pll_clock;
|
||||
|
||||
|
@ -706,15 +735,15 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
|
|||
* Ex. 25MHz or 40MHz, we have to adjust the cycle_time.
|
||||
* The pdc20275 controller employs PLL circuit to help correct timing registers setting.
|
||||
*/
|
||||
pll_clock = pdc_detect_pll_input_clock(pe);
|
||||
pll_clock = pdc_detect_pll_input_clock(host);
|
||||
|
||||
if (pll_clock < 0) /* counter overflow? Try again. */
|
||||
pll_clock = pdc_detect_pll_input_clock(pe);
|
||||
pll_clock = pdc_detect_pll_input_clock(host);
|
||||
|
||||
dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
|
||||
dev_printk(KERN_INFO, host->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
|
||||
|
||||
/* Adjust PLL control register */
|
||||
pdc_adjust_pll(pe, pll_clock, board_idx);
|
||||
pdc_adjust_pll(host, pll_clock, board_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -746,8 +775,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
|
|||
* Called when an instance of PCI adapter is inserted.
|
||||
* This function checks whether the hardware is supported,
|
||||
* initialize hardware and register an instance of ata_host to
|
||||
* libata by providing struct ata_probe_ent and ata_device_add().
|
||||
* (implements struct pci_driver.probe() )
|
||||
* libata. (implements struct pci_driver.probe() )
|
||||
*
|
||||
* @pdev: instance of pci_dev found
|
||||
* @ent: matching entry in the id_tbl[]
|
||||
|
@ -756,14 +784,21 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
|
|||
{
|
||||
static int printed_version;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
|
||||
struct ata_probe_ent *probe_ent;
|
||||
const struct ata_port_info *ppi[] =
|
||||
{ &pdc2027x_port_info[board_idx], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
int rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* alloc host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -771,6 +806,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
|
|||
rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
|
@ -780,46 +816,22 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Prepare the probe entry */
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
mmio_base = host->iomap[PDC_MMIO_BAR];
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
pdc_ata_setup_port(&host->ports[0]->ioaddr, mmio_base + 0x17c0);
|
||||
host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x1000;
|
||||
pdc_ata_setup_port(&host->ports[1]->ioaddr, mmio_base + 0x15c0);
|
||||
host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x1008;
|
||||
|
||||
probe_ent->sht = pdc2027x_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = pdc2027x_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = pdc2027x_port_info[board_idx].pio_mask;
|
||||
probe_ent->mwdma_mask = pdc2027x_port_info[board_idx].mwdma_mask;
|
||||
probe_ent->udma_mask = pdc2027x_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = pdc2027x_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
|
||||
|
||||
pdc_ata_setup_port(&probe_ent->port[0], mmio_base + 0x17c0);
|
||||
probe_ent->port[0].bmdma_addr = mmio_base + 0x1000;
|
||||
pdc_ata_setup_port(&probe_ent->port[1], mmio_base + 0x15c0);
|
||||
probe_ent->port[1].bmdma_addr = mmio_base + 0x1008;
|
||||
|
||||
probe_ent->n_ports = 2;
|
||||
|
||||
pci_set_master(pdev);
|
||||
//pci_enable_intx(pdev);
|
||||
|
||||
/* initialize adapter */
|
||||
if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0)
|
||||
if (pdc_hardware_init(host, board_idx) != 0)
|
||||
return -EIO;
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&pdc2027x_sht);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,45 +22,17 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_pdc202xx_old"
|
||||
#define DRV_VERSION "0.4.0"
|
||||
#define DRV_VERSION "0.4.2"
|
||||
|
||||
/**
|
||||
* pdc2024x_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int pdc2024x_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
||||
static void pdc2024x_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, pdc2024x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
|
||||
static int pdc2026x_pre_reset(struct ata_port *ap)
|
||||
static int pdc2026x_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u16 cis;
|
||||
|
||||
pci_read_config_word(pdev, 0x50, &cis);
|
||||
if (cis & (1 << (10 + ap->port_no)))
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void pdc2026x_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, pdc2026x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
return ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,7 +216,6 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
|
|||
|
||||
/**
|
||||
* pdc2026x_dev_config - device setup hook
|
||||
* @ap: ATA port
|
||||
* @adev: newly found device
|
||||
*
|
||||
* Perform chip specific early setup. We need to lock the transfer
|
||||
|
@ -252,7 +223,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
|
|||
* barf.
|
||||
*/
|
||||
|
||||
static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev)
|
||||
static void pdc2026x_dev_config(struct ata_device *adev)
|
||||
{
|
||||
adev->max_sectors = 256;
|
||||
}
|
||||
|
@ -292,8 +263,9 @@ static struct ata_port_operations pdc2024x_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = pdc2024x_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -326,8 +298,9 @@ static struct ata_port_operations pdc2026x_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = pdc2026x_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = pdc2026x_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = pdc2026x_bmdma_start,
|
||||
|
|
|
@ -80,13 +80,13 @@ static struct ata_port_operations pata_platform_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
||||
.data_xfer = ata_data_xfer_noirq,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -135,7 +135,8 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
|
|||
static int __devinit pata_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *io_res, *ctl_res;
|
||||
struct ata_probe_ent ae;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
unsigned int mmio;
|
||||
|
||||
/*
|
||||
|
@ -175,44 +176,41 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
|
|||
/*
|
||||
* Now that that's out of the way, wire up the port..
|
||||
*/
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &pdev->dev;
|
||||
ae.port_ops = &pata_platform_port_ops;
|
||||
ae.sht = &pata_platform_sht;
|
||||
ae.n_ports = 1;
|
||||
ae.pio_mask = pio_mask;
|
||||
ae.irq = platform_get_irq(pdev, 0);
|
||||
ae.irq_flags = 0;
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
ap = host->ports[0];
|
||||
|
||||
ap->ops = &pata_platform_port_ops;
|
||||
ap->pio_mask = pio_mask;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
|
||||
/*
|
||||
* Handle the MMIO case
|
||||
*/
|
||||
if (mmio) {
|
||||
ae.port[0].cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
|
||||
ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
|
||||
io_res->end - io_res->start + 1);
|
||||
ae.port[0].ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
|
||||
ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
|
||||
ctl_res->end - ctl_res->start + 1);
|
||||
} else {
|
||||
ae.port[0].cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
|
||||
ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
|
||||
io_res->end - io_res->start + 1);
|
||||
ae.port[0].ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
|
||||
ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
|
||||
ctl_res->end - ctl_res->start + 1);
|
||||
}
|
||||
if (!ae.port[0].cmd_addr || !ae.port[0].ctl_addr) {
|
||||
if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
|
||||
dev_err(&pdev->dev, "failed to map IO/CTL base\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
|
||||
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
|
||||
|
||||
pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
|
||||
pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data);
|
||||
|
||||
if (unlikely(ata_device_add(&ae) == 0))
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
/* activate */
|
||||
return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
|
||||
0, &pata_platform_sht);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -183,13 +183,13 @@ static struct ata_port_operations qdi6500_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = qdi_qc_issue_prot,
|
||||
|
||||
.data_xfer = qdi_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -211,13 +211,13 @@ static struct ata_port_operations qdi6580_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = qdi_qc_issue_prot,
|
||||
|
||||
.data_xfer = qdi_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -238,8 +238,9 @@ static struct ata_port_operations qdi6580_port_ops = {
|
|||
|
||||
static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
|
||||
{
|
||||
struct ata_probe_ent ae;
|
||||
struct platform_device *pdev;
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
void __iomem *io_addr, *ctl_addr;
|
||||
int ret;
|
||||
|
||||
|
@ -257,34 +258,31 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
|
|||
if (!io_addr || !ctl_addr)
|
||||
goto fail;
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &pdev->dev;
|
||||
ret = -ENOMEM;
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
goto fail;
|
||||
ap = host->ports[0];
|
||||
|
||||
if (type == 6580) {
|
||||
ae.port_ops = &qdi6580_port_ops;
|
||||
ae.pio_mask = 0x1F;
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
|
||||
ap->ops = &qdi6580_port_ops;
|
||||
ap->pio_mask = 0x1F;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
} else {
|
||||
ae.port_ops = &qdi6500_port_ops;
|
||||
ae.pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
|
||||
ATA_FLAG_NO_IORDY;
|
||||
ap->ops = &qdi6500_port_ops;
|
||||
ap->pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
|
||||
ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
|
||||
}
|
||||
|
||||
ae.sht = &qdi_sht;
|
||||
ae.n_ports = 1;
|
||||
ae.irq = irq;
|
||||
ae.irq_flags = 0;
|
||||
ae.port[0].cmd_addr = io_addr;
|
||||
ae.port[0].altstatus_addr = ctl_addr;
|
||||
ae.port[0].ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ae.port[0]);
|
||||
ap->ioaddr.cmd_addr = io_addr;
|
||||
ap->ioaddr.altstatus_addr = ctl_addr;
|
||||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
/*
|
||||
* Hook in a private data structure per channel
|
||||
*/
|
||||
ae.private_data = &qdi_data[nr_qdi_host];
|
||||
ap->private_data = &qdi_data[nr_qdi_host];
|
||||
|
||||
qdi_data[nr_qdi_host].timing = port;
|
||||
qdi_data[nr_qdi_host].fast = fast;
|
||||
|
@ -292,8 +290,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
|
|||
|
||||
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
|
||||
|
||||
ret = -ENODEV;
|
||||
if (!ata_device_add(&ae))
|
||||
/* activate */
|
||||
ret = ata_host_activate(host, irq, ata_interrupt, 0, &qdi_sht);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
|
||||
|
|
|
@ -24,40 +24,12 @@
|
|||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_radisys"
|
||||
#define DRV_VERSION "0.4.1"
|
||||
|
||||
/**
|
||||
* radisys_probe_init - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int radisys_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* radisys_pata_error_handler - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
* @classes:
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void radisys_pata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, radisys_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
#define DRV_VERSION "0.4.4"
|
||||
|
||||
/**
|
||||
* radisys_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: um
|
||||
* @ap: ATA port
|
||||
* @adev: Device whose timings we are configuring
|
||||
*
|
||||
* Set PIO mode for device, in host controller PCI config space.
|
||||
*
|
||||
|
@ -248,8 +220,9 @@ static const struct ata_port_operations radisys_pata_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = radisys_pata_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_unknown,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -24,31 +24,6 @@
|
|||
#define DRV_VERSION "0.2.3"
|
||||
|
||||
|
||||
/**
|
||||
* rz1000_prereset - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generics
|
||||
*/
|
||||
|
||||
static int rz1000_prereset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* rz1000_error_handler - probe reset
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Perform the ATA standard reset sequence
|
||||
*/
|
||||
|
||||
static void rz1000_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, rz1000_prereset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* rz1000_set_mode - mode setting function
|
||||
* @ap: ATA interface
|
||||
|
@ -122,8 +97,9 @@ static struct ata_port_operations rz1000_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = rz1000_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
|
|
|
@ -216,6 +216,7 @@ static struct ata_port_operations sc1200_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -1016,7 +1016,6 @@ static const struct ata_port_operations scc_pata_ops = {
|
|||
.error_handler = scc_error_handler,
|
||||
.post_internal_cmd = scc_bmdma_stop,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = scc_bmdma_irq_clear,
|
||||
.irq_on = scc_irq_on,
|
||||
.irq_ack = scc_irq_ack,
|
||||
|
@ -1027,7 +1026,6 @@ static const struct ata_port_operations scc_pata_ops = {
|
|||
|
||||
static struct ata_port_info scc_port_info[] = {
|
||||
{
|
||||
.sht = &scc_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x00,
|
||||
|
@ -1040,10 +1038,10 @@ static struct ata_port_info scc_port_info[] = {
|
|||
* scc_reset_controller - initialize SCC PATA controller.
|
||||
*/
|
||||
|
||||
static int scc_reset_controller(struct ata_probe_ent *probe_ent)
|
||||
static int scc_reset_controller(struct ata_host *host)
|
||||
{
|
||||
void __iomem *ctrl_base = probe_ent->iomap[SCC_CTRL_BAR];
|
||||
void __iomem *bmid_base = probe_ent->iomap[SCC_BMID_BAR];
|
||||
void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR];
|
||||
void __iomem *bmid_base = host->iomap[SCC_BMID_BAR];
|
||||
void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
|
||||
void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG;
|
||||
void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE;
|
||||
|
@ -1104,17 +1102,15 @@ static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base)
|
|||
ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD;
|
||||
}
|
||||
|
||||
static int scc_host_init(struct ata_probe_ent *probe_ent)
|
||||
static int scc_host_init(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
int rc;
|
||||
|
||||
rc = scc_reset_controller(probe_ent);
|
||||
rc = scc_reset_controller(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent->n_ports = 1;
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -1122,7 +1118,7 @@ static int scc_host_init(struct ata_probe_ent *probe_ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
scc_setup_ports(&probe_ent->port[0], probe_ent->iomap[SCC_BMID_BAR]);
|
||||
scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
|
@ -1145,14 +1141,18 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
{
|
||||
static int printed_version;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL };
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
int rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev,
|
||||
"version " DRV_VERSION "\n");
|
||||
|
||||
host = ata_port_alloc_pinfo(&pdev->dev, ppi, 1);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -1162,33 +1162,14 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (!probe_ent)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = dev;
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
probe_ent->sht = scc_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = scc_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = scc_port_info[board_idx].pio_mask;
|
||||
probe_ent->udma_mask = scc_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = scc_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
rc = scc_host_init(probe_ent);
|
||||
rc = scc_host_init(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&scc_sht);
|
||||
}
|
||||
|
||||
static struct pci_driver scc_pci_driver = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* ata-serverworks.c - Serverworks PATA for new ATA layer
|
||||
* pata_serverworks.c - Serverworks PATA for new ATA layer
|
||||
* (C) 2005 Red Hat Inc
|
||||
* Alan Cox <alan@redhat.com>
|
||||
*
|
||||
|
@ -137,14 +137,14 @@ static struct sv_cable_table cable_detect[] = {
|
|||
};
|
||||
|
||||
/**
|
||||
* serverworks_pre_reset - cable detection
|
||||
* serverworks_cable_detect - cable detection
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Perform cable detection according to the device and subvendor
|
||||
* identifications
|
||||
*/
|
||||
|
||||
static int serverworks_pre_reset(struct ata_port *ap) {
|
||||
static int serverworks_cable_detect(struct ata_port *ap) {
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct sv_cable_table *cb = cable_detect;
|
||||
|
||||
|
@ -152,8 +152,7 @@ static int serverworks_pre_reset(struct ata_port *ap) {
|
|||
if (cb->device == pdev->device &&
|
||||
(cb->subvendor == pdev->subsystem_vendor ||
|
||||
cb->subvendor == PCI_ANY_ID)) {
|
||||
ap->cbl = cb->cable_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
return cb->cable_detect(ap);
|
||||
}
|
||||
cb++;
|
||||
}
|
||||
|
@ -162,11 +161,6 @@ static int serverworks_pre_reset(struct ata_port *ap) {
|
|||
return -1; /* kill compiler warning */
|
||||
}
|
||||
|
||||
static void serverworks_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, serverworks_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* serverworks_is_csb - Check for CSB or OSB
|
||||
* @pdev: PCI device to check
|
||||
|
@ -191,31 +185,31 @@ static u8 serverworks_is_csb(struct pci_dev *pdev)
|
|||
|
||||
/**
|
||||
* serverworks_osb4_filter - mode selection filter
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
* @mask: Mask of proposed modes
|
||||
*
|
||||
* Filter the offered modes for the device to apply controller
|
||||
* specific rules. OSB4 requires no UDMA for disks due to a FIFO
|
||||
* bug we hit.
|
||||
*/
|
||||
|
||||
static unsigned long serverworks_osb4_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
|
||||
static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
if (adev->class == ATA_DEV_ATA)
|
||||
mask &= ~ATA_MASK_UDMA;
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* serverworks_csb_filter - mode selection filter
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
* @mask: Mask of proposed modes
|
||||
*
|
||||
* Check the blacklist and disable UDMA5 if matched
|
||||
*/
|
||||
|
||||
static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
|
||||
static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask)
|
||||
{
|
||||
const char *p;
|
||||
char model_num[ATA_ID_PROD_LEN + 1];
|
||||
|
@ -223,7 +217,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at
|
|||
|
||||
/* Disk, UDMA */
|
||||
if (adev->class != ATA_DEV_ATA)
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
|
||||
/* Actually do need to check */
|
||||
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
|
||||
|
@ -232,7 +226,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at
|
|||
if (!strcmp(p, model_num))
|
||||
mask &= ~(0x1F << ATA_SHIFT_UDMA);
|
||||
}
|
||||
return ata_pci_default_filter(ap, adev, mask);
|
||||
return ata_pci_default_filter(adev, mask);
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,8 +333,9 @@ static struct ata_port_operations serverworks_osb4_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = serverworks_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = serverworks_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -374,8 +369,9 @@ static struct ata_port_operations serverworks_csb_port_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = serverworks_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = serverworks_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_sil680"
|
||||
#define DRV_VERSION "0.4.5"
|
||||
#define DRV_VERSION "0.4.6"
|
||||
|
||||
/**
|
||||
* sil680_selreg - return register base
|
||||
|
@ -91,12 +91,6 @@ static int sil680_cable_detect(struct ata_port *ap) {
|
|||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
static int sil680_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = sil680_cable_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* sil680_bus_reset - reset the SIL680 bus
|
||||
* @ap: ATA port to reset
|
||||
|
@ -119,7 +113,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
|
|||
|
||||
static void sil680_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, sil680_pre_reset, sil680_bus_reset, NULL, ata_std_postreset);
|
||||
ata_bmdma_drive_eh(ap, ata_std_prereset, sil680_bus_reset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,6 +251,7 @@ static struct ata_port_operations sil680_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sil680_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = sil680_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "sis.h"
|
||||
|
||||
#define DRV_NAME "pata_sis"
|
||||
#define DRV_VERSION "0.5.0"
|
||||
#define DRV_VERSION "0.5.1"
|
||||
|
||||
struct sis_chipset {
|
||||
u16 device; /* PCI host ID */
|
||||
|
@ -86,14 +86,55 @@ static int sis_port_base(struct ata_device *adev)
|
|||
}
|
||||
|
||||
/**
|
||||
* sis_133_pre_reset - check for 40/80 pin
|
||||
* sis_133_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection for the later UDMA133 capable
|
||||
* SiS chipset.
|
||||
*/
|
||||
|
||||
static int sis_133_pre_reset(struct ata_port *ap)
|
||||
static int sis_133_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u16 tmp;
|
||||
|
||||
/* The top bit of this register is the cable detect bit */
|
||||
pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp);
|
||||
if ((tmp & 0x8000) && !sis_short_ata40(pdev))
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
/**
|
||||
* sis_66_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection on the UDMA66, UDMA100 and early UDMA133
|
||||
* SiS IDE controllers.
|
||||
*/
|
||||
|
||||
static int sis_66_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
/* Older chips keep cable detect in bits 4/5 of reg 0x48 */
|
||||
pci_read_config_byte(pdev, 0x48, &tmp);
|
||||
tmp >>= ap->port_no;
|
||||
if ((tmp & 0x10) && !sis_short_ata40(pdev))
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sis_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int sis_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
static const struct pci_bits sis_enable_bits[] = {
|
||||
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
|
@ -101,21 +142,13 @@ static int sis_133_pre_reset(struct ata_port *ap)
|
|||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u16 tmp;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
/* The top bit of this register is the cable detect bit */
|
||||
pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp);
|
||||
if ((tmp & 0x8000) && !sis_short_ata40(pdev))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sis_error_handler - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
|
@ -124,97 +157,9 @@ static int sis_133_pre_reset(struct ata_port *ap)
|
|||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void sis_133_error_handler(struct ata_port *ap)
|
||||
static void sis_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, sis_133_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sis_66_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform cable detection on the UDMA66, UDMA100 and early UDMA133
|
||||
* SiS IDE controllers.
|
||||
*/
|
||||
|
||||
static int sis_66_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
static const struct pci_bits sis_enable_bits[] = {
|
||||
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
{ 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
|
||||
ata_port_disable(ap);
|
||||
ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
|
||||
return 0;
|
||||
}
|
||||
/* Older chips keep cable detect in bits 4/5 of reg 0x48 */
|
||||
pci_read_config_byte(pdev, 0x48, &tmp);
|
||||
tmp >>= ap->port_no;
|
||||
if ((tmp & 0x10) && !sis_short_ata40(pdev))
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* sis_66_error_handler - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
* @classes:
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void sis_66_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, sis_66_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* sis_old_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int sis_old_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
static const struct pci_bits sis_enable_bits[] = {
|
||||
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
{ 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
|
||||
ata_port_disable(ap);
|
||||
ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
|
||||
return 0;
|
||||
}
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sis_old_error_handler - Probe specified port on PATA host controller
|
||||
* @ap: Port to probe
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void sis_old_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, sis_old_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
ata_bmdma_drive_eh(ap, sis_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -494,7 +439,7 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
|
|||
int drive_pci = sis_port_base(adev);
|
||||
u16 timing;
|
||||
|
||||
const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
|
||||
static const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
|
||||
|
||||
pci_read_config_word(pdev, drive_pci, &timing);
|
||||
|
||||
|
@ -531,8 +476,8 @@ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev)
|
|||
u32 reg54;
|
||||
|
||||
/* bits 4- cycle time 8 - cvs time */
|
||||
const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 };
|
||||
const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 };
|
||||
static const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 };
|
||||
static const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 };
|
||||
|
||||
/* If bit 14 is set then the registers are mapped at 0x70 not 0x40 */
|
||||
pci_read_config_dword(pdev, 0x54, ®54);
|
||||
|
@ -595,8 +540,9 @@ static const struct ata_port_operations sis_133_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sis_133_error_handler,
|
||||
.error_handler = sis_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = sis_133_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -628,8 +574,9 @@ static const struct ata_port_operations sis_133_early_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sis_66_error_handler,
|
||||
.error_handler = sis_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = sis_66_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -661,9 +608,9 @@ static const struct ata_port_operations sis_100_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sis_66_error_handler,
|
||||
.error_handler = sis_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
|
||||
.cable_detect = sis_66_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -692,10 +639,11 @@ static const struct ata_port_operations sis_66_ops = {
|
|||
.check_status = ata_check_status,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
.cable_detect = sis_66_cable_detect,
|
||||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sis_66_error_handler,
|
||||
.error_handler = sis_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
|
@ -728,8 +676,9 @@ static const struct ata_port_operations sis_old_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sis_old_error_handler,
|
||||
.error_handler = sis_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -58,7 +58,6 @@ static int sl82c105_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -238,6 +237,7 @@ static struct ata_port_operations sl82c105_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = sl82c105_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = sl82c105_bmdma_start,
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_triflex"
|
||||
#define DRV_VERSION "0.2.7"
|
||||
#define DRV_VERSION "0.2.8"
|
||||
|
||||
/**
|
||||
* triflex_prereset - probe begin
|
||||
|
@ -63,7 +63,6 @@ static int triflex_prereset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -214,6 +213,7 @@ static struct ata_port_operations triflex_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = triflex_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = triflex_bmdma_start,
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_via"
|
||||
#define DRV_VERSION "0.2.1"
|
||||
#define DRV_VERSION "0.3.1"
|
||||
|
||||
/*
|
||||
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
|
||||
|
@ -135,16 +135,23 @@ static const struct via_isa_bridge {
|
|||
*/
|
||||
|
||||
static int via_cable_detect(struct ata_port *ap) {
|
||||
const struct via_isa_bridge *config = ap->host->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 ata66;
|
||||
|
||||
/* Early chips are 40 wire */
|
||||
if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
|
||||
return ATA_CBL_PATA40;
|
||||
/* UDMA 66 chips have only drive side logic */
|
||||
else if((config->flags & VIA_UDMA) < VIA_UDMA_100)
|
||||
return ATA_CBL_PATA_UNK;
|
||||
/* UDMA 100 or later */
|
||||
pci_read_config_dword(pdev, 0x50, &ata66);
|
||||
/* Check both the drive cable reporting bits, we might not have
|
||||
two drives */
|
||||
if (ata66 & (0x10100000 >> (16 * ap->port_no)))
|
||||
return ATA_CBL_PATA80;
|
||||
else
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
static int via_pre_reset(struct ata_port *ap)
|
||||
|
@ -156,22 +163,10 @@ static int via_pre_reset(struct ata_port *ap)
|
|||
{ 0x40, 1, 0x02, 0x02 },
|
||||
{ 0x40, 1, 0x01, 0x01 }
|
||||
};
|
||||
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
|
||||
ap->cbl = via_cable_detect(ap);
|
||||
/* The UDMA66 series has no cable detect so do drive side detect */
|
||||
else if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA_UNK;
|
||||
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
|
@ -327,6 +322,7 @@ static struct ata_port_operations via_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = via_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = via_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
@ -362,6 +358,7 @@ static struct ata_port_operations via_port_ops_noirq = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = via_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = via_cable_detect,
|
||||
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -36,7 +35,7 @@ static int probe_winbond = 1;
|
|||
static int probe_winbond;
|
||||
#endif
|
||||
|
||||
static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED;
|
||||
static DEFINE_SPINLOCK(winbond_lock);
|
||||
|
||||
static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
|
||||
{
|
||||
|
@ -152,13 +151,13 @@ static struct ata_port_operations winbond_port_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
||||
.data_xfer = winbond_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -179,11 +178,9 @@ static struct ata_port_operations winbond_port_ops = {
|
|||
|
||||
static __init int winbond_init_one(unsigned long port)
|
||||
{
|
||||
struct ata_probe_ent ae;
|
||||
struct platform_device *pdev;
|
||||
int ret;
|
||||
u8 reg;
|
||||
int i;
|
||||
int i, rc;
|
||||
|
||||
reg = winbond_readcfg(port, 0x81);
|
||||
reg |= 0x80; /* jumpered mode off */
|
||||
|
@ -202,58 +199,56 @@ static __init int winbond_init_one(unsigned long port)
|
|||
|
||||
for (i = 0; i < 2 ; i ++) {
|
||||
unsigned long cmd_port = 0x1F0 - (0x80 * i);
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
void __iomem *cmd_addr, *ctl_addr;
|
||||
|
||||
if (reg & (1 << i)) {
|
||||
/*
|
||||
* Fill in a probe structure first of all
|
||||
*/
|
||||
if (!(reg & (1 << i)))
|
||||
continue;
|
||||
|
||||
pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
|
||||
ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
|
||||
if (!cmd_addr || !ctl_addr) {
|
||||
platform_device_unregister(pdev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = -ENOMEM;
|
||||
host = ata_host_alloc(&pdev->dev, 1);
|
||||
if (!host)
|
||||
goto err_unregister;
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &pdev->dev;
|
||||
rc = -ENOMEM;
|
||||
cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
|
||||
ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
|
||||
if (!cmd_addr || !ctl_addr)
|
||||
goto err_unregister;
|
||||
|
||||
ae.port_ops = &winbond_port_ops;
|
||||
ae.pio_mask = 0x1F;
|
||||
ap = host->ports[0];
|
||||
ap->ops = &winbond_port_ops;
|
||||
ap->pio_mask = 0x1F;
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
ap->ioaddr.cmd_addr = cmd_addr;
|
||||
ap->ioaddr.altstatus_addr = ctl_addr;
|
||||
ap->ioaddr.ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ap->ioaddr);
|
||||
|
||||
ae.sht = &winbond_sht;
|
||||
/* hook in a private data structure per channel */
|
||||
host->private_data = &winbond_data[nr_winbond_host];
|
||||
winbond_data[nr_winbond_host].config = port;
|
||||
winbond_data[nr_winbond_host].platform_dev = pdev;
|
||||
|
||||
ae.n_ports = 1;
|
||||
ae.irq = 14 + i;
|
||||
ae.irq_flags = 0;
|
||||
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
|
||||
ae.port[0].cmd_addr = cmd_addr;
|
||||
ae.port[0].altstatus_addr = ctl_addr;
|
||||
ae.port[0].ctl_addr = ctl_addr;
|
||||
ata_std_ports(&ae.port[0]);
|
||||
/*
|
||||
* Hook in a private data structure per channel
|
||||
*/
|
||||
ae.private_data = &winbond_data[nr_winbond_host];
|
||||
winbond_data[nr_winbond_host].config = port;
|
||||
winbond_data[nr_winbond_host].platform_dev = pdev;
|
||||
/* activate */
|
||||
rc = ata_host_activate(host, 14 + i, ata_interrupt, 0,
|
||||
&winbond_sht);
|
||||
if (rc)
|
||||
goto err_unregister;
|
||||
|
||||
ret = ata_device_add(&ae);
|
||||
if (ret == 0) {
|
||||
platform_device_unregister(pdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
|
||||
}
|
||||
winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
platform_device_unregister(pdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,9 +52,9 @@
|
|||
/* macro to calculate base address for ADMA regs */
|
||||
#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
|
||||
|
||||
/* macro to obtain addresses from ata_host */
|
||||
#define ADMA_HOST_REGS(host,port_no) \
|
||||
ADMA_REGS((host)->iomap[ADMA_MMIO_BAR], port_no)
|
||||
/* macro to obtain addresses from ata_port */
|
||||
#define ADMA_PORT_REGS(ap) \
|
||||
ADMA_REGS((ap)->host->iomap[ADMA_MMIO_BAR], ap->port_no)
|
||||
|
||||
enum {
|
||||
ADMA_MMIO_BAR = 4,
|
||||
|
@ -128,7 +128,6 @@ struct adma_port_priv {
|
|||
|
||||
static int adma_ata_init_one (struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent);
|
||||
static irqreturn_t adma_intr (int irq, void *dev_instance);
|
||||
static int adma_port_start(struct ata_port *ap);
|
||||
static void adma_host_stop(struct ata_host *host);
|
||||
static void adma_port_stop(struct ata_port *ap);
|
||||
|
@ -172,7 +171,6 @@ static const struct ata_port_operations adma_ata_ops = {
|
|||
.qc_issue = adma_qc_issue,
|
||||
.eng_timeout = adma_eng_timeout,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = adma_intr,
|
||||
.irq_clear = adma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -186,7 +184,6 @@ static const struct ata_port_operations adma_ata_ops = {
|
|||
static struct ata_port_info adma_port_info[] = {
|
||||
/* board_1841_idx */
|
||||
{
|
||||
.sht = &adma_ata_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
|
||||
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
|
||||
ATA_FLAG_PIO_POLLING,
|
||||
|
@ -229,8 +226,10 @@ static void adma_irq_clear(struct ata_port *ap)
|
|||
/* nothing */
|
||||
}
|
||||
|
||||
static void adma_reset_engine(void __iomem *chan)
|
||||
static void adma_reset_engine(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *chan = ADMA_PORT_REGS(ap);
|
||||
|
||||
/* reset ADMA to idle state */
|
||||
writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
|
||||
udelay(2);
|
||||
|
@ -241,14 +240,14 @@ static void adma_reset_engine(void __iomem *chan)
|
|||
static void adma_reinit_engine(struct ata_port *ap)
|
||||
{
|
||||
struct adma_port_priv *pp = ap->private_data;
|
||||
void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
|
||||
void __iomem *chan = ADMA_PORT_REGS(ap);
|
||||
|
||||
/* mask/clear ATA interrupts */
|
||||
writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
|
||||
ata_check_status(ap);
|
||||
|
||||
/* reset the ADMA engine */
|
||||
adma_reset_engine(chan);
|
||||
adma_reset_engine(ap);
|
||||
|
||||
/* set in-FIFO threshold to 0x100 */
|
||||
writew(0x100, chan + ADMA_FIFO_IN);
|
||||
|
@ -268,7 +267,7 @@ static void adma_reinit_engine(struct ata_port *ap)
|
|||
|
||||
static inline void adma_enter_reg_mode(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
|
||||
void __iomem *chan = ADMA_PORT_REGS(ap);
|
||||
|
||||
writew(aPIOMD4, chan + ADMA_CONTROL);
|
||||
readb(chan + ADMA_STATUS); /* flush */
|
||||
|
@ -415,7 +414,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc)
|
|||
static inline void adma_packet_start(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
|
||||
void __iomem *chan = ADMA_PORT_REGS(ap);
|
||||
|
||||
VPRINTK("ENTER, ap %p\n", ap);
|
||||
|
||||
|
@ -453,7 +452,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host)
|
|||
struct ata_port *ap = host->ports[port_no];
|
||||
struct adma_port_priv *pp;
|
||||
struct ata_queued_cmd *qc;
|
||||
void __iomem *chan = ADMA_HOST_REGS(host, port_no);
|
||||
void __iomem *chan = ADMA_PORT_REGS(ap);
|
||||
u8 status = readb(chan + ADMA_STATUS);
|
||||
|
||||
if (status == 0)
|
||||
|
@ -575,7 +574,7 @@ static int adma_port_start(struct ata_port *ap)
|
|||
|
||||
static void adma_port_stop(struct ata_port *ap)
|
||||
{
|
||||
adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no));
|
||||
adma_reset_engine(ap);
|
||||
}
|
||||
|
||||
static void adma_host_stop(struct ata_host *host)
|
||||
|
@ -583,21 +582,19 @@ static void adma_host_stop(struct ata_host *host)
|
|||
unsigned int port_no;
|
||||
|
||||
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
|
||||
adma_reset_engine(ADMA_HOST_REGS(host, port_no));
|
||||
adma_reset_engine(host->ports[port_no]);
|
||||
}
|
||||
|
||||
static void adma_host_init(unsigned int chip_id,
|
||||
struct ata_probe_ent *probe_ent)
|
||||
static void adma_host_init(struct ata_host *host, unsigned int chip_id)
|
||||
{
|
||||
unsigned int port_no;
|
||||
void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR];
|
||||
|
||||
/* enable/lock aGO operation */
|
||||
writeb(7, mmio_base + ADMA_MODE_LOCK);
|
||||
writeb(7, host->iomap[ADMA_MMIO_BAR] + ADMA_MODE_LOCK);
|
||||
|
||||
/* reset the ADMA logic */
|
||||
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
|
||||
adma_reset_engine(ADMA_REGS(mmio_base, port_no));
|
||||
adma_reset_engine(host->ports[port_no]);
|
||||
}
|
||||
|
||||
static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
|
||||
|
@ -623,14 +620,21 @@ static int adma_ata_init_one(struct pci_dev *pdev,
|
|||
const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent = NULL;
|
||||
void __iomem *mmio_base;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
const struct ata_port_info *ppi[] = { &adma_port_info[board_idx], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
int rc, port_no;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* alloc host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, ADMA_PORTS);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -641,46 +645,23 @@ static int adma_ata_init_one(struct pci_dev *pdev,
|
|||
rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR];
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
mmio_base = host->iomap[ADMA_MMIO_BAR];
|
||||
|
||||
rc = adma_set_dma_masks(pdev, mmio_base);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
probe_ent->sht = adma_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = adma_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = adma_port_info[board_idx].pio_mask;
|
||||
probe_ent->mwdma_mask = adma_port_info[board_idx].mwdma_mask;
|
||||
probe_ent->udma_mask = adma_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = adma_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->n_ports = ADMA_PORTS;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
|
||||
adma_ata_setup_port(&probe_ent->port[port_no],
|
||||
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
|
||||
adma_ata_setup_port(&host->ports[port_no]->ioaddr,
|
||||
ADMA_ATA_REGS(mmio_base, port_no));
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* initialize adapter */
|
||||
adma_host_init(board_idx, probe_ent);
|
||||
adma_host_init(host, board_idx);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, adma_intr, IRQF_SHARED,
|
||||
&adma_ata_sht);
|
||||
}
|
||||
|
||||
static int __init adma_ata_init(void)
|
||||
|
|
|
@ -488,11 +488,11 @@ static void inic_error_handler(struct ata_port *ap)
|
|||
static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
|
||||
{
|
||||
/* make DMA engine forget about the failed command */
|
||||
if (qc->err_mask)
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
inic_reset_port(inic_port_base(qc->ap));
|
||||
}
|
||||
|
||||
static void inic_dev_config(struct ata_port *ap, struct ata_device *dev)
|
||||
static void inic_dev_config(struct ata_device *dev)
|
||||
{
|
||||
/* inic can only handle upto LBA28 max sectors */
|
||||
if (dev->max_sectors > ATA_MAX_SECTORS)
|
||||
|
@ -559,7 +559,6 @@ static struct ata_port_operations inic_port_ops = {
|
|||
.bmdma_stop = inic_bmdma_stop,
|
||||
.bmdma_status = inic_bmdma_status,
|
||||
|
||||
.irq_handler = inic_interrupt,
|
||||
.irq_clear = inic_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -580,7 +579,6 @@ static struct ata_port_operations inic_port_ops = {
|
|||
};
|
||||
|
||||
static struct ata_port_info inic_port_info = {
|
||||
.sht = &inic_sht,
|
||||
/* For some reason, ATA_PROT_ATAPI is broken on this
|
||||
* controller, and no, PIO_POLLING does't fix it. It somehow
|
||||
* manages to report the wrong ireason and ignoring ireason
|
||||
|
@ -642,7 +640,9 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
|
|||
void __iomem *mmio_base = host->iomap[MMIO_BAR];
|
||||
int rc;
|
||||
|
||||
ata_pci_device_do_resume(pdev);
|
||||
rc = ata_pci_device_do_resume(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
|
||||
rc = init_controller(mmio_base, hpriv->cached_hctl);
|
||||
|
@ -659,8 +659,8 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
|
|||
static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_port_info *pinfo = &inic_port_info;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
const struct ata_port_info *ppi[] = { &inic_port_info, NULL };
|
||||
struct ata_host *host;
|
||||
struct inic_host_priv *hpriv;
|
||||
void __iomem * const *iomap;
|
||||
int i, rc;
|
||||
|
@ -668,6 +668,15 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* alloc host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!host || !hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
host->private_data = hpriv;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -675,7 +684,22 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
iomap = pcim_iomap_table(pdev);
|
||||
host->iomap = iomap = pcim_iomap_table(pdev);
|
||||
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
struct ata_ioports *port = &host->ports[i]->ioaddr;
|
||||
void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
|
||||
|
||||
port->cmd_addr = iomap[2 * i];
|
||||
port->altstatus_addr =
|
||||
port->ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
|
||||
port->scr_addr = port_base + PORT_SCR;
|
||||
|
||||
ata_std_ports(port);
|
||||
}
|
||||
|
||||
hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
|
||||
|
||||
/* Set dma_mask. This devices doesn't support 64bit addressing. */
|
||||
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
||||
|
@ -692,43 +716,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return rc;
|
||||
}
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!probe_ent || !hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = &pdev->dev;
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
probe_ent->sht = pinfo->sht;
|
||||
probe_ent->port_flags = pinfo->flags;
|
||||
probe_ent->pio_mask = pinfo->pio_mask;
|
||||
probe_ent->mwdma_mask = pinfo->mwdma_mask;
|
||||
probe_ent->udma_mask = pinfo->udma_mask;
|
||||
probe_ent->port_ops = pinfo->port_ops;
|
||||
probe_ent->n_ports = NR_PORTS;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
|
||||
probe_ent->iomap = iomap;
|
||||
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
struct ata_ioports *port = &probe_ent->port[i];
|
||||
void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
|
||||
|
||||
port->cmd_addr = iomap[2 * i];
|
||||
port->altstatus_addr =
|
||||
port->ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
|
||||
port->scr_addr = port_base + PORT_SCR;
|
||||
|
||||
ata_std_ports(port);
|
||||
}
|
||||
|
||||
probe_ent->private_data = hpriv;
|
||||
hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
|
||||
|
||||
rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
|
@ -737,13 +724,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, inic_interrupt, IRQF_SHARED,
|
||||
&inic_sht);
|
||||
}
|
||||
|
||||
static const struct pci_device_id inic_pci_tbl[] = {
|
||||
|
|
|
@ -253,10 +253,7 @@ enum {
|
|||
#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
|
||||
|
||||
enum {
|
||||
/* Our DMA boundary is determined by an ePRD being unable to handle
|
||||
* anything larger than 64KB
|
||||
*/
|
||||
MV_DMA_BOUNDARY = 0xffffU,
|
||||
MV_DMA_BOUNDARY = 0xffffffffU,
|
||||
|
||||
EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
|
||||
|
||||
|
@ -350,7 +347,6 @@ static void mv_port_stop(struct ata_port *ap);
|
|||
static void mv_qc_prep(struct ata_queued_cmd *qc);
|
||||
static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
|
||||
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
|
||||
static irqreturn_t mv_interrupt(int irq, void *dev_instance);
|
||||
static void mv_eng_timeout(struct ata_port *ap);
|
||||
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
|
||||
|
@ -384,10 +380,10 @@ static struct scsi_host_template mv_sht = {
|
|||
.queuecommand = ata_scsi_queuecmd,
|
||||
.can_queue = MV_USE_Q_DEPTH,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = MV_MAX_SG_CT / 2,
|
||||
.sg_tablesize = MV_MAX_SG_CT,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
.use_clustering = 1,
|
||||
.proc_name = DRV_NAME,
|
||||
.dma_boundary = MV_DMA_BOUNDARY,
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
|
@ -405,6 +401,7 @@ static const struct ata_port_operations mv5_ops = {
|
|||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.phy_reset = mv_phy_reset,
|
||||
.cable_detect = ata_cable_sata,
|
||||
|
||||
.qc_prep = mv_qc_prep,
|
||||
.qc_issue = mv_qc_issue,
|
||||
|
@ -412,7 +409,6 @@ static const struct ata_port_operations mv5_ops = {
|
|||
|
||||
.eng_timeout = mv_eng_timeout,
|
||||
|
||||
.irq_handler = mv_interrupt,
|
||||
.irq_clear = mv_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -434,6 +430,7 @@ static const struct ata_port_operations mv6_ops = {
|
|||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.phy_reset = mv_phy_reset,
|
||||
.cable_detect = ata_cable_sata,
|
||||
|
||||
.qc_prep = mv_qc_prep,
|
||||
.qc_issue = mv_qc_issue,
|
||||
|
@ -441,7 +438,6 @@ static const struct ata_port_operations mv6_ops = {
|
|||
|
||||
.eng_timeout = mv_eng_timeout,
|
||||
|
||||
.irq_handler = mv_interrupt,
|
||||
.irq_clear = mv_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -463,6 +459,7 @@ static const struct ata_port_operations mv_iie_ops = {
|
|||
.dev_select = ata_std_dev_select,
|
||||
|
||||
.phy_reset = mv_phy_reset,
|
||||
.cable_detect = ata_cable_sata,
|
||||
|
||||
.qc_prep = mv_qc_prep_iie,
|
||||
.qc_issue = mv_qc_issue,
|
||||
|
@ -470,7 +467,6 @@ static const struct ata_port_operations mv_iie_ops = {
|
|||
|
||||
.eng_timeout = mv_eng_timeout,
|
||||
|
||||
.irq_handler = mv_interrupt,
|
||||
.irq_clear = mv_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -484,35 +480,30 @@ static const struct ata_port_operations mv_iie_ops = {
|
|||
|
||||
static const struct ata_port_info mv_port_info[] = {
|
||||
{ /* chip_504x */
|
||||
.sht = &mv_sht,
|
||||
.flags = MV_COMMON_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &mv5_ops,
|
||||
},
|
||||
{ /* chip_508x */
|
||||
.sht = &mv_sht,
|
||||
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &mv5_ops,
|
||||
},
|
||||
{ /* chip_5080 */
|
||||
.sht = &mv_sht,
|
||||
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &mv5_ops,
|
||||
},
|
||||
{ /* chip_604x */
|
||||
.sht = &mv_sht,
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &mv6_ops,
|
||||
},
|
||||
{ /* chip_608x */
|
||||
.sht = &mv_sht,
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
|
||||
MV_FLAG_DUAL_HC),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
|
@ -520,14 +511,12 @@ static const struct ata_port_info mv_port_info[] = {
|
|||
.port_ops = &mv6_ops,
|
||||
},
|
||||
{ /* chip_6042 */
|
||||
.sht = &mv_sht,
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &mv_iie_ops,
|
||||
},
|
||||
{ /* chip_7042 */
|
||||
.sht = &mv_sht,
|
||||
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
|
@ -551,6 +540,9 @@ static const struct pci_device_id mv_pci_tbl[] = {
|
|||
|
||||
{ PCI_VDEVICE(TTI, 0x2310), chip_7042 },
|
||||
|
||||
/* add Marvell 7042 support */
|
||||
{ PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
|
@ -585,6 +577,39 @@ static const struct mv_hw_ops mv6xxx_ops = {
|
|||
static int msi; /* Use PCI msi; either zero (off, default) or non-zero */
|
||||
|
||||
|
||||
/* move to PCI layer or libata core? */
|
||||
static int pci_go_64(struct pci_dev *pdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
|
||||
rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
|
||||
if (rc) {
|
||||
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"64-bit DMA enable failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"32-bit DMA enable failed\n");
|
||||
return rc;
|
||||
}
|
||||
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"32-bit consistent DMA enable failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
@ -798,20 +823,18 @@ static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
|
|||
{
|
||||
unsigned int ofs = mv_scr_offset(sc_reg_in);
|
||||
|
||||
if (0xffffffffU != ofs) {
|
||||
if (0xffffffffU != ofs)
|
||||
return readl(mv_ap_base(ap) + ofs);
|
||||
} else {
|
||||
else
|
||||
return (u32) ofs;
|
||||
}
|
||||
}
|
||||
|
||||
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
|
||||
{
|
||||
unsigned int ofs = mv_scr_offset(sc_reg_in);
|
||||
|
||||
if (0xffffffffU != ofs) {
|
||||
if (0xffffffffU != ofs)
|
||||
writelfl(val, mv_ap_base(ap) + ofs);
|
||||
}
|
||||
}
|
||||
|
||||
static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
|
||||
|
@ -959,38 +982,30 @@ static void mv_port_stop(struct ata_port *ap)
|
|||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static void mv_fill_sg(struct ata_queued_cmd *qc)
|
||||
static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct mv_port_priv *pp = qc->ap->private_data;
|
||||
unsigned int i = 0;
|
||||
unsigned int n_sg = 0;
|
||||
struct scatterlist *sg;
|
||||
struct mv_sg *mv_sg;
|
||||
|
||||
mv_sg = pp->sg_tbl;
|
||||
ata_for_each_sg(sg, qc) {
|
||||
dma_addr_t addr;
|
||||
u32 sg_len, len, offset;
|
||||
dma_addr_t addr = sg_dma_address(sg);
|
||||
u32 sg_len = sg_dma_len(sg);
|
||||
|
||||
addr = sg_dma_address(sg);
|
||||
sg_len = sg_dma_len(sg);
|
||||
mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
|
||||
mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
|
||||
mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff);
|
||||
|
||||
while (sg_len) {
|
||||
offset = addr & MV_DMA_BOUNDARY;
|
||||
len = sg_len;
|
||||
if ((offset + sg_len) > 0x10000)
|
||||
len = 0x10000 - offset;
|
||||
if (ata_sg_is_last(sg, qc))
|
||||
mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
|
||||
|
||||
pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
|
||||
pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
|
||||
pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff);
|
||||
|
||||
sg_len -= len;
|
||||
addr += len;
|
||||
|
||||
if (!sg_len && ata_sg_is_last(sg, qc))
|
||||
pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
|
||||
|
||||
i++;
|
||||
}
|
||||
mv_sg++;
|
||||
n_sg++;
|
||||
}
|
||||
|
||||
return n_sg;
|
||||
}
|
||||
|
||||
static inline unsigned mv_inc_q_index(unsigned index)
|
||||
|
@ -1320,17 +1335,15 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
|
|||
int shift, port, port0, hard_port, handled;
|
||||
unsigned int err_mask;
|
||||
|
||||
if (hc == 0) {
|
||||
if (hc == 0)
|
||||
port0 = 0;
|
||||
} else {
|
||||
else
|
||||
port0 = MV_PORTS_PER_HC;
|
||||
}
|
||||
|
||||
/* we'll need the HC success int register in most cases */
|
||||
hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
|
||||
if (hc_irq_cause) {
|
||||
if (hc_irq_cause)
|
||||
writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
|
||||
}
|
||||
|
||||
VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
|
||||
hc,relevant,hc_irq_cause);
|
||||
|
@ -1425,9 +1438,8 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
|
|||
/* check the cases where we either have nothing pending or have read
|
||||
* a bogus register value which can indicate HW removal or PCI fault
|
||||
*/
|
||||
if (!irq_stat || (0xffffffffU == irq_stat)) {
|
||||
if (!irq_stat || (0xffffffffU == irq_stat))
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
n_hcs = mv_get_hc_count(host->ports[0]->flags);
|
||||
spin_lock(&host->lock);
|
||||
|
@ -1952,7 +1964,6 @@ comreset_retry:
|
|||
ata_port_disable(ap);
|
||||
return;
|
||||
}
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
|
||||
/* even after SStatus reflects that device is ready,
|
||||
* it seems to take a while for link to be fully
|
||||
|
@ -2077,9 +2088,10 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
|
|||
readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
|
||||
}
|
||||
|
||||
static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
|
||||
unsigned int board_idx)
|
||||
static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
struct mv_host_priv *hpriv = host->private_data;
|
||||
u8 rev_id;
|
||||
u32 hp_flags = hpriv->hp_flags;
|
||||
|
||||
|
@ -2177,8 +2189,8 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
|
|||
|
||||
/**
|
||||
* mv_init_host - Perform some early initialization of the host.
|
||||
* @pdev: host PCI device
|
||||
* @probe_ent: early data struct representing the host
|
||||
* @host: ATA host to initialize
|
||||
* @board_idx: controller index
|
||||
*
|
||||
* If possible, do an early global reset of the host. Then do
|
||||
* our port init and clear/unmask all/relevant host interrupts.
|
||||
|
@ -2186,24 +2198,23 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
|
|||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
|
||||
unsigned int board_idx)
|
||||
static int mv_init_host(struct ata_host *host, unsigned int board_idx)
|
||||
{
|
||||
int rc = 0, n_hc, port, hc;
|
||||
void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR];
|
||||
struct mv_host_priv *hpriv = probe_ent->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
|
||||
struct mv_host_priv *hpriv = host->private_data;
|
||||
|
||||
/* global interrupt mask */
|
||||
writel(0, mmio + HC_MAIN_IRQ_MASK_OFS);
|
||||
|
||||
rc = mv_chip_id(pdev, hpriv, board_idx);
|
||||
rc = mv_chip_id(host, board_idx);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
n_hc = mv_get_hc_count(probe_ent->port_flags);
|
||||
probe_ent->n_ports = MV_PORTS_PER_HC * n_hc;
|
||||
n_hc = mv_get_hc_count(host->ports[0]->flags);
|
||||
|
||||
for (port = 0; port < probe_ent->n_ports; port++)
|
||||
for (port = 0; port < host->n_ports; port++)
|
||||
hpriv->ops->read_preamp(hpriv, port, mmio);
|
||||
|
||||
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
|
||||
|
@ -2214,7 +2225,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
|
|||
hpriv->ops->reset_bus(pdev, mmio);
|
||||
hpriv->ops->enable_leds(hpriv, mmio);
|
||||
|
||||
for (port = 0; port < probe_ent->n_ports; port++) {
|
||||
for (port = 0; port < host->n_ports; port++) {
|
||||
if (IS_60XX(hpriv)) {
|
||||
void __iomem *port_mmio = mv_port_base(mmio, port);
|
||||
|
||||
|
@ -2227,9 +2238,9 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
|
|||
hpriv->ops->phy_errata(hpriv, mmio, port);
|
||||
}
|
||||
|
||||
for (port = 0; port < probe_ent->n_ports; port++) {
|
||||
for (port = 0; port < host->n_ports; port++) {
|
||||
void __iomem *port_mmio = mv_port_base(mmio, port);
|
||||
mv_port_init(&probe_ent->port[port], port_mmio);
|
||||
mv_port_init(&host->ports[port]->ioaddr, port_mmio);
|
||||
}
|
||||
|
||||
for (hc = 0; hc < n_hc; hc++) {
|
||||
|
@ -2268,17 +2279,17 @@ done:
|
|||
|
||||
/**
|
||||
* mv_print_info - Dump key info to kernel log for perusal.
|
||||
* @probe_ent: early data struct representing the host
|
||||
* @host: ATA host to print info about
|
||||
*
|
||||
* FIXME: complete this.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
static void mv_print_info(struct ata_probe_ent *probe_ent)
|
||||
static void mv_print_info(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
|
||||
struct mv_host_priv *hpriv = probe_ent->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
struct mv_host_priv *hpriv = host->private_data;
|
||||
u8 rev_id, scc;
|
||||
const char *scc_s;
|
||||
|
||||
|
@ -2297,7 +2308,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
|
|||
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"%u slots %u ports %s mode IRQ via %s\n",
|
||||
(unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
|
||||
(unsigned)MV_MAX_Q_DEPTH, host->n_ports,
|
||||
scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
|
||||
}
|
||||
|
||||
|
@ -2312,50 +2323,42 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
|
|||
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version = 0;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct mv_host_priv *hpriv;
|
||||
unsigned int board_idx = (unsigned int)ent->driver_data;
|
||||
int rc;
|
||||
const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
|
||||
struct ata_host *host;
|
||||
struct mv_host_priv *hpriv;
|
||||
int n_ports, rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* allocate host */
|
||||
n_ports = mv_get_hc_count(ppi[0]->flags) * MV_PORTS_PER_HC;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!host || !hpriv)
|
||||
return -ENOMEM;
|
||||
host->private_data = hpriv;
|
||||
|
||||
/* acquire resources */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
pci_set_master(pdev);
|
||||
|
||||
rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME);
|
||||
if (rc == -EBUSY)
|
||||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->sht = mv_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = mv_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = mv_port_info[board_idx].pio_mask;
|
||||
probe_ent->udma_mask = mv_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = mv_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
probe_ent->private_data = hpriv;
|
||||
rc = pci_go_64(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* initialize adapter */
|
||||
rc = mv_init_host(pdev, probe_ent, board_idx);
|
||||
rc = mv_init_host(host, board_idx);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -2364,13 +2367,11 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pci_intx(pdev, 1);
|
||||
|
||||
mv_dump_pci_cfg(pdev, 0x68);
|
||||
mv_print_info(probe_ent);
|
||||
mv_print_info(host);
|
||||
|
||||
if (ata_device_add(probe_ent) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
|
||||
&mv_sht);
|
||||
}
|
||||
|
||||
static int __init mv_init(void)
|
||||
|
|
|
@ -260,6 +260,7 @@ static int nv_adma_port_resume(struct ata_port *ap);
|
|||
static void nv_adma_error_handler(struct ata_port *ap);
|
||||
static void nv_adma_host_stop(struct ata_host *host);
|
||||
static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
|
||||
static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
|
||||
|
||||
enum nv_host_type
|
||||
{
|
||||
|
@ -368,7 +369,6 @@ static const struct ata_port_operations nv_generic_ops = {
|
|||
.error_handler = nv_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = nv_generic_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -395,7 +395,6 @@ static const struct ata_port_operations nv_nf2_ops = {
|
|||
.error_handler = nv_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = nv_nf2_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -422,7 +421,6 @@ static const struct ata_port_operations nv_ck804_ops = {
|
|||
.error_handler = nv_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = nv_ck804_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -435,7 +433,7 @@ static const struct ata_port_operations nv_ck804_ops = {
|
|||
static const struct ata_port_operations nv_adma_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.tf_read = nv_adma_tf_read,
|
||||
.check_atapi_dma = nv_adma_check_atapi_dma,
|
||||
.exec_command = ata_exec_command,
|
||||
.check_status = ata_check_status,
|
||||
|
@ -451,7 +449,6 @@ static const struct ata_port_operations nv_adma_ops = {
|
|||
.error_handler = nv_adma_error_handler,
|
||||
.post_internal_cmd = nv_adma_post_internal_cmd,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = nv_adma_interrupt,
|
||||
.irq_clear = nv_adma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -476,6 +473,7 @@ static struct ata_port_info nv_port_info[] = {
|
|||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
.port_ops = &nv_generic_ops,
|
||||
.irq_handler = nv_generic_interrupt,
|
||||
},
|
||||
/* nforce2/3 */
|
||||
{
|
||||
|
@ -486,6 +484,7 @@ static struct ata_port_info nv_port_info[] = {
|
|||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
.port_ops = &nv_nf2_ops,
|
||||
.irq_handler = nv_nf2_interrupt,
|
||||
},
|
||||
/* ck804 */
|
||||
{
|
||||
|
@ -496,6 +495,7 @@ static struct ata_port_info nv_port_info[] = {
|
|||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
.port_ops = &nv_ck804_ops,
|
||||
.irq_handler = nv_ck804_interrupt,
|
||||
},
|
||||
/* ADMA */
|
||||
{
|
||||
|
@ -507,6 +507,7 @@ static struct ata_port_info nv_port_info[] = {
|
|||
.mwdma_mask = NV_MWDMA_MASK,
|
||||
.udma_mask = NV_UDMA_MASK,
|
||||
.port_ops = &nv_adma_ops,
|
||||
.irq_handler = nv_adma_interrupt,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -667,6 +668,18 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
|
|||
return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
|
||||
}
|
||||
|
||||
static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
||||
{
|
||||
/* Since commands where a result TF is requested are not
|
||||
executed in ADMA mode, the only time this function will be called
|
||||
in ADMA mode will be if a command fails. In this case we
|
||||
don't care about going into register mode with ADMA commands
|
||||
pending, as the commands will all shortly be aborted anyway. */
|
||||
nv_adma_register_mode(ap);
|
||||
|
||||
ata_tf_read(ap, tf);
|
||||
}
|
||||
|
||||
static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
|
||||
{
|
||||
unsigned int idx = 0;
|
||||
|
@ -738,19 +751,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (flags & NV_CPB_RESP_DONE) {
|
||||
if (likely(flags & NV_CPB_RESP_DONE)) {
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
|
||||
VPRINTK("CPB flags done, flags=0x%x\n", flags);
|
||||
if (likely(qc)) {
|
||||
/* Grab the ATA port status for non-NCQ commands.
|
||||
For NCQ commands the current status may have nothing to do with
|
||||
the command just completed. */
|
||||
if (qc->tf.protocol != ATA_PROT_NCQ) {
|
||||
u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
|
||||
qc->err_mask |= ac_err_mask(ata_status);
|
||||
}
|
||||
DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
|
||||
qc->err_mask);
|
||||
DPRINTK("Completing qc from tag %d\n",cpb_num);
|
||||
ata_qc_complete(qc);
|
||||
} else {
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
|
@ -1074,14 +1079,14 @@ static int nv_adma_port_resume(struct ata_port *ap)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
|
||||
static void nv_adma_setup_port(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = probe_ent->iomap[NV_MMIO_BAR];
|
||||
struct ata_ioports *ioport = &probe_ent->port[port];
|
||||
void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR];
|
||||
struct ata_ioports *ioport = &ap->ioaddr;
|
||||
|
||||
VPRINTK("ENTER\n");
|
||||
|
||||
mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
|
||||
mmio += NV_ADMA_PORT + ap->port_no * NV_ADMA_PORT_SIZE;
|
||||
|
||||
ioport->cmd_addr = mmio;
|
||||
ioport->data_addr = mmio + (ATA_REG_DATA * 4);
|
||||
|
@ -1098,9 +1103,9 @@ static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int por
|
|||
ioport->ctl_addr = mmio + 0x20;
|
||||
}
|
||||
|
||||
static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
|
||||
static int nv_adma_host_init(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
unsigned int i;
|
||||
u32 tmp32;
|
||||
|
||||
|
@ -1115,8 +1120,8 @@ static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
|
|||
|
||||
pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
|
||||
|
||||
for (i = 0; i < probe_ent->n_ports; i++)
|
||||
nv_adma_setup_port(probe_ent, i);
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
nv_adma_setup_port(host->ports[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1167,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
|
|||
struct nv_adma_port_priv *pp = qc->ap->private_data;
|
||||
|
||||
/* ADMA engine can only be used for non-ATAPI DMA commands,
|
||||
or interrupt-driven no-data commands. */
|
||||
or interrupt-driven no-data commands, where a result taskfile
|
||||
is not required. */
|
||||
if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
|
||||
(qc->tf.flags & ATA_TFLAG_POLLING))
|
||||
(qc->tf.flags & ATA_TFLAG_POLLING) ||
|
||||
(qc->flags & ATA_QCFLAG_RESULT_TF))
|
||||
return 1;
|
||||
|
||||
if((qc->flags & ATA_QCFLAG_DMAMAP) ||
|
||||
|
@ -1473,14 +1480,13 @@ static void nv_adma_error_handler(struct ata_port *ap)
|
|||
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version = 0;
|
||||
struct ata_port_info *ppi[2];
|
||||
struct ata_probe_ent *probe_ent;
|
||||
const struct ata_port_info *ppi[2];
|
||||
struct ata_host *host;
|
||||
struct nv_host_priv *hpriv;
|
||||
int rc;
|
||||
u32 bar;
|
||||
void __iomem *base;
|
||||
unsigned long type = ent->driver_data;
|
||||
int mask_set = 0;
|
||||
|
||||
// Make sure this is a SATA controller by counting the number of bars
|
||||
// (NVIDIA SATA controllers will always have six bars). Otherwise,
|
||||
|
@ -1496,50 +1502,38 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = pci_request_regions(pdev, DRV_NAME);
|
||||
if (rc) {
|
||||
pcim_pin_device(pdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if(type >= CK804 && adma_enabled) {
|
||||
/* determine type and allocate host */
|
||||
if (type >= CK804 && adma_enabled) {
|
||||
dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
|
||||
type = ADMA;
|
||||
if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
|
||||
!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
|
||||
mask_set = 1;
|
||||
}
|
||||
|
||||
if(!mask_set) {
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = -ENOMEM;
|
||||
ppi[0] = ppi[1] = &nv_port_info[type];
|
||||
rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
ppi[0] = ppi[1] = &nv_port_info[type];
|
||||
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
if (!probe_ent)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!pcim_iomap(pdev, NV_MMIO_BAR, 0))
|
||||
return -EIO;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
probe_ent->private_data = hpriv;
|
||||
hpriv->type = type;
|
||||
host->private_data = hpriv;
|
||||
|
||||
base = probe_ent->iomap[NV_MMIO_BAR];
|
||||
probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
|
||||
probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
|
||||
/* set 64bit dma masks, may fail */
|
||||
if (type == ADMA) {
|
||||
if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0)
|
||||
pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
|
||||
}
|
||||
|
||||
/* request and iomap NV_MMIO_BAR */
|
||||
rc = pcim_iomap_regions(pdev, 1 << NV_MMIO_BAR, DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* configure SCR access */
|
||||
base = host->iomap[NV_MMIO_BAR];
|
||||
host->ports[0]->ioaddr.scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
|
||||
host->ports[1]->ioaddr.scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
|
||||
|
||||
/* enable SATA space for CK804 */
|
||||
if (type >= CK804) {
|
||||
|
@ -1550,20 +1544,16 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* init ADMA */
|
||||
if (type == ADMA) {
|
||||
rc = nv_adma_host_init(probe_ent);
|
||||
rc = nv_adma_host_init(host);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ata_device_add(probe_ent);
|
||||
if (rc != NV_PORTS)
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, ppi[0]->irq_handler,
|
||||
IRQF_SHARED, ppi[0]->sht);
|
||||
}
|
||||
|
||||
static void nv_remove_one (struct pci_dev *pdev)
|
||||
|
|
|
@ -45,10 +45,11 @@
|
|||
#include "sata_promise.h"
|
||||
|
||||
#define DRV_NAME "sata_promise"
|
||||
#define DRV_VERSION "2.00"
|
||||
#define DRV_VERSION "2.05"
|
||||
|
||||
|
||||
enum {
|
||||
PDC_MAX_PORTS = 4,
|
||||
PDC_MMIO_BAR = 3,
|
||||
|
||||
/* register offsets */
|
||||
|
@ -70,14 +71,31 @@ enum {
|
|||
PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */
|
||||
PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */
|
||||
|
||||
PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
|
||||
(1<<8) | (1<<9) | (1<<10),
|
||||
/* PDC_GLOBAL_CTL bit definitions */
|
||||
PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */
|
||||
PDC_SH_ERR = (1 << 9), /* PCI error while loading S/G table */
|
||||
PDC_DH_ERR = (1 << 10), /* PCI error while loading data */
|
||||
PDC2_HTO_ERR = (1 << 12), /* host bus timeout */
|
||||
PDC2_ATA_HBA_ERR = (1 << 13), /* error during SATA DATA FIS transmission */
|
||||
PDC2_ATA_DMA_CNT_ERR = (1 << 14), /* DMA DATA FIS size differs from S/G count */
|
||||
PDC_OVERRUN_ERR = (1 << 19), /* S/G byte count larger than HD requires */
|
||||
PDC_UNDERRUN_ERR = (1 << 20), /* S/G byte count less than HD requires */
|
||||
PDC_DRIVE_ERR = (1 << 21), /* drive error */
|
||||
PDC_PCI_SYS_ERR = (1 << 22), /* PCI system error */
|
||||
PDC1_PCI_PARITY_ERR = (1 << 23), /* PCI parity error (from SATA150 driver) */
|
||||
PDC1_ERR_MASK = PDC1_PCI_PARITY_ERR,
|
||||
PDC2_ERR_MASK = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR,
|
||||
PDC_ERR_MASK = (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC_OVERRUN_ERR
|
||||
| PDC_UNDERRUN_ERR | PDC_DRIVE_ERR | PDC_PCI_SYS_ERR
|
||||
| PDC1_ERR_MASK | PDC2_ERR_MASK),
|
||||
|
||||
board_2037x = 0, /* FastTrak S150 TX2plus */
|
||||
board_20319 = 1, /* FastTrak S150 TX4 */
|
||||
board_20619 = 2, /* FastTrak TX4000 */
|
||||
board_2057x = 3, /* SATAII150 Tx2plus */
|
||||
board_40518 = 4, /* SATAII150 Tx4 */
|
||||
board_2037x_pata = 1, /* FastTrak S150 TX2plus PATA port */
|
||||
board_20319 = 2, /* FastTrak S150 TX4 */
|
||||
board_20619 = 3, /* FastTrak TX4000 */
|
||||
board_2057x = 4, /* SATAII150 Tx2plus */
|
||||
board_2057x_pata = 5, /* SATAII150 Tx2plus */
|
||||
board_40518 = 6, /* SATAII150 Tx4 */
|
||||
|
||||
PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */
|
||||
|
||||
|
@ -100,8 +118,10 @@ enum {
|
|||
ATA_FLAG_MMIO |
|
||||
ATA_FLAG_PIO_POLLING,
|
||||
|
||||
/* hp->flags bits */
|
||||
PDC_FLAG_GEN_II = (1 << 0),
|
||||
/* ap->flags bits */
|
||||
PDC_FLAG_GEN_II = (1 << 24),
|
||||
PDC_FLAG_SATA_PATA = (1 << 25), /* supports SATA + PATA */
|
||||
PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */
|
||||
};
|
||||
|
||||
|
||||
|
@ -110,28 +130,25 @@ struct pdc_port_priv {
|
|||
dma_addr_t pkt_dma;
|
||||
};
|
||||
|
||||
struct pdc_host_priv {
|
||||
unsigned long flags;
|
||||
unsigned long port_flags[ATA_MAX_PORTS];
|
||||
};
|
||||
|
||||
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
|
||||
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
static irqreturn_t pdc_interrupt (int irq, void *dev_instance);
|
||||
static int pdc_port_start(struct ata_port *ap);
|
||||
static int pdc_common_port_start(struct ata_port *ap);
|
||||
static int pdc_sata_port_start(struct ata_port *ap);
|
||||
static void pdc_qc_prep(struct ata_queued_cmd *qc);
|
||||
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
|
||||
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
|
||||
static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static void pdc_irq_clear(struct ata_port *ap);
|
||||
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
|
||||
static void pdc_freeze(struct ata_port *ap);
|
||||
static void pdc_thaw(struct ata_port *ap);
|
||||
static void pdc_error_handler(struct ata_port *ap);
|
||||
static void pdc_pata_error_handler(struct ata_port *ap);
|
||||
static void pdc_sata_error_handler(struct ata_port *ap);
|
||||
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
|
||||
|
||||
static int pdc_pata_cable_detect(struct ata_port *ap);
|
||||
static int pdc_sata_cable_detect(struct ata_port *ap);
|
||||
|
||||
static struct scsi_host_template pdc_ata_sht = {
|
||||
.module = THIS_MODULE,
|
||||
|
@ -164,17 +181,17 @@ static const struct ata_port_operations pdc_sata_ops = {
|
|||
.qc_issue = pdc_qc_issue_prot,
|
||||
.freeze = pdc_freeze,
|
||||
.thaw = pdc_thaw,
|
||||
.error_handler = pdc_error_handler,
|
||||
.error_handler = pdc_sata_error_handler,
|
||||
.post_internal_cmd = pdc_post_internal_cmd,
|
||||
.cable_detect = pdc_sata_cable_detect,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = pdc_interrupt,
|
||||
.irq_clear = pdc_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.scr_read = pdc_sata_scr_read,
|
||||
.scr_write = pdc_sata_scr_write,
|
||||
.port_start = pdc_port_start,
|
||||
.port_start = pdc_sata_port_start,
|
||||
};
|
||||
|
||||
/* First-generation chips need a more restrictive ->check_atapi_dma op */
|
||||
|
@ -185,23 +202,23 @@ static const struct ata_port_operations pdc_old_sata_ops = {
|
|||
.check_status = ata_check_status,
|
||||
.exec_command = pdc_exec_command_mmio,
|
||||
.dev_select = ata_std_dev_select,
|
||||
.check_atapi_dma = pdc_old_check_atapi_dma,
|
||||
.check_atapi_dma = pdc_old_sata_check_atapi_dma,
|
||||
|
||||
.qc_prep = pdc_qc_prep,
|
||||
.qc_issue = pdc_qc_issue_prot,
|
||||
.freeze = pdc_freeze,
|
||||
.thaw = pdc_thaw,
|
||||
.error_handler = pdc_error_handler,
|
||||
.error_handler = pdc_sata_error_handler,
|
||||
.post_internal_cmd = pdc_post_internal_cmd,
|
||||
.cable_detect = pdc_sata_cable_detect,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = pdc_interrupt,
|
||||
.irq_clear = pdc_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.scr_read = pdc_sata_scr_read,
|
||||
.scr_write = pdc_sata_scr_write,
|
||||
.port_start = pdc_port_start,
|
||||
.port_start = pdc_sata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations pdc_pata_ops = {
|
||||
|
@ -217,32 +234,41 @@ static const struct ata_port_operations pdc_pata_ops = {
|
|||
.qc_issue = pdc_qc_issue_prot,
|
||||
.freeze = pdc_freeze,
|
||||
.thaw = pdc_thaw,
|
||||
.error_handler = pdc_error_handler,
|
||||
.error_handler = pdc_pata_error_handler,
|
||||
.post_internal_cmd = pdc_post_internal_cmd,
|
||||
.cable_detect = pdc_pata_cable_detect,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.irq_handler = pdc_interrupt,
|
||||
.irq_clear = pdc_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = pdc_port_start,
|
||||
.port_start = pdc_common_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_info pdc_port_info[] = {
|
||||
/* board_2037x */
|
||||
{
|
||||
.sht = &pdc_ata_sht,
|
||||
.flags = PDC_COMMON_FLAGS,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
|
||||
PDC_FLAG_SATA_PATA,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &pdc_old_sata_ops,
|
||||
},
|
||||
|
||||
/* board_2037x_pata */
|
||||
{
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &pdc_pata_ops,
|
||||
},
|
||||
|
||||
/* board_20319 */
|
||||
{
|
||||
.sht = &pdc_ata_sht,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
|
||||
PDC_FLAG_4_PORTS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
|
@ -251,8 +277,8 @@ static const struct ata_port_info pdc_port_info[] = {
|
|||
|
||||
/* board_20619 */
|
||||
{
|
||||
.sht = &pdc_ata_sht,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
|
||||
PDC_FLAG_4_PORTS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
|
@ -261,18 +287,28 @@ static const struct ata_port_info pdc_port_info[] = {
|
|||
|
||||
/* board_2057x */
|
||||
{
|
||||
.sht = &pdc_ata_sht,
|
||||
.flags = PDC_COMMON_FLAGS,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
|
||||
PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &pdc_sata_ops,
|
||||
},
|
||||
|
||||
/* board_2057x_pata */
|
||||
{
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
|
||||
PDC_FLAG_GEN_II,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &pdc_pata_ops,
|
||||
},
|
||||
|
||||
/* board_40518 */
|
||||
{
|
||||
.sht = &pdc_ata_sht,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
|
||||
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
|
||||
PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
|
@ -313,18 +349,12 @@ static struct pci_driver pdc_ata_pci_driver = {
|
|||
};
|
||||
|
||||
|
||||
static int pdc_port_start(struct ata_port *ap)
|
||||
static int pdc_common_port_start(struct ata_port *ap)
|
||||
{
|
||||
struct device *dev = ap->host->dev;
|
||||
struct pdc_host_priv *hp = ap->host->private_data;
|
||||
struct pdc_port_priv *pp;
|
||||
int rc;
|
||||
|
||||
/* fix up port flags and cable type for SATA+PATA chips */
|
||||
ap->flags |= hp->port_flags[ap->port_no];
|
||||
if (ap->flags & ATA_FLAG_SATA)
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
|
||||
rc = ata_port_start(ap);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -339,8 +369,19 @@ static int pdc_port_start(struct ata_port *ap)
|
|||
|
||||
ap->private_data = pp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pdc_sata_port_start(struct ata_port *ap)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pdc_common_port_start(ap);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* fix up PHYMODE4 align timing */
|
||||
if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) {
|
||||
if (ap->flags & PDC_FLAG_GEN_II) {
|
||||
void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
|
||||
unsigned int tmp;
|
||||
|
||||
|
@ -374,23 +415,25 @@ static void pdc_reset_port(struct ata_port *ap)
|
|||
readl(mmio); /* flush */
|
||||
}
|
||||
|
||||
static void pdc_pata_cbl_detect(struct ata_port *ap)
|
||||
static int pdc_pata_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
u8 tmp;
|
||||
void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
|
||||
|
||||
tmp = readb(mmio);
|
||||
if (tmp & 0x01)
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
if (tmp & 0x01) {
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
ap->udma_mask &= ATA_UDMA_MASK_40C;
|
||||
} else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
static int pdc_sata_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
return ATA_CBL_SATA;
|
||||
}
|
||||
|
||||
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
|
||||
{
|
||||
if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
|
||||
if (sc_reg > SCR_CONTROL)
|
||||
return 0xffffffffU;
|
||||
return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
}
|
||||
|
@ -399,7 +442,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
|
|||
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
|
||||
u32 val)
|
||||
{
|
||||
if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
|
||||
if (sc_reg > SCR_CONTROL)
|
||||
return;
|
||||
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
}
|
||||
|
@ -555,52 +598,79 @@ static void pdc_thaw(struct ata_port *ap)
|
|||
readl(mmio + PDC_CTLSTAT); /* flush */
|
||||
}
|
||||
|
||||
static int pdc_pre_reset(struct ata_port *ap)
|
||||
static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset)
|
||||
{
|
||||
if (!sata_scr_valid(ap))
|
||||
pdc_pata_cbl_detect(ap);
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static void pdc_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_reset_fn_t hardreset;
|
||||
|
||||
if (!(ap->pflags & ATA_PFLAG_FROZEN))
|
||||
pdc_reset_port(ap);
|
||||
|
||||
hardreset = NULL;
|
||||
if (sata_scr_valid(ap))
|
||||
hardreset = sata_std_hardreset;
|
||||
|
||||
/* perform recovery */
|
||||
ata_do_eh(ap, pdc_pre_reset, ata_std_softreset, hardreset,
|
||||
ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
static void pdc_pata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
pdc_common_error_handler(ap, NULL);
|
||||
}
|
||||
|
||||
static void pdc_sata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
pdc_common_error_handler(ap, sata_std_hardreset);
|
||||
}
|
||||
|
||||
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
qc->err_mask |= AC_ERR_OTHER;
|
||||
|
||||
/* make DMA engine forget about the failed command */
|
||||
if (qc->err_mask)
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
pdc_reset_port(ap);
|
||||
}
|
||||
|
||||
static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
|
||||
u32 port_status, u32 err_mask)
|
||||
{
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
unsigned int ac_err_mask = 0;
|
||||
|
||||
ata_ehi_clear_desc(ehi);
|
||||
ata_ehi_push_desc(ehi, "port_status 0x%08x", port_status);
|
||||
port_status &= err_mask;
|
||||
|
||||
if (port_status & PDC_DRIVE_ERR)
|
||||
ac_err_mask |= AC_ERR_DEV;
|
||||
if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR))
|
||||
ac_err_mask |= AC_ERR_HSM;
|
||||
if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR))
|
||||
ac_err_mask |= AC_ERR_ATA_BUS;
|
||||
if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR
|
||||
| PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR))
|
||||
ac_err_mask |= AC_ERR_HOST_BUS;
|
||||
|
||||
if (sata_scr_valid(ap))
|
||||
ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR);
|
||||
|
||||
qc->err_mask |= ac_err_mask;
|
||||
|
||||
pdc_reset_port(ap);
|
||||
}
|
||||
|
||||
static inline unsigned int pdc_host_intr( struct ata_port *ap,
|
||||
struct ata_queued_cmd *qc)
|
||||
{
|
||||
unsigned int handled = 0;
|
||||
u32 tmp;
|
||||
void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
|
||||
void __iomem *port_mmio = ap->ioaddr.cmd_addr;
|
||||
u32 port_status, err_mask;
|
||||
|
||||
tmp = readl(mmio);
|
||||
if (tmp & PDC_ERR_MASK) {
|
||||
qc->err_mask |= AC_ERR_DEV;
|
||||
pdc_reset_port(ap);
|
||||
err_mask = PDC_ERR_MASK;
|
||||
if (ap->flags & PDC_FLAG_GEN_II)
|
||||
err_mask &= ~PDC1_ERR_MASK;
|
||||
else
|
||||
err_mask &= ~PDC2_ERR_MASK;
|
||||
port_status = readl(port_mmio + PDC_GLOBAL_CTL);
|
||||
if (unlikely(port_status & err_mask)) {
|
||||
pdc_error_intr(ap, qc, port_status, err_mask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (qc->tf.protocol) {
|
||||
|
@ -767,44 +837,40 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
|
|||
return pio;
|
||||
}
|
||||
|
||||
static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc)
|
||||
static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
|
||||
/* First generation chips cannot use ATAPI DMA on SATA ports */
|
||||
if (sata_scr_valid(ap))
|
||||
return 1;
|
||||
return pdc_check_atapi_dma(qc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base,
|
||||
void __iomem *scr_addr)
|
||||
static void pdc_ata_setup_port(struct ata_port *ap,
|
||||
void __iomem *base, void __iomem *scr_addr)
|
||||
{
|
||||
port->cmd_addr = base;
|
||||
port->data_addr = base;
|
||||
port->feature_addr =
|
||||
port->error_addr = base + 0x4;
|
||||
port->nsect_addr = base + 0x8;
|
||||
port->lbal_addr = base + 0xc;
|
||||
port->lbam_addr = base + 0x10;
|
||||
port->lbah_addr = base + 0x14;
|
||||
port->device_addr = base + 0x18;
|
||||
port->command_addr =
|
||||
port->status_addr = base + 0x1c;
|
||||
port->altstatus_addr =
|
||||
port->ctl_addr = base + 0x38;
|
||||
port->scr_addr = scr_addr;
|
||||
ap->ioaddr.cmd_addr = base;
|
||||
ap->ioaddr.data_addr = base;
|
||||
ap->ioaddr.feature_addr =
|
||||
ap->ioaddr.error_addr = base + 0x4;
|
||||
ap->ioaddr.nsect_addr = base + 0x8;
|
||||
ap->ioaddr.lbal_addr = base + 0xc;
|
||||
ap->ioaddr.lbam_addr = base + 0x10;
|
||||
ap->ioaddr.lbah_addr = base + 0x14;
|
||||
ap->ioaddr.device_addr = base + 0x18;
|
||||
ap->ioaddr.command_addr =
|
||||
ap->ioaddr.status_addr = base + 0x1c;
|
||||
ap->ioaddr.altstatus_addr =
|
||||
ap->ioaddr.ctl_addr = base + 0x38;
|
||||
ap->ioaddr.scr_addr = scr_addr;
|
||||
}
|
||||
|
||||
|
||||
static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
||||
static void pdc_host_init(struct ata_host *host)
|
||||
{
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
struct pdc_host_priv *hp = pe->private_data;
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II;
|
||||
int hotplug_offset;
|
||||
u32 tmp;
|
||||
|
||||
if (hp->flags & PDC_FLAG_GEN_II)
|
||||
if (is_gen2)
|
||||
hotplug_offset = PDC2_SATA_PLUG_CSR;
|
||||
else
|
||||
hotplug_offset = PDC_SATA_PLUG_CSR;
|
||||
|
@ -818,7 +884,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
|||
/* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
|
||||
tmp = readl(mmio + PDC_FLASH_CTL);
|
||||
tmp |= 0x02000; /* bit 13 (enable bmr burst) */
|
||||
if (!(hp->flags & PDC_FLAG_GEN_II))
|
||||
if (!is_gen2)
|
||||
tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
|
||||
writel(tmp, mmio + PDC_FLASH_CTL);
|
||||
|
||||
|
@ -831,7 +897,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
|||
writel(tmp | 0xff0000, mmio + hotplug_offset);
|
||||
|
||||
/* don't initialise TBG or SLEW on 2nd generation chips */
|
||||
if (hp->flags & PDC_FLAG_GEN_II)
|
||||
if (is_gen2)
|
||||
return;
|
||||
|
||||
/* reduce TBG clock to 133 Mhz. */
|
||||
|
@ -853,16 +919,16 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
|||
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct pdc_host_priv *hp;
|
||||
const struct ata_port_info *pi = &pdc_port_info[ent->driver_data];
|
||||
const struct ata_port_info *ppi[PDC_MAX_PORTS];
|
||||
struct ata_host *host;
|
||||
void __iomem *base;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
int rc;
|
||||
u8 tmp;
|
||||
int n_ports, i, rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* enable and acquire resources */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -872,6 +938,37 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
base = pcim_iomap_table(pdev)[PDC_MMIO_BAR];
|
||||
|
||||
/* determine port configuration and setup host */
|
||||
n_ports = 2;
|
||||
if (pi->flags & PDC_FLAG_4_PORTS)
|
||||
n_ports = 4;
|
||||
for (i = 0; i < n_ports; i++)
|
||||
ppi[i] = pi;
|
||||
|
||||
if (pi->flags & PDC_FLAG_SATA_PATA) {
|
||||
u8 tmp = readb(base + PDC_FLASH_CTL+1);
|
||||
if (!(tmp & 0x80)) {
|
||||
ppi[n_ports++] = pi + 1;
|
||||
dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
|
||||
}
|
||||
}
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
|
||||
if (!host) {
|
||||
dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
pdc_ata_setup_port(host->ports[i],
|
||||
base + 0x200 + i * 0x80,
|
||||
base + 0x400 + i * 0x100);
|
||||
|
||||
/* initialize adapter */
|
||||
pdc_host_init(host);
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
|
@ -880,81 +977,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL);
|
||||
if (hp == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->private_data = hp;
|
||||
|
||||
probe_ent->sht = pdc_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = pdc_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
|
||||
probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
|
||||
probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
base = probe_ent->iomap[PDC_MMIO_BAR];
|
||||
|
||||
pdc_ata_setup_port(&probe_ent->port[0], base + 0x200, base + 0x400);
|
||||
pdc_ata_setup_port(&probe_ent->port[1], base + 0x280, base + 0x500);
|
||||
|
||||
/* notice 4-port boards */
|
||||
switch (board_idx) {
|
||||
case board_40518:
|
||||
hp->flags |= PDC_FLAG_GEN_II;
|
||||
/* Fall through */
|
||||
case board_20319:
|
||||
probe_ent->n_ports = 4;
|
||||
pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, base + 0x600);
|
||||
pdc_ata_setup_port(&probe_ent->port[3], base + 0x380, base + 0x700);
|
||||
break;
|
||||
case board_2057x:
|
||||
hp->flags |= PDC_FLAG_GEN_II;
|
||||
/* Fall through */
|
||||
case board_2037x:
|
||||
/* TX2plus boards also have a PATA port */
|
||||
tmp = readb(base + PDC_FLASH_CTL+1);
|
||||
if (!(tmp & 0x80)) {
|
||||
probe_ent->n_ports = 3;
|
||||
pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, NULL);
|
||||
hp->port_flags[2] = ATA_FLAG_SLAVE_POSS;
|
||||
printk(KERN_INFO DRV_NAME " PATA port found\n");
|
||||
} else
|
||||
probe_ent->n_ports = 2;
|
||||
hp->port_flags[0] = ATA_FLAG_SATA;
|
||||
hp->port_flags[1] = ATA_FLAG_SATA;
|
||||
break;
|
||||
case board_20619:
|
||||
probe_ent->n_ports = 4;
|
||||
pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, NULL);
|
||||
pdc_ata_setup_port(&probe_ent->port[3], base + 0x380, NULL);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
/* start host, request IRQ and attach */
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* initialize adapter */
|
||||
pdc_host_init(board_idx, probe_ent);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, pdc_interrupt, IRQF_SHARED,
|
||||
&pdc_ata_sht);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ struct qs_port_priv {
|
|||
static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg);
|
||||
static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||
static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
static irqreturn_t qs_intr (int irq, void *dev_instance);
|
||||
static int qs_port_start(struct ata_port *ap);
|
||||
static void qs_host_stop(struct ata_host *host);
|
||||
static void qs_phy_reset(struct ata_port *ap);
|
||||
|
@ -158,7 +157,6 @@ static const struct ata_port_operations qs_ata_ops = {
|
|||
.qc_issue = qs_qc_issue,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.eng_timeout = qs_eng_timeout,
|
||||
.irq_handler = qs_intr,
|
||||
.irq_clear = qs_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -173,7 +171,6 @@ static const struct ata_port_operations qs_ata_ops = {
|
|||
static const struct ata_port_info qs_port_info[] = {
|
||||
/* board_2068_idx */
|
||||
{
|
||||
.sht = &qs_ata_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_SATA_RESET |
|
||||
//FIXME ATA_FLAG_SRST |
|
||||
|
@ -530,16 +527,16 @@ static void qs_host_stop(struct ata_host *host)
|
|||
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
|
||||
}
|
||||
|
||||
static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
||||
static void qs_host_init(struct ata_host *host, unsigned int chip_id)
|
||||
{
|
||||
void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR];
|
||||
void __iomem *mmio_base = host->iomap[QS_MMIO_BAR];
|
||||
unsigned int port_no;
|
||||
|
||||
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
|
||||
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
|
||||
|
||||
/* reset each channel in turn */
|
||||
for (port_no = 0; port_no < pe->n_ports; ++port_no) {
|
||||
for (port_no = 0; port_no < host->n_ports; ++port_no) {
|
||||
u8 __iomem *chan = mmio_base + (port_no * 0x4000);
|
||||
writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1);
|
||||
writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
|
||||
|
@ -547,7 +544,7 @@ static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
|||
}
|
||||
writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */
|
||||
|
||||
for (port_no = 0; port_no < pe->n_ports; ++port_no) {
|
||||
for (port_no = 0; port_no < host->n_ports; ++port_no) {
|
||||
u8 __iomem *chan = mmio_base + (port_no * 0x4000);
|
||||
/* set FIFO depths to same settings as Windows driver */
|
||||
writew(32, chan + QS_CFC_HUFT);
|
||||
|
@ -607,14 +604,20 @@ static int qs_ata_init_one(struct pci_dev *pdev,
|
|||
const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
void __iomem * const *iomap;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL };
|
||||
struct ata_host *host;
|
||||
int rc, port_no;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* alloc host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -625,47 +628,24 @@ static int qs_ata_init_one(struct pci_dev *pdev,
|
|||
rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
iomap = pcim_iomap_table(pdev);
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]);
|
||||
rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
probe_ent->sht = qs_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = qs_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = qs_port_info[board_idx].pio_mask;
|
||||
probe_ent->mwdma_mask = qs_port_info[board_idx].mwdma_mask;
|
||||
probe_ent->udma_mask = qs_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = qs_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = iomap;
|
||||
probe_ent->n_ports = QS_PORTS;
|
||||
|
||||
for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
|
||||
for (port_no = 0; port_no < host->n_ports; ++port_no) {
|
||||
void __iomem *chan =
|
||||
probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
|
||||
qs_ata_setup_port(&probe_ent->port[port_no], chan);
|
||||
host->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
|
||||
qs_ata_setup_port(&host->ports[port_no]->ioaddr, chan);
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* initialize adapter */
|
||||
qs_host_init(board_idx, probe_ent);
|
||||
qs_host_init(host, board_idx);
|
||||
|
||||
if (ata_device_add(probe_ent) != QS_PORTS)
|
||||
return -EIO;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED,
|
||||
&qs_ata_sht);
|
||||
}
|
||||
|
||||
static int __init qs_ata_init(void)
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "sata_sil"
|
||||
#define DRV_VERSION "2.1"
|
||||
#define DRV_VERSION "2.2"
|
||||
|
||||
enum {
|
||||
SIL_MMIO_BAR = 5,
|
||||
|
@ -114,11 +114,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
|||
#ifdef CONFIG_PM
|
||||
static int sil_pci_device_resume(struct pci_dev *pdev);
|
||||
#endif
|
||||
static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
|
||||
static void sil_dev_config(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 irqreturn_t sil_interrupt(int irq, void *dev_instance);
|
||||
static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
|
||||
static void sil_freeze(struct ata_port *ap);
|
||||
static void sil_thaw(struct ata_port *ap);
|
||||
|
||||
|
@ -197,7 +196,7 @@ static const struct ata_port_operations sil_ops = {
|
|||
.check_status = ata_check_status,
|
||||
.exec_command = ata_exec_command,
|
||||
.dev_select = ata_std_dev_select,
|
||||
.post_set_mode = sil_post_set_mode,
|
||||
.set_mode = sil_set_mode,
|
||||
.bmdma_setup = ata_bmdma_setup,
|
||||
.bmdma_start = ata_bmdma_start,
|
||||
.bmdma_stop = ata_bmdma_stop,
|
||||
|
@ -209,7 +208,6 @@ static const struct ata_port_operations sil_ops = {
|
|||
.thaw = sil_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_handler = sil_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -221,7 +219,6 @@ static const struct ata_port_operations sil_ops = {
|
|||
static const struct ata_port_info sil_port_info[] = {
|
||||
/* sil_3112 */
|
||||
{
|
||||
.sht = &sil_sht,
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
|
@ -230,7 +227,6 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
},
|
||||
/* sil_3112_no_sata_irq */
|
||||
{
|
||||
.sht = &sil_sht,
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
|
||||
SIL_FLAG_NO_SATA_IRQ,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
|
@ -240,7 +236,6 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
},
|
||||
/* sil_3512 */
|
||||
{
|
||||
.sht = &sil_sht,
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
|
@ -249,7 +244,6 @@ static const struct ata_port_info sil_port_info[] = {
|
|||
},
|
||||
/* sil_3114 */
|
||||
{
|
||||
.sht = &sil_sht,
|
||||
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
|
@ -297,7 +291,16 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
|
|||
return cache_line;
|
||||
}
|
||||
|
||||
static void sil_post_set_mode (struct ata_port *ap)
|
||||
/**
|
||||
* sil_set_mode - wrap set_mode functions
|
||||
* @ap: port to set up
|
||||
* @r_failed: returned device when we fail
|
||||
*
|
||||
* Wrap the libata method for device setup as after the setup we need
|
||||
* to inspect the results and do some configuration work
|
||||
*/
|
||||
|
||||
static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed)
|
||||
{
|
||||
struct ata_host *host = ap->host;
|
||||
struct ata_device *dev;
|
||||
|
@ -305,6 +308,11 @@ static void sil_post_set_mode (struct ata_port *ap)
|
|||
void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
|
||||
u32 tmp, dev_mode[2];
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
rc = ata_do_set_mode(ap, r_failed);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
dev = &ap->device[i];
|
||||
|
@ -323,6 +331,7 @@ static void sil_post_set_mode (struct ata_port *ap)
|
|||
tmp |= (dev_mode[1] << 4);
|
||||
writel(tmp, addr);
|
||||
readl(addr); /* flush */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
|
||||
|
@ -521,7 +530,6 @@ static void sil_thaw(struct ata_port *ap)
|
|||
|
||||
/**
|
||||
* sil_dev_config - Apply device/host-specific errata fixups
|
||||
* @ap: Port containing device to be examined
|
||||
* @dev: Device to be examined
|
||||
*
|
||||
* After the IDENTIFY [PACKET] DEVICE step is complete, and a
|
||||
|
@ -548,8 +556,9 @@ static void sil_thaw(struct ata_port *ap)
|
|||
* appreciated.
|
||||
* - But then again UDMA5 is hardly anything to complain about
|
||||
*/
|
||||
static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
|
||||
static void sil_dev_config(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
|
||||
unsigned int n, quirks = 0;
|
||||
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||
|
@ -583,10 +592,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void sil_init_controller(struct pci_dev *pdev,
|
||||
int n_ports, unsigned long port_flags,
|
||||
void __iomem *mmio_base)
|
||||
static void sil_init_controller(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
|
||||
u8 cls;
|
||||
u32 tmp;
|
||||
int i;
|
||||
|
@ -596,7 +605,7 @@ static void sil_init_controller(struct pci_dev *pdev,
|
|||
if (cls) {
|
||||
cls >>= 3;
|
||||
cls++; /* cls = (line_size/8)+1 */
|
||||
for (i = 0; i < n_ports; i++)
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
writew(cls << 8 | cls,
|
||||
mmio_base + sil_port[i].fifo_cfg);
|
||||
} else
|
||||
|
@ -604,10 +613,10 @@ static void sil_init_controller(struct pci_dev *pdev,
|
|||
"cache line size not set. Driver may not function\n");
|
||||
|
||||
/* Apply R_ERR on DMA activate FIS errata workaround */
|
||||
if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
|
||||
if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) {
|
||||
int cnt;
|
||||
|
||||
for (i = 0, cnt = 0; i < n_ports; i++) {
|
||||
for (i = 0, cnt = 0; i < host->n_ports; i++) {
|
||||
tmp = readl(mmio_base + sil_port[i].sfis_cfg);
|
||||
if ((tmp & 0x3) != 0x01)
|
||||
continue;
|
||||
|
@ -620,7 +629,7 @@ static void sil_init_controller(struct pci_dev *pdev,
|
|||
}
|
||||
}
|
||||
|
||||
if (n_ports == 4) {
|
||||
if (host->n_ports == 4) {
|
||||
/* flip the magic "make 4 ports work" bit */
|
||||
tmp = readl(mmio_base + sil_port[2].bmdma);
|
||||
if ((tmp & SIL_INTR_STEERING) == 0)
|
||||
|
@ -632,15 +641,26 @@ static void sil_init_controller(struct pci_dev *pdev,
|
|||
static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
int board_id = ent->driver_data;
|
||||
const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
int rc;
|
||||
int n_ports, rc;
|
||||
unsigned int i;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* allocate host */
|
||||
n_ports = 2;
|
||||
if (board_id == sil_3114)
|
||||
n_ports = 4;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -650,6 +670,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
|
@ -658,45 +679,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
mmio_base = host->iomap[SIL_MMIO_BAR];
|
||||
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
|
||||
probe_ent->sht = sil_port_info[ent->driver_data].sht;
|
||||
probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
|
||||
probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
|
||||
probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
|
||||
probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->port_flags = sil_port_info[ent->driver_data].flags;
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
|
||||
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
mmio_base = probe_ent->iomap[SIL_MMIO_BAR];
|
||||
|
||||
for (i = 0; i < probe_ent->n_ports; i++) {
|
||||
probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf;
|
||||
probe_ent->port[i].altstatus_addr =
|
||||
probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl;
|
||||
probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma;
|
||||
probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr;
|
||||
ata_std_ports(&probe_ent->port[i]);
|
||||
ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
|
||||
ioaddr->altstatus_addr =
|
||||
ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
|
||||
ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
|
||||
ioaddr->scr_addr = mmio_base + sil_port[i].scr;
|
||||
ata_std_ports(ioaddr);
|
||||
}
|
||||
|
||||
sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
|
||||
mmio_base);
|
||||
/* initialize and activate */
|
||||
sil_init_controller(host);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED,
|
||||
&sil_sht);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -709,8 +710,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
sil_init_controller(pdev, host->n_ports, host->ports[0]->flags,
|
||||
host->iomap[SIL_MMIO_BAR]);
|
||||
sil_init_controller(host);
|
||||
ata_host_resume(host);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -323,7 +323,7 @@ struct sil24_port_priv {
|
|||
struct ata_taskfile tf; /* Cached taskfile registers */
|
||||
};
|
||||
|
||||
static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
|
||||
static void sil24_dev_config(struct ata_device *dev);
|
||||
static u8 sil24_check_status(struct ata_port *ap);
|
||||
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
|
||||
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
|
||||
|
@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
|
|||
static void sil24_qc_prep(struct ata_queued_cmd *qc);
|
||||
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
|
||||
static void sil24_irq_clear(struct ata_port *ap);
|
||||
static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
|
||||
static void sil24_freeze(struct ata_port *ap);
|
||||
static void sil24_thaw(struct ata_port *ap);
|
||||
static void sil24_error_handler(struct ata_port *ap);
|
||||
|
@ -401,7 +400,6 @@ static const struct ata_port_operations sil24_ops = {
|
|||
.qc_prep = sil24_qc_prep,
|
||||
.qc_issue = sil24_qc_issue,
|
||||
|
||||
.irq_handler = sil24_interrupt,
|
||||
.irq_clear = sil24_irq_clear,
|
||||
.irq_on = ata_dummy_irq_on,
|
||||
.irq_ack = ata_dummy_irq_ack,
|
||||
|
@ -424,10 +422,9 @@ static const struct ata_port_operations sil24_ops = {
|
|||
#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
|
||||
#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
|
||||
|
||||
static struct ata_port_info sil24_port_info[] = {
|
||||
static const struct ata_port_info sil24_port_info[] = {
|
||||
/* sil_3124 */
|
||||
{
|
||||
.sht = &sil24_sht,
|
||||
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
|
||||
SIL24_FLAG_PCIX_IRQ_WOC,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
|
@ -437,7 +434,6 @@ static struct ata_port_info sil24_port_info[] = {
|
|||
},
|
||||
/* sil_3132 */
|
||||
{
|
||||
.sht = &sil24_sht,
|
||||
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
|
@ -446,7 +442,6 @@ static struct ata_port_info sil24_port_info[] = {
|
|||
},
|
||||
/* sil_3131/sil_3531 */
|
||||
{
|
||||
.sht = &sil24_sht,
|
||||
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
|
@ -462,9 +457,9 @@ static int sil24_tag(int tag)
|
|||
return tag;
|
||||
}
|
||||
|
||||
static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
|
||||
static void sil24_dev_config(struct ata_device *dev)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
void __iomem *port = dev->ap->ioaddr.cmd_addr;
|
||||
|
||||
if (dev->cdb_len == 16)
|
||||
writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
|
||||
|
@ -924,11 +919,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
|
|||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
qc->err_mask |= AC_ERR_OTHER;
|
||||
|
||||
/* make DMA engine forget about the failed command */
|
||||
if (qc->err_mask)
|
||||
if (qc->flags & ATA_QCFLAG_FAILED)
|
||||
sil24_init_port(ap);
|
||||
}
|
||||
|
||||
|
@ -964,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
|
||||
unsigned long port_flags,
|
||||
void __iomem *host_base,
|
||||
void __iomem *port_base)
|
||||
static void sil24_init_controller(struct ata_host *host)
|
||||
{
|
||||
void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
|
||||
void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
|
||||
u32 tmp;
|
||||
int i;
|
||||
|
||||
|
@ -979,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
|
|||
writel(0, host_base + HOST_CTRL);
|
||||
|
||||
/* init ports */
|
||||
for (i = 0; i < n_ports; i++) {
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
void __iomem *port = port_base + i * PORT_REGS_SIZE;
|
||||
|
||||
/* Initial PHY setting */
|
||||
|
@ -993,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
|
|||
PORT_CS_PORT_RST,
|
||||
PORT_CS_PORT_RST, 10, 100);
|
||||
if (tmp & PORT_CS_PORT_RST)
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
dev_printk(KERN_ERR, host->dev,
|
||||
"failed to clear port RST\n");
|
||||
}
|
||||
|
||||
/* Configure IRQ WoC */
|
||||
if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC)
|
||||
if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
|
||||
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
|
||||
else
|
||||
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
|
||||
|
@ -1026,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
|
|||
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version = 0;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int board_id = (unsigned int)ent->driver_data;
|
||||
struct ata_port_info *pinfo = &sil24_port_info[board_id];
|
||||
struct ata_probe_ent *probe_ent;
|
||||
void __iomem *host_base;
|
||||
void __iomem *port_base;
|
||||
struct ata_port_info pi = sil24_port_info[ent->driver_data];
|
||||
const struct ata_port_info *ppi[] = { &pi, NULL };
|
||||
void __iomem * const *iomap;
|
||||
struct ata_host *host;
|
||||
int i, rc;
|
||||
u32 tmp;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* acquire resources */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -1047,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
iomap = pcim_iomap_table(pdev);
|
||||
|
||||
/* allocate & init probe_ent */
|
||||
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (!probe_ent)
|
||||
/* apply workaround for completion IRQ loss on PCI-X errata */
|
||||
if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
|
||||
tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
|
||||
if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"Applying completion IRQ loss on PCI-X "
|
||||
"errata fix\n");
|
||||
else
|
||||
pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
|
||||
}
|
||||
|
||||
/* allocate and fill host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi,
|
||||
SIL24_FLAG2NPORTS(ppi[0]->flags));
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
host->iomap = iomap;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
|
||||
|
||||
probe_ent->sht = pinfo->sht;
|
||||
probe_ent->port_flags = pinfo->flags;
|
||||
probe_ent->pio_mask = pinfo->pio_mask;
|
||||
probe_ent->mwdma_mask = pinfo->mwdma_mask;
|
||||
probe_ent->udma_mask = pinfo->udma_mask;
|
||||
probe_ent->port_ops = pinfo->port_ops;
|
||||
probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->flags);
|
||||
host->ports[i]->ioaddr.cmd_addr = port;
|
||||
host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
ata_std_ports(&host->ports[i]->ioaddr);
|
||||
}
|
||||
|
||||
host_base = probe_ent->iomap[SIL24_HOST_BAR];
|
||||
port_base = probe_ent->iomap[SIL24_PORT_BAR];
|
||||
|
||||
/*
|
||||
* Configure the device
|
||||
*/
|
||||
/* configure and activate the device */
|
||||
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
|
||||
rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
|
||||
if (rc) {
|
||||
|
@ -1099,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/* Apply workaround for completion IRQ loss on PCI-X errata */
|
||||
if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
|
||||
tmp = readl(host_base + HOST_CTRL);
|
||||
if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"Applying completion IRQ loss on PCI-X "
|
||||
"errata fix\n");
|
||||
else
|
||||
probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
|
||||
}
|
||||
|
||||
for (i = 0; i < probe_ent->n_ports; i++) {
|
||||
void __iomem *port = port_base + i * PORT_REGS_SIZE;
|
||||
|
||||
probe_ent->port[i].cmd_addr = port;
|
||||
probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
|
||||
|
||||
ata_std_ports(&probe_ent->port[i]);
|
||||
}
|
||||
|
||||
sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
|
||||
host_base, port_base);
|
||||
sil24_init_controller(host);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
|
||||
&sil24_sht);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -1136,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
|
|||
{
|
||||
struct ata_host *host = dev_get_drvdata(&pdev->dev);
|
||||
void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
|
||||
void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
|
||||
int rc;
|
||||
|
||||
rc = ata_pci_device_do_resume(pdev);
|
||||
|
@ -1146,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
|
|||
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
|
||||
writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
|
||||
|
||||
sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags,
|
||||
host_base, port_base);
|
||||
sil24_init_controller(host);
|
||||
|
||||
ata_host_resume(host);
|
||||
|
||||
|
|
|
@ -121,7 +121,6 @@ static const struct ata_port_operations sis_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -131,7 +130,6 @@ static const struct ata_port_operations sis_ops = {
|
|||
};
|
||||
|
||||
static struct ata_port_info sis_port_info = {
|
||||
.sht = &sis_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x7,
|
||||
|
@ -256,12 +254,13 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
|
|||
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent = NULL;
|
||||
int rc;
|
||||
struct ata_port_info pi = sis_port_info;
|
||||
const struct ata_port_info *ppi[2] = { &pi, &pi };
|
||||
struct ata_host *host;
|
||||
u32 genctl, val;
|
||||
struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
|
||||
u8 pmr;
|
||||
u8 port2_start = 0x20;
|
||||
int rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
@ -270,19 +269,6 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = pci_request_regions(pdev, DRV_NAME);
|
||||
if (rc) {
|
||||
pcim_pin_device(pdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* check and see if the SCRs are in IO space or PCI cfg space */
|
||||
pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
|
||||
if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
|
||||
|
@ -349,30 +335,26 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
break;
|
||||
}
|
||||
|
||||
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
if (!probe_ent)
|
||||
return -ENOMEM;
|
||||
rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
|
||||
if (!(pi.flags & SIS_FLAG_CFGSCR)) {
|
||||
void __iomem *mmio;
|
||||
|
||||
mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0);
|
||||
if (!mmio)
|
||||
return -ENOMEM;
|
||||
rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME);
|
||||
if (rc)
|
||||
return rc;
|
||||
mmio = host->iomap[SIS_SCR_PCI_BAR];
|
||||
|
||||
probe_ent->port[0].scr_addr = mmio;
|
||||
probe_ent->port[1].scr_addr = mmio + port2_start;
|
||||
host->ports[0]->ioaddr.scr_addr = mmio;
|
||||
host->ports[1]->ioaddr.scr_addr = mmio + port2_start;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -EIO;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&sis_sht);
|
||||
}
|
||||
|
||||
static int __init sis_init(void)
|
||||
|
|
|
@ -56,7 +56,9 @@
|
|||
#define DRV_VERSION "2.1"
|
||||
|
||||
enum {
|
||||
K2_FLAG_NO_ATAPI_DMA = (1 << 29),
|
||||
/* ap->flags bits */
|
||||
K2_FLAG_SATA_8_PORTS = (1 << 24),
|
||||
K2_FLAG_NO_ATAPI_DMA = (1 << 25),
|
||||
|
||||
/* Taskfile registers offsets */
|
||||
K2_SATA_TF_CMD_OFFSET = 0x00,
|
||||
|
@ -90,17 +92,6 @@ enum {
|
|||
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);
|
||||
|
||||
|
||||
|
@ -354,7 +345,6 @@ static const struct ata_port_operations k2_sata_ops = {
|
|||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -363,6 +353,28 @@ static const struct ata_port_operations k2_sata_ops = {
|
|||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_info k2_port_info[] = {
|
||||
/* board_svw4 */
|
||||
{
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &k2_sata_ops,
|
||||
},
|
||||
/* board_svw8 */
|
||||
{
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
|
||||
K2_FLAG_SATA_8_PORTS,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &k2_sata_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
|
||||
{
|
||||
port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET;
|
||||
|
@ -386,17 +398,24 @@ static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
|
|||
static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
const struct ata_port_info *ppi[] =
|
||||
{ &k2_port_info[ent->driver_data], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
const struct k2_board_info *board_info =
|
||||
&k2_board_info[ent->driver_data];
|
||||
int rc;
|
||||
int i;
|
||||
int n_ports, i, rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* allocate host */
|
||||
n_ports = 4;
|
||||
if (ppi[0]->flags & K2_FLAG_SATA_8_PORTS)
|
||||
n_ports = 8;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* If this driver happens to only be useful on Apple's K2, then
|
||||
* we should check that here as it has a normal Serverworks ID
|
||||
|
@ -404,6 +423,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* Check if we have resources mapped at all (second function may
|
||||
* have been disabled by firmware)
|
||||
|
@ -417,6 +437,15 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
mmio_base = host->iomap[5];
|
||||
|
||||
/* 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 < host->n_ports; i++)
|
||||
k2_sata_setup_port(&host->ports[i]->ioaddr,
|
||||
mmio_base + i * K2_SATA_PORT_OFFSET);
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
|
@ -425,38 +454,6 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
probe_ent->sht = &k2_sata_sht;
|
||||
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO | board_info->port_flags;
|
||||
probe_ent->port_ops = &k2_sata_ops;
|
||||
probe_ent->n_ports = 4;
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
/* We don't care much about the PIO/UDMA masks, but the core won't like us
|
||||
* if we don't fill these
|
||||
*/
|
||||
probe_ent->pio_mask = 0x1f;
|
||||
probe_ent->mwdma_mask = 0x7;
|
||||
probe_ent->udma_mask = 0x7f;
|
||||
|
||||
mmio_base = probe_ent->iomap[5];
|
||||
|
||||
/* 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 < board_info->n_ports; i++)
|
||||
k2_sata_setup_port(&probe_ent->port[i],
|
||||
mmio_base + i * K2_SATA_PORT_OFFSET);
|
||||
|
||||
/* Clear a magic bit in SCR1 according to Darwin, those help
|
||||
* some funky seagate drives (though so far, those were already
|
||||
* set by the firmware on the machines I had access to)
|
||||
|
@ -469,12 +466,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
|||
writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&k2_sata_sht);
|
||||
}
|
||||
|
||||
/* 0x240 is device ID for Apple K2 device
|
||||
|
|
|
@ -151,24 +151,23 @@ struct pdc_host_priv {
|
|||
|
||||
|
||||
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
|
||||
static void pdc_eng_timeout(struct ata_port *ap);
|
||||
static void pdc_20621_phy_reset (struct ata_port *ap);
|
||||
static int pdc_port_start(struct ata_port *ap);
|
||||
static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
|
||||
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
|
||||
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
|
||||
static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
|
||||
static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
|
||||
static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
|
||||
static unsigned int pdc20621_dimm_init(struct ata_host *host);
|
||||
static int pdc20621_detect_dimm(struct ata_host *host);
|
||||
static unsigned int pdc20621_i2c_read(struct ata_host *host,
|
||||
u32 device, u32 subaddr, u32 *pdata);
|
||||
static int pdc20621_prog_dimm0(struct ata_probe_ent *pe);
|
||||
static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe);
|
||||
static int pdc20621_prog_dimm0(struct ata_host *host);
|
||||
static unsigned int pdc20621_prog_dimm_global(struct ata_host *host);
|
||||
#ifdef ATA_VERBOSE_DEBUG
|
||||
static void pdc20621_get_from_dimm(struct ata_probe_ent *pe,
|
||||
static void pdc20621_get_from_dimm(struct ata_host *host,
|
||||
void *psource, u32 offset, u32 size);
|
||||
#endif
|
||||
static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
|
||||
static void pdc20621_put_to_dimm(struct ata_host *host,
|
||||
void *psource, u32 offset, u32 size);
|
||||
static void pdc20621_irq_clear(struct ata_port *ap);
|
||||
static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
|
||||
|
@ -204,7 +203,6 @@ static const struct ata_port_operations pdc_20621_ops = {
|
|||
.qc_issue = pdc20621_qc_issue_prot,
|
||||
.data_xfer = ata_data_xfer,
|
||||
.eng_timeout = pdc_eng_timeout,
|
||||
.irq_handler = pdc20621_interrupt,
|
||||
.irq_clear = pdc20621_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -214,7 +212,6 @@ static const struct ata_port_operations pdc_20621_ops = {
|
|||
static const struct ata_port_info pdc_port_info[] = {
|
||||
/* board_20621 */
|
||||
{
|
||||
.sht = &pdc_sata_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_SRST | ATA_FLAG_MMIO |
|
||||
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
|
||||
|
@ -882,15 +879,15 @@ static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
|
|||
|
||||
|
||||
#ifdef ATA_VERBOSE_DEBUG
|
||||
static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
|
||||
static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
|
||||
u32 offset, u32 size)
|
||||
{
|
||||
u32 window_size;
|
||||
u16 idx;
|
||||
u8 page_mask;
|
||||
long dist;
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
|
||||
|
||||
/* hard-code chip #0 */
|
||||
mmio += PDC_CHIP0_OFS;
|
||||
|
@ -937,15 +934,15 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
|
|||
#endif
|
||||
|
||||
|
||||
static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
|
||||
static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
|
||||
u32 offset, u32 size)
|
||||
{
|
||||
u32 window_size;
|
||||
u16 idx;
|
||||
u8 page_mask;
|
||||
long dist;
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
|
||||
|
||||
/* hard-code chip #0 */
|
||||
mmio += PDC_CHIP0_OFS;
|
||||
|
@ -987,10 +984,10 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
|
|||
}
|
||||
|
||||
|
||||
static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
|
||||
static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
|
||||
u32 subaddr, u32 *pdata)
|
||||
{
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
u32 i2creg = 0;
|
||||
u32 status;
|
||||
u32 count =0;
|
||||
|
@ -1023,17 +1020,17 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
|
|||
}
|
||||
|
||||
|
||||
static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
|
||||
static int pdc20621_detect_dimm(struct ata_host *host)
|
||||
{
|
||||
u32 data=0 ;
|
||||
if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
PDC_DIMM_SPD_SYSTEM_FREQ, &data)) {
|
||||
if (data == 100)
|
||||
return 100;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
|
||||
if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
|
||||
if(data <= 0x75)
|
||||
return 133;
|
||||
} else
|
||||
|
@ -1043,13 +1040,13 @@ static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
|
|||
}
|
||||
|
||||
|
||||
static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
|
||||
static int pdc20621_prog_dimm0(struct ata_host *host)
|
||||
{
|
||||
u32 spd0[50];
|
||||
u32 data = 0;
|
||||
int size, i;
|
||||
u8 bdimmsize;
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
static const struct {
|
||||
unsigned int reg;
|
||||
unsigned int ofs;
|
||||
|
@ -1072,7 +1069,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
|
|||
mmio += PDC_CHIP0_OFS;
|
||||
|
||||
for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++)
|
||||
pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
pdc_i2c_read_data[i].reg,
|
||||
&spd0[pdc_i2c_read_data[i].ofs]);
|
||||
|
||||
|
@ -1108,11 +1105,11 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
|
|||
}
|
||||
|
||||
|
||||
static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
|
||||
static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
|
||||
{
|
||||
u32 data, spd0;
|
||||
int error, i;
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
|
||||
/* hard-code chip #0 */
|
||||
mmio += PDC_CHIP0_OFS;
|
||||
|
@ -1129,7 +1126,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
|
|||
readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
|
||||
|
||||
/* Turn on for ECC */
|
||||
pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
PDC_DIMM_SPD_TYPE, &spd0);
|
||||
if (spd0 == 0x02) {
|
||||
data |= (0x01 << 16);
|
||||
|
@ -1156,7 +1153,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
|
|||
}
|
||||
|
||||
|
||||
static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
|
||||
static unsigned int pdc20621_dimm_init(struct ata_host *host)
|
||||
{
|
||||
int speed, size, length;
|
||||
u32 addr,spd0,pci_status;
|
||||
|
@ -1166,7 +1163,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
|
|||
u32 ticks=0;
|
||||
u32 clock=0;
|
||||
u32 fparam=0;
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
|
||||
/* hard-code chip #0 */
|
||||
mmio += PDC_CHIP0_OFS;
|
||||
|
@ -1225,18 +1222,18 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
|
|||
Read SPD of DIMM by I2C interface,
|
||||
and program the DIMM Module Controller.
|
||||
*/
|
||||
if (!(speed = pdc20621_detect_dimm(pe))) {
|
||||
if (!(speed = pdc20621_detect_dimm(host))) {
|
||||
printk(KERN_ERR "Detect Local DIMM Fail\n");
|
||||
return 1; /* DIMM error */
|
||||
}
|
||||
VPRINTK("Local DIMM Speed = %d\n", speed);
|
||||
|
||||
/* Programming DIMM0 Module Control Register (index_CID0:80h) */
|
||||
size = pdc20621_prog_dimm0(pe);
|
||||
size = pdc20621_prog_dimm0(host);
|
||||
VPRINTK("Local DIMM Size = %dMB\n",size);
|
||||
|
||||
/* Programming DIMM Module Global Control Register (index_CID0:88h) */
|
||||
if (pdc20621_prog_dimm_global(pe)) {
|
||||
if (pdc20621_prog_dimm_global(host)) {
|
||||
printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -1249,20 +1246,20 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
|
|||
'9','8','0','3','1','6','1','2',0,0};
|
||||
u8 test_parttern2[40] = {0};
|
||||
|
||||
pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x10040, 40);
|
||||
pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x40, 40);
|
||||
pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x10040, 40);
|
||||
pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x40, 40);
|
||||
|
||||
pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40);
|
||||
pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
|
||||
pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x10040, 40);
|
||||
pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
|
||||
printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
|
||||
test_parttern2[1], &(test_parttern2[2]));
|
||||
pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040,
|
||||
pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x10040,
|
||||
40);
|
||||
printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
|
||||
test_parttern2[1], &(test_parttern2[2]));
|
||||
|
||||
pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40);
|
||||
pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
|
||||
pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x40, 40);
|
||||
pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
|
||||
printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
|
||||
test_parttern2[1], &(test_parttern2[2]));
|
||||
}
|
||||
|
@ -1270,14 +1267,14 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
|
|||
|
||||
/* ECC initiliazation. */
|
||||
|
||||
pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
PDC_DIMM_SPD_TYPE, &spd0);
|
||||
if (spd0 == 0x02) {
|
||||
VPRINTK("Start ECC initialization\n");
|
||||
addr = 0;
|
||||
length = size * 1024 * 1024;
|
||||
while (addr < length) {
|
||||
pdc20621_put_to_dimm(pe, (void *) &tmp, addr,
|
||||
pdc20621_put_to_dimm(host, (void *) &tmp, addr,
|
||||
sizeof(u32));
|
||||
addr += sizeof(u32);
|
||||
}
|
||||
|
@ -1287,10 +1284,10 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
|
|||
}
|
||||
|
||||
|
||||
static void pdc_20621_init(struct ata_probe_ent *pe)
|
||||
static void pdc_20621_init(struct ata_host *host)
|
||||
{
|
||||
u32 tmp;
|
||||
void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
|
||||
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
|
||||
|
||||
/* hard-code chip #0 */
|
||||
mmio += PDC_CHIP0_OFS;
|
||||
|
@ -1321,15 +1318,25 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
|
|||
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
const struct ata_port_info *ppi[] =
|
||||
{ &pdc_port_info[ent->driver_data], NULL };
|
||||
struct ata_host *host;
|
||||
void __iomem *base;
|
||||
struct pdc_host_priv *hpriv;
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
int rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* allocate host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!host || !hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
host->private_data = hpriv;
|
||||
|
||||
/* acquire resources and fill host */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -1340,7 +1347,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
|
|||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
|
||||
pdc_sata_setup_port(&host->ports[0]->ioaddr, base + 0x200);
|
||||
pdc_sata_setup_port(&host->ports[1]->ioaddr, base + 0x280);
|
||||
pdc_sata_setup_port(&host->ports[2]->ioaddr, base + 0x300);
|
||||
pdc_sata_setup_port(&host->ports[3]->ioaddr, base + 0x380);
|
||||
|
||||
/* configure and activate */
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -1348,50 +1363,13 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
if (pdc20621_dimm_init(host))
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
probe_ent->sht = pdc_port_info[board_idx].sht;
|
||||
probe_ent->port_flags = pdc_port_info[board_idx].flags;
|
||||
probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
|
||||
probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
|
||||
probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
|
||||
probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
|
||||
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
probe_ent->private_data = hpriv;
|
||||
base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
|
||||
|
||||
probe_ent->n_ports = 4;
|
||||
pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
|
||||
pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
|
||||
pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
|
||||
pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
|
||||
pdc_20621_init(host);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/* initialize adapter */
|
||||
/* initialize local dimm */
|
||||
if (pdc20621_dimm_init(probe_ent))
|
||||
return -ENOMEM;
|
||||
pdc_20621_init(probe_ent);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, pdc20621_interrupt,
|
||||
IRQF_SHARED, &pdc_sata_sht);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -115,7 +115,6 @@ static const struct ata_port_operations uli_ops = {
|
|||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -127,7 +126,6 @@ static const struct ata_port_operations uli_ops = {
|
|||
};
|
||||
|
||||
static struct ata_port_info uli_port_info = {
|
||||
.sht = &uli_sht,
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_IGN_SIMPLEX,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
|
@ -185,12 +183,13 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
|
|||
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct ata_port_info *ppi[2];
|
||||
int rc;
|
||||
const struct ata_port_info *ppi[] = { &uli_port_info, NULL };
|
||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||
struct ata_host *host;
|
||||
struct uli_priv *hpriv;
|
||||
void __iomem * const *iomap;
|
||||
struct ata_ioports *ioaddr;
|
||||
int n_ports, rc;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
@ -199,54 +198,42 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = pci_request_regions(pdev, DRV_NAME);
|
||||
if (rc) {
|
||||
pcim_pin_device(pdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
n_ports = 2;
|
||||
if (board_idx == uli_5287)
|
||||
n_ports = 4;
|
||||
rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
ppi[0] = ppi[1] = &uli_port_info;
|
||||
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
if (!probe_ent)
|
||||
return -ENOMEM;
|
||||
|
||||
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
host->private_data = hpriv;
|
||||
|
||||
probe_ent->private_data = hpriv;
|
||||
|
||||
iomap = pcim_iomap_table(pdev);
|
||||
iomap = host->iomap;
|
||||
|
||||
switch (board_idx) {
|
||||
case uli_5287:
|
||||
hpriv->scr_cfg_addr[0] = ULI5287_BASE;
|
||||
hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
|
||||
probe_ent->n_ports = 4;
|
||||
|
||||
probe_ent->port[2].cmd_addr = iomap[0] + 8;
|
||||
probe_ent->port[2].altstatus_addr =
|
||||
probe_ent->port[2].ctl_addr = (void __iomem *)
|
||||
ioaddr = &host->ports[2]->ioaddr;
|
||||
ioaddr->cmd_addr = iomap[0] + 8;
|
||||
ioaddr->altstatus_addr =
|
||||
ioaddr->ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
|
||||
probe_ent->port[2].bmdma_addr = iomap[4] + 16;
|
||||
ioaddr->bmdma_addr = iomap[4] + 16;
|
||||
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
probe_ent->port[3].cmd_addr = iomap[2] + 8;
|
||||
probe_ent->port[3].altstatus_addr =
|
||||
probe_ent->port[3].ctl_addr = (void __iomem *)
|
||||
ioaddr = &host->ports[3]->ioaddr;
|
||||
ioaddr->cmd_addr = iomap[2] + 8;
|
||||
ioaddr->altstatus_addr =
|
||||
ioaddr->ctl_addr = (void __iomem *)
|
||||
((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
|
||||
probe_ent->port[3].bmdma_addr = iomap[4] + 24;
|
||||
ioaddr->bmdma_addr = iomap[4] + 24;
|
||||
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
|
||||
|
||||
ata_std_ports(&probe_ent->port[2]);
|
||||
ata_std_ports(&probe_ent->port[3]);
|
||||
ata_std_ports(ioaddr);
|
||||
break;
|
||||
|
||||
case uli_5289:
|
||||
|
@ -266,12 +253,8 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
pci_set_master(pdev);
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&uli_sht);
|
||||
}
|
||||
|
||||
static int __init uli_init(void)
|
||||
|
|
|
@ -64,8 +64,6 @@ enum {
|
|||
PORT0 = (1 << 1),
|
||||
PORT1 = (1 << 0),
|
||||
ALL_PORTS = PORT0 | PORT1,
|
||||
PATA_PORT = 2, /* PATA is port 2 */
|
||||
N_PORTS = 3,
|
||||
|
||||
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
|
||||
|
||||
|
@ -78,11 +76,9 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
|
|||
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
|
||||
static void svia_noop_freeze(struct ata_port *ap);
|
||||
static void vt6420_error_handler(struct ata_port *ap);
|
||||
static void vt6421_sata_error_handler(struct ata_port *ap);
|
||||
static void vt6421_pata_error_handler(struct ata_port *ap);
|
||||
static int vt6421_pata_cable_detect(struct ata_port *ap);
|
||||
static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
|
||||
static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
|
||||
static int vt6421_port_start(struct ata_port *ap);
|
||||
|
||||
static const struct pci_device_id svia_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(VIA, 0x5337), vt6420 },
|
||||
|
@ -141,7 +137,6 @@ static const struct ata_port_operations vt6420_sata_ops = {
|
|||
.error_handler = vt6420_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -172,15 +167,15 @@ static const struct ata_port_operations vt6421_pata_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = vt6421_pata_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = vt6421_pata_cable_detect,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
||||
.port_start = vt6421_port_start,
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations vt6421_sata_ops = {
|
||||
|
@ -203,10 +198,10 @@ static const struct ata_port_operations vt6421_sata_ops = {
|
|||
|
||||
.freeze = ata_bmdma_freeze,
|
||||
.thaw = ata_bmdma_thaw,
|
||||
.error_handler = vt6421_sata_error_handler,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.cable_detect = ata_cable_sata,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -214,11 +209,10 @@ static const struct ata_port_operations vt6421_sata_ops = {
|
|||
.scr_read = svia_scr_read,
|
||||
.scr_write = svia_scr_write,
|
||||
|
||||
.port_start = vt6421_port_start,
|
||||
.port_start = ata_port_start,
|
||||
};
|
||||
|
||||
static struct ata_port_info vt6420_port_info = {
|
||||
.sht = &svia_sht,
|
||||
static const struct ata_port_info vt6420_port_info = {
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
|
@ -226,6 +220,22 @@ static struct ata_port_info vt6420_port_info = {
|
|||
.port_ops = &vt6420_sata_ops,
|
||||
};
|
||||
|
||||
static struct ata_port_info vt6421_sport_info = {
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &vt6421_sata_ops,
|
||||
};
|
||||
|
||||
static struct ata_port_info vt6421_pport_info = {
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &vt6421_pata_ops,
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("Jeff Garzik");
|
||||
MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -330,35 +340,15 @@ static void vt6420_error_handler(struct ata_port *ap)
|
|||
NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static int vt6421_pata_prereset(struct ata_port *ap)
|
||||
static int vt6421_pata_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u8 tmp;
|
||||
|
||||
pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp);
|
||||
if (tmp & 0x10)
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vt6421_pata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, vt6421_pata_prereset, ata_std_softreset,
|
||||
NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static int vt6421_sata_prereset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vt6421_sata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, vt6421_sata_prereset, ata_std_softreset,
|
||||
NULL, ata_std_postreset);
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
|
||||
|
@ -375,16 +365,6 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
|
|||
pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]);
|
||||
}
|
||||
|
||||
static int vt6421_port_start(struct ata_port *ap)
|
||||
{
|
||||
if (ap->port_no == PATA_PORT) {
|
||||
ap->ops = &vt6421_pata_ops;
|
||||
ap->mwdma_mask = 0;
|
||||
ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST;
|
||||
}
|
||||
return ata_port_start(ap);
|
||||
}
|
||||
|
||||
static const unsigned int svia_bar_sizes[] = {
|
||||
8, 4, 8, 4, 16, 256
|
||||
};
|
||||
|
@ -403,79 +383,78 @@ static void __iomem * vt6421_scr_addr(void __iomem *addr, unsigned int port)
|
|||
return addr + (port * 64);
|
||||
}
|
||||
|
||||
static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
|
||||
void __iomem * const *iomap, unsigned int port)
|
||||
static void vt6421_init_addrs(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *reg_addr = iomap[port];
|
||||
void __iomem *bmdma_addr = iomap[4] + (port * 8);
|
||||
void __iomem * const * iomap = ap->host->iomap;
|
||||
void __iomem *reg_addr = iomap[ap->port_no];
|
||||
void __iomem *bmdma_addr = iomap[4] + (ap->port_no * 8);
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
probe_ent->port[port].cmd_addr = reg_addr;
|
||||
probe_ent->port[port].altstatus_addr =
|
||||
probe_ent->port[port].ctl_addr = (void __iomem *)
|
||||
ioaddr->cmd_addr = reg_addr;
|
||||
ioaddr->altstatus_addr =
|
||||
ioaddr->ctl_addr = (void __iomem *)
|
||||
((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS);
|
||||
probe_ent->port[port].bmdma_addr = bmdma_addr;
|
||||
probe_ent->port[port].scr_addr = vt6421_scr_addr(iomap[5], port);
|
||||
ioaddr->bmdma_addr = bmdma_addr;
|
||||
ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no);
|
||||
|
||||
ata_std_ports(&probe_ent->port[port]);
|
||||
ata_std_ports(ioaddr);
|
||||
}
|
||||
|
||||
static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
|
||||
static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
|
||||
{
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct ata_port_info *ppi[2];
|
||||
void __iomem *bar5;
|
||||
const struct ata_port_info *ppi[] = { &vt6420_port_info, NULL };
|
||||
struct ata_host *host;
|
||||
int rc;
|
||||
|
||||
ppi[0] = ppi[1] = &vt6420_port_info;
|
||||
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
|
||||
if (!probe_ent)
|
||||
return NULL;
|
||||
rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
|
||||
if (rc)
|
||||
return rc;
|
||||
*r_host = host;
|
||||
|
||||
bar5 = pcim_iomap(pdev, 5, 0);
|
||||
if (!bar5) {
|
||||
rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n");
|
||||
return NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
probe_ent->port[0].scr_addr = svia_scr_addr(bar5, 0);
|
||||
probe_ent->port[1].scr_addr = svia_scr_addr(bar5, 1);
|
||||
host->ports[0]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 0);
|
||||
host->ports[1]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 1);
|
||||
|
||||
return probe_ent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
|
||||
static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
|
||||
{
|
||||
struct ata_probe_ent *probe_ent;
|
||||
unsigned int i;
|
||||
const struct ata_port_info *ppi[] =
|
||||
{ &vt6421_sport_info, &vt6421_sport_info, &vt6421_pport_info };
|
||||
struct ata_host *host;
|
||||
int i, rc;
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (!probe_ent)
|
||||
return NULL;
|
||||
*r_host = host = ata_host_alloc_pinfo(&pdev->dev, ppi, ARRAY_SIZE(ppi));
|
||||
if (!host) {
|
||||
dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(probe_ent, 0, sizeof(*probe_ent));
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME);
|
||||
if (rc) {
|
||||
dev_printk(KERN_ERR, &pdev->dev, "failed to request/iomap "
|
||||
"PCI BARs (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
probe_ent->sht = &svia_sht;
|
||||
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
|
||||
probe_ent->port_ops = &vt6421_sata_ops;
|
||||
probe_ent->n_ports = N_PORTS;
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
probe_ent->pio_mask = 0x1f;
|
||||
probe_ent->mwdma_mask = 0x07;
|
||||
probe_ent->udma_mask = 0x7f;
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
vt6421_init_addrs(host->ports[i]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
if (!pcim_iomap(pdev, i, 0)) {
|
||||
dev_printk(KERN_ERR, &pdev->dev,
|
||||
"failed to iomap PCI BAR %d\n", i);
|
||||
return NULL;
|
||||
}
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < N_PORTS; i++)
|
||||
vt6421_init_addrs(probe_ent, pcim_iomap_table(pdev), i);
|
||||
|
||||
return probe_ent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void svia_configure(struct pci_dev *pdev)
|
||||
|
@ -522,7 +501,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
static int printed_version;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct ata_host *host;
|
||||
int board_id = (int) ent->driver_data;
|
||||
const int *bar_sizes;
|
||||
u8 tmp8;
|
||||
|
@ -534,12 +513,6 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = pci_request_regions(pdev, DRV_NAME);
|
||||
if (rc) {
|
||||
pcim_pin_device(pdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (board_id == vt6420) {
|
||||
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
|
||||
if (tmp8 & SATA_2DEV) {
|
||||
|
@ -565,32 +538,18 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (board_id == vt6420)
|
||||
probe_ent = vt6420_init_probe_ent(pdev);
|
||||
rc = vt6420_prepare_host(pdev, &host);
|
||||
else
|
||||
probe_ent = vt6421_init_probe_ent(pdev);
|
||||
|
||||
if (!probe_ent) {
|
||||
dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = vt6421_prepare_host(pdev, &host);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
svia_configure(pdev);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||
&svia_sht);
|
||||
}
|
||||
|
||||
static int __init svia_init(void)
|
||||
|
|
|
@ -333,7 +333,6 @@ static const struct ata_port_operations vsc_sata_ops = {
|
|||
.thaw = vsc_thaw,
|
||||
.error_handler = ata_bmdma_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
.irq_handler = vsc_sata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
.irq_on = ata_irq_on,
|
||||
.irq_ack = ata_irq_ack,
|
||||
|
@ -367,30 +366,50 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
|
|||
|
||||
static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
static const struct ata_port_info pi = {
|
||||
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &vsc_sata_ops,
|
||||
};
|
||||
const struct ata_port_info *ppi[] = { &pi, NULL };
|
||||
static int printed_version;
|
||||
struct ata_probe_ent *probe_ent;
|
||||
struct ata_host *host;
|
||||
void __iomem *mmio_base;
|
||||
int rc;
|
||||
int i, rc;
|
||||
u8 cls;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
/* allocate host */
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* Check if we have needed resource mapped.
|
||||
*/
|
||||
/* check if we have needed resource mapped */
|
||||
if (pci_resource_len(pdev, 0) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* map IO regions and intialize host accordingly */
|
||||
rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME);
|
||||
if (rc == -EBUSY)
|
||||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
host->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
mmio_base = host->iomap[VSC_MMIO_BAR];
|
||||
|
||||
for (i = 0; i < host->n_ports; i++)
|
||||
vsc_sata_setup_port(&host->ports[i]->ioaddr,
|
||||
mmio_base + (i + 1) * VSC_SATA_PORT_OFFSET);
|
||||
|
||||
/*
|
||||
* Use 32 bit DMA mask, because 64 bit address support is poor.
|
||||
|
@ -402,12 +421,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
|
||||
if (probe_ent == NULL)
|
||||
return -ENOMEM;
|
||||
probe_ent->dev = pci_dev_to_dev(pdev);
|
||||
INIT_LIST_HEAD(&probe_ent->node);
|
||||
|
||||
/*
|
||||
* Due to a bug in the chip, the default cache line size can't be
|
||||
* used (unless the default is non-zero).
|
||||
|
@ -418,33 +431,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
|
|||
|
||||
if (pci_enable_msi(pdev) == 0)
|
||||
pci_intx(pdev, 0);
|
||||
else
|
||||
probe_ent->irq_flags = IRQF_SHARED;
|
||||
|
||||
probe_ent->sht = &vsc_sata_sht;
|
||||
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
||||
ATA_FLAG_MMIO;
|
||||
probe_ent->port_ops = &vsc_sata_ops;
|
||||
probe_ent->n_ports = 4;
|
||||
probe_ent->irq = pdev->irq;
|
||||
probe_ent->iomap = pcim_iomap_table(pdev);
|
||||
|
||||
/* We don't care much about the PIO/UDMA masks, but the core won't like us
|
||||
* if we don't fill these
|
||||
*/
|
||||
probe_ent->pio_mask = 0x1f;
|
||||
probe_ent->mwdma_mask = 0x07;
|
||||
probe_ent->udma_mask = 0x7f;
|
||||
|
||||
mmio_base = probe_ent->iomap[VSC_MMIO_BAR];
|
||||
|
||||
/* We have 4 ports per PCI function */
|
||||
vsc_sata_setup_port(&probe_ent->port[0], mmio_base + 1 * VSC_SATA_PORT_OFFSET);
|
||||
vsc_sata_setup_port(&probe_ent->port[1], mmio_base + 2 * VSC_SATA_PORT_OFFSET);
|
||||
vsc_sata_setup_port(&probe_ent->port[2], mmio_base + 3 * VSC_SATA_PORT_OFFSET);
|
||||
vsc_sata_setup_port(&probe_ent->port[3], mmio_base + 4 * VSC_SATA_PORT_OFFSET);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
/*
|
||||
* Config offset 0x98 is "Extended Control and Status Register 0"
|
||||
|
@ -454,11 +440,9 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
|
|||
*/
|
||||
pci_write_config_dword(pdev, 0x98, 0);
|
||||
|
||||
if (!ata_device_add(probe_ent))
|
||||
return -ENODEV;
|
||||
|
||||
devm_kfree(&pdev->dev, probe_ent);
|
||||
return 0;
|
||||
pci_set_master(pdev);
|
||||
return ata_host_activate(host, pdev->irq, vsc_sata_interrupt,
|
||||
IRQF_SHARED, &vsc_sata_sht);
|
||||
}
|
||||
|
||||
static const struct pci_device_id vsc_sata_pci_tbl[] = {
|
||||
|
|
|
@ -1303,119 +1303,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
|
|||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic );
|
||||
#endif
|
||||
|
||||
enum ide_combined_type { COMBINED = 0, IDE = 1, LIBATA = 2 };
|
||||
/* Defaults to combined */
|
||||
static enum ide_combined_type combined_mode;
|
||||
|
||||
static int __init combined_setup(char *str)
|
||||
{
|
||||
if (!strncmp(str, "ide", 3))
|
||||
combined_mode = IDE;
|
||||
else if (!strncmp(str, "libata", 6))
|
||||
combined_mode = LIBATA;
|
||||
else /* "combined" or anything else defaults to old behavior */
|
||||
combined_mode = COMBINED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
__setup("combined_mode=", combined_setup);
|
||||
|
||||
#ifdef CONFIG_SATA_INTEL_COMBINED
|
||||
static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
|
||||
{
|
||||
u8 prog, comb, tmp;
|
||||
int ich = 0;
|
||||
|
||||
/*
|
||||
* Narrow down to Intel SATA PCI devices.
|
||||
*/
|
||||
switch (pdev->device) {
|
||||
/* PCI ids taken from drivers/scsi/ata_piix.c */
|
||||
case 0x24d1:
|
||||
case 0x24df:
|
||||
case 0x25a3:
|
||||
case 0x25b0:
|
||||
ich = 5;
|
||||
break;
|
||||
case 0x2651:
|
||||
case 0x2652:
|
||||
case 0x2653:
|
||||
case 0x2680: /* ESB2 */
|
||||
ich = 6;
|
||||
break;
|
||||
case 0x27c0:
|
||||
case 0x27c4:
|
||||
ich = 7;
|
||||
break;
|
||||
case 0x2828: /* ICH8M */
|
||||
ich = 8;
|
||||
break;
|
||||
default:
|
||||
/* we do not handle this PCI device */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read combined mode register.
|
||||
*/
|
||||
pci_read_config_byte(pdev, 0x90, &tmp); /* combined mode reg */
|
||||
|
||||
if (ich == 5) {
|
||||
tmp &= 0x6; /* interesting bits 2:1, PATA primary/secondary */
|
||||
if (tmp == 0x4) /* bits 10x */
|
||||
comb = (1 << 0); /* SATA port 0, PATA port 1 */
|
||||
else if (tmp == 0x6) /* bits 11x */
|
||||
comb = (1 << 2); /* PATA port 0, SATA port 1 */
|
||||
else
|
||||
return; /* not in combined mode */
|
||||
} else {
|
||||
WARN_ON((ich != 6) && (ich != 7) && (ich != 8));
|
||||
tmp &= 0x3; /* interesting bits 1:0 */
|
||||
if (tmp & (1 << 0))
|
||||
comb = (1 << 2); /* PATA port 0, SATA port 1 */
|
||||
else if (tmp & (1 << 1))
|
||||
comb = (1 << 0); /* SATA port 0, PATA port 1 */
|
||||
else
|
||||
return; /* not in combined mode */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read programming interface register.
|
||||
* (Tells us if it's legacy or native mode)
|
||||
*/
|
||||
pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
|
||||
|
||||
/* if SATA port is in native mode, we're ok. */
|
||||
if (prog & comb)
|
||||
return;
|
||||
|
||||
/* Don't reserve any so the IDE driver can get them (but only if
|
||||
* combined_mode=ide).
|
||||
*/
|
||||
if (combined_mode == IDE)
|
||||
return;
|
||||
|
||||
/* Grab them both for libata if combined_mode=libata. */
|
||||
if (combined_mode == LIBATA) {
|
||||
request_region(0x1f0, 8, "libata"); /* port 0 */
|
||||
request_region(0x170, 8, "libata"); /* port 1 */
|
||||
return;
|
||||
}
|
||||
|
||||
/* SATA port is in legacy mode. Reserve port so that
|
||||
* IDE driver does not attempt to use it. If request_region
|
||||
* fails, it will be obvious at boot time, so we don't bother
|
||||
* checking return values.
|
||||
*/
|
||||
if (comb == (1 << 0))
|
||||
request_region(0x1f0, 8, "libata"); /* port 0 */
|
||||
else
|
||||
request_region(0x170, 8, "libata"); /* port 1 */
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_combined );
|
||||
#endif /* CONFIG_SATA_INTEL_COMBINED */
|
||||
|
||||
|
||||
int pcie_mch_quirk;
|
||||
EXPORT_SYMBOL(pcie_mch_quirk);
|
||||
|
||||
|
|
|
@ -3770,7 +3770,8 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
|
|||
* Return value:
|
||||
* 0 on success / non-zero on failure
|
||||
**/
|
||||
static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes)
|
||||
static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ipr_sata_port *sata_port = ap->private_data;
|
||||
struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
|
||||
|
|
|
@ -159,11 +159,19 @@ enum {
|
|||
ATA_CMD_INIT_DEV_PARAMS = 0x91,
|
||||
ATA_CMD_READ_NATIVE_MAX = 0xF8,
|
||||
ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
|
||||
ATA_CMD_SET_MAX = 0xF9,
|
||||
ATA_CMD_SET_MAX_EXT = 0x37,
|
||||
ATA_CMD_READ_LOG_EXT = 0x2f,
|
||||
|
||||
/* READ_LOG_EXT pages */
|
||||
ATA_LOG_SATA_NCQ = 0x10,
|
||||
|
||||
/* READ/WRITE LONG (obsolete) */
|
||||
ATA_CMD_READ_LONG = 0x22,
|
||||
ATA_CMD_READ_LONG_ONCE = 0x23,
|
||||
ATA_CMD_WRITE_LONG = 0x32,
|
||||
ATA_CMD_WRITE_LONG_ONCE = 0x33,
|
||||
|
||||
/* SETFEATURES stuff */
|
||||
SETFEATURES_XFER = 0x03,
|
||||
XFER_UDMA_7 = 0x47,
|
||||
|
@ -194,6 +202,8 @@ enum {
|
|||
SETFEATURES_WC_ON = 0x02, /* Enable write cache */
|
||||
SETFEATURES_WC_OFF = 0x82, /* Disable write cache */
|
||||
|
||||
SETFEATURES_SPINUP = 0x07, /* Spin-up drive */
|
||||
|
||||
/* ATAPI stuff */
|
||||
ATAPI_PKT_DMA = (1 << 0),
|
||||
ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
|
||||
|
|
|
@ -99,7 +99,6 @@ extern struct resource ioport_resource;
|
|||
extern struct resource iomem_resource;
|
||||
|
||||
extern int request_resource(struct resource *root, struct resource *new);
|
||||
extern struct resource * ____request_resource(struct resource *root, struct resource *new);
|
||||
extern int release_resource(struct resource *new);
|
||||
extern int insert_resource(struct resource *parent, struct resource *new);
|
||||
extern int allocate_resource(struct resource *root, struct resource *new,
|
||||
|
|
|
@ -210,6 +210,7 @@ enum {
|
|||
|
||||
/* host set flags */
|
||||
ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */
|
||||
ATA_HOST_STARTED = (1 << 1), /* Host started */
|
||||
|
||||
/* various lengths of time */
|
||||
ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
|
||||
|
@ -281,11 +282,13 @@ enum {
|
|||
ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */
|
||||
ATA_EHI_QUIET = (1 << 3), /* be quiet */
|
||||
|
||||
ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */
|
||||
ATA_EHI_PRINTINFO = (1 << 17), /* print configuration info */
|
||||
ATA_EHI_SETMODE = (1 << 18), /* configure transfer mode */
|
||||
ATA_EHI_POST_SETMODE = (1 << 19), /* revaildating after setmode */
|
||||
ATA_EHI_DID_SOFTRESET = (1 << 16), /* already soft-reset this port */
|
||||
ATA_EHI_DID_HARDRESET = (1 << 17), /* already soft-reset this port */
|
||||
ATA_EHI_PRINTINFO = (1 << 18), /* print configuration info */
|
||||
ATA_EHI_SETMODE = (1 << 19), /* configure transfer mode */
|
||||
ATA_EHI_POST_SETMODE = (1 << 20), /* revaildating after setmode */
|
||||
|
||||
ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
|
||||
ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
|
||||
|
||||
/* max repeat if error condition is still set after ->error_handler */
|
||||
|
@ -367,34 +370,6 @@ struct ata_ioports {
|
|||
void __iomem *scr_addr;
|
||||
};
|
||||
|
||||
struct ata_probe_ent {
|
||||
struct list_head node;
|
||||
struct device *dev;
|
||||
const struct ata_port_operations *port_ops;
|
||||
struct scsi_host_template *sht;
|
||||
struct ata_ioports port[ATA_MAX_PORTS];
|
||||
unsigned int n_ports;
|
||||
unsigned int dummy_port_mask;
|
||||
unsigned int pio_mask;
|
||||
unsigned int mwdma_mask;
|
||||
unsigned int udma_mask;
|
||||
unsigned long irq;
|
||||
unsigned long irq2;
|
||||
unsigned int irq_flags;
|
||||
unsigned long port_flags;
|
||||
unsigned long _host_flags;
|
||||
void __iomem * const *iomap;
|
||||
void *private_data;
|
||||
|
||||
/* port_info for the secondary port. Together with irq2, it's
|
||||
* used to implement non-uniform secondary port. Currently,
|
||||
* the only user is ata_piix combined mode. This workaround
|
||||
* will be removed together with ata_probe_ent when init model
|
||||
* is updated.
|
||||
*/
|
||||
const struct ata_port_info *pinfo2;
|
||||
};
|
||||
|
||||
struct ata_host {
|
||||
spinlock_t lock;
|
||||
struct device *dev;
|
||||
|
@ -427,6 +402,7 @@ struct ata_queued_cmd {
|
|||
int dma_dir;
|
||||
|
||||
unsigned int pad_len;
|
||||
unsigned int sect_size;
|
||||
|
||||
unsigned int nbytes;
|
||||
unsigned int curbytes;
|
||||
|
@ -472,6 +448,7 @@ struct ata_device {
|
|||
struct scsi_device *sdev; /* attached SCSI device */
|
||||
/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
|
||||
u64 n_sectors; /* size of device, if ATA */
|
||||
u64 n_sectors_boot; /* size of ATA device at startup */
|
||||
unsigned int class; /* ATA_DEV_xxx */
|
||||
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
|
||||
u8 pio_mode;
|
||||
|
@ -597,11 +574,11 @@ struct ata_port {
|
|||
struct ata_port_operations {
|
||||
void (*port_disable) (struct ata_port *);
|
||||
|
||||
void (*dev_config) (struct ata_port *, struct ata_device *);
|
||||
void (*dev_config) (struct ata_device *);
|
||||
|
||||
void (*set_piomode) (struct ata_port *, struct ata_device *);
|
||||
void (*set_dmamode) (struct ata_port *, struct ata_device *);
|
||||
unsigned long (*mode_filter) (const struct ata_port *, struct ata_device *, unsigned long);
|
||||
unsigned long (*mode_filter) (struct ata_device *, unsigned long);
|
||||
|
||||
void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
|
||||
void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
|
||||
|
@ -616,6 +593,8 @@ struct ata_port_operations {
|
|||
|
||||
void (*post_set_mode) (struct ata_port *ap);
|
||||
|
||||
int (*cable_detect) (struct ata_port *ap);
|
||||
|
||||
int (*check_atapi_dma) (struct ata_queued_cmd *qc);
|
||||
|
||||
void (*bmdma_setup) (struct ata_queued_cmd *qc);
|
||||
|
@ -664,6 +643,7 @@ struct ata_port_info {
|
|||
unsigned long mwdma_mask;
|
||||
unsigned long udma_mask;
|
||||
const struct ata_port_operations *port_ops;
|
||||
irq_handler_t irq_handler;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
|
@ -686,6 +666,7 @@ extern const unsigned long sata_deb_timing_hotplug[];
|
|||
extern const unsigned long sata_deb_timing_long[];
|
||||
|
||||
extern const struct ata_port_operations ata_dummy_port_ops;
|
||||
extern const struct ata_port_info ata_dummy_port_info;
|
||||
|
||||
static inline const unsigned long *
|
||||
sata_ehc_deb_timing(struct ata_eh_context *ehc)
|
||||
|
@ -701,6 +682,7 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
|
|||
return ap->ops == &ata_dummy_port_ops;
|
||||
}
|
||||
|
||||
extern void sata_print_link_status(struct ata_port *ap);
|
||||
extern void ata_port_probe(struct ata_port *);
|
||||
extern void __sata_phy_reset(struct ata_port *ap);
|
||||
extern void sata_phy_reset(struct ata_port *ap);
|
||||
|
@ -728,7 +710,15 @@ extern int ata_pci_device_resume(struct pci_dev *pdev);
|
|||
#endif
|
||||
extern int ata_pci_clear_simplex(struct pci_dev *pdev);
|
||||
#endif /* CONFIG_PCI */
|
||||
extern int ata_device_add(const struct ata_probe_ent *ent);
|
||||
extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
|
||||
extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
|
||||
const struct ata_port_info * const * ppi, int n_ports);
|
||||
extern int ata_host_start(struct ata_host *host);
|
||||
extern int ata_host_register(struct ata_host *host,
|
||||
struct scsi_host_template *sht);
|
||||
extern int ata_host_activate(struct ata_host *host, int irq,
|
||||
irq_handler_t irq_handler, unsigned long irq_flags,
|
||||
struct scsi_host_template *sht);
|
||||
extern void ata_host_detach(struct ata_host *host);
|
||||
extern void ata_host_init(struct ata_host *, struct device *,
|
||||
unsigned long, const struct ata_port_operations *);
|
||||
|
@ -828,11 +818,17 @@ extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
|
|||
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
|
||||
int queue_depth);
|
||||
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
|
||||
extern int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
|
||||
extern u8 ata_irq_on(struct ata_port *ap);
|
||||
extern u8 ata_dummy_irq_on(struct ata_port *ap);
|
||||
extern u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
|
||||
extern u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq);
|
||||
|
||||
extern int ata_cable_40wire(struct ata_port *ap);
|
||||
extern int ata_cable_80wire(struct ata_port *ap);
|
||||
extern int ata_cable_sata(struct ata_port *ap);
|
||||
extern int ata_cable_unknown(struct ata_port *ap);
|
||||
|
||||
/*
|
||||
* Timing helpers
|
||||
*/
|
||||
|
@ -870,10 +866,13 @@ struct pci_bits {
|
|||
unsigned long val;
|
||||
};
|
||||
|
||||
extern struct ata_probe_ent *
|
||||
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
|
||||
extern int ata_pci_init_native_host(struct ata_host *host,
|
||||
unsigned int port_mask);
|
||||
extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
|
||||
const struct ata_port_info * const * ppi,
|
||||
int n_ports, struct ata_host **r_host);
|
||||
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
|
||||
extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_device *, unsigned long);
|
||||
extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
|
@ -1173,6 +1172,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
|
|||
qc->n_elem = 0;
|
||||
qc->err_mask = 0;
|
||||
qc->pad_len = 0;
|
||||
qc->sect_size = ATA_SECT_SIZE;
|
||||
|
||||
ata_tf_init(qc->dev, &qc->tf);
|
||||
|
||||
|
@ -1220,7 +1220,7 @@ static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
|
|||
|
||||
static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
|
||||
{
|
||||
return (struct ata_port *) &host->hostdata[0];
|
||||
return *(struct ata_port **)&host->hostdata[0];
|
||||
}
|
||||
|
||||
#endif /* __LINUX_LIBATA_H__ */
|
||||
|
|
|
@ -838,6 +838,7 @@ void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
|
|||
void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
|
||||
void __iomem * const * pcim_iomap_table(struct pci_dev *pdev);
|
||||
int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);
|
||||
void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask);
|
||||
|
||||
extern int pci_pci_problems;
|
||||
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
|
||||
|
|
|
@ -368,7 +368,6 @@
|
|||
#define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379
|
||||
#define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a
|
||||
#define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380
|
||||
#define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381
|
||||
#define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
|
||||
#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c
|
||||
|
||||
|
|
|
@ -212,27 +212,6 @@ int request_resource(struct resource *root, struct resource *new)
|
|||
|
||||
EXPORT_SYMBOL(request_resource);
|
||||
|
||||
/**
|
||||
* ____request_resource - reserve a resource, with resource conflict returned
|
||||
* @root: root resource descriptor
|
||||
* @new: resource descriptor desired by caller
|
||||
*
|
||||
* Returns:
|
||||
* On success, NULL is returned.
|
||||
* On error, a pointer to the conflicting resource is returned.
|
||||
*/
|
||||
struct resource *____request_resource(struct resource *root, struct resource *new)
|
||||
{
|
||||
struct resource *conflict;
|
||||
|
||||
write_lock(&resource_lock);
|
||||
conflict = __request_resource(root, new);
|
||||
write_unlock(&resource_lock);
|
||||
return conflict;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(____request_resource);
|
||||
|
||||
/**
|
||||
* release_resource - release a previously reserved resource
|
||||
* @old: resource pointer
|
||||
|
|
26
lib/devres.c
26
lib/devres.c
|
@ -296,5 +296,31 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
|
|||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(pcim_iomap_regions);
|
||||
|
||||
/**
|
||||
* pcim_iounmap_regions - Unmap and release PCI BARs
|
||||
* @pdev: PCI device to map IO resources for
|
||||
* @mask: Mask of BARs to unmap and release
|
||||
*
|
||||
* Unamp and release regions specified by @mask.
|
||||
*/
|
||||
void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask)
|
||||
{
|
||||
void __iomem * const *iomap;
|
||||
int i;
|
||||
|
||||
iomap = pcim_iomap_table(pdev);
|
||||
if (!iomap)
|
||||
return;
|
||||
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
if (!(mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
pcim_iounmap(pdev, iomap[i]);
|
||||
pci_release_region(pdev, i);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pcim_iounmap_regions);
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue