mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
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: (82 commits) [PATCH] pata_ali: small fixes [PATCH] pata_via: VIA 8251 bridged systems are now out and about [PATCH] trivial piix: swap bogus dot for comma space [PATCH] sata_promise: PHYMODE4 fixup [PATCH] libata: always use polling IDENTIFY [libata] pata_cs5535: fix build [PATCH] ahci: do not powerdown during initialization [PATCH] libata: prepare ata_sg_clean() for invocation from EH [PATCH] libata: separate out rw ATA taskfile building into ata_build_rw_tf() [PATCH] libata: implement ata_exec_internal_sg() [PATCH] libata: make sure IRQ is cleared after ata_bmdma_freeze() [PATCH] libata: move BMDMA host status recording from EH to interrupt handler [PATCH] libata: make sure sdev doesn't go away while rescanning [PATCH] libata: don't request sense if the port is frozen [PATCH] libata: fix READ CAPACITY simulation [PATCH] libata: implement ATA_FLAG_SETXFER_POLLING and use it in pata_via, take #2 [PATCH] libata: set IRQF_SHARED for legacy PCI IDE IRQs [PATCH] libata: remove unused HSM_ST_UNKNOWN [PATCH] libata: kill unnecessary sht->max_sectors initializations [PATCH] libata: add missing sht->slave_destroy ...
This commit is contained in:
commit
ff51a98799
@ -328,6 +328,15 @@ config PATA_TRIFLEX
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_MARVELL
|
||||
tristate "Marvell PATA support via legacy mode"
|
||||
depends on PCI
|
||||
help
|
||||
This option enables limited support for the Marvell 88SE6145 ATA
|
||||
controller.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_MPIIX
|
||||
tristate "Intel PATA MPIIX support"
|
||||
depends on PCI
|
||||
@ -483,6 +492,32 @@ config PATA_WINBOND
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_WINBOND_VLB
|
||||
tristate "Winbond W83759A VLB PATA support (Experimental)"
|
||||
depends on ISA && EXPERIMENTAL
|
||||
help
|
||||
Support for the Winbond W83759A controller on Vesa Local Bus
|
||||
systems.
|
||||
|
||||
config PATA_PLATFORM
|
||||
tristate "Generic platform device PATA support"
|
||||
depends on EMBEDDED
|
||||
help
|
||||
This option enables support for generic directly connected ATA
|
||||
devices commonly found on embedded systems.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_IXP4XX_CF
|
||||
tristate "IXP4XX Compact Flash support"
|
||||
depends on ARCH_IXP4XX
|
||||
help
|
||||
This option enables support for a Compact Flash connected on
|
||||
the ixp4xx expansion bus. This driver had been written for
|
||||
Loft/Avila boards in mind but can work with others.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endif
|
||||
endmenu
|
||||
|
||||
|
@ -38,6 +38,7 @@ obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
|
||||
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
|
||||
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
|
||||
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
|
||||
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
|
||||
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
|
||||
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
|
||||
obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
|
||||
@ -51,8 +52,11 @@ obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
|
||||
obj-$(CONFIG_PATA_SIL680) += pata_sil680.o
|
||||
obj-$(CONFIG_PATA_VIA) += pata_via.o
|
||||
obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
|
||||
obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
|
||||
obj-$(CONFIG_PATA_SIS) += pata_sis.o
|
||||
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
|
||||
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
|
||||
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
|
||||
# Should be last but one libata driver
|
||||
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
|
||||
# Should be last libata driver
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
enum {
|
||||
AHCI_PCI_BAR = 5,
|
||||
AHCI_MAX_PORTS = 32,
|
||||
AHCI_MAX_SG = 168, /* hardware max is 64K */
|
||||
AHCI_DMA_BOUNDARY = 0xffffffff,
|
||||
AHCI_USE_CLUSTERING = 0,
|
||||
@ -77,8 +78,9 @@ enum {
|
||||
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
|
||||
|
||||
board_ahci = 0,
|
||||
board_ahci_vt8251 = 1,
|
||||
board_ahci_ign_iferr = 2,
|
||||
board_ahci_pi = 1,
|
||||
board_ahci_vt8251 = 2,
|
||||
board_ahci_ign_iferr = 3,
|
||||
|
||||
/* global controller registers */
|
||||
HOST_CAP = 0x00, /* host capabilities */
|
||||
@ -167,9 +169,9 @@ enum {
|
||||
AHCI_FLAG_MSI = (1 << 0),
|
||||
|
||||
/* ap->flags bits */
|
||||
AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24),
|
||||
AHCI_FLAG_NO_NCQ = (1 << 25),
|
||||
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 26), /* ignore IRQ_IF_ERR */
|
||||
AHCI_FLAG_NO_NCQ = (1 << 24),
|
||||
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
|
||||
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
|
||||
};
|
||||
|
||||
struct ahci_cmd_hdr {
|
||||
@ -216,6 +218,7 @@ static u8 ahci_check_status(struct ata_port *ap);
|
||||
static void ahci_freeze(struct ata_port *ap);
|
||||
static void ahci_thaw(struct ata_port *ap);
|
||||
static void ahci_error_handler(struct ata_port *ap);
|
||||
static void ahci_vt8251_error_handler(struct ata_port *ap);
|
||||
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
|
||||
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
|
||||
static int ahci_port_resume(struct ata_port *ap);
|
||||
@ -275,6 +278,37 @@ static const struct ata_port_operations ahci_ops = {
|
||||
.port_stop = ahci_port_stop,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations ahci_vt8251_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
.check_status = ahci_check_status,
|
||||
.check_altstatus = ahci_check_status,
|
||||
.dev_select = ata_noop_dev_select,
|
||||
|
||||
.tf_read = ahci_tf_read,
|
||||
|
||||
.qc_prep = ahci_qc_prep,
|
||||
.qc_issue = ahci_qc_issue,
|
||||
|
||||
.irq_handler = ahci_interrupt,
|
||||
.irq_clear = ahci_irq_clear,
|
||||
|
||||
.scr_read = ahci_scr_read,
|
||||
.scr_write = ahci_scr_write,
|
||||
|
||||
.freeze = ahci_freeze,
|
||||
.thaw = ahci_thaw,
|
||||
|
||||
.error_handler = ahci_vt8251_error_handler,
|
||||
.post_internal_cmd = ahci_post_internal_cmd,
|
||||
|
||||
.port_suspend = ahci_port_suspend,
|
||||
.port_resume = ahci_port_resume,
|
||||
|
||||
.port_start = ahci_port_start,
|
||||
.port_stop = ahci_port_stop,
|
||||
};
|
||||
|
||||
static const struct ata_port_info ahci_port_info[] = {
|
||||
/* board_ahci */
|
||||
{
|
||||
@ -286,16 +320,26 @@ static const struct ata_port_info ahci_port_info[] = {
|
||||
.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,
|
||||
.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 |
|
||||
AHCI_FLAG_RESET_NEEDS_CLO | AHCI_FLAG_NO_NCQ,
|
||||
ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
|
||||
.port_ops = &ahci_ops,
|
||||
.port_ops = &ahci_vt8251_ops,
|
||||
},
|
||||
/* board_ahci_ign_iferr */
|
||||
{
|
||||
@ -322,22 +366,22 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
|
||||
{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
|
||||
{ PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
|
||||
{ PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
|
||||
|
||||
/* JMicron */
|
||||
{ PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
|
||||
@ -372,6 +416,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
|
||||
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
|
||||
|
||||
/* Generic, PCI class code for AHCI */
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
0x010601, 0xffffff, board_ahci },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
@ -386,6 +434,11 @@ static struct pci_driver ahci_pci_driver = {
|
||||
};
|
||||
|
||||
|
||||
static inline int ahci_nr_ports(u32 cap)
|
||||
{
|
||||
return (cap & 0x1f) + 1;
|
||||
}
|
||||
|
||||
static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
|
||||
{
|
||||
return base + 0x100 + (port * 0x80);
|
||||
@ -559,9 +612,6 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
|
||||
static void ahci_init_port(void __iomem *port_mmio, u32 cap,
|
||||
dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
|
||||
{
|
||||
/* power up */
|
||||
ahci_power_up(port_mmio, cap);
|
||||
|
||||
/* enable FIS reception */
|
||||
ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
|
||||
|
||||
@ -587,19 +637,17 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* put device into slumber mode */
|
||||
ahci_power_down(port_mmio, cap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
||||
{
|
||||
u32 cap_save, tmp;
|
||||
u32 cap_save, impl_save, tmp;
|
||||
|
||||
cap_save = readl(mmio + HOST_CAP);
|
||||
cap_save &= ( (1<<28) | (1<<17) );
|
||||
cap_save |= (1 << 27);
|
||||
impl_save = readl(mmio + HOST_PORTS_IMPL);
|
||||
|
||||
/* global controller reset */
|
||||
tmp = readl(mmio + HOST_CTL);
|
||||
@ -620,10 +668,21 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* turn on AHCI mode */
|
||||
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(0xf, mmio + HOST_PORTS_IMPL);
|
||||
writel(impl_save, mmio + HOST_PORTS_IMPL);
|
||||
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
|
||||
@ -639,7 +698,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
|
||||
int n_ports, u32 cap)
|
||||
int n_ports, unsigned int port_flags,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
int i, rc;
|
||||
u32 tmp;
|
||||
@ -648,13 +708,12 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, i);
|
||||
const char *emsg = NULL;
|
||||
|
||||
#if 0 /* BIOSen initialize this incorrectly */
|
||||
if (!(hpriv->port_map & (1 << i)))
|
||||
if ((port_flags & AHCI_FLAG_HONOR_PI) &&
|
||||
!(hpriv->port_map & (1 << i)))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* make sure port is not active */
|
||||
rc = ahci_deinit_port(port_mmio, cap, &emsg);
|
||||
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
|
||||
if (rc)
|
||||
dev_printk(KERN_WARNING, &pdev->dev,
|
||||
"%s (%d)\n", emsg, rc);
|
||||
@ -729,17 +788,6 @@ static int ahci_clo(struct ata_port *ap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_prereset(struct ata_port *ap)
|
||||
{
|
||||
if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) &&
|
||||
(ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) {
|
||||
/* ATA_BUSY hasn't cleared, so send a CLO */
|
||||
ahci_clo(ap);
|
||||
}
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
@ -877,6 +925,31 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
void __iomem *mmio = ap->host->mmio_base;
|
||||
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
ahci_stop_engine(port_mmio);
|
||||
|
||||
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);
|
||||
|
||||
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
|
||||
|
||||
/* vt8251 doesn't clear BSY on signature FIS reception,
|
||||
* request follow-up softreset.
|
||||
*/
|
||||
return rc ?: -EAGAIN;
|
||||
}
|
||||
|
||||
static void ahci_postreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
|
||||
@ -1196,7 +1269,23 @@ static void ahci_error_handler(struct ata_port *ap)
|
||||
}
|
||||
|
||||
/* perform recovery */
|
||||
ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset,
|
||||
ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset,
|
||||
ahci_postreset);
|
||||
}
|
||||
|
||||
static void ahci_vt8251_error_handler(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->host->mmio_base;
|
||||
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);
|
||||
}
|
||||
|
||||
/* perform recovery */
|
||||
ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset,
|
||||
ahci_postreset);
|
||||
}
|
||||
|
||||
@ -1226,7 +1315,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
|
||||
int rc;
|
||||
|
||||
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
|
||||
if (rc) {
|
||||
if (rc == 0)
|
||||
ahci_power_down(port_mmio, hpriv->cap);
|
||||
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);
|
||||
@ -1242,6 +1333,7 @@ static int ahci_port_resume(struct ata_port *ap)
|
||||
void __iomem *mmio = ap->host->mmio_base;
|
||||
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);
|
||||
|
||||
return 0;
|
||||
@ -1281,7 +1373,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
ahci_init_controller(mmio, pdev, host->n_ports, hpriv->cap);
|
||||
ahci_init_controller(mmio, pdev, host->n_ports,
|
||||
host->ports[0]->flags, hpriv);
|
||||
}
|
||||
|
||||
ata_host_resume(host);
|
||||
@ -1347,6 +1440,9 @@ static int ahci_port_start(struct ata_port *ap)
|
||||
|
||||
ap->private_data = pp;
|
||||
|
||||
/* power up port */
|
||||
ahci_power_up(port_mmio, hpriv->cap);
|
||||
|
||||
/* initialize port */
|
||||
ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
|
||||
|
||||
@ -1393,7 +1489,7 @@ 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->mmio_base;
|
||||
unsigned int i, using_dac;
|
||||
unsigned int i, cap_n_ports, using_dac;
|
||||
int rc;
|
||||
|
||||
rc = ahci_reset_controller(mmio, pdev);
|
||||
@ -1402,10 +1498,34 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
|
||||
|
||||
hpriv->cap = readl(mmio + HOST_CAP);
|
||||
hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
|
||||
probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
|
||||
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, probe_ent->n_ports);
|
||||
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 &&
|
||||
@ -1437,7 +1557,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
|
||||
for (i = 0; i < probe_ent->n_ports; i++)
|
||||
ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
|
||||
|
||||
ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap);
|
||||
ahci_init_controller(mmio, pdev, probe_ent->n_ports,
|
||||
probe_ent->port_flags, hpriv);
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "ata_generic"
|
||||
#define DRV_VERSION "0.2.6"
|
||||
#define DRV_VERSION "0.2.10"
|
||||
|
||||
/*
|
||||
* A generic parallel ATA driver using libata
|
||||
@ -109,7 +109,6 @@ static struct scsi_host_template generic_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -118,6 +117,8 @@ static struct scsi_host_template generic_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations generic_port_ops = {
|
||||
@ -226,12 +227,14 @@ static struct pci_driver ata_generic_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = ata_generic,
|
||||
.probe = ata_generic_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init ata_generic_init(void)
|
||||
{
|
||||
return pci_module_init(&ata_generic_pci_driver);
|
||||
return pci_register_driver(&ata_generic_pci_driver);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
* Documentation
|
||||
* Publically available from Intel web site. Errata documentation
|
||||
* is also publically available. As an aide to anyone hacking on this
|
||||
* driver the list of errata that are relevant is below.going back to
|
||||
* driver the list of errata that are relevant is below, going back to
|
||||
* PIIX4. Older device documentation is now a bit tricky to find.
|
||||
*
|
||||
* The chipsets all follow very much the same design. The orginal Triton
|
||||
@ -93,7 +93,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "ata_piix"
|
||||
#define DRV_VERSION "2.00ac6"
|
||||
#define DRV_VERSION "2.00ac7"
|
||||
|
||||
enum {
|
||||
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
|
||||
@ -101,11 +101,13 @@ enum {
|
||||
ICH5_PCS = 0x92, /* port control and status */
|
||||
PIIX_SCC = 0x0A, /* sub-class code register */
|
||||
|
||||
PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */
|
||||
PIIX_FLAG_SCR = (1 << 26), /* SCR available */
|
||||
PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
|
||||
PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
|
||||
|
||||
PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS,
|
||||
PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
|
||||
|
||||
/* combined mode. if set, PATA is channel 0.
|
||||
* if clear, PATA is channel 1.
|
||||
*/
|
||||
@ -122,11 +124,10 @@ enum {
|
||||
ich_pata_100 = 3, /* ICH up to UDMA 100 */
|
||||
ich_pata_133 = 4, /* ICH up to UDMA 133 */
|
||||
ich5_sata = 5,
|
||||
esb_sata = 6,
|
||||
ich6_sata = 7,
|
||||
ich6_sata_ahci = 8,
|
||||
ich6m_sata_ahci = 9,
|
||||
ich8_sata_ahci = 10,
|
||||
ich6_sata = 6,
|
||||
ich6_sata_ahci = 7,
|
||||
ich6m_sata_ahci = 8,
|
||||
ich8_sata_ahci = 9,
|
||||
|
||||
/* constants for mapping table */
|
||||
P0 = 0, /* port 0 */
|
||||
@ -143,13 +144,11 @@ enum {
|
||||
struct piix_map_db {
|
||||
const u32 mask;
|
||||
const u16 port_enable;
|
||||
const int present_shift;
|
||||
const int map[][4];
|
||||
};
|
||||
|
||||
struct piix_host_priv {
|
||||
const int *map;
|
||||
const struct piix_map_db *map_db;
|
||||
};
|
||||
|
||||
static int piix_init_one (struct pci_dev *pdev,
|
||||
@ -214,9 +213,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
||||
/* 82801EB (ICH5) */
|
||||
{ 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
|
||||
/* 6300ESB (ICH5 variant with broken PCS present bits) */
|
||||
{ 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
|
||||
{ 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
|
||||
/* 6300ESB pretending RAID */
|
||||
{ 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
|
||||
{ 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
|
||||
/* 82801FB/FW (ICH6/ICH6W) */
|
||||
{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
|
||||
/* 82801FR/FRW (ICH6R/ICH6RW) */
|
||||
@ -367,7 +366,6 @@ static const struct ata_port_operations piix_sata_ops = {
|
||||
static const struct piix_map_db ich5_map_db = {
|
||||
.mask = 0x7,
|
||||
.port_enable = 0x3,
|
||||
.present_shift = 4,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, NA, P1, NA }, /* 000b */
|
||||
@ -384,7 +382,6 @@ static const struct piix_map_db ich5_map_db = {
|
||||
static const struct piix_map_db ich6_map_db = {
|
||||
.mask = 0x3,
|
||||
.port_enable = 0xf,
|
||||
.present_shift = 4,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, P2, P1, P3 }, /* 00b */
|
||||
@ -397,7 +394,6 @@ static const struct piix_map_db ich6_map_db = {
|
||||
static const struct piix_map_db ich6m_map_db = {
|
||||
.mask = 0x3,
|
||||
.port_enable = 0x5,
|
||||
.present_shift = 4,
|
||||
|
||||
/* Map 01b isn't specified in the doc but some notebooks use
|
||||
* it anyway. MAP 01b have been spotted on both ICH6M and
|
||||
@ -415,7 +411,6 @@ static const struct piix_map_db ich6m_map_db = {
|
||||
static const struct piix_map_db ich8_map_db = {
|
||||
.mask = 0x3,
|
||||
.port_enable = 0x3,
|
||||
.present_shift = 8,
|
||||
.map = {
|
||||
/* PM PS SM SS MAP */
|
||||
{ P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */
|
||||
@ -427,7 +422,6 @@ static const struct piix_map_db ich8_map_db = {
|
||||
|
||||
static const struct piix_map_db *piix_map_db_table[] = {
|
||||
[ich5_sata] = &ich5_map_db,
|
||||
[esb_sata] = &ich5_map_db,
|
||||
[ich6_sata] = &ich6_map_db,
|
||||
[ich6_sata_ahci] = &ich6_map_db,
|
||||
[ich6m_sata_ahci] = &ich6m_map_db,
|
||||
@ -438,7 +432,7 @@ static struct ata_port_info piix_port_info[] = {
|
||||
/* piix_pata_33: 0: PIIX3 or 4 at 33MHz */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
|
||||
.udma_mask = ATA_UDMA_MASK_40C,
|
||||
@ -448,7 +442,7 @@ static struct ata_port_info piix_port_info[] = {
|
||||
/* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio 0-4 */
|
||||
.mwdma_mask = 0x06, /* Check: maybe 0x07 */
|
||||
.udma_mask = ATA_UDMA2, /* UDMA33 */
|
||||
@ -457,7 +451,7 @@ static struct ata_port_info piix_port_info[] = {
|
||||
/* ich_pata_66: 2 ICH controllers up to 66MHz */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS,
|
||||
.flags = PIIX_PATA_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio 0-4 */
|
||||
.mwdma_mask = 0x06, /* MWDMA0 is broken on chip */
|
||||
.udma_mask = ATA_UDMA4,
|
||||
@ -467,7 +461,7 @@ static struct ata_port_info piix_port_info[] = {
|
||||
/* ich_pata_100: 3 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
|
||||
.flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x06, /* mwdma1-2 */
|
||||
.udma_mask = ATA_UDMA5, /* udma0-5 */
|
||||
@ -477,7 +471,7 @@ static struct ata_port_info piix_port_info[] = {
|
||||
/* ich_pata_133: 4 ICH with full UDMA6 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
|
||||
.flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
|
||||
.pio_mask = 0x1f, /* pio 0-4 */
|
||||
.mwdma_mask = 0x06, /* Check: maybe 0x07 */
|
||||
.udma_mask = ATA_UDMA6, /* UDMA133 */
|
||||
@ -487,41 +481,27 @@ static struct ata_port_info piix_port_info[] = {
|
||||
/* ich5_sata: 5 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR |
|
||||
PIIX_FLAG_IGNORE_PCS,
|
||||
.flags = PIIX_SATA_FLAGS,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* i6300esb_sata: 6 */
|
||||
/* ich6_sata: 6 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich6_sata: 7 */
|
||||
/* ich6_sata_ahci: 7 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
.udma_mask = 0x7f, /* udma0-6 */
|
||||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich6_sata_ahci: 8 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
PIIX_FLAG_AHCI,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
@ -529,11 +509,10 @@ static struct ata_port_info piix_port_info[] = {
|
||||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich6m_sata_ahci: 9 */
|
||||
/* ich6m_sata_ahci: 8 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
PIIX_FLAG_AHCI,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
@ -541,11 +520,10 @@ static struct ata_port_info piix_port_info[] = {
|
||||
.port_ops = &piix_sata_ops,
|
||||
},
|
||||
|
||||
/* ich8_sata_ahci: 10 */
|
||||
/* ich8_sata_ahci: 9 */
|
||||
{
|
||||
.sht = &piix_sht,
|
||||
.flags = ATA_FLAG_SATA |
|
||||
PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
|
||||
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
|
||||
PIIX_FLAG_AHCI,
|
||||
.pio_mask = 0x1f, /* pio0-4 */
|
||||
.mwdma_mask = 0x07, /* mwdma0-2 */
|
||||
@ -566,10 +544,22 @@ MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
static int force_pcs = 0;
|
||||
module_param(force_pcs, int, 0444);
|
||||
MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
|
||||
"device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)");
|
||||
struct ich_laptop {
|
||||
u16 device;
|
||||
u16 subvendor;
|
||||
u16 subdevice;
|
||||
};
|
||||
|
||||
/*
|
||||
* List of laptops that use short cables rather than 80 wire
|
||||
*/
|
||||
|
||||
static const struct ich_laptop ich_laptop[] = {
|
||||
/* devid, subvendor, subdev */
|
||||
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
|
||||
/* end marker */
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
/**
|
||||
* piix_pata_cbl_detect - Probe host controller cable detect info
|
||||
@ -585,12 +575,24 @@ MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
|
||||
static void ich_pata_cbl_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;
|
||||
}
|
||||
lap++;
|
||||
}
|
||||
|
||||
/* check BIOS cable detect results */
|
||||
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
|
||||
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
|
||||
@ -659,84 +661,9 @@ static void ich_pata_error_handler(struct ata_port *ap)
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
/**
|
||||
* piix_sata_present_mask - determine present mask for SATA host controller
|
||||
* @ap: Target port
|
||||
*
|
||||
* Reads SATA PCI device's PCI config register Port Configuration
|
||||
* and Status (PCS) to determine port and device availability.
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*
|
||||
* RETURNS:
|
||||
* determined present_mask
|
||||
*/
|
||||
static unsigned int piix_sata_present_mask(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct piix_host_priv *hpriv = ap->host->private_data;
|
||||
const unsigned int *map = hpriv->map;
|
||||
int base = 2 * ap->port_no;
|
||||
unsigned int present_mask = 0;
|
||||
int port, i;
|
||||
u16 pcs;
|
||||
|
||||
pci_read_config_word(pdev, ICH5_PCS, &pcs);
|
||||
DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
port = map[base + i];
|
||||
if (port < 0)
|
||||
continue;
|
||||
if ((ap->flags & PIIX_FLAG_IGNORE_PCS) ||
|
||||
(pcs & 1 << (hpriv->map_db->present_shift + port)))
|
||||
present_mask |= 1 << i;
|
||||
}
|
||||
|
||||
DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
|
||||
ap->id, pcs, present_mask);
|
||||
|
||||
return present_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* piix_sata_softreset - reset SATA host port via ATA SRST
|
||||
* @ap: port to reset
|
||||
* @classes: resulting classes of attached devices
|
||||
*
|
||||
* Reset SATA host port via ATA SRST. On controllers with
|
||||
* reliable PCS present bits, the bits are used to determine
|
||||
* device presence.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes)
|
||||
{
|
||||
unsigned int present_mask;
|
||||
int i, rc;
|
||||
|
||||
present_mask = piix_sata_present_mask(ap);
|
||||
|
||||
rc = ata_std_softreset(ap, classes);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
if (!(present_mask & (1 << i)))
|
||||
classes[i] = ATA_DEV_NONE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void piix_sata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL,
|
||||
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
|
||||
ata_std_postreset);
|
||||
}
|
||||
|
||||
@ -1051,18 +978,6 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev,
|
||||
pci_write_config_word(pdev, ICH5_PCS, new_pcs);
|
||||
msleep(150);
|
||||
}
|
||||
|
||||
if (force_pcs == 1) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"force ignoring PCS (0x%x)\n", new_pcs);
|
||||
pinfo[0].flags |= PIIX_FLAG_IGNORE_PCS;
|
||||
pinfo[1].flags |= PIIX_FLAG_IGNORE_PCS;
|
||||
} else if (force_pcs == 2) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"force honoring PCS (0x%x)\n", new_pcs);
|
||||
pinfo[0].flags &= ~PIIX_FLAG_IGNORE_PCS;
|
||||
pinfo[1].flags &= ~PIIX_FLAG_IGNORE_PCS;
|
||||
}
|
||||
}
|
||||
|
||||
static void __devinit piix_init_sata_map(struct pci_dev *pdev,
|
||||
@ -1112,7 +1027,6 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
|
||||
"invalid MAP value %u\n", map_value);
|
||||
|
||||
hpriv->map = map;
|
||||
hpriv->map_db = map_db;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,7 +199,8 @@ static const u8 ata_rw_cmds[] = {
|
||||
|
||||
/**
|
||||
* ata_rwcmd_protocol - set taskfile r/w commands and protocol
|
||||
* @qc: command to examine and configure
|
||||
* @tf: command to examine and configure
|
||||
* @dev: device tf belongs to
|
||||
*
|
||||
* Examine the device configuration and tf->flags to calculate
|
||||
* the proper read/write commands and protocol to use.
|
||||
@ -207,10 +208,8 @@ static const u8 ata_rw_cmds[] = {
|
||||
* LOCKING:
|
||||
* caller.
|
||||
*/
|
||||
int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
|
||||
static int ata_rwcmd_protocol(struct ata_taskfile *tf, struct ata_device *dev)
|
||||
{
|
||||
struct ata_taskfile *tf = &qc->tf;
|
||||
struct ata_device *dev = qc->dev;
|
||||
u8 cmd;
|
||||
|
||||
int index, fua, lba48, write;
|
||||
@ -222,7 +221,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
|
||||
if (dev->flags & ATA_DFLAG_PIO) {
|
||||
tf->protocol = ATA_PROT_PIO;
|
||||
index = dev->multi_count ? 0 : 8;
|
||||
} else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) {
|
||||
} else if (lba48 && (dev->ap->flags & ATA_FLAG_PIO_LBA48)) {
|
||||
/* Unable to use DMA due to host limitation */
|
||||
tf->protocol = ATA_PROT_PIO;
|
||||
index = dev->multi_count ? 0 : 8;
|
||||
@ -239,6 +238,174 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_tf_read_block - Read block address from ATA taskfile
|
||||
* @tf: ATA taskfile of interest
|
||||
* @dev: ATA device @tf belongs to
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Read block address from @tf. This function can handle all
|
||||
* three address formats - LBA, LBA48 and CHS. tf->protocol and
|
||||
* flags select the address format to use.
|
||||
*
|
||||
* RETURNS:
|
||||
* Block address read from @tf.
|
||||
*/
|
||||
u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
|
||||
{
|
||||
u64 block = 0;
|
||||
|
||||
if (tf->flags & ATA_TFLAG_LBA) {
|
||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||
block |= (u64)tf->hob_lbah << 40;
|
||||
block |= (u64)tf->hob_lbam << 32;
|
||||
block |= tf->hob_lbal << 24;
|
||||
} else
|
||||
block |= (tf->device & 0xf) << 24;
|
||||
|
||||
block |= tf->lbah << 16;
|
||||
block |= tf->lbam << 8;
|
||||
block |= tf->lbal;
|
||||
} else {
|
||||
u32 cyl, head, sect;
|
||||
|
||||
cyl = tf->lbam | (tf->lbah << 8);
|
||||
head = tf->device & 0xf;
|
||||
sect = tf->lbal;
|
||||
|
||||
block = (cyl * dev->heads + head) * dev->sectors + sect;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_build_rw_tf - Build ATA taskfile for given read/write request
|
||||
* @tf: Target ATA taskfile
|
||||
* @dev: ATA device @tf belongs to
|
||||
* @block: Block address
|
||||
* @n_block: Number of blocks
|
||||
* @tf_flags: RW/FUA etc...
|
||||
* @tag: tag
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* Build ATA taskfile @tf for read/write request described by
|
||||
* @block, @n_block, @tf_flags and @tag on @dev.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* 0 on success, -ERANGE if the request is too large for @dev,
|
||||
* -EINVAL if the request is invalid.
|
||||
*/
|
||||
int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
|
||||
u64 block, u32 n_block, unsigned int tf_flags,
|
||||
unsigned int tag)
|
||||
{
|
||||
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
||||
tf->flags |= tf_flags;
|
||||
|
||||
if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
|
||||
ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ &&
|
||||
likely(tag != ATA_TAG_INTERNAL)) {
|
||||
/* yay, NCQ */
|
||||
if (!lba_48_ok(block, n_block))
|
||||
return -ERANGE;
|
||||
|
||||
tf->protocol = ATA_PROT_NCQ;
|
||||
tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
|
||||
|
||||
if (tf->flags & ATA_TFLAG_WRITE)
|
||||
tf->command = ATA_CMD_FPDMA_WRITE;
|
||||
else
|
||||
tf->command = ATA_CMD_FPDMA_READ;
|
||||
|
||||
tf->nsect = tag << 3;
|
||||
tf->hob_feature = (n_block >> 8) & 0xff;
|
||||
tf->feature = n_block & 0xff;
|
||||
|
||||
tf->hob_lbah = (block >> 40) & 0xff;
|
||||
tf->hob_lbam = (block >> 32) & 0xff;
|
||||
tf->hob_lbal = (block >> 24) & 0xff;
|
||||
tf->lbah = (block >> 16) & 0xff;
|
||||
tf->lbam = (block >> 8) & 0xff;
|
||||
tf->lbal = block & 0xff;
|
||||
|
||||
tf->device = 1 << 6;
|
||||
if (tf->flags & ATA_TFLAG_FUA)
|
||||
tf->device |= 1 << 7;
|
||||
} else if (dev->flags & ATA_DFLAG_LBA) {
|
||||
tf->flags |= ATA_TFLAG_LBA;
|
||||
|
||||
if (lba_28_ok(block, n_block)) {
|
||||
/* use LBA28 */
|
||||
tf->device |= (block >> 24) & 0xf;
|
||||
} else if (lba_48_ok(block, n_block)) {
|
||||
if (!(dev->flags & ATA_DFLAG_LBA48))
|
||||
return -ERANGE;
|
||||
|
||||
/* use LBA48 */
|
||||
tf->flags |= ATA_TFLAG_LBA48;
|
||||
|
||||
tf->hob_nsect = (n_block >> 8) & 0xff;
|
||||
|
||||
tf->hob_lbah = (block >> 40) & 0xff;
|
||||
tf->hob_lbam = (block >> 32) & 0xff;
|
||||
tf->hob_lbal = (block >> 24) & 0xff;
|
||||
} else
|
||||
/* request too large even for LBA48 */
|
||||
return -ERANGE;
|
||||
|
||||
if (unlikely(ata_rwcmd_protocol(tf, dev) < 0))
|
||||
return -EINVAL;
|
||||
|
||||
tf->nsect = n_block & 0xff;
|
||||
|
||||
tf->lbah = (block >> 16) & 0xff;
|
||||
tf->lbam = (block >> 8) & 0xff;
|
||||
tf->lbal = block & 0xff;
|
||||
|
||||
tf->device |= ATA_LBA;
|
||||
} else {
|
||||
/* CHS */
|
||||
u32 sect, head, cyl, track;
|
||||
|
||||
/* The request -may- be too large for CHS addressing. */
|
||||
if (!lba_28_ok(block, n_block))
|
||||
return -ERANGE;
|
||||
|
||||
if (unlikely(ata_rwcmd_protocol(tf, dev) < 0))
|
||||
return -EINVAL;
|
||||
|
||||
/* Convert LBA to CHS */
|
||||
track = (u32)block / dev->sectors;
|
||||
cyl = track / dev->heads;
|
||||
head = track % dev->heads;
|
||||
sect = (u32)block % dev->sectors + 1;
|
||||
|
||||
DPRINTK("block %u track %u cyl %u head %u sect %u\n",
|
||||
(u32)block, track, cyl, head, sect);
|
||||
|
||||
/* Check whether the converted CHS can fit.
|
||||
Cylinder: 0-65535
|
||||
Head: 0-15
|
||||
Sector: 1-255*/
|
||||
if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
|
||||
return -ERANGE;
|
||||
|
||||
tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
|
||||
tf->lbal = sect;
|
||||
tf->lbam = cyl;
|
||||
tf->lbah = cyl >> 8;
|
||||
tf->device |= head;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
|
||||
* @pio_mask: pio_mask
|
||||
@ -999,13 +1166,13 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_exec_internal - execute libata internal command
|
||||
* ata_exec_internal_sg - execute libata internal command
|
||||
* @dev: Device to which the command is sent
|
||||
* @tf: Taskfile registers for the command and the result
|
||||
* @cdb: CDB for packet command
|
||||
* @dma_dir: Data tranfer direction of the command
|
||||
* @buf: Data buffer of the command
|
||||
* @buflen: Length of data buffer
|
||||
* @sg: sg list for the data buffer of the command
|
||||
* @n_elem: Number of sg entries
|
||||
*
|
||||
* Executes libata internal command with timeout. @tf contains
|
||||
* command on entry and result on return. Timeout and error
|
||||
@ -1019,9 +1186,10 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
|
||||
* RETURNS:
|
||||
* Zero on success, AC_ERR_* mask on failure
|
||||
*/
|
||||
unsigned ata_exec_internal(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, void *buf, unsigned int buflen)
|
||||
unsigned ata_exec_internal_sg(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, struct scatterlist *sg,
|
||||
unsigned int n_elem)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
u8 command = tf->command;
|
||||
@ -1077,7 +1245,12 @@ unsigned ata_exec_internal(struct ata_device *dev,
|
||||
qc->flags |= ATA_QCFLAG_RESULT_TF;
|
||||
qc->dma_dir = dma_dir;
|
||||
if (dma_dir != DMA_NONE) {
|
||||
ata_sg_init_one(qc, buf, buflen);
|
||||
unsigned int i, buflen = 0;
|
||||
|
||||
for (i = 0; i < n_elem; i++)
|
||||
buflen += sg[i].length;
|
||||
|
||||
ata_sg_init(qc, sg, n_elem);
|
||||
qc->nsect = buflen / ATA_SECT_SIZE;
|
||||
}
|
||||
|
||||
@ -1160,6 +1333,35 @@ unsigned ata_exec_internal(struct ata_device *dev,
|
||||
return err_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_exec_internal_sg - execute libata internal command
|
||||
* @dev: Device to which the command is sent
|
||||
* @tf: Taskfile registers for the command and the result
|
||||
* @cdb: CDB for packet command
|
||||
* @dma_dir: Data tranfer direction of the command
|
||||
* @buf: Data buffer of the command
|
||||
* @buflen: Length of data buffer
|
||||
*
|
||||
* Wrapper around ata_exec_internal_sg() which takes simple
|
||||
* buffer instead of sg list.
|
||||
*
|
||||
* LOCKING:
|
||||
* None. Should be called with kernel context, might sleep.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, AC_ERR_* mask on failure
|
||||
*/
|
||||
unsigned ata_exec_internal(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, void *buf, unsigned int buflen)
|
||||
{
|
||||
struct scatterlist sg;
|
||||
|
||||
sg_init_one(&sg, buf, buflen);
|
||||
|
||||
return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_do_simple_cmd - execute simple internal command
|
||||
* @dev: Device to which the command is sent
|
||||
@ -1224,7 +1426,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
|
||||
* ata_dev_read_id - Read ID data from the specified device
|
||||
* @dev: target device
|
||||
* @p_class: pointer to class of the target device (may be changed)
|
||||
* @post_reset: is this read ID post-reset?
|
||||
* @flags: ATA_READID_* flags
|
||||
* @id: buffer to read IDENTIFY data into
|
||||
*
|
||||
* Read ID data from the specified device. ATA_CMD_ID_ATA is
|
||||
@ -1239,7 +1441,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
int post_reset, u16 *id)
|
||||
unsigned int flags, u16 *id)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
unsigned int class = *p_class;
|
||||
@ -1271,10 +1473,17 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
}
|
||||
|
||||
tf.protocol = ATA_PROT_PIO;
|
||||
tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
|
||||
|
||||
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
|
||||
id, sizeof(id[0]) * ATA_ID_WORDS);
|
||||
if (err_mask) {
|
||||
if (err_mask & AC_ERR_NODEV_HINT) {
|
||||
DPRINTK("ata%u.%d: NODEV after polling detection\n",
|
||||
ap->id, dev->devno);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
rc = -EIO;
|
||||
reason = "I/O error";
|
||||
goto err_out;
|
||||
@ -1294,7 +1503,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (post_reset && class == ATA_DEV_ATA) {
|
||||
if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
|
||||
/*
|
||||
* The exact sequence expected by certain pre-ATA4 drives is:
|
||||
* SRST RESET
|
||||
@ -1314,7 +1523,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
/* current CHS translation info (id[53-58]) might be
|
||||
* changed. reread the identify device info.
|
||||
*/
|
||||
post_reset = 0;
|
||||
flags &= ~ATA_READID_POSTRESET;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
@ -1345,7 +1554,10 @@ static void ata_dev_config_ncq(struct ata_device *dev,
|
||||
desc[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
|
||||
snprintf(desc, desc_sz, "NCQ (not used)");
|
||||
return;
|
||||
}
|
||||
if (ap->flags & ATA_FLAG_NCQ) {
|
||||
hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
|
||||
dev->flags |= ATA_DFLAG_NCQ;
|
||||
@ -1374,7 +1586,6 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
|
||||
/**
|
||||
* ata_dev_configure - Configure the specified ATA/ATAPI device
|
||||
* @dev: Target device to configure
|
||||
* @print_info: Enable device info printout
|
||||
*
|
||||
* Configure @dev according to @dev->id. Generic and low-level
|
||||
* driver specific fixups are also applied.
|
||||
@ -1385,9 +1596,10 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise
|
||||
*/
|
||||
int ata_dev_configure(struct ata_device *dev, int print_info)
|
||||
int ata_dev_configure(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->ap;
|
||||
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
|
||||
const u16 *id = dev->id;
|
||||
unsigned int xfer_mask;
|
||||
char revbuf[7]; /* XYZ-99\0 */
|
||||
@ -1454,6 +1666,10 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
|
||||
if (ata_id_has_lba48(id)) {
|
||||
dev->flags |= ATA_DFLAG_LBA48;
|
||||
lba_desc = "LBA48";
|
||||
|
||||
if (dev->n_sectors >= (1UL << 28) &&
|
||||
ata_id_has_flush_ext(id))
|
||||
dev->flags |= ATA_DFLAG_FLUSH_EXT;
|
||||
}
|
||||
|
||||
/* config NCQ */
|
||||
@ -1530,6 +1746,11 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
|
||||
cdb_intr_string);
|
||||
}
|
||||
|
||||
/* determine max_sectors */
|
||||
dev->max_sectors = ATA_MAX_SECTORS;
|
||||
if (dev->flags & ATA_DFLAG_LBA48)
|
||||
dev->max_sectors = ATA_MAX_SECTORS_LBA48;
|
||||
|
||||
if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
|
||||
/* Let the user know. We don't want to disallow opens for
|
||||
rescue purposes, or in case the vendor is just a blithering
|
||||
@ -1631,11 +1852,14 @@ int ata_bus_probe(struct ata_port *ap)
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
|
||||
rc = ata_dev_read_id(dev, &dev->class, ATA_READID_POSTRESET,
|
||||
dev->id);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
rc = ata_dev_configure(dev, 1);
|
||||
ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
|
||||
rc = ata_dev_configure(dev);
|
||||
ap->eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
|
||||
if (rc)
|
||||
goto fail;
|
||||
}
|
||||
@ -2153,6 +2377,7 @@ int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
|
||||
|
||||
static int ata_dev_set_mode(struct ata_device *dev)
|
||||
{
|
||||
struct ata_eh_context *ehc = &dev->ap->eh_context;
|
||||
unsigned int err_mask;
|
||||
int rc;
|
||||
|
||||
@ -2167,7 +2392,9 @@ static int ata_dev_set_mode(struct ata_device *dev)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ehc->i.flags |= ATA_EHI_POST_SETMODE;
|
||||
rc = ata_dev_revalidate(dev, 0);
|
||||
ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -2325,11 +2552,14 @@ static inline void ata_tf_to_host(struct ata_port *ap,
|
||||
* Sleep until ATA Status register bit BSY clears,
|
||||
* or a timeout occurs.
|
||||
*
|
||||
* LOCKING: None.
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
|
||||
unsigned int ata_busy_sleep (struct ata_port *ap,
|
||||
unsigned long tmout_pat, unsigned long tmout)
|
||||
int ata_busy_sleep(struct ata_port *ap,
|
||||
unsigned long tmout_pat, unsigned long tmout)
|
||||
{
|
||||
unsigned long timer_start, timeout;
|
||||
u8 status;
|
||||
@ -2337,27 +2567,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
|
||||
status = ata_busy_wait(ap, ATA_BUSY, 300);
|
||||
timer_start = jiffies;
|
||||
timeout = timer_start + tmout_pat;
|
||||
while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
|
||||
while (status != 0xff && (status & ATA_BUSY) &&
|
||||
time_before(jiffies, timeout)) {
|
||||
msleep(50);
|
||||
status = ata_busy_wait(ap, ATA_BUSY, 3);
|
||||
}
|
||||
|
||||
if (status & ATA_BUSY)
|
||||
if (status != 0xff && (status & ATA_BUSY))
|
||||
ata_port_printk(ap, KERN_WARNING,
|
||||
"port is slow to respond, please be patient "
|
||||
"(Status 0x%x)\n", status);
|
||||
|
||||
timeout = timer_start + tmout;
|
||||
while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
|
||||
while (status != 0xff && (status & ATA_BUSY) &&
|
||||
time_before(jiffies, timeout)) {
|
||||
msleep(50);
|
||||
status = ata_chk_status(ap);
|
||||
}
|
||||
|
||||
if (status == 0xff)
|
||||
return -ENODEV;
|
||||
|
||||
if (status & ATA_BUSY) {
|
||||
ata_port_printk(ap, KERN_ERR, "port failed to respond "
|
||||
"(%lu secs, Status 0x%x)\n",
|
||||
tmout / HZ, status);
|
||||
return 1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2448,10 +2683,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
|
||||
* the bus shows 0xFF because the odd clown forgets the D7
|
||||
* pulldown resistor.
|
||||
*/
|
||||
if (ata_check_status(ap) == 0xFF) {
|
||||
ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
|
||||
return AC_ERR_OTHER;
|
||||
}
|
||||
if (ata_check_status(ap) == 0xFF)
|
||||
return 0;
|
||||
|
||||
ata_bus_post_reset(ap, devmask);
|
||||
|
||||
@ -2777,9 +3010,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
|
||||
}
|
||||
|
||||
/**
|
||||
* sata_std_hardreset - reset host port via SATA phy reset
|
||||
* sata_port_hardreset - reset port via SATA phy reset
|
||||
* @ap: port to reset
|
||||
* @class: resulting class of attached device
|
||||
* @timing: timing parameters { interval, duratinon, timeout } in msec
|
||||
*
|
||||
* SATA phy-reset host port using DET bits of SControl register.
|
||||
*
|
||||
@ -2789,10 +3022,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
const unsigned long *timing = sata_ehc_deb_timing(ehc);
|
||||
u32 scontrol;
|
||||
int rc;
|
||||
|
||||
@ -2805,24 +3036,24 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
* and Sil3124.
|
||||
*/
|
||||
if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
|
||||
return rc;
|
||||
goto out;
|
||||
|
||||
scontrol = (scontrol & 0x0f0) | 0x304;
|
||||
|
||||
if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
|
||||
return rc;
|
||||
goto out;
|
||||
|
||||
sata_set_spd(ap);
|
||||
}
|
||||
|
||||
/* issue phy wake/reset */
|
||||
if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
|
||||
return rc;
|
||||
goto out;
|
||||
|
||||
scontrol = (scontrol & 0x0f0) | 0x301;
|
||||
|
||||
if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
|
||||
return rc;
|
||||
goto out;
|
||||
|
||||
/* Couldn't find anything in SATA I/II specs, but AHCI-1.1
|
||||
* 10.4.2 says at least 1 ms.
|
||||
@ -2830,7 +3061,40 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
msleep(1);
|
||||
|
||||
/* bring phy back */
|
||||
sata_phy_resume(ap, timing);
|
||||
rc = sata_phy_resume(ap, timing);
|
||||
out:
|
||||
DPRINTK("EXIT, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* sata_std_hardreset - reset host port via SATA phy reset
|
||||
* @ap: port to reset
|
||||
* @class: resulting class of attached device
|
||||
*
|
||||
* SATA phy-reset host port using DET bits of SControl register,
|
||||
* wait for !BSY and classify the attached device.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
{
|
||||
const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
/* do hardreset */
|
||||
rc = sata_port_hardreset(ap, timing);
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_ERR,
|
||||
"COMRESET failed (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* TODO: phy layer with polling, timeouts, etc. */
|
||||
if (ata_port_offline(ap)) {
|
||||
@ -2969,7 +3233,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
|
||||
/**
|
||||
* ata_dev_revalidate - Revalidate ATA device
|
||||
* @dev: device to revalidate
|
||||
* @post_reset: is this revalidation after reset?
|
||||
* @readid_flags: read ID flags
|
||||
*
|
||||
* Re-read IDENTIFY page and make sure @dev is still attached to
|
||||
* the port.
|
||||
@ -2980,7 +3244,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
|
||||
* RETURNS:
|
||||
* 0 on success, negative errno otherwise
|
||||
*/
|
||||
int ata_dev_revalidate(struct ata_device *dev, int post_reset)
|
||||
int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
|
||||
{
|
||||
unsigned int class = dev->class;
|
||||
u16 *id = (void *)dev->ap->sector_buf;
|
||||
@ -2992,7 +3256,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
|
||||
}
|
||||
|
||||
/* read ID data */
|
||||
rc = ata_dev_read_id(dev, &class, post_reset, id);
|
||||
rc = ata_dev_read_id(dev, &class, readid_flags, id);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
@ -3005,7 +3269,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
|
||||
memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
|
||||
|
||||
/* configure device according to the new ID */
|
||||
rc = ata_dev_configure(dev, 0);
|
||||
rc = ata_dev_configure(dev);
|
||||
if (rc == 0)
|
||||
return 0;
|
||||
|
||||
@ -3014,37 +3278,55 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const char * const ata_dma_blacklist [] = {
|
||||
"WDC AC11000H", NULL,
|
||||
"WDC AC22100H", NULL,
|
||||
"WDC AC32500H", NULL,
|
||||
"WDC AC33100H", NULL,
|
||||
"WDC AC31600H", NULL,
|
||||
"WDC AC32100H", "24.09P07",
|
||||
"WDC AC23200L", "21.10N21",
|
||||
"Compaq CRD-8241B", NULL,
|
||||
"CRD-8400B", NULL,
|
||||
"CRD-8480B", NULL,
|
||||
"CRD-8482B", NULL,
|
||||
"CRD-84", NULL,
|
||||
"SanDisk SDP3B", NULL,
|
||||
"SanDisk SDP3B-64", NULL,
|
||||
"SANYO CD-ROM CRD", NULL,
|
||||
"HITACHI CDR-8", NULL,
|
||||
"HITACHI CDR-8335", NULL,
|
||||
"HITACHI CDR-8435", NULL,
|
||||
"Toshiba CD-ROM XM-6202B", NULL,
|
||||
"TOSHIBA CD-ROM XM-1702BC", NULL,
|
||||
"CD-532E-A", NULL,
|
||||
"E-IDE CD-ROM CR-840", NULL,
|
||||
"CD-ROM Drive/F5A", NULL,
|
||||
"WPI CDD-820", NULL,
|
||||
"SAMSUNG CD-ROM SC-148C", NULL,
|
||||
"SAMSUNG CD-ROM SC", NULL,
|
||||
"SanDisk SDP3B-64", NULL,
|
||||
"ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,
|
||||
"_NEC DV5800A", NULL,
|
||||
"SAMSUNG CD-ROM SN-124", "N001"
|
||||
struct ata_blacklist_entry {
|
||||
const char *model_num;
|
||||
const char *model_rev;
|
||||
unsigned long horkage;
|
||||
};
|
||||
|
||||
static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||
/* Devices with DMA related problems under Linux */
|
||||
{ "WDC AC11000H", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "WDC AC22100H", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "WDC AC32500H", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "WDC AC33100H", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "WDC AC31600H", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "WDC AC32100H", "24.09P07", ATA_HORKAGE_NODMA },
|
||||
{ "WDC AC23200L", "21.10N21", ATA_HORKAGE_NODMA },
|
||||
{ "Compaq CRD-8241B", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "CRD-8400B", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "CRD-8480B", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "CRD-8482B", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "CRD-84", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SanDisk SDP3B", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SANYO CD-ROM CRD", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "HITACHI CDR-8", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "HITACHI CDR-8335", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "HITACHI CDR-8435", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "Toshiba CD-ROM XM-6202B", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "CD-532E-A", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "E-IDE CD-ROM CR-840",NULL, ATA_HORKAGE_NODMA },
|
||||
{ "CD-ROM Drive/F5A", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "WPI CDD-820", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
|
||||
{ "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
|
||||
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
|
||||
|
||||
/* Devices we expect to fail diagnostics */
|
||||
|
||||
/* Devices where NCQ should be avoided */
|
||||
/* NCQ is slow */
|
||||
{ "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
|
||||
|
||||
/* Devices with NCQ limits */
|
||||
|
||||
/* End Marker */
|
||||
{ }
|
||||
};
|
||||
|
||||
static int ata_strim(char *s, size_t len)
|
||||
@ -3059,20 +3341,12 @@ static int ata_strim(char *s, size_t len)
|
||||
return len;
|
||||
}
|
||||
|
||||
static int ata_dma_blacklisted(const struct ata_device *dev)
|
||||
unsigned long ata_device_blacklisted(const struct ata_device *dev)
|
||||
{
|
||||
unsigned char model_num[40];
|
||||
unsigned char model_rev[16];
|
||||
unsigned int nlen, rlen;
|
||||
int i;
|
||||
|
||||
/* We don't support polling DMA.
|
||||
* DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
|
||||
* if the LLDD handles only interrupts in the HSM_ST_LAST state.
|
||||
*/
|
||||
if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
|
||||
(dev->flags & ATA_DFLAG_CDB_INTR))
|
||||
return 1;
|
||||
const struct ata_blacklist_entry *ad = ata_device_blacklist;
|
||||
|
||||
ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
|
||||
sizeof(model_num));
|
||||
@ -3081,17 +3355,30 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
|
||||
nlen = ata_strim(model_num, sizeof(model_num));
|
||||
rlen = ata_strim(model_rev, sizeof(model_rev));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) {
|
||||
if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) {
|
||||
if (ata_dma_blacklist[i+1] == NULL)
|
||||
return 1;
|
||||
if (!strncmp(ata_dma_blacklist[i], model_rev, rlen))
|
||||
return 1;
|
||||
while (ad->model_num) {
|
||||
if (!strncmp(ad->model_num, model_num, nlen)) {
|
||||
if (ad->model_rev == NULL)
|
||||
return ad->horkage;
|
||||
if (!strncmp(ad->model_rev, model_rev, rlen))
|
||||
return ad->horkage;
|
||||
}
|
||||
ad++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ata_dma_blacklisted(const struct ata_device *dev)
|
||||
{
|
||||
/* We don't support polling DMA.
|
||||
* DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
|
||||
* if the LLDD handles only interrupts in the HSM_ST_LAST state.
|
||||
*/
|
||||
if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
|
||||
(dev->flags & ATA_DFLAG_CDB_INTR))
|
||||
return 1;
|
||||
return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_xfermask - Compute supported xfermask of the given device
|
||||
* @dev: Device to compute xfermask for
|
||||
@ -3119,6 +3406,13 @@ static void ata_dev_xfermask(struct ata_device *dev)
|
||||
*/
|
||||
if (ap->cbl == ATA_CBL_PATA40)
|
||||
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
|
||||
/* Apply drive side cable rule. Unknown or 80 pin cables reported
|
||||
* host side are checked drive side as well. Cases where we know a
|
||||
* 40wire cable is used safely for 80 are not checked here.
|
||||
*/
|
||||
if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
|
||||
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
|
||||
|
||||
|
||||
xfer_mask &= ata_pack_xfermask(dev->pio_mask,
|
||||
dev->mwdma_mask, dev->udma_mask);
|
||||
@ -3236,8 +3530,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
|
||||
static void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||
void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct scatterlist *sg = qc->__sg;
|
||||
@ -3395,19 +3688,15 @@ void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
|
||||
|
||||
void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
|
||||
qc->flags |= ATA_QCFLAG_SINGLE;
|
||||
|
||||
memset(&qc->sgent, 0, sizeof(qc->sgent));
|
||||
qc->__sg = &qc->sgent;
|
||||
qc->n_elem = 1;
|
||||
qc->orig_n_elem = 1;
|
||||
qc->buf_virt = buf;
|
||||
qc->nbytes = buflen;
|
||||
|
||||
sg = qc->__sg;
|
||||
sg_init_one(sg, buf, buflen);
|
||||
sg_init_one(&qc->sgent, buf, buflen);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4200,8 +4489,12 @@ fsm_start:
|
||||
/* device stops HSM for abort/error */
|
||||
qc->err_mask |= AC_ERR_DEV;
|
||||
else
|
||||
/* HSM violation. Let EH handle this */
|
||||
qc->err_mask |= AC_ERR_HSM;
|
||||
/* HSM violation. Let EH handle this.
|
||||
* Phantom devices also trigger this
|
||||
* condition. Mark hint.
|
||||
*/
|
||||
qc->err_mask |= AC_ERR_HSM |
|
||||
AC_ERR_NODEV_HINT;
|
||||
|
||||
ap->hsm_task_state = HSM_ST_ERR;
|
||||
goto fsm_start;
|
||||
@ -4440,6 +4733,14 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
|
||||
qc->complete_fn(qc);
|
||||
}
|
||||
|
||||
static void fill_result_tf(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
|
||||
ap->ops->tf_read(ap, &qc->result_tf);
|
||||
qc->result_tf.flags = qc->tf.flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_qc_complete - Complete an active ATA command
|
||||
* @qc: Command to complete
|
||||
@ -4477,7 +4778,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
||||
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
|
||||
if (!ata_tag_internal(qc->tag)) {
|
||||
/* always fill result TF for failed qc */
|
||||
ap->ops->tf_read(ap, &qc->result_tf);
|
||||
fill_result_tf(qc);
|
||||
ata_qc_schedule_eh(qc);
|
||||
return;
|
||||
}
|
||||
@ -4485,7 +4786,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
||||
|
||||
/* read result TF if requested */
|
||||
if (qc->flags & ATA_QCFLAG_RESULT_TF)
|
||||
ap->ops->tf_read(ap, &qc->result_tf);
|
||||
fill_result_tf(qc);
|
||||
|
||||
__ata_qc_complete(qc);
|
||||
} else {
|
||||
@ -4494,7 +4795,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
||||
|
||||
/* read result TF if failed or requested */
|
||||
if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
|
||||
ap->ops->tf_read(ap, &qc->result_tf);
|
||||
fill_result_tf(qc);
|
||||
|
||||
__ata_qc_complete(qc);
|
||||
}
|
||||
@ -4674,6 +4975,14 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
|
||||
}
|
||||
}
|
||||
|
||||
/* Some controllers show flaky interrupt behavior after
|
||||
* setting xfer mode. Use polling instead.
|
||||
*/
|
||||
if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
|
||||
qc->tf.feature == SETFEATURES_XFER) &&
|
||||
(ap->flags & ATA_FLAG_SETXFER_POLLING))
|
||||
qc->tf.flags |= ATA_TFLAG_POLLING;
|
||||
|
||||
/* select the device */
|
||||
ata_dev_select(ap, qc->dev->devno, 1, 0);
|
||||
|
||||
@ -4782,6 +5091,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
|
||||
inline unsigned int ata_host_intr (struct ata_port *ap,
|
||||
struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
u8 status, host_stat = 0;
|
||||
|
||||
VPRINTK("ata%u: protocol %d task_state %d\n",
|
||||
@ -4842,6 +5152,11 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
|
||||
ap->ops->irq_clear(ap);
|
||||
|
||||
ata_hsm_move(ap, qc, status, 0);
|
||||
|
||||
if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
|
||||
qc->tf.protocol == ATA_PROT_ATAPI_DMA))
|
||||
ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
|
||||
|
||||
return 1; /* irq handled */
|
||||
|
||||
idle_irq:
|
||||
@ -5048,7 +5363,7 @@ int ata_flush_cache(struct ata_device *dev)
|
||||
if (!ata_try_flush_cache(dev))
|
||||
return 0;
|
||||
|
||||
if (ata_id_has_flush_ext(dev->id))
|
||||
if (dev->flags & ATA_DFLAG_FLUSH_EXT)
|
||||
cmd = ATA_CMD_FLUSH_EXT;
|
||||
else
|
||||
cmd = ATA_CMD_FLUSH;
|
||||
@ -5520,9 +5835,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
|
||||
ap->ioaddr.bmdma_addr,
|
||||
irq_line);
|
||||
|
||||
ata_chk_status(ap);
|
||||
host->ops->irq_clear(ap);
|
||||
ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
|
||||
/* freeze port before requesting IRQ */
|
||||
ata_eh_freeze_port(ap);
|
||||
}
|
||||
|
||||
/* obtain irq, that may be shared between channels */
|
||||
@ -6120,6 +6434,7 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
|
||||
EXPORT_SYMBOL_GPL(ata_bus_reset);
|
||||
EXPORT_SYMBOL_GPL(ata_std_prereset);
|
||||
EXPORT_SYMBOL_GPL(ata_std_softreset);
|
||||
EXPORT_SYMBOL_GPL(sata_port_hardreset);
|
||||
EXPORT_SYMBOL_GPL(sata_std_hardreset);
|
||||
EXPORT_SYMBOL_GPL(ata_std_postreset);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_classify);
|
||||
@ -6146,6 +6461,7 @@ EXPORT_SYMBOL_GPL(ata_host_suspend);
|
||||
EXPORT_SYMBOL_GPL(ata_host_resume);
|
||||
EXPORT_SYMBOL_GPL(ata_id_string);
|
||||
EXPORT_SYMBOL_GPL(ata_id_c_string);
|
||||
EXPORT_SYMBOL_GPL(ata_device_blacklisted);
|
||||
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
|
||||
|
@ -1136,19 +1136,21 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
|
||||
break;
|
||||
|
||||
case ATA_DEV_ATAPI:
|
||||
tmp = atapi_eh_request_sense(qc->dev,
|
||||
qc->scsicmd->sense_buffer);
|
||||
if (!tmp) {
|
||||
/* ATA_QCFLAG_SENSE_VALID is used to tell
|
||||
* atapi_qc_complete() that sense data is
|
||||
* already valid.
|
||||
*
|
||||
* TODO: interpret sense data and set
|
||||
* appropriate err_mask.
|
||||
*/
|
||||
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
||||
} else
|
||||
qc->err_mask |= tmp;
|
||||
if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
tmp = atapi_eh_request_sense(qc->dev,
|
||||
qc->scsicmd->sense_buffer);
|
||||
if (!tmp) {
|
||||
/* ATA_QCFLAG_SENSE_VALID is used to
|
||||
* tell atapi_qc_complete() that sense
|
||||
* data is already valid.
|
||||
*
|
||||
* TODO: interpret sense data and set
|
||||
* appropriate err_mask.
|
||||
*/
|
||||
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
||||
} else
|
||||
qc->err_mask |= tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
|
||||
@ -1433,16 +1435,39 @@ static void ata_eh_report(struct ata_port *ap)
|
||||
}
|
||||
|
||||
for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
|
||||
static const char *dma_str[] = {
|
||||
[DMA_BIDIRECTIONAL] = "bidi",
|
||||
[DMA_TO_DEVICE] = "out",
|
||||
[DMA_FROM_DEVICE] = "in",
|
||||
[DMA_NONE] = "",
|
||||
};
|
||||
struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
|
||||
struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
|
||||
unsigned int nbytes;
|
||||
|
||||
if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask)
|
||||
continue;
|
||||
|
||||
ata_dev_printk(qc->dev, KERN_ERR, "tag %d cmd 0x%x "
|
||||
"Emask 0x%x stat 0x%x err 0x%x (%s)\n",
|
||||
qc->tag, qc->tf.command, qc->err_mask,
|
||||
qc->result_tf.command, qc->result_tf.feature,
|
||||
ata_err_string(qc->err_mask));
|
||||
nbytes = qc->nbytes;
|
||||
if (!nbytes)
|
||||
nbytes = qc->nsect << 9;
|
||||
|
||||
ata_dev_printk(qc->dev, KERN_ERR,
|
||||
"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
||||
"tag %d cdb 0x%x data %u %s\n "
|
||||
"res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
|
||||
"Emask 0x%x (%s)\n",
|
||||
cmd->command, cmd->feature, cmd->nsect,
|
||||
cmd->lbal, cmd->lbam, cmd->lbah,
|
||||
cmd->hob_feature, cmd->hob_nsect,
|
||||
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
|
||||
cmd->device, qc->tag, qc->cdb[0], nbytes,
|
||||
dma_str[qc->dma_dir],
|
||||
res->command, res->feature, res->nsect,
|
||||
res->lbal, res->lbam, res->lbah,
|
||||
res->hob_feature, res->hob_nsect,
|
||||
res->hob_lbal, res->hob_lbam, res->hob_lbah,
|
||||
res->device, qc->err_mask, ata_err_string(qc->err_mask));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1634,11 +1659,14 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
unsigned int action;
|
||||
unsigned int action, readid_flags = 0;
|
||||
|
||||
dev = &ap->device[i];
|
||||
action = ata_eh_dev_action(dev);
|
||||
|
||||
if (ehc->i.flags & ATA_EHI_DID_RESET)
|
||||
readid_flags |= ATA_READID_POSTRESET;
|
||||
|
||||
if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
|
||||
if (ata_port_offline(ap)) {
|
||||
rc = -EIO;
|
||||
@ -1646,13 +1674,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
|
||||
}
|
||||
|
||||
ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
|
||||
rc = ata_dev_revalidate(dev,
|
||||
ehc->i.flags & ATA_EHI_DID_RESET);
|
||||
rc = ata_dev_revalidate(dev, readid_flags);
|
||||
if (rc)
|
||||
break;
|
||||
|
||||
ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
|
||||
|
||||
/* Configuration may have changed, reconfigure
|
||||
* transfer mode.
|
||||
*/
|
||||
ehc->i.flags |= ATA_EHI_SETMODE;
|
||||
|
||||
/* schedule the scsi_rescan_device() here */
|
||||
queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
|
||||
} else if (dev->class == ATA_DEV_UNKNOWN &&
|
||||
@ -1660,18 +1692,35 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
|
||||
ata_class_enabled(ehc->classes[dev->devno])) {
|
||||
dev->class = ehc->classes[dev->devno];
|
||||
|
||||
rc = ata_dev_read_id(dev, &dev->class, 1, dev->id);
|
||||
if (rc == 0)
|
||||
rc = ata_dev_configure(dev, 1);
|
||||
rc = ata_dev_read_id(dev, &dev->class, readid_flags,
|
||||
dev->id);
|
||||
if (rc == 0) {
|
||||
ehc->i.flags |= ATA_EHI_PRINTINFO;
|
||||
rc = ata_dev_configure(dev);
|
||||
ehc->i.flags &= ~ATA_EHI_PRINTINFO;
|
||||
} else if (rc == -ENOENT) {
|
||||
/* IDENTIFY was issued to non-existent
|
||||
* device. No need to reset. Just
|
||||
* thaw and kill the device.
|
||||
*/
|
||||
ata_eh_thaw_port(ap);
|
||||
dev->class = ATA_DEV_UNKNOWN;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
dev->class = ATA_DEV_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
if (ata_dev_enabled(dev)) {
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
/* new device discovered, configure xfermode */
|
||||
ehc->i.flags |= ATA_EHI_SETMODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1987,13 +2036,14 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
||||
if (rc)
|
||||
goto dev_fail;
|
||||
|
||||
/* configure transfer mode if the port has been reset */
|
||||
if (ehc->i.flags & ATA_EHI_DID_RESET) {
|
||||
/* configure transfer mode if necessary */
|
||||
if (ehc->i.flags & ATA_EHI_SETMODE) {
|
||||
rc = ata_set_mode(ap, &dev);
|
||||
if (rc) {
|
||||
down_xfermask = 1;
|
||||
goto dev_fail;
|
||||
}
|
||||
ehc->i.flags &= ~ATA_EHI_SETMODE;
|
||||
}
|
||||
|
||||
/* suspend devices */
|
||||
|
@ -671,7 +671,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
|
||||
}
|
||||
|
||||
/*
|
||||
* ata_gen_ata_desc_sense - Generate check condition sense block.
|
||||
* ata_gen_passthru_sense - Generate check condition sense block.
|
||||
* @qc: Command that completed.
|
||||
*
|
||||
* This function is specific to the ATA descriptor format sense
|
||||
@ -681,9 +681,9 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
|
||||
* block. Clear sense key, ASC & ASCQ if there is no error.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
* None.
|
||||
*/
|
||||
void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
|
||||
static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct scsi_cmnd *cmd = qc->scsicmd;
|
||||
struct ata_taskfile *tf = &qc->result_tf;
|
||||
@ -713,12 +713,9 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
|
||||
|
||||
desc[0] = 0x09;
|
||||
|
||||
/*
|
||||
* Set length of additional sense data.
|
||||
* Since we only populate descriptor 0, the total
|
||||
* length is the same (fixed) length as descriptor 0.
|
||||
*/
|
||||
desc[1] = sb[7] = 14;
|
||||
/* set length of additional sense data */
|
||||
sb[7] = 14;
|
||||
desc[1] = 12;
|
||||
|
||||
/*
|
||||
* Copy registers into sense buffer.
|
||||
@ -746,56 +743,56 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_gen_fixed_sense - generate a SCSI fixed sense block
|
||||
* ata_gen_ata_sense - generate a SCSI fixed sense block
|
||||
* @qc: Command that we are erroring out
|
||||
*
|
||||
* Leverage ata_to_sense_error() to give us the codes. Fit our
|
||||
* LBA in here if there's room.
|
||||
* Generate sense block for a failed ATA command @qc. Descriptor
|
||||
* format is used to accomodate LBA48 block address.
|
||||
*
|
||||
* LOCKING:
|
||||
* inherited from caller
|
||||
* None.
|
||||
*/
|
||||
void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
|
||||
static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_device *dev = qc->dev;
|
||||
struct scsi_cmnd *cmd = qc->scsicmd;
|
||||
struct ata_taskfile *tf = &qc->result_tf;
|
||||
unsigned char *sb = cmd->sense_buffer;
|
||||
unsigned char *desc = sb + 8;
|
||||
int verbose = qc->ap->ops->error_handler == NULL;
|
||||
u64 block;
|
||||
|
||||
memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
|
||||
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
|
||||
|
||||
/*
|
||||
* Use ata_to_sense_error() to map status register bits
|
||||
/* sense data is current and format is descriptor */
|
||||
sb[0] = 0x72;
|
||||
|
||||
/* Use ata_to_sense_error() to map status register bits
|
||||
* onto sense key, asc & ascq.
|
||||
*/
|
||||
if (qc->err_mask ||
|
||||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||
ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
|
||||
&sb[2], &sb[12], &sb[13], verbose);
|
||||
sb[2] &= 0x0f;
|
||||
&sb[1], &sb[2], &sb[3], verbose);
|
||||
sb[1] &= 0x0f;
|
||||
}
|
||||
|
||||
sb[0] = 0x70;
|
||||
sb[7] = 0x0a;
|
||||
block = ata_tf_read_block(&qc->result_tf, dev);
|
||||
|
||||
if (tf->flags & ATA_TFLAG_LBA48) {
|
||||
/* TODO: find solution for LBA48 descriptors */
|
||||
}
|
||||
/* information sense data descriptor */
|
||||
sb[7] = 12;
|
||||
desc[0] = 0x00;
|
||||
desc[1] = 10;
|
||||
|
||||
else if (tf->flags & ATA_TFLAG_LBA) {
|
||||
/* A small (28b) LBA will fit in the 32b info field */
|
||||
sb[0] |= 0x80; /* set valid bit */
|
||||
sb[3] = tf->device & 0x0f;
|
||||
sb[4] = tf->lbah;
|
||||
sb[5] = tf->lbam;
|
||||
sb[6] = tf->lbal;
|
||||
}
|
||||
|
||||
else {
|
||||
/* TODO: C/H/S */
|
||||
}
|
||||
desc[2] |= 0x80; /* valid */
|
||||
desc[6] = block >> 40;
|
||||
desc[7] = block >> 32;
|
||||
desc[8] = block >> 24;
|
||||
desc[9] = block >> 16;
|
||||
desc[10] = block >> 8;
|
||||
desc[11] = block;
|
||||
}
|
||||
|
||||
static void ata_scsi_sdev_config(struct scsi_device *sdev)
|
||||
@ -807,23 +804,10 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
|
||||
static void ata_scsi_dev_config(struct scsi_device *sdev,
|
||||
struct ata_device *dev)
|
||||
{
|
||||
unsigned int max_sectors;
|
||||
/* configure max sectors */
|
||||
blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
|
||||
|
||||
/* TODO: 2048 is an arbitrary number, not the
|
||||
* hardware maximum. This should be increased to
|
||||
* 65534 when Jens Axboe's patch for dynamically
|
||||
* determining max_sectors is merged.
|
||||
*/
|
||||
max_sectors = ATA_MAX_SECTORS;
|
||||
if (dev->flags & ATA_DFLAG_LBA48)
|
||||
max_sectors = ATA_MAX_SECTORS_LBA48;
|
||||
if (dev->max_sectors)
|
||||
max_sectors = dev->max_sectors;
|
||||
|
||||
blk_queue_max_sectors(sdev->request_queue, max_sectors);
|
||||
|
||||
/*
|
||||
* SATA DMA transfers must be multiples of 4 byte, so
|
||||
/* SATA DMA transfers must be multiples of 4 byte, so
|
||||
* we need to pad ATAPI transfers using an extra sg.
|
||||
* Decrement max hw segments accordingly.
|
||||
*/
|
||||
@ -1040,8 +1024,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
|
||||
tf->flags |= ATA_TFLAG_DEVICE;
|
||||
tf->protocol = ATA_PROT_NODATA;
|
||||
|
||||
if ((qc->dev->flags & ATA_DFLAG_LBA48) &&
|
||||
(ata_id_has_flush_ext(qc->dev->id)))
|
||||
if (qc->dev->flags & ATA_DFLAG_FLUSH_EXT)
|
||||
tf->command = ATA_CMD_FLUSH_EXT;
|
||||
else
|
||||
tf->command = ATA_CMD_FLUSH;
|
||||
@ -1282,17 +1265,14 @@ nothing_to_do:
|
||||
|
||||
static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
|
||||
{
|
||||
struct ata_taskfile *tf = &qc->tf;
|
||||
struct ata_device *dev = qc->dev;
|
||||
unsigned int tf_flags = 0;
|
||||
u64 block;
|
||||
u32 n_block;
|
||||
|
||||
qc->flags |= ATA_QCFLAG_IO;
|
||||
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
|
||||
int rc;
|
||||
|
||||
if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
|
||||
scsicmd[0] == WRITE_16)
|
||||
tf->flags |= ATA_TFLAG_WRITE;
|
||||
tf_flags |= ATA_TFLAG_WRITE;
|
||||
|
||||
/* Calculate the SCSI LBA, transfer length and FUA. */
|
||||
switch (scsicmd[0]) {
|
||||
@ -1300,7 +1280,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
|
||||
case WRITE_10:
|
||||
scsi_10_lba_len(scsicmd, &block, &n_block);
|
||||
if (unlikely(scsicmd[1] & (1 << 3)))
|
||||
tf->flags |= ATA_TFLAG_FUA;
|
||||
tf_flags |= ATA_TFLAG_FUA;
|
||||
break;
|
||||
case READ_6:
|
||||
case WRITE_6:
|
||||
@ -1316,7 +1296,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
|
||||
case WRITE_16:
|
||||
scsi_16_lba_len(scsicmd, &block, &n_block);
|
||||
if (unlikely(scsicmd[1] & (1 << 3)))
|
||||
tf->flags |= ATA_TFLAG_FUA;
|
||||
tf_flags |= ATA_TFLAG_FUA;
|
||||
break;
|
||||
default:
|
||||
DPRINTK("no-byte command\n");
|
||||
@ -1334,106 +1314,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
|
||||
*/
|
||||
goto nothing_to_do;
|
||||
|
||||
if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
|
||||
ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) {
|
||||
/* yay, NCQ */
|
||||
if (!lba_48_ok(block, n_block))
|
||||
goto out_of_range;
|
||||
qc->flags |= ATA_QCFLAG_IO;
|
||||
qc->nsect = n_block;
|
||||
|
||||
tf->protocol = ATA_PROT_NCQ;
|
||||
tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
|
||||
|
||||
if (tf->flags & ATA_TFLAG_WRITE)
|
||||
tf->command = ATA_CMD_FPDMA_WRITE;
|
||||
else
|
||||
tf->command = ATA_CMD_FPDMA_READ;
|
||||
|
||||
qc->nsect = n_block;
|
||||
|
||||
tf->nsect = qc->tag << 3;
|
||||
tf->hob_feature = (n_block >> 8) & 0xff;
|
||||
tf->feature = n_block & 0xff;
|
||||
|
||||
tf->hob_lbah = (block >> 40) & 0xff;
|
||||
tf->hob_lbam = (block >> 32) & 0xff;
|
||||
tf->hob_lbal = (block >> 24) & 0xff;
|
||||
tf->lbah = (block >> 16) & 0xff;
|
||||
tf->lbam = (block >> 8) & 0xff;
|
||||
tf->lbal = block & 0xff;
|
||||
|
||||
tf->device = 1 << 6;
|
||||
if (tf->flags & ATA_TFLAG_FUA)
|
||||
tf->device |= 1 << 7;
|
||||
} else if (dev->flags & ATA_DFLAG_LBA) {
|
||||
tf->flags |= ATA_TFLAG_LBA;
|
||||
|
||||
if (lba_28_ok(block, n_block)) {
|
||||
/* use LBA28 */
|
||||
tf->device |= (block >> 24) & 0xf;
|
||||
} else if (lba_48_ok(block, n_block)) {
|
||||
if (!(dev->flags & ATA_DFLAG_LBA48))
|
||||
goto out_of_range;
|
||||
|
||||
/* use LBA48 */
|
||||
tf->flags |= ATA_TFLAG_LBA48;
|
||||
|
||||
tf->hob_nsect = (n_block >> 8) & 0xff;
|
||||
|
||||
tf->hob_lbah = (block >> 40) & 0xff;
|
||||
tf->hob_lbam = (block >> 32) & 0xff;
|
||||
tf->hob_lbal = (block >> 24) & 0xff;
|
||||
} else
|
||||
/* request too large even for LBA48 */
|
||||
goto out_of_range;
|
||||
|
||||
if (unlikely(ata_rwcmd_protocol(qc) < 0))
|
||||
goto invalid_fld;
|
||||
|
||||
qc->nsect = n_block;
|
||||
tf->nsect = n_block & 0xff;
|
||||
|
||||
tf->lbah = (block >> 16) & 0xff;
|
||||
tf->lbam = (block >> 8) & 0xff;
|
||||
tf->lbal = block & 0xff;
|
||||
|
||||
tf->device |= ATA_LBA;
|
||||
} else {
|
||||
/* CHS */
|
||||
u32 sect, head, cyl, track;
|
||||
|
||||
/* The request -may- be too large for CHS addressing. */
|
||||
if (!lba_28_ok(block, n_block))
|
||||
goto out_of_range;
|
||||
|
||||
if (unlikely(ata_rwcmd_protocol(qc) < 0))
|
||||
goto invalid_fld;
|
||||
|
||||
/* Convert LBA to CHS */
|
||||
track = (u32)block / dev->sectors;
|
||||
cyl = track / dev->heads;
|
||||
head = track % dev->heads;
|
||||
sect = (u32)block % dev->sectors + 1;
|
||||
|
||||
DPRINTK("block %u track %u cyl %u head %u sect %u\n",
|
||||
(u32)block, track, cyl, head, sect);
|
||||
|
||||
/* Check whether the converted CHS can fit.
|
||||
Cylinder: 0-65535
|
||||
Head: 0-15
|
||||
Sector: 1-255*/
|
||||
if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
|
||||
goto out_of_range;
|
||||
|
||||
qc->nsect = n_block;
|
||||
tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
|
||||
tf->lbal = sect;
|
||||
tf->lbam = cyl;
|
||||
tf->lbah = cyl >> 8;
|
||||
tf->device |= head;
|
||||
}
|
||||
|
||||
return 0;
|
||||
rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
|
||||
qc->tag);
|
||||
if (likely(rc == 0))
|
||||
return 0;
|
||||
|
||||
if (rc == -ERANGE)
|
||||
goto out_of_range;
|
||||
/* treat all other errors as -EINVAL, fall through */
|
||||
invalid_fld:
|
||||
ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||
/* "Invalid field in cbd" */
|
||||
@ -1477,7 +1368,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
||||
*/
|
||||
if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
|
||||
((cdb[2] & 0x20) || need_sense)) {
|
||||
ata_gen_ata_desc_sense(qc);
|
||||
ata_gen_passthru_sense(qc);
|
||||
} else {
|
||||
if (!need_sense) {
|
||||
cmd->result = SAM_STAT_GOOD;
|
||||
@ -1488,7 +1379,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
|
||||
* good for smaller LBA (and maybe CHS?)
|
||||
* devices.
|
||||
*/
|
||||
ata_gen_fixed_sense(qc);
|
||||
ata_gen_ata_sense(qc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1714,6 +1605,22 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
|
||||
args->done(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* ATA_SCSI_RBUF_SET - helper to set values in SCSI response buffer
|
||||
* @idx: byte index into SCSI response buffer
|
||||
* @val: value to set
|
||||
*
|
||||
* To be used by SCSI command simulator functions. This macros
|
||||
* expects two local variables, u8 *rbuf and unsigned int buflen,
|
||||
* are in scope.
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*/
|
||||
#define ATA_SCSI_RBUF_SET(idx, val) do { \
|
||||
if ((idx) < buflen) rbuf[(idx)] = (u8)(val); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_std - Simulate INQUIRY command
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
@ -2173,67 +2080,42 @@ saving_not_supp:
|
||||
* Simulate READ CAPACITY commands.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
* None.
|
||||
*/
|
||||
|
||||
unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
|
||||
unsigned int buflen)
|
||||
{
|
||||
u64 n_sectors;
|
||||
u32 tmp;
|
||||
u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
|
||||
|
||||
VPRINTK("ENTER\n");
|
||||
|
||||
if (ata_id_has_lba(args->id)) {
|
||||
if (ata_id_has_lba48(args->id))
|
||||
n_sectors = ata_id_u64(args->id, 100);
|
||||
else
|
||||
n_sectors = ata_id_u32(args->id, 60);
|
||||
} else {
|
||||
/* CHS default translation */
|
||||
n_sectors = args->id[1] * args->id[3] * args->id[6];
|
||||
|
||||
if (ata_id_current_chs_valid(args->id))
|
||||
/* CHS current translation */
|
||||
n_sectors = ata_id_u32(args->id, 57);
|
||||
}
|
||||
|
||||
n_sectors--; /* ATA TotalUserSectors - 1 */
|
||||
|
||||
if (args->cmd->cmnd[0] == READ_CAPACITY) {
|
||||
if( n_sectors >= 0xffffffffULL )
|
||||
tmp = 0xffffffff ; /* Return max count on overflow */
|
||||
else
|
||||
tmp = n_sectors ;
|
||||
if (last_lba >= 0xffffffffULL)
|
||||
last_lba = 0xffffffff;
|
||||
|
||||
/* sector count, 32-bit */
|
||||
rbuf[0] = tmp >> (8 * 3);
|
||||
rbuf[1] = tmp >> (8 * 2);
|
||||
rbuf[2] = tmp >> (8 * 1);
|
||||
rbuf[3] = tmp;
|
||||
ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 3));
|
||||
ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 2));
|
||||
ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 1));
|
||||
ATA_SCSI_RBUF_SET(3, last_lba);
|
||||
|
||||
/* sector size */
|
||||
tmp = ATA_SECT_SIZE;
|
||||
rbuf[6] = tmp >> 8;
|
||||
rbuf[7] = tmp;
|
||||
|
||||
ATA_SCSI_RBUF_SET(6, ATA_SECT_SIZE >> 8);
|
||||
ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE);
|
||||
} else {
|
||||
/* sector count, 64-bit */
|
||||
tmp = n_sectors >> (8 * 4);
|
||||
rbuf[2] = tmp >> (8 * 3);
|
||||
rbuf[3] = tmp >> (8 * 2);
|
||||
rbuf[4] = tmp >> (8 * 1);
|
||||
rbuf[5] = tmp;
|
||||
tmp = n_sectors;
|
||||
rbuf[6] = tmp >> (8 * 3);
|
||||
rbuf[7] = tmp >> (8 * 2);
|
||||
rbuf[8] = tmp >> (8 * 1);
|
||||
rbuf[9] = tmp;
|
||||
ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 7));
|
||||
ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 6));
|
||||
ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 5));
|
||||
ATA_SCSI_RBUF_SET(3, last_lba >> (8 * 4));
|
||||
ATA_SCSI_RBUF_SET(4, last_lba >> (8 * 3));
|
||||
ATA_SCSI_RBUF_SET(5, last_lba >> (8 * 2));
|
||||
ATA_SCSI_RBUF_SET(6, last_lba >> (8 * 1));
|
||||
ATA_SCSI_RBUF_SET(7, last_lba);
|
||||
|
||||
/* sector size */
|
||||
tmp = ATA_SECT_SIZE;
|
||||
rbuf[12] = tmp >> 8;
|
||||
rbuf[13] = tmp;
|
||||
ATA_SCSI_RBUF_SET(10, ATA_SECT_SIZE >> 8);
|
||||
ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2319,7 +2201,7 @@ static void atapi_sense_complete(struct ata_queued_cmd *qc)
|
||||
* a sense descriptors, since that's only
|
||||
* correct for ATA, not ATAPI
|
||||
*/
|
||||
ata_gen_ata_desc_sense(qc);
|
||||
ata_gen_passthru_sense(qc);
|
||||
}
|
||||
|
||||
qc->scsidone(qc->scsicmd);
|
||||
@ -2394,7 +2276,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
|
||||
* sense descriptors, since that's only
|
||||
* correct for ATA, not ATAPI
|
||||
*/
|
||||
ata_gen_ata_desc_sense(qc);
|
||||
ata_gen_passthru_sense(qc);
|
||||
}
|
||||
|
||||
/* SCSI EH automatically locks door if sdev->locked is
|
||||
@ -2427,7 +2309,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
|
||||
* a sense descriptors, since that's only
|
||||
* correct for ATA, not ATAPI
|
||||
*/
|
||||
ata_gen_ata_desc_sense(qc);
|
||||
ata_gen_passthru_sense(qc);
|
||||
} else {
|
||||
u8 *scsicmd = cmd->cmnd;
|
||||
|
||||
@ -3182,10 +3064,12 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
if (rc == 0) {
|
||||
ata_port_schedule_eh(ap);
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
ata_port_wait_eh(ap);
|
||||
} else
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -3205,15 +3089,27 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
|
||||
void ata_scsi_dev_rescan(void *data)
|
||||
{
|
||||
struct ata_port *ap = data;
|
||||
struct ata_device *dev;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
dev = &ap->device[i];
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
if (ata_dev_enabled(dev) && dev->sdev)
|
||||
scsi_rescan_device(&(dev->sdev->sdev_gendev));
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
struct scsi_device *sdev = dev->sdev;
|
||||
|
||||
if (!ata_dev_enabled(dev) || !sdev)
|
||||
continue;
|
||||
if (scsi_device_get(sdev))
|
||||
continue;
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
scsi_rescan_device(&(sdev->sdev_gendev));
|
||||
scsi_device_put(sdev);
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,35 @@
|
||||
|
||||
#include "libata.h"
|
||||
|
||||
/**
|
||||
* ata_irq_on - Enable interrupts on a port.
|
||||
* @ap: Port on which interrupts are enabled.
|
||||
*
|
||||
* Enable interrupts on a legacy IDE device using MMIO or PIO,
|
||||
* wait for idle, clear any pending interrupts.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
u8 ata_irq_on(struct ata_port *ap)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u8 tmp;
|
||||
|
||||
ap->ctl &= ~ATA_NIEN;
|
||||
ap->last_ctl = ap->ctl;
|
||||
|
||||
if (ap->flags & ATA_FLAG_MMIO)
|
||||
writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
|
||||
else
|
||||
outb(ap->ctl, ioaddr->ctl_addr);
|
||||
tmp = ata_wait_idle(ap);
|
||||
|
||||
ap->ops->irq_clear(ap);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_tf_load_pio - send taskfile registers to host controller
|
||||
* @ap: Port to which output is sent
|
||||
@ -671,6 +700,14 @@ void ata_bmdma_freeze(struct ata_port *ap)
|
||||
writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
|
||||
else
|
||||
outb(ap->ctl, ioaddr->ctl_addr);
|
||||
|
||||
/* Under certain circumstances, some controllers raise IRQ on
|
||||
* ATA_NIEN manipulation. Also, many controllers fail to mask
|
||||
* previously pending IRQ on ATA_NIEN assertion. Clear it.
|
||||
*/
|
||||
ata_chk_status(ap);
|
||||
|
||||
ap->ops->irq_clear(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -714,7 +751,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
||||
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
|
||||
ata_postreset_fn_t postreset)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
struct ata_queued_cmd *qc;
|
||||
unsigned long flags;
|
||||
int thaw = 0;
|
||||
@ -732,9 +768,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
||||
qc->tf.protocol == ATA_PROT_ATAPI_DMA)) {
|
||||
u8 host_stat;
|
||||
|
||||
host_stat = ata_bmdma_status(ap);
|
||||
|
||||
ata_ehi_push_desc(&ehc->i, "BMDMA stat 0x%x", host_stat);
|
||||
host_stat = ap->ops->bmdma_status(ap);
|
||||
|
||||
/* BMDMA controllers indicate host bus error by
|
||||
* setting DMA_ERR bit and timing out. As it wasn't
|
||||
@ -877,6 +911,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
|
||||
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;
|
||||
|
@ -39,26 +39,39 @@ struct ata_scsi_args {
|
||||
};
|
||||
|
||||
/* libata-core.c */
|
||||
enum {
|
||||
/* flags for ata_dev_read_id() */
|
||||
ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */
|
||||
};
|
||||
|
||||
extern struct workqueue_struct *ata_aux_wq;
|
||||
extern int atapi_enabled;
|
||||
extern int atapi_dmadir;
|
||||
extern int libata_fua;
|
||||
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
|
||||
extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
|
||||
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
|
||||
u64 block, u32 n_block, unsigned int tf_flags,
|
||||
unsigned int tag);
|
||||
extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
|
||||
extern void ata_dev_disable(struct ata_device *dev);
|
||||
extern void ata_port_flush_task(struct ata_port *ap);
|
||||
extern unsigned ata_exec_internal(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, void *buf, unsigned int buflen);
|
||||
extern unsigned ata_exec_internal_sg(struct ata_device *dev,
|
||||
struct ata_taskfile *tf, const u8 *cdb,
|
||||
int dma_dir, struct scatterlist *sg,
|
||||
unsigned int n_elem);
|
||||
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
|
||||
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
|
||||
int post_reset, u16 *id);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
|
||||
extern int ata_dev_configure(struct ata_device *dev, int print_info);
|
||||
unsigned int flags, u16 *id);
|
||||
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
|
||||
extern int ata_dev_configure(struct ata_device *dev);
|
||||
extern int sata_down_spd_limit(struct ata_port *ap);
|
||||
extern int sata_set_spd_needed(struct ata_port *ap);
|
||||
extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0);
|
||||
extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
|
||||
extern void ata_sg_clean(struct ata_queued_cmd *qc);
|
||||
extern void ata_qc_free(struct ata_queued_cmd *qc);
|
||||
extern void ata_qc_issue(struct ata_queued_cmd *qc);
|
||||
extern void __ata_qc_complete(struct ata_queued_cmd *qc);
|
||||
@ -120,4 +133,7 @@ extern void ata_scsi_error(struct Scsi_Host *host);
|
||||
extern void ata_port_wait_eh(struct ata_port *ap);
|
||||
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
|
||||
|
||||
/* libata-sff.c */
|
||||
extern u8 ata_irq_on(struct ata_port *ap);
|
||||
|
||||
#endif /* __LIBATA_H__ */
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#define DRV_NAME "pata_ali"
|
||||
#define DRV_VERSION "0.6.6"
|
||||
#define DRV_VERSION "0.7.2"
|
||||
|
||||
/*
|
||||
* Cable special cases
|
||||
@ -78,7 +78,7 @@ static int ali_c2_cable_detect(struct ata_port *ap)
|
||||
implement the detect logic */
|
||||
|
||||
if (ali_cable_override(pdev))
|
||||
return ATA_CBL_PATA80;
|
||||
return ATA_CBL_PATA40_SHORT;
|
||||
|
||||
/* Host view cable detect 0x4A bit 0 primary bit 1 secondary
|
||||
Bit set for 40 pin */
|
||||
@ -337,9 +337,6 @@ static struct scsi_host_template ali_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
/* Keep LBA28 counts so large I/O's don't turn LBA48 and PIO
|
||||
with older controllers. Not locked so will grow on C5 or later */
|
||||
.max_sectors = 255,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -348,6 +345,8 @@ static struct scsi_host_template ali_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -497,6 +496,69 @@ static struct ata_port_operations ali_c5_port_ops = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ali_init_chipset - chip setup function
|
||||
* @pdev: PCI device of ATA controller
|
||||
*
|
||||
* Perform the setup on the device that must be done both at boot
|
||||
* and at resume time.
|
||||
*/
|
||||
|
||||
static void ali_init_chipset(struct pci_dev *pdev)
|
||||
{
|
||||
u8 rev, tmp;
|
||||
struct pci_dev *north, *isa_bridge;
|
||||
|
||||
pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
|
||||
|
||||
/*
|
||||
* The chipset revision selects the driver operations and
|
||||
* mode data.
|
||||
*/
|
||||
|
||||
if (rev >= 0x20 && rev < 0xC2) {
|
||||
/* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
|
||||
pci_read_config_byte(pdev, 0x4B, &tmp);
|
||||
/* Clear CD-ROM DMA write bit */
|
||||
tmp &= 0x7F;
|
||||
pci_write_config_byte(pdev, 0x4B, tmp);
|
||||
} else if (rev >= 0xC2) {
|
||||
/* Enable cable detection logic */
|
||||
pci_read_config_byte(pdev, 0x4B, &tmp);
|
||||
pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
|
||||
}
|
||||
north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
|
||||
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
|
||||
|
||||
if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) {
|
||||
/* Configure the ALi bridge logic. For non ALi rely on BIOS.
|
||||
Set the south bridge enable bit */
|
||||
pci_read_config_byte(isa_bridge, 0x79, &tmp);
|
||||
if (rev == 0xC2)
|
||||
pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
|
||||
else if (rev > 0xC2 && rev < 0xC5)
|
||||
pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
|
||||
}
|
||||
if (rev >= 0x20) {
|
||||
/*
|
||||
* CD_ROM DMA on (0x53 bit 0). Enable this even if we want
|
||||
* to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
|
||||
* via 0x54/55.
|
||||
*/
|
||||
pci_read_config_byte(pdev, 0x53, &tmp);
|
||||
if (rev <= 0x20)
|
||||
tmp &= ~0x02;
|
||||
if (rev >= 0xc7)
|
||||
tmp |= 0x03;
|
||||
else
|
||||
tmp |= 0x01; /* CD_ROM enable for DMA */
|
||||
pci_write_config_byte(pdev, 0x53, tmp);
|
||||
}
|
||||
pci_dev_put(isa_bridge);
|
||||
pci_dev_put(north);
|
||||
ata_pci_clear_simplex(pdev);
|
||||
}
|
||||
/**
|
||||
* ali_init_one - discovery callback
|
||||
* @pdev: PCI device ID
|
||||
@ -570,7 +632,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
||||
static struct ata_port_info *port_info[2];
|
||||
u8 rev, tmp;
|
||||
struct pci_dev *north, *isa_bridge;
|
||||
struct pci_dev *isa_bridge;
|
||||
|
||||
pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
|
||||
|
||||
@ -582,11 +644,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (rev < 0x20) {
|
||||
port_info[0] = port_info[1] = &info_early;
|
||||
} else if (rev < 0xC2) {
|
||||
/* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
|
||||
pci_read_config_byte(pdev, 0x4B, &tmp);
|
||||
/* Clear CD-ROM DMA write bit */
|
||||
tmp &= 0x7F;
|
||||
pci_write_config_byte(pdev, 0x4B, tmp);
|
||||
port_info[0] = port_info[1] = &info_20;
|
||||
} else if (rev == 0xC2) {
|
||||
port_info[0] = port_info[1] = &info_c2;
|
||||
@ -597,54 +654,25 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
} else
|
||||
port_info[0] = port_info[1] = &info_c5;
|
||||
|
||||
if (rev >= 0xC2) {
|
||||
/* Enable cable detection logic */
|
||||
pci_read_config_byte(pdev, 0x4B, &tmp);
|
||||
pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
|
||||
}
|
||||
|
||||
north = pci_get_slot(pdev->bus, PCI_DEVFN(0,0));
|
||||
ali_init_chipset(pdev);
|
||||
|
||||
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
|
||||
|
||||
if (north && north->vendor == PCI_VENDOR_ID_AL) {
|
||||
/* Configure the ALi bridge logic. For non ALi rely on BIOS.
|
||||
Set the south bridge enable bit */
|
||||
pci_read_config_byte(isa_bridge, 0x79, &tmp);
|
||||
if (rev == 0xC2)
|
||||
pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
|
||||
else if (rev > 0xC2)
|
||||
pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
|
||||
if (isa_bridge && rev >= 0x20 && rev < 0xC2) {
|
||||
/* Are we paired with a UDMA capable chip */
|
||||
pci_read_config_byte(isa_bridge, 0x5E, &tmp);
|
||||
if ((tmp & 0x1E) == 0x12)
|
||||
port_info[0] = port_info[1] = &info_20_udma;
|
||||
pci_dev_put(isa_bridge);
|
||||
}
|
||||
|
||||
if (rev >= 0x20) {
|
||||
if (rev < 0xC2) {
|
||||
/* Are we paired with a UDMA capable chip */
|
||||
pci_read_config_byte(isa_bridge, 0x5E, &tmp);
|
||||
if ((tmp & 0x1E) == 0x12)
|
||||
port_info[0] = port_info[1] = &info_20_udma;
|
||||
}
|
||||
/*
|
||||
* CD_ROM DMA on (0x53 bit 0). Enable this even if we want
|
||||
* to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
|
||||
* via 0x54/55.
|
||||
*/
|
||||
pci_read_config_byte(pdev, 0x53, &tmp);
|
||||
if (rev <= 0x20)
|
||||
tmp &= ~0x02;
|
||||
if (rev >= 0xc7)
|
||||
tmp |= 0x03;
|
||||
else
|
||||
tmp |= 0x01; /* CD_ROM enable for DMA */
|
||||
pci_write_config_byte(pdev, 0x53, tmp);
|
||||
}
|
||||
|
||||
pci_dev_put(isa_bridge);
|
||||
pci_dev_put(north);
|
||||
|
||||
ata_pci_clear_simplex(pdev);
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int ali_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
ali_init_chipset(pdev);
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id ali[] = {
|
||||
{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), },
|
||||
{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), },
|
||||
@ -656,7 +684,9 @@ static struct pci_driver ali_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = ali,
|
||||
.probe = ali_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ali_reinit_one,
|
||||
};
|
||||
|
||||
static int __init ali_init(void)
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_amd"
|
||||
#define DRV_VERSION "0.2.4"
|
||||
#define DRV_VERSION "0.2.7"
|
||||
|
||||
/**
|
||||
* timing_setup - shared timing computation and load
|
||||
@ -326,7 +326,6 @@ static struct scsi_host_template amd_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -335,6 +334,8 @@ static struct scsi_host_template amd_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations amd33_port_ops = {
|
||||
@ -662,6 +663,23 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int amd_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
if (pdev->vendor == PCI_VENDOR_ID_AMD) {
|
||||
u8 fifo;
|
||||
pci_read_config_byte(pdev, 0x41, &fifo);
|
||||
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
|
||||
/* FIFO is broken */
|
||||
pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
|
||||
else
|
||||
pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
|
||||
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
|
||||
pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
|
||||
ata_pci_clear_simplex(pdev);
|
||||
}
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id amd[] = {
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7409), 1 },
|
||||
@ -689,7 +707,9 @@ static struct pci_driver amd_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = amd,
|
||||
.probe = amd_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = amd_reinit_one,
|
||||
};
|
||||
|
||||
static int __init amd_init(void)
|
||||
|
@ -307,7 +307,6 @@ static struct scsi_host_template artop_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_atiixp"
|
||||
#define DRV_VERSION "0.4.3"
|
||||
#define DRV_VERSION "0.4.4"
|
||||
|
||||
enum {
|
||||
ATIIXP_IDE_PIO_TIMING = 0x40,
|
||||
@ -209,7 +209,6 @@ static struct scsi_host_template atiixp_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -218,6 +217,8 @@ static struct scsi_host_template atiixp_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations atiixp_port_ops = {
|
||||
@ -281,7 +282,9 @@ static struct pci_driver atiixp_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = atiixp,
|
||||
.probe = atiixp_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.resume = ata_pci_device_resume,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
};
|
||||
|
||||
static int __init atiixp_init(void)
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_cmd64x"
|
||||
#define DRV_VERSION "0.2.1"
|
||||
#define DRV_VERSION "0.2.2"
|
||||
|
||||
/*
|
||||
* CMD64x specific registers definition.
|
||||
@ -268,7 +268,6 @@ static struct scsi_host_template cmd64x_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -277,6 +276,8 @@ static struct scsi_host_template cmd64x_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cmd64x_port_ops = {
|
||||
@ -469,6 +470,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int cmd64x_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
u8 mrdmode;
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
|
||||
pci_read_config_byte(pdev, MRDMODE, &mrdmode);
|
||||
mrdmode &= ~ 0x30; /* IRQ set up */
|
||||
mrdmode |= 0x02; /* Memory read line enable */
|
||||
pci_write_config_byte(pdev, MRDMODE, mrdmode);
|
||||
#ifdef CONFIG_PPC
|
||||
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
|
||||
#endif
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id cmd64x[] = {
|
||||
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
|
||||
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
|
||||
@ -482,7 +497,9 @@ static struct pci_driver cmd64x_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = cmd64x,
|
||||
.probe = cmd64x_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = cmd64x_reinit_one,
|
||||
};
|
||||
|
||||
static int __init cmd64x_init(void)
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_cs5520"
|
||||
#define DRV_VERSION "0.6.2"
|
||||
#define DRV_VERSION "0.6.3"
|
||||
|
||||
struct pio_clocks
|
||||
{
|
||||
@ -159,7 +159,6 @@ static struct scsi_host_template cs5520_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -168,6 +167,8 @@ static struct scsi_host_template cs5520_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cs5520_port_ops = {
|
||||
@ -297,6 +298,22 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
|
||||
dev_set_drvdata(dev, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* cs5520_reinit_one - device resume
|
||||
* @pdev: PCI device
|
||||
*
|
||||
* Do any reconfiguration work needed by a resume from RAM. We need
|
||||
* to restore DMA mode support on BIOSen which disabled it
|
||||
*/
|
||||
|
||||
static int cs5520_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
u8 pcicfg;
|
||||
pci_read_config_byte(pdev, 0x60, &pcicfg);
|
||||
if ((pcicfg & 0x40) == 0)
|
||||
pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
/* For now keep DMA off. We can set it for all but A rev CS5510 once the
|
||||
core ATA code can handle it */
|
||||
|
||||
@ -311,7 +328,9 @@ static struct pci_driver cs5520_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = pata_cs5520,
|
||||
.probe = cs5520_init_one,
|
||||
.remove = cs5520_remove_one
|
||||
.remove = cs5520_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = cs5520_reinit_one,
|
||||
};
|
||||
|
||||
static int __init cs5520_init(void)
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#define DRV_NAME "pata_cs5530"
|
||||
#define DRV_VERSION "0.6"
|
||||
#define DRV_VERSION "0.7.1"
|
||||
|
||||
/**
|
||||
* cs5530_set_piomode - PIO setup
|
||||
@ -173,7 +173,6 @@ static struct scsi_host_template cs5530_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -182,6 +181,8 @@ static struct scsi_host_template cs5530_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cs5530_port_ops = {
|
||||
@ -239,38 +240,18 @@ static int cs5530_is_palmax(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* cs5530_init_one - Initialise a CS5530
|
||||
* @dev: PCI device
|
||||
* @id: Entry in match table
|
||||
* cs5530_init_chip - Chipset init
|
||||
*
|
||||
* Install a driver for the newly found CS5530 companion chip. Most of
|
||||
* this is just housekeeping. We have to set the chip up correctly and
|
||||
* turn off various bits of emulation magic.
|
||||
* Perform the chip initialisation work that is shared between both
|
||||
* setup and resume paths
|
||||
*/
|
||||
|
||||
static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
static int cs5530_init_chip(void)
|
||||
{
|
||||
int compiler_warning_pointless_fix;
|
||||
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
|
||||
static struct ata_port_info info = {
|
||||
.sht = &cs5530_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x07,
|
||||
.port_ops = &cs5530_port_ops
|
||||
};
|
||||
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
|
||||
static struct ata_port_info info_palmax_secondary = {
|
||||
.sht = &cs5530_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.port_ops = &cs5530_port_ops
|
||||
};
|
||||
static struct ata_port_info *port_info[2] = { &info, &info };
|
||||
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL;
|
||||
|
||||
dev = NULL;
|
||||
while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
|
||||
switch (dev->device) {
|
||||
case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
|
||||
@ -291,7 +272,7 @@ static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
}
|
||||
|
||||
pci_set_master(cs5530_0);
|
||||
compiler_warning_pointless_fix = pci_set_mwi(cs5530_0);
|
||||
pci_set_mwi(cs5530_0);
|
||||
|
||||
/*
|
||||
* Set PCI CacheLineSize to 16-bytes:
|
||||
@ -339,13 +320,7 @@ static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
pci_dev_put(master_0);
|
||||
pci_dev_put(cs5530_0);
|
||||
|
||||
if (cs5530_is_palmax())
|
||||
port_info[1] = &info_palmax_secondary;
|
||||
|
||||
/* Now kick off ATA set up */
|
||||
return ata_pci_init_one(dev, port_info, 2);
|
||||
|
||||
return 0;
|
||||
fail_put:
|
||||
if (master_0)
|
||||
pci_dev_put(master_0);
|
||||
@ -354,6 +329,53 @@ fail_put:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* cs5530_init_one - Initialise a CS5530
|
||||
* @dev: PCI device
|
||||
* @id: Entry in match table
|
||||
*
|
||||
* Install a driver for the newly found CS5530 companion chip. Most of
|
||||
* this is just housekeeping. We have to set the chip up correctly and
|
||||
* turn off various bits of emulation magic.
|
||||
*/
|
||||
|
||||
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static struct ata_port_info info = {
|
||||
.sht = &cs5530_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x07,
|
||||
.port_ops = &cs5530_port_ops
|
||||
};
|
||||
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
|
||||
static struct ata_port_info info_palmax_secondary = {
|
||||
.sht = &cs5530_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.port_ops = &cs5530_port_ops
|
||||
};
|
||||
static struct ata_port_info *port_info[2] = { &info, &info };
|
||||
|
||||
/* Chip initialisation */
|
||||
if (cs5530_init_chip())
|
||||
return -ENODEV;
|
||||
|
||||
if (cs5530_is_palmax())
|
||||
port_info[1] = &info_palmax_secondary;
|
||||
|
||||
/* Now kick off ATA set up */
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int cs5530_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
/* If we fail on resume we are doomed */
|
||||
BUG_ON(cs5530_init_chip());
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id cs5530[] = {
|
||||
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
|
||||
|
||||
@ -364,7 +386,9 @@ static struct pci_driver cs5530_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = cs5530,
|
||||
.probe = cs5530_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = cs5530_reinit_one,
|
||||
};
|
||||
|
||||
static int __init cs5530_init(void)
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define DRV_NAME "cs5535"
|
||||
#define DRV_VERSION "0.2.10"
|
||||
#define DRV_VERSION "0.2.11"
|
||||
|
||||
/*
|
||||
* The Geode (Aka Athlon GX now) uses an internal MSR based
|
||||
@ -177,7 +177,6 @@ static struct scsi_host_template cs5535_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -186,6 +185,8 @@ static struct scsi_host_template cs5535_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cs5535_port_ops = {
|
||||
@ -268,7 +269,9 @@ static struct pci_driver cs5535_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = cs5535,
|
||||
.probe = cs5535_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init cs5535_init(void)
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_cypress"
|
||||
#define DRV_VERSION "0.1.2"
|
||||
#define DRV_VERSION "0.1.4"
|
||||
|
||||
/* here are the offset definitions for the registers */
|
||||
|
||||
@ -128,7 +128,6 @@ static struct scsi_host_template cy82c693_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -137,6 +136,8 @@ static struct scsi_host_template cy82c693_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations cy82c693_port_ops = {
|
||||
@ -204,7 +205,9 @@ static struct pci_driver cy82c693_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = cy82c693,
|
||||
.probe = cy82c693_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init cy82c693_init(void)
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_efar"
|
||||
#define DRV_VERSION "0.4.2"
|
||||
#define DRV_VERSION "0.4.3"
|
||||
|
||||
/**
|
||||
* efar_pre_reset - check for 40/80 pin
|
||||
@ -226,7 +226,6 @@ static struct scsi_host_template efar_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -235,6 +234,8 @@ static struct scsi_host_template efar_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations efar_ops = {
|
||||
@ -316,6 +317,8 @@ static struct pci_driver efar_pci_driver = {
|
||||
.id_table = efar_pci_tbl,
|
||||
.probe = efar_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init efar_init(void)
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt366"
|
||||
#define DRV_VERSION "0.5"
|
||||
#define DRV_VERSION "0.5.3"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_speed;
|
||||
@ -222,9 +222,17 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
|
||||
|
||||
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;
|
||||
@ -322,7 +330,6 @@ static struct scsi_host_template hpt36x_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -331,6 +338,8 @@ static struct scsi_host_template hpt36x_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -372,6 +381,27 @@ static struct ata_port_operations hpt366_port_ops = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
/**
|
||||
* hpt36x_init_chipset - common chip setup
|
||||
* @dev: PCI device
|
||||
*
|
||||
* Perform the chip setup work that must be done at both init and
|
||||
* resume time
|
||||
*/
|
||||
|
||||
static void hpt36x_init_chipset(struct pci_dev *dev)
|
||||
{
|
||||
u8 drive_fast;
|
||||
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
|
||||
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
|
||||
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
|
||||
|
||||
pci_read_config_byte(dev, 0x51, &drive_fast);
|
||||
if (drive_fast & 0x80)
|
||||
pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt36x_init_one - Initialise an HPT366/368
|
||||
* @dev: PCI device
|
||||
@ -407,7 +437,6 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
u32 class_rev;
|
||||
u32 reg1;
|
||||
u8 drive_fast;
|
||||
|
||||
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
|
||||
class_rev &= 0xFF;
|
||||
@ -417,14 +446,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
if (class_rev > 2)
|
||||
return -ENODEV;
|
||||
|
||||
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
|
||||
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
|
||||
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
|
||||
|
||||
pci_read_config_byte(dev, 0x51, &drive_fast);
|
||||
if (drive_fast & 0x80)
|
||||
pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
|
||||
hpt36x_init_chipset(dev);
|
||||
|
||||
pci_read_config_dword(dev, 0x40, ®1);
|
||||
|
||||
@ -445,9 +467,15 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
return ata_pci_init_one(dev, port_info, 2);
|
||||
}
|
||||
|
||||
static int hpt36x_reinit_one(struct pci_dev *dev)
|
||||
{
|
||||
hpt36x_init_chipset(dev);
|
||||
return ata_pci_device_resume(dev);
|
||||
}
|
||||
|
||||
|
||||
static const struct pci_device_id hpt36x[] = {
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
|
||||
|
||||
{ },
|
||||
};
|
||||
|
||||
@ -455,7 +483,9 @@ static struct pci_driver hpt36x_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = hpt36x,
|
||||
.probe = hpt36x_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = hpt36x_reinit_one,
|
||||
};
|
||||
|
||||
static int __init hpt36x_init(void)
|
||||
@ -463,13 +493,11 @@ static int __init hpt36x_init(void)
|
||||
return pci_register_driver(&hpt36x_pci_driver);
|
||||
}
|
||||
|
||||
|
||||
static void __exit hpt36x_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&hpt36x_pci_driver);
|
||||
}
|
||||
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -768,7 +768,6 @@ static struct scsi_host_template hpt37x_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -334,7 +334,6 @@ static struct scsi_host_template hpt3x2n_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt3x3"
|
||||
#define DRV_VERSION "0.4.1"
|
||||
#define DRV_VERSION "0.4.2"
|
||||
|
||||
static int hpt3x3_probe_init(struct ata_port *ap)
|
||||
{
|
||||
@ -111,7 +111,6 @@ static struct scsi_host_template hpt3x3_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -120,6 +119,8 @@ static struct scsi_host_template hpt3x3_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations hpt3x3_port_ops = {
|
||||
@ -157,6 +158,27 @@ static struct ata_port_operations hpt3x3_port_ops = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
/**
|
||||
* hpt3x3_init_chipset - chip setup
|
||||
* @dev: PCI device
|
||||
*
|
||||
* Perform the setup required at boot and on resume.
|
||||
*/
|
||||
|
||||
static void hpt3x3_init_chipset(struct pci_dev *dev)
|
||||
{
|
||||
u16 cmd;
|
||||
/* Initialize the board */
|
||||
pci_write_config_word(dev, 0x80, 0x00);
|
||||
/* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
if (cmd & PCI_COMMAND_MEMORY)
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
|
||||
else
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hpt3x3_init_one - Initialise an HPT343/363
|
||||
* @dev: PCI device
|
||||
@ -178,21 +200,18 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
.port_ops = &hpt3x3_port_ops
|
||||
};
|
||||
static struct ata_port_info *port_info[2] = { &info, &info };
|
||||
u16 cmd;
|
||||
|
||||
/* Initialize the board */
|
||||
pci_write_config_word(dev, 0x80, 0x00);
|
||||
/* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
if (cmd & PCI_COMMAND_MEMORY)
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
|
||||
else
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
|
||||
|
||||
hpt3x3_init_chipset(dev);
|
||||
/* Now kick off ATA set up */
|
||||
return ata_pci_init_one(dev, port_info, 2);
|
||||
}
|
||||
|
||||
static int hpt3x3_reinit_one(struct pci_dev *dev)
|
||||
{
|
||||
hpt3x3_init_chipset(dev);
|
||||
return ata_pci_device_resume(dev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id hpt3x3[] = {
|
||||
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), },
|
||||
|
||||
@ -203,7 +222,9 @@ static struct pci_driver hpt3x3_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = hpt3x3,
|
||||
.probe = hpt3x3_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = hpt3x3_reinit_one,
|
||||
};
|
||||
|
||||
static int __init hpt3x3_init(void)
|
||||
|
@ -27,7 +27,6 @@ static struct scsi_host_template isapnp_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -80,7 +80,7 @@
|
||||
|
||||
|
||||
#define DRV_NAME "pata_it821x"
|
||||
#define DRV_VERSION "0.3.2"
|
||||
#define DRV_VERSION "0.3.3"
|
||||
|
||||
struct it821x_dev
|
||||
{
|
||||
@ -666,9 +666,6 @@ static struct scsi_host_template it821x_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
/* 255 sectors to begin with. This is locked in smart mode but not
|
||||
in pass through */
|
||||
.max_sectors = 255,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -677,6 +674,8 @@ static struct scsi_host_template it821x_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations it821x_smart_port_ops = {
|
||||
@ -809,6 +808,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int it821x_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
/* Resume - turn raid back off if need be */
|
||||
if (it8212_noraid)
|
||||
it821x_disable_raid(pdev);
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id it821x[] = {
|
||||
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
|
||||
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
|
||||
@ -820,7 +827,9 @@ static struct pci_driver it821x_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = it821x,
|
||||
.probe = it821x_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = it821x_reinit_one,
|
||||
};
|
||||
|
||||
static int __init it821x_init(void)
|
||||
|
271
drivers/ata/pata_ixp4xx_cf.c
Normal file
271
drivers/ata/pata_ixp4xx_cf.c
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* ixp4xx PATA/Compact Flash driver
|
||||
* Copyright (c) 2006 Tower Technologies
|
||||
* Author: Alessandro Zummo <a.zummo@towertech.it>
|
||||
*
|
||||
* An ATA driver to handle a Compact Flash connected
|
||||
* to the ixp4xx expansion bus in TrueIDE mode. The CF
|
||||
* must have it chip selects connected to two CS lines
|
||||
* on the ixp4xx. The interrupt line is optional, if not
|
||||
* specified the driver will run in polling mode.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
#define DRV_NAME "pata_ixp4xx_cf"
|
||||
#define DRV_VERSION "0.1.1"
|
||||
|
||||
static void ixp4xx_set_mode(struct ata_port *ap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
if (ata_dev_enabled(dev)) {
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ixp4xx_phy_reset(struct ata_port *ap)
|
||||
{
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
ata_port_probe(ap);
|
||||
ata_bus_reset(ap);
|
||||
}
|
||||
|
||||
static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
|
||||
unsigned int buflen, int write_data)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int words = buflen >> 1;
|
||||
u16 *buf16 = (u16 *) buf;
|
||||
struct ata_port *ap = adev->ap;
|
||||
void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
|
||||
struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
|
||||
|
||||
/* set the expansion bus in 16bit mode and restore
|
||||
* 8 bit mode after the transaction.
|
||||
*/
|
||||
*data->cs0_cfg &= ~(0x01);
|
||||
udelay(100);
|
||||
|
||||
/* Transfer multiple of 2 bytes */
|
||||
if (write_data) {
|
||||
for (i = 0; i < words; i++)
|
||||
writew(buf16[i], mmio);
|
||||
} else {
|
||||
for (i = 0; i < words; i++)
|
||||
buf16[i] = readw(mmio);
|
||||
}
|
||||
|
||||
/* Transfer trailing 1 byte, if any. */
|
||||
if (unlikely(buflen & 0x01)) {
|
||||
u16 align_buf[1] = { 0 };
|
||||
unsigned char *trailing_buf = buf + buflen - 1;
|
||||
|
||||
if (write_data) {
|
||||
memcpy(align_buf, trailing_buf, 1);
|
||||
writew(align_buf[0], mmio);
|
||||
} else {
|
||||
align_buf[0] = readw(mmio);
|
||||
memcpy(trailing_buf, align_buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
udelay(100);
|
||||
*data->cs0_cfg |= 0x01;
|
||||
}
|
||||
|
||||
static void ixp4xx_irq_clear(struct ata_port *ap)
|
||||
{
|
||||
}
|
||||
|
||||
static void ixp4xx_host_stop (struct ata_host *host)
|
||||
{
|
||||
struct ixp4xx_pata_data *data = host->dev->platform_data;
|
||||
|
||||
iounmap(data->cs0);
|
||||
iounmap(data->cs1);
|
||||
}
|
||||
|
||||
static struct scsi_host_template ixp4xx_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,
|
||||
};
|
||||
|
||||
static struct ata_port_operations ixp4xx_port_ops = {
|
||||
.set_mode = ixp4xx_set_mode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.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,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
.eng_timeout = ata_eng_timeout,
|
||||
.data_xfer = ixp4xx_mmio_data_xfer,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ixp4xx_irq_clear,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ixp4xx_host_stop,
|
||||
|
||||
.phy_reset = ixp4xx_phy_reset,
|
||||
};
|
||||
|
||||
static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
|
||||
struct ixp4xx_pata_data *data)
|
||||
{
|
||||
ioaddr->cmd_addr = (unsigned long) data->cs0;
|
||||
ioaddr->altstatus_addr = (unsigned long) data->cs1 + 0x06;
|
||||
ioaddr->ctl_addr = (unsigned long) data->cs1 + 0x06;
|
||||
|
||||
ata_std_ports(ioaddr);
|
||||
|
||||
#ifndef __ARMEB__
|
||||
|
||||
/* adjust the addresses to handle the address swizzling of the
|
||||
* ixp4xx in little endian mode.
|
||||
*/
|
||||
|
||||
ioaddr->data_addr ^= 0x02;
|
||||
ioaddr->cmd_addr ^= 0x03;
|
||||
ioaddr->altstatus_addr ^= 0x03;
|
||||
ioaddr->ctl_addr ^= 0x03;
|
||||
ioaddr->error_addr ^= 0x03;
|
||||
ioaddr->feature_addr ^= 0x03;
|
||||
ioaddr->nsect_addr ^= 0x03;
|
||||
ioaddr->lbal_addr ^= 0x03;
|
||||
ioaddr->lbam_addr ^= 0x03;
|
||||
ioaddr->lbah_addr ^= 0x03;
|
||||
ioaddr->device_addr ^= 0x03;
|
||||
ioaddr->status_addr ^= 0x03;
|
||||
ioaddr->command_addr ^= 0x03;
|
||||
#endif
|
||||
}
|
||||
|
||||
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 ixp4xx_pata_data *data = pdev->dev.platform_data;
|
||||
|
||||
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
|
||||
if (!cs0 || !cs1)
|
||||
return -EINVAL;
|
||||
|
||||
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
|
||||
|
||||
data->cs0 = ioremap(cs0->start, 0x1000);
|
||||
data->cs1 = ioremap(cs1->start, 0x1000);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq)
|
||||
set_irq_type(irq, IRQT_HIGH);
|
||||
|
||||
/* Setup expansion bus chip selects */
|
||||
*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);
|
||||
|
||||
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;
|
||||
|
||||
/* run in polling mode if no irq has been assigned */
|
||||
if (!irq)
|
||||
ae.port_flags |= ATA_FLAG_PIO_POLLING;
|
||||
|
||||
ixp4xx_setup_port(&ae.port[0], data);
|
||||
|
||||
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
ret = ata_device_add(&ae);
|
||||
if (ret == 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
|
||||
{
|
||||
struct ata_host *host = platform_get_drvdata(dev);
|
||||
|
||||
ata_host_remove(host);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ixp4xx_pata_platform_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ixp4xx_pata_probe,
|
||||
.remove = __devexit_p(ixp4xx_pata_remove),
|
||||
};
|
||||
|
||||
static int __init ixp4xx_pata_init(void)
|
||||
{
|
||||
return platform_driver_register(&ixp4xx_pata_platform_driver);
|
||||
}
|
||||
|
||||
static void __exit ixp4xx_pata_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ixp4xx_pata_platform_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
|
||||
MODULE_DESCRIPTION("low-level driver for ixp4xx Compact Flash PATA");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
module_init(ixp4xx_pata_init);
|
||||
module_exit(ixp4xx_pata_exit);
|
@ -19,7 +19,7 @@
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_jmicron"
|
||||
#define DRV_VERSION "0.1.2"
|
||||
#define DRV_VERSION "0.1.4"
|
||||
|
||||
typedef enum {
|
||||
PORT_PATA0 = 0,
|
||||
@ -128,8 +128,6 @@ static struct scsi_host_template jmicron_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
/* Special handling needed if you have sector or LBA48 limits */
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -213,12 +211,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
|
||||
|
||||
/* FIXME: We may want a way to override this in future */
|
||||
pci_write_config_byte(pdev, 0x41, 0xa1);
|
||||
|
||||
/* PATA controller is fn 1, AHCI is fn 0 */
|
||||
if (PCI_FUNC(pdev->devfn) != 1)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* PATA controller is fn 1, AHCI is fn 0 */
|
||||
if (PCI_FUNC(pdev->devfn) != 1)
|
||||
return -ENODEV;
|
||||
|
||||
if ( id->driver_data == 365 || id->driver_data == 366) {
|
||||
/* The 365/66 have two PATA channels, redirect the second */
|
||||
pci_read_config_dword(pdev, 0x80, ®);
|
||||
@ -229,6 +226,27 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int jmicron_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
switch(pdev->device) {
|
||||
case PCI_DEVICE_ID_JMICRON_JMB368:
|
||||
break;
|
||||
case PCI_DEVICE_ID_JMICRON_JMB365:
|
||||
case PCI_DEVICE_ID_JMICRON_JMB366:
|
||||
/* Restore mapping or disks swap and boy does it get ugly */
|
||||
pci_read_config_dword(pdev, 0x80, ®);
|
||||
reg |= (1 << 24); /* IDE1 to PATA IDE secondary */
|
||||
pci_write_config_dword(pdev, 0x80, reg);
|
||||
/* Fall through */
|
||||
default:
|
||||
/* Make sure AHCI is turned back on */
|
||||
pci_write_config_byte(pdev, 0x41, 0xa1);
|
||||
}
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id jmicron_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
|
||||
{ PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
|
||||
@ -244,6 +262,8 @@ static struct pci_driver jmicron_pci_driver = {
|
||||
.id_table = jmicron_pci_tbl,
|
||||
.probe = jmicron_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = jmicron_reinit_one,
|
||||
};
|
||||
|
||||
static int __init jmicron_init(void)
|
||||
|
@ -128,7 +128,6 @@ static struct scsi_host_template legacy_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
224
drivers/ata/pata_marvell.c
Normal file
224
drivers/ata/pata_marvell.c
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Marvell PATA driver.
|
||||
*
|
||||
* For the moment we drive the PATA port in legacy mode. That
|
||||
* isn't making full use of the device functionality but it is
|
||||
* easy to get working.
|
||||
*
|
||||
* (c) 2006 Red Hat <alan@redhat.com>
|
||||
*/
|
||||
|
||||
#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 <linux/device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_marvell"
|
||||
#define DRV_VERSION "0.1.1"
|
||||
|
||||
/**
|
||||
* marvell_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
*
|
||||
* Perform the PATA port setup we need.
|
||||
*/
|
||||
|
||||
static int marvell_pre_reset(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 devices;
|
||||
void __iomem *barp;
|
||||
int i;
|
||||
|
||||
/* Check if our port is enabled */
|
||||
|
||||
barp = pci_iomap(pdev, 5, 0x10);
|
||||
if (barp == NULL)
|
||||
return -ENOMEM;
|
||||
printk("BAR5:");
|
||||
for(i = 0; i <= 0x0F; i++)
|
||||
printk("%02X:%02X ", i, readb(barp + i));
|
||||
printk("\n");
|
||||
|
||||
devices = readl(barp + 0x0C);
|
||||
pci_iounmap(pdev, barp);
|
||||
|
||||
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
|
||||
(!(devices & 0x10))) /* PATA enable ? */
|
||||
return -ENOENT;
|
||||
|
||||
/* Cable type */
|
||||
switch(ap->port_no)
|
||||
{
|
||||
case 0:
|
||||
if (inb(ap->ioaddr.bmdma_addr + 1) & 1)
|
||||
ap->cbl = ATA_CBL_PATA40;
|
||||
else
|
||||
ap->cbl = ATA_CBL_PATA80;
|
||||
break;
|
||||
|
||||
case 1: /* Legacy SATA port */
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
break;
|
||||
}
|
||||
return ata_std_prereset(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* marvell_error_handler - Setup and error handler
|
||||
* @ap: Port to handle
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static void marvell_error_handler(struct ata_port *ap)
|
||||
{
|
||||
return ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset,
|
||||
NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
/* No PIO or DMA methods needed for this device */
|
||||
|
||||
static struct scsi_host_template marvell_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,
|
||||
/* Use standard CHS mapping rules */
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations marvell_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
|
||||
/* Task file is PCI ATA format, use helpers */
|
||||
.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 = marvell_error_handler,
|
||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||
|
||||
/* BMDMA handling is PCI ATA format, use helpers */
|
||||
.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 = ata_qc_issue_prot,
|
||||
.data_xfer = ata_pio_data_xfer,
|
||||
|
||||
/* Timeout handling */
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
|
||||
/* Generic PATA PCI ATA helpers */
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* marvell_init_one - Register Marvell ATA PCI device with kernel services
|
||||
* @pdev: PCI device to register
|
||||
* @ent: Entry in marvell_pci_tbl matching with @pdev
|
||||
*
|
||||
* Called from kernel PCI layer.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from PCI layer (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, or -ERRNO value.
|
||||
*/
|
||||
|
||||
static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static struct ata_port_info info = {
|
||||
.sht = &marvell_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x3f,
|
||||
|
||||
.port_ops = &marvell_ops,
|
||||
};
|
||||
static struct ata_port_info info_sata = {
|
||||
.sht = &marvell_sht,
|
||||
/* Slave possible as its magically mapped not real */
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
|
||||
.port_ops = &marvell_ops,
|
||||
};
|
||||
struct ata_port_info *port_info[2] = { &info, &info_sata };
|
||||
int n_port = 2;
|
||||
|
||||
if (pdev->device == 0x6101)
|
||||
n_port = 1;
|
||||
|
||||
return ata_pci_init_one(pdev, port_info, n_port);
|
||||
}
|
||||
|
||||
static const struct pci_device_id marvell_pci_tbl[] = {
|
||||
{ PCI_DEVICE(0x11AB, 0x6101), },
|
||||
{ PCI_DEVICE(0x11AB, 0x6145), },
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
static struct pci_driver marvell_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = marvell_pci_tbl,
|
||||
.probe = marvell_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init marvell_init(void)
|
||||
{
|
||||
return pci_register_driver(&marvell_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit marvell_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&marvell_pci_driver);
|
||||
}
|
||||
|
||||
module_init(marvell_init);
|
||||
module_exit(marvell_exit);
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("SCSI low-level driver for Marvell ATA in legacy mode");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, marvell_pci_tbl);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_mpiix"
|
||||
#define DRV_VERSION "0.7.2"
|
||||
#define DRV_VERSION "0.7.3"
|
||||
|
||||
enum {
|
||||
IDETIM = 0x6C, /* IDE control register */
|
||||
@ -159,7 +159,6 @@ static struct scsi_host_template mpiix_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -168,6 +167,8 @@ static struct scsi_host_template mpiix_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations mpiix_port_ops = {
|
||||
@ -285,7 +286,9 @@ static struct pci_driver mpiix_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = mpiix,
|
||||
.probe = mpiix_init_one,
|
||||
.remove = mpiix_remove_one
|
||||
.remove = mpiix_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init mpiix_init(void)
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_netcell"
|
||||
#define DRV_VERSION "0.1.5"
|
||||
#define DRV_VERSION "0.1.6"
|
||||
|
||||
/**
|
||||
* netcell_probe_init - check for 40/80 pin
|
||||
@ -54,8 +54,6 @@ static struct scsi_host_template netcell_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
/* Special handling needed if you have sector or LBA48 limits */
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -65,6 +63,8 @@ static struct scsi_host_template netcell_sht = {
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
/* Use standard CHS mapping rules */
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations netcell_ops = {
|
||||
@ -153,6 +153,8 @@ static struct pci_driver netcell_pci_driver = {
|
||||
.id_table = netcell_pci_tbl,
|
||||
.probe = netcell_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init netcell_init(void)
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_ns87410"
|
||||
#define DRV_VERSION "0.4.2"
|
||||
#define DRV_VERSION "0.4.3"
|
||||
|
||||
/**
|
||||
* ns87410_pre_reset - probe begin
|
||||
@ -149,7 +149,6 @@ static struct scsi_host_template ns87410_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -158,6 +157,8 @@ static struct scsi_host_template ns87410_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations ns87410_port_ops = {
|
||||
@ -210,7 +211,9 @@ static struct pci_driver ns87410_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = ns87410,
|
||||
.probe = ns87410_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init ns87410_init(void)
|
||||
|
@ -224,7 +224,6 @@ static struct scsi_host_template oldpiix_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -233,6 +232,8 @@ static struct scsi_host_template oldpiix_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations oldpiix_pata_ops = {
|
||||
@ -314,6 +315,8 @@ static struct pci_driver oldpiix_pci_driver = {
|
||||
.id_table = oldpiix_pci_tbl,
|
||||
.probe = oldpiix_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init oldpiix_init(void)
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_opti"
|
||||
#define DRV_VERSION "0.2.5"
|
||||
#define DRV_VERSION "0.2.7"
|
||||
|
||||
enum {
|
||||
READ_REG = 0, /* index of Read cycle timing register */
|
||||
@ -109,30 +109,6 @@ static void opti_write_reg(struct ata_port *ap, u8 val, int reg)
|
||||
outb(0x83, regio + 2);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* opti_read_reg - control register read
|
||||
* @ap: ATA port
|
||||
* @reg: control register number
|
||||
*
|
||||
* The Opti uses magic 'trapdoor' register accesses to do configuration
|
||||
* rather than using PCI space as other controllers do. The double inw
|
||||
* on the error register activates configuration mode. We can then read
|
||||
* the control register
|
||||
*/
|
||||
|
||||
static u8 opti_read_reg(struct ata_port *ap, int reg)
|
||||
{
|
||||
unsigned long regio = ap->ioaddr.cmd_addr;
|
||||
u8 ret;
|
||||
inw(regio + 1);
|
||||
inw(regio + 1);
|
||||
outb(3, regio + 2);
|
||||
ret = inb(regio + reg);
|
||||
outb(0x83, regio + 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* opti_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
@ -195,7 +171,6 @@ static struct scsi_host_template opti_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -204,12 +179,13 @@ static struct scsi_host_template opti_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations opti_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = opti_set_piomode,
|
||||
/* .set_dmamode = opti_set_dmamode, */
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
.check_status = ata_check_status,
|
||||
@ -267,7 +243,9 @@ static struct pci_driver opti_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = opti,
|
||||
.probe = opti_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init opti_init(void)
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_optidma"
|
||||
#define DRV_VERSION "0.2.2"
|
||||
#define DRV_VERSION "0.2.3"
|
||||
|
||||
enum {
|
||||
READ_REG = 0, /* index of Read cycle timing register */
|
||||
@ -352,7 +352,6 @@ static struct scsi_host_template optidma_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -361,6 +360,8 @@ static struct scsi_host_template optidma_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations optidma_port_ops = {
|
||||
@ -522,7 +523,9 @@ static struct pci_driver optidma_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = optidma,
|
||||
.probe = optidma_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init optidma_init(void)
|
||||
|
@ -62,7 +62,6 @@ static struct scsi_host_template pcmcia_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -134,7 +134,6 @@ static struct scsi_host_template pdc2027x_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -854,7 +853,7 @@ static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
|
||||
*/
|
||||
static int __init pdc2027x_init(void)
|
||||
{
|
||||
return pci_module_init(&pdc2027x_pci_driver);
|
||||
return pci_register_driver(&pdc2027x_pci_driver);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_pdc202xx_old"
|
||||
#define DRV_VERSION "0.2.1"
|
||||
#define DRV_VERSION "0.2.3"
|
||||
|
||||
/**
|
||||
* pdc2024x_pre_reset - probe begin
|
||||
@ -63,7 +63,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc_configure_piomode - set chip PIO timing
|
||||
* pdc202xx_configure_piomode - set chip PIO timing
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
* @pio: PIO mode
|
||||
@ -73,7 +73,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
|
||||
* versa
|
||||
*/
|
||||
|
||||
static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
|
||||
static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
|
||||
@ -98,7 +98,7 @@ static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev,
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc_set_piomode - set initial PIO mode data
|
||||
* pdc202xx_set_piomode - set initial PIO mode data
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*
|
||||
@ -106,13 +106,13 @@ static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev,
|
||||
* but we want to set the PIO timing by default.
|
||||
*/
|
||||
|
||||
static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
static void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
pdc_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
|
||||
pdc202xx_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc_configure_dmamode - set DMA mode in chip
|
||||
* pdc202xx_configure_dmamode - set DMA mode in chip
|
||||
* @ap: ATA interface
|
||||
* @adev: ATA device
|
||||
*
|
||||
@ -120,7 +120,7 @@ static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
* to occur.
|
||||
*/
|
||||
|
||||
static void pdc_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
|
||||
@ -184,7 +184,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
|
||||
|
||||
/* The DMA clocks may have been trashed by a reset. FIXME: make conditional
|
||||
and move to qc_issue ? */
|
||||
pdc_set_dmamode(ap, qc->dev);
|
||||
pdc202xx_set_dmamode(ap, qc->dev);
|
||||
|
||||
/* Cases the state machine will not complete correctly without help */
|
||||
if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA)
|
||||
@ -254,7 +254,7 @@ static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev)
|
||||
adev->max_sectors = 256;
|
||||
}
|
||||
|
||||
static struct scsi_host_template pdc_sht = {
|
||||
static struct scsi_host_template pdc202xx_sht = {
|
||||
.module = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
.ioctl = ata_scsi_ioctl,
|
||||
@ -262,7 +262,6 @@ static struct scsi_host_template pdc_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -271,12 +270,14 @@ static struct scsi_host_template pdc_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations pdc2024x_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pdc_set_piomode,
|
||||
.set_dmamode = pdc_set_dmamode,
|
||||
.set_piomode = pdc202xx_set_piomode,
|
||||
.set_dmamode = pdc202xx_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
@ -308,8 +309,8 @@ static struct ata_port_operations pdc2024x_port_ops = {
|
||||
|
||||
static struct ata_port_operations pdc2026x_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = pdc_set_piomode,
|
||||
.set_dmamode = pdc_set_dmamode,
|
||||
.set_piomode = pdc202xx_set_piomode,
|
||||
.set_dmamode = pdc202xx_set_dmamode,
|
||||
.mode_filter = ata_pci_default_filter,
|
||||
.tf_load = ata_tf_load,
|
||||
.tf_read = ata_tf_read,
|
||||
@ -340,11 +341,11 @@ static struct ata_port_operations pdc2026x_port_ops = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
static struct ata_port_info info[3] = {
|
||||
{
|
||||
.sht = &pdc_sht,
|
||||
.sht = &pdc202xx_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
@ -352,7 +353,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
.port_ops = &pdc2024x_port_ops
|
||||
},
|
||||
{
|
||||
.sht = &pdc_sht,
|
||||
.sht = &pdc202xx_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
@ -360,7 +361,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
.port_ops = &pdc2026x_port_ops
|
||||
},
|
||||
{
|
||||
.sht = &pdc_sht,
|
||||
.sht = &pdc202xx_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
@ -386,7 +387,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
return ata_pci_init_one(dev, port_info, 2);
|
||||
}
|
||||
|
||||
static const struct pci_device_id pdc[] = {
|
||||
static const struct pci_device_id pdc202xx[] = {
|
||||
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
|
||||
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
|
||||
{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
|
||||
@ -396,28 +397,30 @@ static const struct pci_device_id pdc[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct pci_driver pdc_pci_driver = {
|
||||
static struct pci_driver pdc202xx_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = pdc,
|
||||
.probe = pdc_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.id_table = pdc202xx,
|
||||
.probe = pdc202xx_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init pdc_init(void)
|
||||
static int __init pdc202xx_init(void)
|
||||
{
|
||||
return pci_register_driver(&pdc_pci_driver);
|
||||
return pci_register_driver(&pdc202xx_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit pdc_exit(void)
|
||||
static void __exit pdc202xx_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&pdc_pci_driver);
|
||||
pci_unregister_driver(&pdc202xx_pci_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, pdc);
|
||||
MODULE_DEVICE_TABLE(pci, pdc202xx);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
module_init(pdc_init);
|
||||
module_exit(pdc_exit);
|
||||
module_init(pdc202xx_init);
|
||||
module_exit(pdc202xx_exit);
|
||||
|
295
drivers/ata/pata_platform.c
Normal file
295
drivers/ata/pata_platform.c
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Generic platform device PATA driver
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
*
|
||||
* Based on pata_pcmcia:
|
||||
*
|
||||
* Copyright 2005-2006 Red Hat Inc <alan@redhat.com>, all rights reserved.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/ata.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pata_platform.h>
|
||||
|
||||
#define DRV_NAME "pata_platform"
|
||||
#define DRV_VERSION "0.1.2"
|
||||
|
||||
static int pio_mask = 1;
|
||||
|
||||
/*
|
||||
* Provide our own set_mode() as we don't want to change anything that has
|
||||
* already been configured..
|
||||
*/
|
||||
static void pata_platform_set_mode(struct ata_port *ap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||
struct ata_device *dev = &ap->device[i];
|
||||
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pata_platform_host_stop(struct ata_host *host)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Unmap the bases for MMIO
|
||||
*/
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
|
||||
if (ap->flags & ATA_FLAG_MMIO) {
|
||||
iounmap((void __iomem *)ap->ioaddr.ctl_addr);
|
||||
iounmap((void __iomem *)ap->ioaddr.cmd_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct scsi_host_template pata_platform_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,
|
||||
};
|
||||
|
||||
static struct ata_port_operations pata_platform_port_ops = {
|
||||
.set_mode = pata_platform_set_mode,
|
||||
|
||||
.port_disable = ata_port_disable,
|
||||
.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,
|
||||
|
||||
.qc_prep = ata_qc_prep,
|
||||
.qc_issue = ata_qc_issue_prot,
|
||||
|
||||
.data_xfer = ata_pio_data_xfer_noirq,
|
||||
|
||||
.irq_handler = ata_interrupt,
|
||||
.irq_clear = ata_bmdma_irq_clear,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = pata_platform_host_stop
|
||||
};
|
||||
|
||||
static void pata_platform_setup_port(struct ata_ioports *ioaddr,
|
||||
struct pata_platform_info *info)
|
||||
{
|
||||
unsigned int shift = 0;
|
||||
|
||||
/* Fixup the port shift for platforms that need it */
|
||||
if (info && info->ioport_shift)
|
||||
shift = info->ioport_shift;
|
||||
|
||||
ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift);
|
||||
ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift);
|
||||
ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
|
||||
ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift);
|
||||
ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift);
|
||||
ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift);
|
||||
ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift);
|
||||
ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift);
|
||||
ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift);
|
||||
ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* pata_platform_probe - attach a platform interface
|
||||
* @pdev: platform device
|
||||
*
|
||||
* Register a platform bus IDE interface. Such interfaces are PIO and we
|
||||
* assume do not support IRQ sharing.
|
||||
*
|
||||
* Platform devices are expected to contain 3 resources per port:
|
||||
*
|
||||
* - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
|
||||
* - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
|
||||
* - IRQ (IORESOURCE_IRQ)
|
||||
*
|
||||
* If the base resources are both mem types, the ioremap() is handled
|
||||
* here. For IORESOURCE_IO, it's assumed that there's no remapping
|
||||
* necessary.
|
||||
*/
|
||||
static int __devinit pata_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *io_res, *ctl_res;
|
||||
struct ata_probe_ent ae;
|
||||
unsigned int mmio;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Simple resource validation ..
|
||||
*/
|
||||
if (unlikely(pdev->num_resources != 3)) {
|
||||
dev_err(&pdev->dev, "invalid number of resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the I/O base first
|
||||
*/
|
||||
io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (io_res == NULL) {
|
||||
io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (unlikely(io_res == NULL))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Then the CTL base
|
||||
*/
|
||||
ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
|
||||
if (ctl_res == NULL) {
|
||||
ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (unlikely(ctl_res == NULL))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for MMIO
|
||||
*/
|
||||
mmio = (( io_res->flags == IORESOURCE_MEM) &&
|
||||
(ctl_res->flags == IORESOURCE_MEM));
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* Handle the MMIO case
|
||||
*/
|
||||
if (mmio) {
|
||||
ae.port_flags |= ATA_FLAG_MMIO;
|
||||
|
||||
ae.port[0].cmd_addr = (unsigned long)ioremap(io_res->start,
|
||||
io_res->end - io_res->start + 1);
|
||||
if (unlikely(!ae.port[0].cmd_addr)) {
|
||||
dev_err(&pdev->dev, "failed to remap IO base\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ae.port[0].ctl_addr = (unsigned long)ioremap(ctl_res->start,
|
||||
ctl_res->end - ctl_res->start + 1);
|
||||
if (unlikely(!ae.port[0].ctl_addr)) {
|
||||
dev_err(&pdev->dev, "failed to remap CTL base\n");
|
||||
ret = -ENXIO;
|
||||
goto bad_remap;
|
||||
}
|
||||
} else {
|
||||
ae.port[0].cmd_addr = io_res->start;
|
||||
ae.port[0].ctl_addr = ctl_res->start;
|
||||
}
|
||||
|
||||
ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
|
||||
|
||||
pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
|
||||
|
||||
if (unlikely(ata_device_add(&ae) == 0)) {
|
||||
ret = -ENODEV;
|
||||
goto add_failed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
add_failed:
|
||||
if (ae.port[0].ctl_addr && mmio)
|
||||
iounmap((void __iomem *)ae.port[0].ctl_addr);
|
||||
bad_remap:
|
||||
if (ae.port[0].cmd_addr && mmio)
|
||||
iounmap((void __iomem *)ae.port[0].cmd_addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pata_platform_remove - unplug a platform interface
|
||||
* @pdev: platform device
|
||||
*
|
||||
* A platform bus ATA device has been unplugged. Perform the needed
|
||||
* cleanup. Also called on module unload for any active devices.
|
||||
*/
|
||||
static int __devexit pata_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
||||
ata_host_remove(host);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pata_platform_driver = {
|
||||
.probe = pata_platform_probe,
|
||||
.remove = __devexit_p(pata_platform_remove),
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init pata_platform_init(void)
|
||||
{
|
||||
return platform_driver_register(&pata_platform_driver);
|
||||
}
|
||||
|
||||
static void __exit pata_platform_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&pata_platform_driver);
|
||||
}
|
||||
module_init(pata_platform_init);
|
||||
module_exit(pata_platform_exit);
|
||||
|
||||
module_param(pio_mask, int, 0);
|
||||
|
||||
MODULE_AUTHOR("Paul Mundt");
|
||||
MODULE_DESCRIPTION("low-level driver for platform device ATA");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
@ -157,7 +157,6 @@ static struct scsi_host_template qdi_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -220,7 +220,6 @@ static struct scsi_host_template radisys_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -229,6 +228,8 @@ static struct scsi_host_template radisys_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations radisys_pata_ops = {
|
||||
@ -311,6 +312,8 @@ static struct pci_driver radisys_pci_driver = {
|
||||
.id_table = radisys_pci_tbl,
|
||||
.probe = radisys_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init radisys_init(void)
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_rz1000"
|
||||
#define DRV_VERSION "0.2.2"
|
||||
#define DRV_VERSION "0.2.3"
|
||||
|
||||
|
||||
/**
|
||||
@ -83,7 +83,6 @@ static struct scsi_host_template rz1000_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -92,6 +91,8 @@ static struct scsi_host_template rz1000_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations rz1000_port_ops = {
|
||||
@ -129,6 +130,19 @@ static struct ata_port_operations rz1000_port_ops = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
static int rz1000_fifo_disable(struct pci_dev *pdev)
|
||||
{
|
||||
u16 reg;
|
||||
/* Be exceptionally paranoid as we must be sure to apply the fix */
|
||||
if (pci_read_config_word(pdev, 0x40, ®) != 0)
|
||||
return -1;
|
||||
reg &= 0xDFFF;
|
||||
if (pci_write_config_word(pdev, 0x40, reg) != 0)
|
||||
return -1;
|
||||
printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* rz1000_init_one - Register RZ1000 ATA PCI device with kernel services
|
||||
* @pdev: PCI device to register
|
||||
@ -143,7 +157,6 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
|
||||
{
|
||||
static int printed_version;
|
||||
struct ata_port_info *port_info[2];
|
||||
u16 reg;
|
||||
static struct ata_port_info info = {
|
||||
.sht = &rz1000_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
@ -154,23 +167,25 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
|
||||
if (!printed_version++)
|
||||
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
|
||||
|
||||
/* Be exceptionally paranoid as we must be sure to apply the fix */
|
||||
if (pci_read_config_word(pdev, 0x40, ®) != 0)
|
||||
goto fail;
|
||||
reg &= 0xDFFF;
|
||||
if (pci_write_config_word(pdev, 0x40, reg) != 0)
|
||||
goto fail;
|
||||
printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n");
|
||||
|
||||
port_info[0] = &info;
|
||||
port_info[1] = &info;
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
fail:
|
||||
if (rz1000_fifo_disable(pdev) == 0) {
|
||||
port_info[0] = &info;
|
||||
port_info[1] = &info;
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
|
||||
/* Not safe to use so skip */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int rz1000_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
/* If this fails on resume (which is a "cant happen" case), we
|
||||
must stop as any progress risks data loss */
|
||||
if (rz1000_fifo_disable(pdev))
|
||||
panic("rz1000 fifo");
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id pata_rz1000[] = {
|
||||
{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
|
||||
{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
|
||||
@ -182,7 +197,9 @@ static struct pci_driver rz1000_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = pata_rz1000,
|
||||
.probe = rz1000_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = rz1000_reinit_one,
|
||||
};
|
||||
|
||||
static int __init rz1000_init(void)
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "sc1200"
|
||||
#define DRV_VERSION "0.2.3"
|
||||
#define DRV_VERSION "0.2.4"
|
||||
|
||||
#define SC1200_REV_A 0x00
|
||||
#define SC1200_REV_B1 0x01
|
||||
@ -186,7 +186,6 @@ static struct scsi_host_template sc1200_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -195,6 +194,8 @@ static struct scsi_host_template sc1200_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations sc1200_port_ops = {
|
||||
@ -264,7 +265,9 @@ static struct pci_driver sc1200_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = sc1200,
|
||||
.probe = sc1200_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init sc1200_init(void)
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_serverworks"
|
||||
#define DRV_VERSION "0.3.7"
|
||||
#define DRV_VERSION "0.3.9"
|
||||
|
||||
#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
|
||||
#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
|
||||
@ -318,7 +318,6 @@ static struct scsi_host_template serverworks_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -327,6 +326,8 @@ static struct scsi_host_template serverworks_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations serverworks_osb4_port_ops = {
|
||||
@ -554,6 +555,30 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
|
||||
return ata_pci_init_one(pdev, port_info, ports);
|
||||
}
|
||||
|
||||
static int serverworks_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
/* Force master latency timer to 64 PCI clocks */
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
|
||||
|
||||
switch (pdev->device)
|
||||
{
|
||||
case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
|
||||
serverworks_fixup_osb4(pdev);
|
||||
break;
|
||||
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
|
||||
ata_pci_clear_simplex(pdev);
|
||||
/* fall through */
|
||||
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
|
||||
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
|
||||
serverworks_fixup_csb(pdev);
|
||||
break;
|
||||
case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
|
||||
serverworks_fixup_ht1000(pdev);
|
||||
break;
|
||||
}
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id serverworks[] = {
|
||||
{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
|
||||
{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
|
||||
@ -568,7 +593,9 @@ static struct pci_driver serverworks_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = serverworks,
|
||||
.probe = serverworks_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = serverworks_reinit_one,
|
||||
};
|
||||
|
||||
static int __init serverworks_init(void)
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_sil680"
|
||||
#define DRV_VERSION "0.3.2"
|
||||
#define DRV_VERSION "0.4.1"
|
||||
|
||||
/**
|
||||
* sil680_selreg - return register base
|
||||
@ -218,7 +218,6 @@ static struct scsi_host_template sil680_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -263,32 +262,20 @@ static struct ata_port_operations sil680_port_ops = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/**
|
||||
* sil680_init_chip - chip setup
|
||||
* @pdev: PCI device
|
||||
*
|
||||
* Perform all the chip setup which must be done both when the device
|
||||
* is powered up on boot and when we resume in case we resumed from RAM.
|
||||
* Returns the final clock settings.
|
||||
*/
|
||||
|
||||
static u8 sil680_init_chip(struct pci_dev *pdev)
|
||||
{
|
||||
static struct ata_port_info info = {
|
||||
.sht = &sil680_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &sil680_port_ops
|
||||
};
|
||||
static struct ata_port_info info_slow = {
|
||||
.sht = &sil680_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x3f,
|
||||
.port_ops = &sil680_port_ops
|
||||
};
|
||||
static struct ata_port_info *port_info[2] = {&info, &info};
|
||||
static int printed_version;
|
||||
u32 class_rev = 0;
|
||||
u8 tmpbyte = 0;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
|
||||
class_rev &= 0xff;
|
||||
/* FIXME: double check */
|
||||
@ -323,8 +310,6 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
pci_read_config_byte(pdev, 0x8A, &tmpbyte);
|
||||
printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
|
||||
tmpbyte & 1, tmpbyte & 0x30);
|
||||
if ((tmpbyte & 0x30) == 0)
|
||||
port_info[0] = port_info[1] = &info_slow;
|
||||
|
||||
pci_write_config_byte(pdev, 0xA1, 0x72);
|
||||
pci_write_config_word(pdev, 0xA2, 0x328A);
|
||||
@ -343,11 +328,51 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break;
|
||||
/* This last case is _NOT_ ok */
|
||||
case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n");
|
||||
return -EIO;
|
||||
}
|
||||
return tmpbyte & 0x30;
|
||||
}
|
||||
|
||||
static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
static struct ata_port_info info = {
|
||||
.sht = &sil680_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f,
|
||||
.port_ops = &sil680_port_ops
|
||||
};
|
||||
static struct ata_port_info info_slow = {
|
||||
.sht = &sil680_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x3f,
|
||||
.port_ops = &sil680_port_ops
|
||||
};
|
||||
static struct ata_port_info *port_info[2] = {&info, &info};
|
||||
static int printed_version;
|
||||
|
||||
if (!printed_version++)
|
||||
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||
|
||||
switch(sil680_init_chip(pdev))
|
||||
{
|
||||
case 0:
|
||||
port_info[0] = port_info[1] = &info_slow;
|
||||
break;
|
||||
case 0x30:
|
||||
return -ENODEV;
|
||||
}
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
static int sil680_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
sil680_init_chip(pdev);
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id sil680[] = {
|
||||
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
|
||||
|
||||
@ -358,7 +383,9 @@ static struct pci_driver sil680_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = sil680,
|
||||
.probe = sil680_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = sil680_reinit_one,
|
||||
};
|
||||
|
||||
static int __init sil680_init(void)
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <linux/ata.h>
|
||||
|
||||
#define DRV_NAME "pata_sis"
|
||||
#define DRV_VERSION "0.4.4"
|
||||
#define DRV_VERSION "0.4.5"
|
||||
|
||||
struct sis_chipset {
|
||||
u16 device; /* PCI host ID */
|
||||
@ -538,7 +538,6 @@ static struct scsi_host_template sis_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -547,6 +546,8 @@ static struct scsi_host_template sis_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations sis_133_ops = {
|
||||
@ -1000,6 +1001,8 @@ static struct pci_driver sis_pci_driver = {
|
||||
.id_table = sis_pci_tbl,
|
||||
.probe = sis_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init sis_init(void)
|
||||
|
@ -230,7 +230,6 @@ static struct scsi_host_template sl82c105_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_triflex"
|
||||
#define DRV_VERSION "0.2.5"
|
||||
#define DRV_VERSION "0.2.7"
|
||||
|
||||
/**
|
||||
* triflex_prereset - probe begin
|
||||
@ -185,7 +185,6 @@ static struct scsi_host_template triflex_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -194,6 +193,8 @@ static struct scsi_host_template triflex_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations triflex_port_ops = {
|
||||
@ -258,7 +259,9 @@ static struct pci_driver triflex_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = triflex,
|
||||
.probe = triflex_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = ata_pci_device_resume,
|
||||
};
|
||||
|
||||
static int __init triflex_init(void)
|
||||
|
@ -23,6 +23,7 @@
|
||||
* VIA VT8233c - UDMA100
|
||||
* VIA VT8235 - UDMA133
|
||||
* VIA VT8237 - UDMA133
|
||||
* VIA VT8251 - UDMA133
|
||||
*
|
||||
* Most registers remain compatible across chips. Others start reserved
|
||||
* and acquire sensible semantics if set to 1 (eg cable detect). A few
|
||||
@ -60,7 +61,7 @@
|
||||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_via"
|
||||
#define DRV_VERSION "0.1.14"
|
||||
#define DRV_VERSION "0.2.0"
|
||||
|
||||
/*
|
||||
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
|
||||
@ -94,6 +95,7 @@ static const struct via_isa_bridge {
|
||||
u8 rev_max;
|
||||
u16 flags;
|
||||
} via_isa_bridges[] = {
|
||||
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
|
||||
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
|
||||
@ -288,7 +290,6 @@ static struct scsi_host_template via_sht = {
|
||||
.can_queue = ATA_DEF_QUEUE,
|
||||
.this_id = ATA_SHT_THIS_ID,
|
||||
.sg_tablesize = LIBATA_MAX_PRD,
|
||||
.max_sectors = ATA_MAX_SECTORS,
|
||||
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
|
||||
.emulated = ATA_SHT_EMULATED,
|
||||
.use_clustering = ATA_SHT_USE_CLUSTERING,
|
||||
@ -297,6 +298,8 @@ static struct scsi_host_template via_sht = {
|
||||
.slave_configure = ata_scsi_slave_config,
|
||||
.slave_destroy = ata_scsi_slave_destroy,
|
||||
.bios_param = ata_std_bios_param,
|
||||
.resume = ata_scsi_device_resume,
|
||||
.suspend = ata_scsi_device_suspend,
|
||||
};
|
||||
|
||||
static struct ata_port_operations via_port_ops = {
|
||||
@ -369,9 +372,43 @@ static struct ata_port_operations via_port_ops_noirq = {
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
/**
|
||||
* via_config_fifo - set up the FIFO
|
||||
* @pdev: PCI device
|
||||
* @flags: configuration flags
|
||||
*
|
||||
* Set the FIFO properties for this device if neccessary. Used both on
|
||||
* set up and on and the resume path
|
||||
*/
|
||||
|
||||
static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
|
||||
{
|
||||
u8 enable;
|
||||
|
||||
/* 0x40 low bits indicate enabled channels */
|
||||
pci_read_config_byte(pdev, 0x40 , &enable);
|
||||
enable &= 3;
|
||||
|
||||
if (flags & VIA_SET_FIFO) {
|
||||
u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
|
||||
u8 fifo;
|
||||
|
||||
pci_read_config_byte(pdev, 0x43, &fifo);
|
||||
|
||||
/* Clear PREQ# until DDACK# for errata */
|
||||
if (flags & VIA_BAD_PREQ)
|
||||
fifo &= 0x7F;
|
||||
else
|
||||
fifo &= 0x9f;
|
||||
/* Turn on FIFO for enabled channels */
|
||||
fifo |= fifo_setting[enable];
|
||||
pci_write_config_byte(pdev, 0x43, fifo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* via_init_one - discovery callback
|
||||
* @pdev: PCI device ID
|
||||
* @pdev: PCI device
|
||||
* @id: PCI table info
|
||||
*
|
||||
* A VIA IDE interface has been discovered. Figure out what revision
|
||||
@ -383,7 +420,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* Early VIA without UDMA support */
|
||||
static struct ata_port_info via_mwdma_info = {
|
||||
.sht = &via_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.port_ops = &via_port_ops
|
||||
@ -391,7 +428,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* Ditto with IRQ masking required */
|
||||
static struct ata_port_info via_mwdma_info_borked = {
|
||||
.sht = &via_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.port_ops = &via_port_ops_noirq,
|
||||
@ -399,7 +436,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* VIA UDMA 33 devices (and borked 66) */
|
||||
static struct ata_port_info via_udma33_info = {
|
||||
.sht = &via_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7,
|
||||
@ -408,7 +445,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* VIA UDMA 66 devices */
|
||||
static struct ata_port_info via_udma66_info = {
|
||||
.sht = &via_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x1f,
|
||||
@ -417,7 +454,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* VIA UDMA 100 devices */
|
||||
static struct ata_port_info via_udma100_info = {
|
||||
.sht = &via_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x3f,
|
||||
@ -426,7 +463,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* UDMA133 with bad AST (All current 133) */
|
||||
static struct ata_port_info via_udma133_info = {
|
||||
.sht = &via_sht,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
|
||||
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
|
||||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = 0x7f, /* FIXME: should check north bridge */
|
||||
@ -471,21 +508,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
}
|
||||
|
||||
/* Initialise the FIFO for the enabled channels. */
|
||||
if (config->flags & VIA_SET_FIFO) {
|
||||
u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
|
||||
u8 fifo;
|
||||
|
||||
pci_read_config_byte(pdev, 0x43, &fifo);
|
||||
|
||||
/* Clear PREQ# until DDACK# for errata */
|
||||
if (config->flags & VIA_BAD_PREQ)
|
||||
fifo &= 0x7F;
|
||||
else
|
||||
fifo &= 0x9f;
|
||||
/* Turn on FIFO for enabled channels */
|
||||
fifo |= fifo_setting[enable];
|
||||
pci_write_config_byte(pdev, 0x43, fifo);
|
||||
}
|
||||
via_config_fifo(pdev, config->flags);
|
||||
|
||||
/* Clock set up */
|
||||
switch(config->flags & VIA_UDMA) {
|
||||
case VIA_UDMA_NONE:
|
||||
@ -529,6 +553,39 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
return ata_pci_init_one(pdev, port_info, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* via_reinit_one - reinit after resume
|
||||
* @pdev; PCI device
|
||||
*
|
||||
* Called when the VIA PATA device is resumed. We must then
|
||||
* reconfigure the fifo and other setup we may have altered. In
|
||||
* addition the kernel needs to have the resume methods on PCI
|
||||
* quirk supported.
|
||||
*/
|
||||
|
||||
static int via_reinit_one(struct pci_dev *pdev)
|
||||
{
|
||||
u32 timing;
|
||||
struct ata_host *host = dev_get_drvdata(&pdev->dev);
|
||||
const struct via_isa_bridge *config = host->private_data;
|
||||
|
||||
via_config_fifo(pdev, config->flags);
|
||||
|
||||
if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
|
||||
/* The 66 MHz devices require we enable the clock */
|
||||
pci_read_config_dword(pdev, 0x50, &timing);
|
||||
timing |= 0x80008;
|
||||
pci_write_config_dword(pdev, 0x50, timing);
|
||||
}
|
||||
if (config->flags & VIA_BAD_CLK66) {
|
||||
/* Disable the 66MHz clock on problem devices */
|
||||
pci_read_config_dword(pdev, 0x50, &timing);
|
||||
timing &= ~0x80008;
|
||||
pci_write_config_dword(pdev, 0x50, timing);
|
||||
}
|
||||
return ata_pci_device_resume(pdev);
|
||||
}
|
||||
|
||||
static const struct pci_device_id via[] = {
|
||||
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
|
||||
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
|
||||
@ -542,7 +599,9 @@ static struct pci_driver via_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = via,
|
||||
.probe = via_init_one,
|
||||
.remove = ata_pci_remove_one
|
||||
.remove = ata_pci_remove_one,
|
||||
.suspend = ata_pci_device_suspend,
|
||||
.resume = via_reinit_one,
|
||||
};
|
||||
|
||||
static int __init via_init(void)
|
||||
|
306
drivers/ata/pata_winbond.c
Normal file
306
drivers/ata/pata_winbond.c
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* pata_winbond.c - Winbond VLB ATA controllers
|
||||
* (C) 2006 Red Hat <alan@redhat.com>
|
||||
*
|
||||
* Support for the Winbond 83759A when operating in advanced mode.
|
||||
* Multichip mode is not currently supported.
|
||||
*/
|
||||
|
||||
#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>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define DRV_NAME "pata_winbond"
|
||||
#define DRV_VERSION "0.0.1"
|
||||
|
||||
#define NR_HOST 4 /* Two winbond controllers, two channels each */
|
||||
|
||||
struct winbond_data {
|
||||
unsigned long config;
|
||||
struct platform_device *platform_dev;
|
||||
};
|
||||
|
||||
static struct ata_host *winbond_host[NR_HOST];
|
||||
static struct winbond_data winbond_data[NR_HOST];
|
||||
static int nr_winbond_host;
|
||||
|
||||
#ifdef MODULE
|
||||
static int probe_winbond = 1;
|
||||
#else
|
||||
static int probe_winbond;
|
||||
#endif
|
||||
|
||||
static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&winbond_lock, flags);
|
||||
outb(reg, port + 0x01);
|
||||
outb(val, port + 0x02);
|
||||
spin_unlock_irqrestore(&winbond_lock, flags);
|
||||
}
|
||||
|
||||
static u8 winbond_readcfg(unsigned long port, u8 reg)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&winbond_lock, flags);
|
||||
outb(reg, port + 0x01);
|
||||
val = inb(port + 0x02);
|
||||
spin_unlock_irqrestore(&winbond_lock, flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct ata_timing t;
|
||||
struct winbond_data *winbond = ap->host->private_data;
|
||||
int active, recovery;
|
||||
u8 reg;
|
||||
int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
|
||||
|
||||
reg = winbond_readcfg(winbond->config, 0x81);
|
||||
|
||||
/* Get the timing data in cycles */
|
||||
if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
|
||||
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
|
||||
else
|
||||
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
|
||||
|
||||
active = (FIT(t.active, 3, 17) - 1) & 0x0F;
|
||||
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
|
||||
timing = (active << 4) | recovery;
|
||||
winbond_writecfg(winbond->config, timing, reg);
|
||||
|
||||
/* Load the setup timing */
|
||||
|
||||
reg = 0x35;
|
||||
if (adev->class != ATA_DEV_ATA)
|
||||
reg |= 0x08; /* FIFO off */
|
||||
if (!ata_pio_need_iordy(adev))
|
||||
reg |= 0x02; /* IORDY off */
|
||||
reg |= (FIT(t.setup, 0, 3) << 6);
|
||||
winbond_writecfg(winbond->config, timing + 1, reg);
|
||||
}
|
||||
|
||||
|
||||
static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
|
||||
{
|
||||
struct ata_port *ap = adev->ap;
|
||||
int slop = buflen & 3;
|
||||
|
||||
if (ata_id_has_dword_io(adev->id)) {
|
||||
if (write_data)
|
||||
outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||
else
|
||||
insl(ap->ioaddr.data_addr, buf, buflen >> 2);
|
||||
|
||||
if (unlikely(slop)) {
|
||||
u32 pad;
|
||||
if (write_data) {
|
||||
memcpy(&pad, buf + buflen - slop, slop);
|
||||
outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||
} else {
|
||||
pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
|
||||
memcpy(buf + buflen - slop, &pad, slop);
|
||||
}
|
||||
}
|
||||
} else
|
||||
ata_pio_data_xfer(adev, buf, buflen, write_data);
|
||||
}
|
||||
|
||||
static struct scsi_host_template winbond_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,
|
||||
};
|
||||
|
||||
static struct ata_port_operations winbond_port_ops = {
|
||||
.port_disable = ata_port_disable,
|
||||
.set_piomode = winbond_set_piomode,
|
||||
|
||||
.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,
|
||||
|
||||
.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,
|
||||
|
||||
.port_start = ata_port_start,
|
||||
.port_stop = ata_port_stop,
|
||||
.host_stop = ata_host_stop
|
||||
};
|
||||
|
||||
/**
|
||||
* winbond_init_one - attach a winbond interface
|
||||
* @type: Type to display
|
||||
* @io: I/O port start
|
||||
* @irq: interrupt line
|
||||
* @fast: True if on a > 33Mhz VLB
|
||||
*
|
||||
* Register a VLB bus IDE interface. Such interfaces are PIO and we
|
||||
* assume do not support IRQ sharing.
|
||||
*/
|
||||
|
||||
static __init int winbond_init_one(unsigned long port)
|
||||
{
|
||||
struct ata_probe_ent ae;
|
||||
struct platform_device *pdev;
|
||||
int ret;
|
||||
u8 reg;
|
||||
int i;
|
||||
|
||||
reg = winbond_readcfg(port, 0x81);
|
||||
reg |= 0x80; /* jumpered mode off */
|
||||
winbond_writecfg(port, 0x81, reg);
|
||||
reg = winbond_readcfg(port, 0x83);
|
||||
reg |= 0xF0; /* local control */
|
||||
winbond_writecfg(port, 0x83, reg);
|
||||
reg = winbond_readcfg(port, 0x85);
|
||||
reg |= 0xF0; /* programmable timing */
|
||||
winbond_writecfg(port, 0x85, reg);
|
||||
|
||||
reg = winbond_readcfg(port, 0x81);
|
||||
|
||||
if (!(reg & 0x03)) /* Disabled */
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 2 ; i ++) {
|
||||
|
||||
if (reg & (1 << i)) {
|
||||
/*
|
||||
* Fill in a probe structure first of all
|
||||
*/
|
||||
|
||||
pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
|
||||
if (pdev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&ae, 0, sizeof(struct ata_probe_ent));
|
||||
INIT_LIST_HEAD(&ae.node);
|
||||
ae.dev = &pdev->dev;
|
||||
|
||||
ae.port_ops = &winbond_port_ops;
|
||||
ae.pio_mask = 0x1F;
|
||||
|
||||
ae.sht = &winbond_sht;
|
||||
|
||||
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 = 0x1F0 - (0x80 * i);
|
||||
ae.port[0].altstatus_addr = ae.port[0].cmd_addr + 0x0206;
|
||||
ae.port[0].ctl_addr = ae.port[0].altstatus_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;
|
||||
|
||||
ret = ata_device_add(&ae);
|
||||
if (ret == 0) {
|
||||
platform_device_unregister(pdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* winbond_init - attach winbond interfaces
|
||||
*
|
||||
* Attach winbond IDE interfaces by scanning the ports it may occupy.
|
||||
*/
|
||||
|
||||
static __init int winbond_init(void)
|
||||
{
|
||||
static const unsigned long config[2] = { 0x130, 0x1B0 };
|
||||
|
||||
int ct = 0;
|
||||
int i;
|
||||
|
||||
if (probe_winbond == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Check both base addresses
|
||||
*/
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (probe_winbond & (1<<i)) {
|
||||
int ret = 0;
|
||||
unsigned long port = config[i];
|
||||
|
||||
if (request_region(port, 2, "pata_winbond")) {
|
||||
ret = winbond_init_one(port);
|
||||
if(ret <= 0)
|
||||
release_region(port, 2);
|
||||
else ct+= ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ct != 0)
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static __exit void winbond_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_winbond_host; i++) {
|
||||
ata_host_remove(winbond_host[i]);
|
||||
release_region(winbond_data[i].config, 2);
|
||||
platform_device_unregister(winbond_data[i].platform_dev);
|
||||
}
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Alan Cox");
|
||||
MODULE_DESCRIPTION("low-level driver for Winbond VL ATA");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
module_init(winbond_init);
|
||||
module_exit(winbond_exit);
|
||||
|
||||
module_param(probe_winbond, int, 0);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,20 +46,19 @@
|
||||
#include "sata_promise.h"
|
||||
|
||||
#define DRV_NAME "sata_promise"
|
||||
#define DRV_VERSION "1.04"
|
||||
#define DRV_VERSION "1.05"
|
||||
|
||||
|
||||
enum {
|
||||
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
|
||||
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
|
||||
PDC_TBG_MODE = 0x41, /* TBG mode */
|
||||
PDC_FLASH_CTL = 0x44, /* Flash control register */
|
||||
PDC_PCI_CTL = 0x48, /* PCI control and status register */
|
||||
PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */
|
||||
PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
|
||||
PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
|
||||
PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */
|
||||
PDC_SLEW_CTL = 0x470, /* slew rate control reg */
|
||||
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),
|
||||
@ -78,6 +77,9 @@ enum {
|
||||
PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
|
||||
ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
|
||||
ATA_FLAG_PIO_POLLING,
|
||||
|
||||
/* hp->flags bits */
|
||||
PDC_FLAG_GEN_II = (1 << 0),
|
||||
};
|
||||
|
||||
|
||||
@ -87,6 +89,7 @@ struct pdc_port_priv {
|
||||
};
|
||||
|
||||
struct pdc_host_priv {
|
||||
unsigned long flags;
|
||||
int hotplug_offset;
|
||||
};
|
||||
|
||||
@ -235,20 +238,20 @@ static const struct ata_port_info pdc_port_info[] = {
|
||||
|
||||
static const struct pci_device_id pdc_ata_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(PROMISE, 0x3371), board_2037x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3570), board_2037x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3571), board_2037x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3373), board_2037x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3375), board_2037x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3376), board_2037x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3570), board_2057x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3571), board_2057x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3574), board_2057x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3d73), board_2057x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3d75), board_2057x },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3d73), board_2037x },
|
||||
|
||||
{ PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3d17), board_20319 },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3d17), board_40518 },
|
||||
{ PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
|
||||
|
||||
{ PCI_VDEVICE(PROMISE, 0x6629), board_20619 },
|
||||
@ -277,6 +280,7 @@ static struct pci_driver pdc_ata_pci_driver = {
|
||||
static int pdc_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;
|
||||
|
||||
@ -298,6 +302,16 @@ static int pdc_port_start(struct ata_port *ap)
|
||||
|
||||
ap->private_data = pp;
|
||||
|
||||
/* fix up PHYMODE4 align timing */
|
||||
if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) {
|
||||
void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = readl(mmio + 0x014);
|
||||
tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */
|
||||
writel(tmp, mmio + 0x014);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_kfree:
|
||||
@ -640,9 +654,11 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
||||
* "TODO: figure out why we do this"
|
||||
*/
|
||||
|
||||
/* change FIFO_SHD to 8 dwords, enable BMR_BURST */
|
||||
/* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
|
||||
tmp = readl(mmio + PDC_FLASH_CTL);
|
||||
tmp |= 0x12000; /* bit 16 (fifo 8 dw) and 13 (bmr burst?) */
|
||||
tmp |= 0x02000; /* bit 13 (enable bmr burst) */
|
||||
if (!(hp->flags & PDC_FLAG_GEN_II))
|
||||
tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
|
||||
writel(tmp, mmio + PDC_FLASH_CTL);
|
||||
|
||||
/* clear plug/unplug flags for all ports */
|
||||
@ -653,6 +669,10 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
|
||||
tmp = readl(mmio + hotplug_offset);
|
||||
writel(tmp | 0xff0000, mmio + hotplug_offset);
|
||||
|
||||
/* don't initialise TBG or SLEW on 2nd generation chips */
|
||||
if (hp->flags & PDC_FLAG_GEN_II)
|
||||
return;
|
||||
|
||||
/* reduce TBG clock to 133 Mhz. */
|
||||
tmp = readl(mmio + PDC_TBG_MODE);
|
||||
tmp &= ~0x30000; /* clear bit 17, 16*/
|
||||
@ -746,6 +766,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
||||
/* notice 4-port boards */
|
||||
switch (board_idx) {
|
||||
case board_40518:
|
||||
hp->flags |= PDC_FLAG_GEN_II;
|
||||
/* Override hotplug offset for SATAII150 */
|
||||
hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
|
||||
/* Fall through */
|
||||
@ -759,15 +780,14 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
|
||||
probe_ent->port[3].scr_addr = base + 0x700;
|
||||
break;
|
||||
case board_2057x:
|
||||
case board_20771:
|
||||
hp->flags |= PDC_FLAG_GEN_II;
|
||||
/* Override hotplug offset for SATAII150 */
|
||||
hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
|
||||
/* Fall through */
|
||||
case board_2037x:
|
||||
probe_ent->n_ports = 2;
|
||||
break;
|
||||
case board_20771:
|
||||
probe_ent->n_ports = 2;
|
||||
break;
|
||||
case board_20619:
|
||||
probe_ent->n_ports = 4;
|
||||
|
||||
|
@ -356,6 +356,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
|
||||
|
||||
static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
|
||||
{
|
||||
struct ata_eh_info *ehi = &ap->eh_info;
|
||||
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||
u8 status;
|
||||
|
||||
@ -428,6 +429,10 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
|
||||
/* kick HSM in the ass */
|
||||
ata_hsm_move(ap, qc, status, 0);
|
||||
|
||||
if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
|
||||
qc->tf.protocol == ATA_PROT_ATAPI_DMA))
|
||||
ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
|
||||
|
||||
return;
|
||||
|
||||
err_hsm:
|
||||
@ -534,6 +539,7 @@ static void sil_thaw(struct ata_port *ap)
|
||||
*/
|
||||
static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
|
||||
{
|
||||
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
|
||||
unsigned int n, quirks = 0;
|
||||
unsigned char model_num[41];
|
||||
|
||||
@ -549,16 +555,18 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
|
||||
if (slow_down ||
|
||||
((ap->flags & SIL_FLAG_MOD15WRITE) &&
|
||||
(quirks & SIL_QUIRK_MOD15WRITE))) {
|
||||
ata_dev_printk(dev, KERN_INFO, "applying Seagate errata fix "
|
||||
"(mod15write workaround)\n");
|
||||
if (print_info)
|
||||
ata_dev_printk(dev, KERN_INFO, "applying Seagate "
|
||||
"errata fix (mod15write workaround)\n");
|
||||
dev->max_sectors = 15;
|
||||
return;
|
||||
}
|
||||
|
||||
/* limit to udma5 */
|
||||
if (quirks & SIL_QUIRK_UDMA5MAX) {
|
||||
ata_dev_printk(dev, KERN_INFO,
|
||||
"applying Maxtor errata fix %s\n", model_num);
|
||||
if (print_info)
|
||||
ata_dev_printk(dev, KERN_INFO, "applying Maxtor "
|
||||
"errata fix %s\n", model_num);
|
||||
dev->udma_mask &= ATA_UDMA5;
|
||||
return;
|
||||
}
|
||||
|
@ -100,10 +100,14 @@ enum {
|
||||
*/
|
||||
PORT_REGS_SIZE = 0x2000,
|
||||
|
||||
PORT_LRAM = 0x0000, /* 31 LRAM slots and PM regs */
|
||||
PORT_LRAM = 0x0000, /* 31 LRAM slots and PMP regs */
|
||||
PORT_LRAM_SLOT_SZ = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */
|
||||
|
||||
PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */
|
||||
PORT_PMP = 0x0f80, /* 8 bytes PMP * 16 (128 bytes) */
|
||||
PORT_PMP_STATUS = 0x0000, /* port device status offset */
|
||||
PORT_PMP_QACTIVE = 0x0004, /* port device QActive offset */
|
||||
PORT_PMP_SIZE = 0x0008, /* 8 bytes per PMP */
|
||||
|
||||
/* 32 bit regs */
|
||||
PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */
|
||||
PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */
|
||||
@ -126,6 +130,7 @@ enum {
|
||||
PORT_PHY_CFG = 0x1050,
|
||||
PORT_SLOT_STAT = 0x1800,
|
||||
PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
|
||||
PORT_CONTEXT = 0x1e04,
|
||||
PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
|
||||
PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
|
||||
PORT_SCONTROL = 0x1f00,
|
||||
@ -139,9 +144,9 @@ enum {
|
||||
PORT_CS_INIT = (1 << 2), /* port initialize */
|
||||
PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
|
||||
PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */
|
||||
PORT_CS_RESUME = (1 << 6), /* port resume */
|
||||
PORT_CS_PMP_RESUME = (1 << 6), /* PMP resume */
|
||||
PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
|
||||
PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */
|
||||
PORT_CS_PMP_EN = (1 << 13), /* port multiplier enable */
|
||||
PORT_CS_RDY = (1 << 31), /* port ready to accept commands */
|
||||
|
||||
/* PORT_IRQ_STAT/ENABLE_SET/CLR */
|
||||
@ -562,7 +567,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
|
||||
|
||||
/* do SRST */
|
||||
prb->ctrl = cpu_to_le16(PRB_CTRL_SRST);
|
||||
prb->fis[1] = 0; /* no PM yet */
|
||||
prb->fis[1] = 0; /* no PMP yet */
|
||||
|
||||
writel((u32)paddr, port + PORT_CMD_ACTIVATE);
|
||||
writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
|
||||
@ -1050,7 +1055,8 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
|
||||
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
|
||||
|
||||
/* Clear port multiplier enable and resume bits */
|
||||
writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
|
||||
writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME,
|
||||
port + PORT_CTRL_CLR);
|
||||
}
|
||||
|
||||
/* Turn on interrupts */
|
||||
|
@ -173,7 +173,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
|
||||
if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
|
||||
pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
|
||||
|
||||
return val|val2;
|
||||
return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */
|
||||
}
|
||||
|
||||
static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
|
||||
@ -212,7 +212,7 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
|
||||
if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
|
||||
val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
|
||||
|
||||
return val | val2;
|
||||
return (val | val2) & 0xfffffffb;
|
||||
}
|
||||
|
||||
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
|
||||
@ -239,7 +239,7 @@ 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;
|
||||
u32 genctl;
|
||||
u32 genctl, val;
|
||||
struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
|
||||
int pci_dev_busy = 0;
|
||||
u8 pmr;
|
||||
@ -285,17 +285,24 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (ent->device != 0x182) {
|
||||
if ((pmr & SIS_PMR_COMBINED) == 0) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"Detected SiS 180/181 chipset in SATA mode\n");
|
||||
"Detected SiS 180/181/964 chipset in SATA mode\n");
|
||||
port2_start = 64;
|
||||
}
|
||||
else {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"Detected SiS 180/181 chipset in combined mode\n");
|
||||
port2_start=0;
|
||||
pi.flags |= ATA_FLAG_SLAVE_POSS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n");
|
||||
pci_read_config_dword ( pdev, 0x6C, &val);
|
||||
if (val & (1L << 31)) {
|
||||
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n");
|
||||
pi.flags |= ATA_FLAG_SLAVE_POSS;
|
||||
}
|
||||
else
|
||||
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n");
|
||||
port2_start = 0x20;
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,19 @@ struct ixp4xx_i2c_pins {
|
||||
unsigned long scl_pin;
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure provide a means for the board setup code
|
||||
* to give information to th pata_ixp4xx driver. It is
|
||||
* passed as platform_data.
|
||||
*/
|
||||
struct ixp4xx_pata_data {
|
||||
volatile u32 *cs0_cfg;
|
||||
volatile u32 *cs1_cfg;
|
||||
unsigned long cs0_bits;
|
||||
unsigned long cs1_bits;
|
||||
void __iomem *cs0;
|
||||
void __iomem *cs1;
|
||||
};
|
||||
|
||||
struct sys_timer;
|
||||
|
||||
|
@ -200,8 +200,9 @@ enum {
|
||||
ATA_CBL_NONE = 0,
|
||||
ATA_CBL_PATA40 = 1,
|
||||
ATA_CBL_PATA80 = 2,
|
||||
ATA_CBL_PATA_UNK = 3,
|
||||
ATA_CBL_SATA = 4,
|
||||
ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */
|
||||
ATA_CBL_PATA_UNK = 4,
|
||||
ATA_CBL_SATA = 5,
|
||||
|
||||
/* SATA Status and Control Registers */
|
||||
SCR_STATUS = 0,
|
||||
@ -342,6 +343,15 @@ static inline int ata_id_is_cfa(const u16 *id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ata_drive_40wire(const u16 *dev_id)
|
||||
{
|
||||
if (ata_id_major_version(dev_id) >= 5 && ata_id_is_sata(dev_id))
|
||||
return 0; /* SATA */
|
||||
if (dev_id[93] & 0x4000)
|
||||
return 0; /* 80 wire */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int atapi_cdb_len(const u16 *dev_id)
|
||||
{
|
||||
u16 tmp = dev_id[0] & 0x3;
|
||||
|
@ -140,6 +140,7 @@ enum {
|
||||
ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */
|
||||
ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */
|
||||
ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */
|
||||
ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
|
||||
ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
|
||||
|
||||
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
|
||||
@ -175,6 +176,7 @@ enum {
|
||||
ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H
|
||||
* Register FIS clearing BSY */
|
||||
ATA_FLAG_DEBUGMSG = (1 << 13),
|
||||
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
|
||||
|
||||
/* The following flag belongs to ap->pflags but is kept in
|
||||
* ap->flags because it's referenced in many LLDs and will be
|
||||
@ -283,6 +285,9 @@ enum {
|
||||
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_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
|
||||
|
||||
@ -307,10 +312,11 @@ enum {
|
||||
(some horkage may be drive/controller pair dependant */
|
||||
|
||||
ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */
|
||||
ATA_HORKAGE_NODMA = (1 << 1), /* DMA problems */
|
||||
ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */
|
||||
};
|
||||
|
||||
enum hsm_task_states {
|
||||
HSM_ST_UNKNOWN, /* state unknown */
|
||||
HSM_ST_IDLE, /* no command on going */
|
||||
HSM_ST, /* (waiting the device to) transfer data */
|
||||
HSM_ST_LAST, /* (waiting the device to) complete command */
|
||||
@ -329,6 +335,7 @@ enum ata_completion_errors {
|
||||
AC_ERR_SYSTEM = (1 << 6), /* system error */
|
||||
AC_ERR_INVALID = (1 << 7), /* invalid argument */
|
||||
AC_ERR_OTHER = (1 << 8), /* unknown */
|
||||
AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */
|
||||
};
|
||||
|
||||
/* forward declarations */
|
||||
@ -700,6 +707,8 @@ extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param);
|
||||
extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
|
||||
extern int ata_std_prereset(struct ata_port *ap);
|
||||
extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
|
||||
extern int sata_port_hardreset(struct ata_port *ap,
|
||||
const unsigned long *timing);
|
||||
extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
|
||||
extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
|
||||
extern void ata_port_disable(struct ata_port *);
|
||||
@ -744,9 +753,8 @@ extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
|
||||
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
|
||||
extern void ata_host_resume(struct ata_host *host);
|
||||
extern int ata_ratelimit(void);
|
||||
extern unsigned int ata_busy_sleep(struct ata_port *ap,
|
||||
unsigned long timeout_pat,
|
||||
unsigned long timeout);
|
||||
extern int ata_busy_sleep(struct ata_port *ap,
|
||||
unsigned long timeout_pat, unsigned long timeout);
|
||||
extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
|
||||
void *data, unsigned long delay);
|
||||
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
|
||||
@ -787,6 +795,7 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
|
||||
unsigned int ofs, unsigned int len);
|
||||
extern void ata_id_c_string(const u16 *id, unsigned char *s,
|
||||
unsigned int ofs, unsigned int len);
|
||||
extern unsigned long ata_device_blacklisted(const struct ata_device *dev);
|
||||
extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
|
||||
extern void ata_bmdma_start (struct ata_queued_cmd *qc);
|
||||
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
|
||||
@ -1061,7 +1070,7 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
|
||||
udelay(10);
|
||||
status = ata_chk_status(ap);
|
||||
max--;
|
||||
} while ((status & bits) && (max > 0));
|
||||
} while (status != 0xff && (status & bits) && (max > 0));
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -1082,7 +1091,7 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
|
||||
{
|
||||
u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
|
||||
|
||||
if (status & (ATA_BUSY | ATA_DRQ)) {
|
||||
if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) {
|
||||
unsigned long l = ap->ioaddr.status_addr;
|
||||
if (ata_msg_warn(ap))
|
||||
printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",
|
||||
@ -1147,37 +1156,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
|
||||
qc->result_tf.feature = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_irq_on - Enable interrupts on a port.
|
||||
* @ap: Port on which interrupts are enabled.
|
||||
*
|
||||
* Enable interrupts on a legacy IDE device using MMIO or PIO,
|
||||
* wait for idle, clear any pending interrupts.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*/
|
||||
|
||||
static inline u8 ata_irq_on(struct ata_port *ap)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
u8 tmp;
|
||||
|
||||
ap->ctl &= ~ATA_NIEN;
|
||||
ap->last_ctl = ap->ctl;
|
||||
|
||||
if (ap->flags & ATA_FLAG_MMIO)
|
||||
writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
|
||||
else
|
||||
outb(ap->ctl, ioaddr->ctl_addr);
|
||||
tmp = ata_wait_idle(ap);
|
||||
|
||||
ap->ops->irq_clear(ap);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ata_irq_ack - Acknowledge a device interrupt.
|
||||
* @ap: Port on which interrupts are enabled.
|
||||
|
13
include/linux/pata_platform.h
Normal file
13
include/linux/pata_platform.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef __LINUX_PATA_PLATFORM_H
|
||||
#define __LINUX_PATA_PLATFORM_H
|
||||
|
||||
struct pata_platform_info {
|
||||
/*
|
||||
* I/O port shift, for platforms with ports that are
|
||||
* constantly spaced and need larger than the 1-byte
|
||||
* spacing used by ata_std_ports().
|
||||
*/
|
||||
unsigned int ioport_shift;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_PATA_PLATFORM_H */
|
Loading…
Reference in New Issue
Block a user