1
0
Fork 0

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
  ...
hifive-unleashed-5.1
Linus Torvalds 2007-04-29 10:48:21 -07:00
commit f73b0a08ea
80 changed files with 3690 additions and 3352 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);
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);
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);

View File

@ -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,

View File

@ -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] = &pi;
if (pcicfg & 2)
ppi[1] = &pi;
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);
}
/**

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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), },

View File

@ -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,

View File

@ -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);
}
/**

View File

@ -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,

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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,

View File

@ -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 *

View File

@ -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[] = {

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -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);
}
/**

View File

@ -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,

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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 = {

View File

@ -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,

View File

@ -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,

View File

@ -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, &reg54);
@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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;
}
/**

View File

@ -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)

View File

@ -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[] = {

View File

@ -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)

View File

@ -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)

View File

@ -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);
}

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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[] = {

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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,

View File

@ -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__ */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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