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:
Linus Torvalds 2006-12-04 13:12:29 -08:00
Родитель a80958f484 8e42a5a220
Коммит ff51a98799
60 изменённых файлов: 3832 добавлений и 991 удалений

Просмотреть файл

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

Просмотреть файл

@ -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, &reg);
@ -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);
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
Просмотреть файл

@ -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
Просмотреть файл

@ -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, &reg) != 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, &reg) != 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
Просмотреть файл

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

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

Просмотреть файл

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