mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge branch 'linus' into release
This commit is contained in:
commit
b2576e1d44
7966 changed files with 918436 additions and 222789 deletions
|
|
@ -456,7 +456,8 @@ config PATA_MARVELL
|
|||
|
||||
config PATA_MPC52xx
|
||||
tristate "Freescale MPC52xx SoC internal IDE"
|
||||
depends on PPC_MPC52xx
|
||||
depends on PPC_MPC52xx && PPC_BESTCOMM
|
||||
select PPC_BESTCOMM_ATA
|
||||
help
|
||||
This option enables support for integrated IDE controller
|
||||
of the Freescale MPC52xx SoC.
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ enum {
|
|||
board_ahci_ign_iferr = 2,
|
||||
board_ahci_sb600 = 3,
|
||||
board_ahci_mv = 4,
|
||||
board_ahci_sb700 = 5,
|
||||
board_ahci_sb700 = 5, /* for SB700 and SB800 */
|
||||
board_ahci_mcp65 = 6,
|
||||
board_ahci_nopmp = 7,
|
||||
|
||||
|
|
@ -439,7 +439,7 @@ static const struct ata_port_info ahci_port_info[] = {
|
|||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
/* board_ahci_sb700 */
|
||||
/* board_ahci_sb700, for SB700 and SB800 */
|
||||
{
|
||||
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
|
|
@ -1119,14 +1119,14 @@ static void ahci_start_port(struct ata_port *ap)
|
|||
|
||||
/* turn on LEDs */
|
||||
if (ap->flags & ATA_FLAG_EM) {
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
emp = &pp->em_priv[link->pmp];
|
||||
ahci_transmit_led_message(ap, emp->led_state, 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (ap->flags & ATA_FLAG_SW_ACTIVITY)
|
||||
ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, EDGE)
|
||||
ahci_init_sw_activity(link);
|
||||
|
||||
}
|
||||
|
|
@ -1361,7 +1361,7 @@ static ssize_t ahci_led_show(struct ata_port *ap, char *buf)
|
|||
struct ahci_em_priv *emp;
|
||||
int rc = 0;
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
emp = &pp->em_priv[link->pmp];
|
||||
rc += sprintf(buf, "%lx\n", emp->led_state);
|
||||
}
|
||||
|
|
@ -1941,7 +1941,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
|
|||
u32 serror;
|
||||
|
||||
/* determine active link */
|
||||
ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, EDGE)
|
||||
if (ata_link_active(link))
|
||||
break;
|
||||
if (!link)
|
||||
|
|
@ -2446,6 +2446,8 @@ static void ahci_print_info(struct ata_host *host)
|
|||
speed_s = "1.5";
|
||||
else if (speed == 2)
|
||||
speed_s = "3";
|
||||
else if (speed == 3)
|
||||
speed_s = "6";
|
||||
else
|
||||
speed_s = "?";
|
||||
|
||||
|
|
@ -2610,6 +2612,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
(pdev->revision == 0xa1 || pdev->revision == 0xa2))
|
||||
hpriv->flags |= AHCI_HFLAG_NO_MSI;
|
||||
|
||||
/* SB800 does NOT need the workaround to ignore SERR_INTERNAL */
|
||||
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
|
||||
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
|
||||
|
||||
if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,10 +57,7 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
|
|||
if (pdev->vendor == PCI_VENDOR_ID_CENATEK)
|
||||
dma_enabled = 0xFF;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->dma_mode = XFER_MW_DMA_0;
|
||||
|
|
|
|||
|
|
@ -154,11 +154,13 @@ struct piix_map_db {
|
|||
|
||||
struct piix_host_priv {
|
||||
const int *map;
|
||||
u32 saved_iocfg;
|
||||
void __iomem *sidpr;
|
||||
};
|
||||
|
||||
static int piix_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent);
|
||||
static void piix_remove_one(struct pci_dev *pdev);
|
||||
static int piix_pata_prereset(struct ata_link *link, unsigned long deadline);
|
||||
static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev);
|
||||
static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
|
||||
|
|
@ -296,7 +298,7 @@ static struct pci_driver piix_pci_driver = {
|
|||
.name = DRV_NAME,
|
||||
.id_table = piix_pci_tbl,
|
||||
.probe = piix_init_one,
|
||||
.remove = ata_pci_remove_one,
|
||||
.remove = piix_remove_one,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = piix_pci_device_suspend,
|
||||
.resume = piix_pci_device_resume,
|
||||
|
|
@ -308,7 +310,7 @@ static struct scsi_host_template piix_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations piix_pata_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.inherits = &ata_bmdma32_port_ops,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
.set_piomode = piix_set_piomode,
|
||||
.set_dmamode = piix_set_dmamode,
|
||||
|
|
@ -610,8 +612,9 @@ static const struct ich_laptop ich_laptop[] = {
|
|||
static int ich_pata_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct piix_host_priv *hpriv = ap->host->private_data;
|
||||
const struct ich_laptop *lap = &ich_laptop[0];
|
||||
u8 tmp, mask;
|
||||
u8 mask;
|
||||
|
||||
/* Check for specials - Acer Aspire 5602WLMi */
|
||||
while (lap->device) {
|
||||
|
|
@ -625,8 +628,7 @@ static int ich_pata_cable_detect(struct ata_port *ap)
|
|||
|
||||
/* check BIOS cable detect results */
|
||||
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
|
||||
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
|
||||
if ((tmp & mask) == 0)
|
||||
if ((hpriv->saved_iocfg & mask) == 0)
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
|
@ -1072,20 +1074,13 @@ static int piix_broken_suspend(void)
|
|||
* matching is necessary because dmi_system_id.matches is
|
||||
* limited to four entries.
|
||||
*/
|
||||
if (dmi_get_system_info(DMI_SYS_VENDOR) &&
|
||||
dmi_get_system_info(DMI_PRODUCT_NAME) &&
|
||||
dmi_get_system_info(DMI_PRODUCT_VERSION) &&
|
||||
dmi_get_system_info(DMI_PRODUCT_SERIAL) &&
|
||||
dmi_get_system_info(DMI_BOARD_VENDOR) &&
|
||||
dmi_get_system_info(DMI_BOARD_NAME) &&
|
||||
dmi_get_system_info(DMI_BOARD_VERSION) &&
|
||||
!strcmp(dmi_get_system_info(DMI_SYS_VENDOR), "TOSHIBA") &&
|
||||
!strcmp(dmi_get_system_info(DMI_PRODUCT_NAME), "000000") &&
|
||||
!strcmp(dmi_get_system_info(DMI_PRODUCT_VERSION), "000000") &&
|
||||
!strcmp(dmi_get_system_info(DMI_PRODUCT_SERIAL), "000000") &&
|
||||
!strcmp(dmi_get_system_info(DMI_BOARD_VENDOR), "TOSHIBA") &&
|
||||
!strcmp(dmi_get_system_info(DMI_BOARD_NAME), "Portable PC") &&
|
||||
!strcmp(dmi_get_system_info(DMI_BOARD_VERSION), "Version A0"))
|
||||
if (dmi_match(DMI_SYS_VENDOR, "TOSHIBA") &&
|
||||
dmi_match(DMI_PRODUCT_NAME, "000000") &&
|
||||
dmi_match(DMI_PRODUCT_VERSION, "000000") &&
|
||||
dmi_match(DMI_PRODUCT_SERIAL, "000000") &&
|
||||
dmi_match(DMI_BOARD_VENDOR, "TOSHIBA") &&
|
||||
dmi_match(DMI_BOARD_NAME, "Portable PC") &&
|
||||
dmi_match(DMI_BOARD_VERSION, "Version A0"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1357,7 +1352,7 @@ static int __devinit piix_init_sidpr(struct ata_host *host)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
|
||||
static void piix_iocfg_bit18_quirk(struct ata_host *host)
|
||||
{
|
||||
static const struct dmi_system_id sysids[] = {
|
||||
{
|
||||
|
|
@ -1374,7 +1369,8 @@ static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
|
|||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
u32 iocfg;
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
struct piix_host_priv *hpriv = host->private_data;
|
||||
|
||||
if (!dmi_check_system(sysids))
|
||||
return;
|
||||
|
|
@ -1383,12 +1379,11 @@ static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
|
|||
* seem to use it to disable a channel. Clear the bit on the
|
||||
* affected systems.
|
||||
*/
|
||||
pci_read_config_dword(pdev, PIIX_IOCFG, &iocfg);
|
||||
if (iocfg & (1 << 18)) {
|
||||
if (hpriv->saved_iocfg & (1 << 18)) {
|
||||
dev_printk(KERN_INFO, &pdev->dev,
|
||||
"applying IOCFG bit18 quirk\n");
|
||||
iocfg &= ~(1 << 18);
|
||||
pci_write_config_dword(pdev, PIIX_IOCFG, iocfg);
|
||||
pci_write_config_dword(pdev, PIIX_IOCFG,
|
||||
hpriv->saved_iocfg & ~(1 << 18));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1437,6 +1432,17 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Save IOCFG, this will be used for cable detection, quirk
|
||||
* detection and restoration on detach. This is necessary
|
||||
* because some ACPI implementations mess up cable related
|
||||
* bits on _STM. Reported on kernel bz#11879.
|
||||
*/
|
||||
pci_read_config_dword(pdev, PIIX_IOCFG, &hpriv->saved_iocfg);
|
||||
|
||||
/* ICH6R may be driven by either ata_piix or ahci driver
|
||||
* regardless of BIOS configuration. Make sure AHCI mode is
|
||||
* off.
|
||||
|
|
@ -1448,10 +1454,6 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
/* SATA map init can change port_info, do it before prepping host */
|
||||
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
if (port_flags & ATA_FLAG_SATA)
|
||||
hpriv->map = piix_init_sata_map(pdev, port_info,
|
||||
piix_map_db_table[ent->driver_data]);
|
||||
|
|
@ -1470,7 +1472,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
/* apply IOCFG bit18 quirk */
|
||||
piix_iocfg_bit18_quirk(pdev);
|
||||
piix_iocfg_bit18_quirk(host);
|
||||
|
||||
/* On ICH5, some BIOSen disable the interrupt using the
|
||||
* PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
|
||||
|
|
@ -1495,6 +1497,16 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
|
|||
return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht);
|
||||
}
|
||||
|
||||
static void piix_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(&pdev->dev);
|
||||
struct piix_host_priv *hpriv = host->private_data;
|
||||
|
||||
pci_write_config_dword(pdev, PIIX_IOCFG, hpriv->saved_iocfg);
|
||||
|
||||
ata_pci_remove_one(pdev);
|
||||
}
|
||||
|
||||
static int __init piix_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap)
|
|||
|
||||
ap->link.device->acpi_handle = NULL;
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
acpi_integer adr = SATA_ADR(ap->port_no, link->pmp);
|
||||
|
||||
link->device->acpi_handle =
|
||||
|
|
@ -123,8 +123,8 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
|
|||
struct ata_link *tlink;
|
||||
struct ata_device *tdev;
|
||||
|
||||
ata_port_for_each_link(tlink, ap)
|
||||
ata_link_for_each_dev(tdev, tlink)
|
||||
ata_for_each_link(tlink, ap, EDGE)
|
||||
ata_for_each_dev(tdev, tlink, ALL)
|
||||
tdev->flags |= ATA_DFLAG_DETACH;
|
||||
}
|
||||
|
||||
|
|
@ -582,12 +582,9 @@ int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm)
|
|||
{
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ENABLED) {
|
||||
unsigned long xfer_mask, udma_mask;
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
xfer_mask = ata_acpi_gtm_xfermask(dev, gtm);
|
||||
ata_unpack_xfermask(xfer_mask, NULL, NULL, &udma_mask);
|
||||
|
||||
|
|
@ -887,7 +884,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
|
|||
* use values set by _STM. Cache _GTF result and
|
||||
* schedule _GTF.
|
||||
*/
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ALL) {
|
||||
ata_acpi_clear_gtf(dev);
|
||||
if (ata_dev_enabled(dev) &&
|
||||
ata_dev_get_GTF(dev, NULL) >= 0)
|
||||
|
|
@ -898,7 +895,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
|
|||
* there's no reason to evaluate IDE _GTF early
|
||||
* without _STM. Clear cache and schedule _GTF.
|
||||
*/
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ALL) {
|
||||
ata_acpi_clear_gtf(dev);
|
||||
if (ata_dev_enabled(dev))
|
||||
dev->flags |= ATA_DFLAG_ACPI_PENDING;
|
||||
|
|
@ -926,8 +923,8 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
|
|||
if (state.event == PM_EVENT_ON)
|
||||
acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);
|
||||
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
if (dev->acpi_handle && ata_dev_enabled(dev))
|
||||
ata_for_each_dev(dev, &ap->link, ENABLED) {
|
||||
if (dev->acpi_handle)
|
||||
acpi_bus_set_power(dev->acpi_handle,
|
||||
state.event == PM_EVENT_ON ?
|
||||
ACPI_STATE_D0 : ACPI_STATE_D3);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include <linux/workqueue.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/async.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
|
|
@ -163,42 +164,118 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
|
||||
/*
|
||||
* Iterator helpers. Don't use directly.
|
||||
/**
|
||||
* ata_link_next - link iteration helper
|
||||
* @link: the previous link, NULL to start
|
||||
* @ap: ATA port containing links to iterate
|
||||
* @mode: iteration mode, one of ATA_LITER_*
|
||||
*
|
||||
* LOCKING:
|
||||
* Host lock or EH context.
|
||||
* LOCKING:
|
||||
* Host lock or EH context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Pointer to the next link.
|
||||
*/
|
||||
struct ata_link *__ata_port_next_link(struct ata_port *ap,
|
||||
struct ata_link *link, bool dev_only)
|
||||
struct ata_link *ata_link_next(struct ata_link *link, struct ata_port *ap,
|
||||
enum ata_link_iter_mode mode)
|
||||
{
|
||||
/* NULL link indicates start of iteration */
|
||||
if (!link) {
|
||||
if (dev_only && sata_pmp_attached(ap))
|
||||
return ap->pmp_link;
|
||||
return &ap->link;
|
||||
}
|
||||
BUG_ON(mode != ATA_LITER_EDGE &&
|
||||
mode != ATA_LITER_PMP_FIRST && mode != ATA_LITER_HOST_FIRST);
|
||||
|
||||
/* we just iterated over the host master link, what's next? */
|
||||
if (link == &ap->link) {
|
||||
if (!sata_pmp_attached(ap)) {
|
||||
if (unlikely(ap->slave_link) && !dev_only)
|
||||
/* NULL link indicates start of iteration */
|
||||
if (!link)
|
||||
switch (mode) {
|
||||
case ATA_LITER_EDGE:
|
||||
case ATA_LITER_PMP_FIRST:
|
||||
if (sata_pmp_attached(ap))
|
||||
return ap->pmp_link;
|
||||
/* fall through */
|
||||
case ATA_LITER_HOST_FIRST:
|
||||
return &ap->link;
|
||||
}
|
||||
|
||||
/* we just iterated over the host link, what's next? */
|
||||
if (link == &ap->link)
|
||||
switch (mode) {
|
||||
case ATA_LITER_HOST_FIRST:
|
||||
if (sata_pmp_attached(ap))
|
||||
return ap->pmp_link;
|
||||
/* fall through */
|
||||
case ATA_LITER_PMP_FIRST:
|
||||
if (unlikely(ap->slave_link))
|
||||
return ap->slave_link;
|
||||
/* fall through */
|
||||
case ATA_LITER_EDGE:
|
||||
return NULL;
|
||||
}
|
||||
return ap->pmp_link;
|
||||
}
|
||||
|
||||
/* slave_link excludes PMP */
|
||||
if (unlikely(link == ap->slave_link))
|
||||
return NULL;
|
||||
|
||||
/* iterate to the next PMP link */
|
||||
/* we were over a PMP link */
|
||||
if (++link < ap->pmp_link + ap->nr_pmp_links)
|
||||
return link;
|
||||
|
||||
if (mode == ATA_LITER_PMP_FIRST)
|
||||
return &ap->link;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_next - device iteration helper
|
||||
* @dev: the previous device, NULL to start
|
||||
* @link: ATA link containing devices to iterate
|
||||
* @mode: iteration mode, one of ATA_DITER_*
|
||||
*
|
||||
* LOCKING:
|
||||
* Host lock or EH context.
|
||||
*
|
||||
* RETURNS:
|
||||
* Pointer to the next device.
|
||||
*/
|
||||
struct ata_device *ata_dev_next(struct ata_device *dev, struct ata_link *link,
|
||||
enum ata_dev_iter_mode mode)
|
||||
{
|
||||
BUG_ON(mode != ATA_DITER_ENABLED && mode != ATA_DITER_ENABLED_REVERSE &&
|
||||
mode != ATA_DITER_ALL && mode != ATA_DITER_ALL_REVERSE);
|
||||
|
||||
/* NULL dev indicates start of iteration */
|
||||
if (!dev)
|
||||
switch (mode) {
|
||||
case ATA_DITER_ENABLED:
|
||||
case ATA_DITER_ALL:
|
||||
dev = link->device;
|
||||
goto check;
|
||||
case ATA_DITER_ENABLED_REVERSE:
|
||||
case ATA_DITER_ALL_REVERSE:
|
||||
dev = link->device + ata_link_max_devices(link) - 1;
|
||||
goto check;
|
||||
}
|
||||
|
||||
next:
|
||||
/* move to the next one */
|
||||
switch (mode) {
|
||||
case ATA_DITER_ENABLED:
|
||||
case ATA_DITER_ALL:
|
||||
if (++dev < link->device + ata_link_max_devices(link))
|
||||
goto check;
|
||||
return NULL;
|
||||
case ATA_DITER_ENABLED_REVERSE:
|
||||
case ATA_DITER_ALL_REVERSE:
|
||||
if (--dev >= link->device)
|
||||
goto check;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
check:
|
||||
if ((mode == ATA_DITER_ENABLED || mode == ATA_DITER_ENABLED_REVERSE) &&
|
||||
!ata_dev_enabled(dev))
|
||||
goto next;
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_phys_link - find physical link for a device
|
||||
* @dev: ATA device to look up physical link for
|
||||
|
|
@ -930,6 +1007,7 @@ static const char *sata_spd_string(unsigned int spd)
|
|||
static const char * const spd_str[] = {
|
||||
"1.5 Gbps",
|
||||
"3.0 Gbps",
|
||||
"6.0 Gbps",
|
||||
};
|
||||
|
||||
if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str))
|
||||
|
|
@ -1107,8 +1185,8 @@ static void ata_lpm_enable(struct ata_host *host)
|
|||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
ap = host->ports[i];
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
ata_dev_disable_pm(dev);
|
||||
}
|
||||
}
|
||||
|
|
@ -1923,6 +2001,10 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
|
|||
as the caller should know this */
|
||||
if (adev->link->ap->flags & ATA_FLAG_NO_IORDY)
|
||||
return 0;
|
||||
/* CF spec. r4.1 Table 22 says no iordy on PIO5 and PIO6. */
|
||||
if (ata_id_is_cfa(adev->id)
|
||||
&& (adev->pio_mode == XFER_PIO_5 || adev->pio_mode == XFER_PIO_6))
|
||||
return 0;
|
||||
/* PIO3 and higher it is mandatory */
|
||||
if (adev->pio_mode > XFER_PIO_2)
|
||||
return 1;
|
||||
|
|
@ -2594,11 +2676,11 @@ int ata_bus_probe(struct ata_port *ap)
|
|||
|
||||
ata_port_probe(ap);
|
||||
|
||||
ata_link_for_each_dev(dev, &ap->link)
|
||||
ata_for_each_dev(dev, &ap->link, ALL)
|
||||
tries[dev->devno] = ATA_PROBE_MAX_TRIES;
|
||||
|
||||
retry:
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ALL) {
|
||||
/* If we issue an SRST then an ATA drive (not ATAPI)
|
||||
* may change configuration and be in PIO0 timing. If
|
||||
* we do a hard reset (or are coming from power on)
|
||||
|
|
@ -2620,7 +2702,7 @@ int ata_bus_probe(struct ata_port *ap)
|
|||
/* reset and determine device classes */
|
||||
ap->ops->phy_reset(ap);
|
||||
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ALL) {
|
||||
if (!(ap->flags & ATA_FLAG_DISABLED) &&
|
||||
dev->class != ATA_DEV_UNKNOWN)
|
||||
classes[dev->devno] = dev->class;
|
||||
|
|
@ -2636,7 +2718,7 @@ int ata_bus_probe(struct ata_port *ap)
|
|||
specific sequence bass-ackwards so that PDIAG- is released by
|
||||
the slave device */
|
||||
|
||||
ata_link_for_each_dev_reverse(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ALL_REVERSE) {
|
||||
if (tries[dev->devno])
|
||||
dev->class = classes[dev->devno];
|
||||
|
||||
|
|
@ -2653,24 +2735,19 @@ int ata_bus_probe(struct ata_port *ap)
|
|||
if (ap->ops->cable_detect)
|
||||
ap->cbl = ap->ops->cable_detect(ap);
|
||||
|
||||
/* We may have SATA bridge glue hiding here irrespective of the
|
||||
reported cable types and sensed types */
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
/* SATA drives indicate we have a bridge. We don't know which
|
||||
end of the link the bridge is which is a problem */
|
||||
/* We may have SATA bridge glue hiding here irrespective of
|
||||
* the reported cable types and sensed types. When SATA
|
||||
* drives indicate we have a bridge, we don't know which end
|
||||
* of the link the bridge is which is a problem.
|
||||
*/
|
||||
ata_for_each_dev(dev, &ap->link, ENABLED)
|
||||
if (ata_id_is_sata(dev->id))
|
||||
ap->cbl = ATA_CBL_SATA;
|
||||
}
|
||||
|
||||
/* After the identify sequence we can now set up the devices. We do
|
||||
this in the normal order so that the user doesn't get confused */
|
||||
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ata_for_each_dev(dev, &ap->link, ENABLED) {
|
||||
ap->link.eh_context.i.flags |= ATA_EHI_PRINTINFO;
|
||||
rc = ata_dev_configure(dev);
|
||||
ap->link.eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
|
||||
|
|
@ -2683,9 +2760,8 @@ int ata_bus_probe(struct ata_port *ap)
|
|||
if (rc)
|
||||
goto fail;
|
||||
|
||||
ata_link_for_each_dev(dev, &ap->link)
|
||||
if (ata_dev_enabled(dev))
|
||||
return 0;
|
||||
ata_for_each_dev(dev, &ap->link, ENABLED)
|
||||
return 0;
|
||||
|
||||
/* no device present, disable port */
|
||||
ata_port_disable(ap);
|
||||
|
|
@ -3331,13 +3407,10 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|||
int rc = 0, used_dma = 0, found = 0;
|
||||
|
||||
/* step 1: calculate xfer_mask */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
unsigned long pio_mask, dma_mask;
|
||||
unsigned int mode_mask;
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
mode_mask = ATA_DMA_MASK_ATA;
|
||||
if (dev->class == ATA_DEV_ATAPI)
|
||||
mode_mask = ATA_DMA_MASK_ATAPI;
|
||||
|
|
@ -3366,10 +3439,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|||
goto out;
|
||||
|
||||
/* step 2: always set host PIO timings */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
if (dev->pio_mode == 0xff) {
|
||||
ata_dev_printk(dev, KERN_WARNING, "no PIO support\n");
|
||||
rc = -EINVAL;
|
||||
|
|
@ -3383,8 +3453,8 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|||
}
|
||||
|
||||
/* step 3: set host DMA timings */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
if (!ata_dma_enabled(dev))
|
||||
continue;
|
||||
|
||||
dev->xfer_mode = dev->dma_mode;
|
||||
|
|
@ -3394,11 +3464,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|||
}
|
||||
|
||||
/* step 4: update devices' xfer mode */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
/* don't update suspended devices' xfer mode */
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
rc = ata_dev_set_mode(dev);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
|
@ -4048,6 +4114,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|||
{ "Maxtor 7V300F0", "VA111630", ATA_HORKAGE_NONCQ },
|
||||
{ "ST380817AS", "3.42", ATA_HORKAGE_NONCQ },
|
||||
{ "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ },
|
||||
{ "OCZ CORE_SSD", "02.10104", ATA_HORKAGE_NONCQ },
|
||||
|
||||
/* Seagate NCQ + FLUSH CACHE firmware bug */
|
||||
{ "ST31500341AS", "SD15", ATA_HORKAGE_NONCQ |
|
||||
|
|
@ -4263,9 +4330,9 @@ static int cable_is_40wire(struct ata_port *ap)
|
|||
* - if you have a non detect capable drive you don't want it
|
||||
* to colour the choice
|
||||
*/
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev) && !ata_is_40wire(dev))
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
if (!ata_is_40wire(dev))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -4672,7 +4739,6 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
|||
/**
|
||||
* ata_qc_new_init - Request an available ATA command, and initialize it
|
||||
* @dev: Device from whom we request an available command structure
|
||||
* @tag: command tag
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
|
|
@ -5218,7 +5284,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
|
|||
}
|
||||
|
||||
ap->pflags |= ATA_PFLAG_PM_PENDING;
|
||||
__ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, HOST_FIRST) {
|
||||
link->eh_info.action |= action;
|
||||
link->eh_info.flags |= ehi_flags;
|
||||
}
|
||||
|
|
@ -5849,6 +5915,54 @@ void ata_host_init(struct ata_host *host, struct device *dev,
|
|||
host->ops = ops;
|
||||
}
|
||||
|
||||
|
||||
static void async_port_probe(void *data, async_cookie_t cookie)
|
||||
{
|
||||
int rc;
|
||||
struct ata_port *ap = data;
|
||||
/* probe */
|
||||
if (ap->ops->error_handler) {
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
unsigned long flags;
|
||||
|
||||
ata_port_probe(ap);
|
||||
|
||||
/* kick EH for boot probing */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
ehi->probe_mask |= ATA_ALL_DEVICES;
|
||||
ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
|
||||
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
|
||||
|
||||
ap->pflags &= ~ATA_PFLAG_INITIALIZING;
|
||||
ap->pflags |= ATA_PFLAG_LOADING;
|
||||
ata_port_schedule_eh(ap);
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
/* wait for EH to finish */
|
||||
ata_port_wait_eh(ap);
|
||||
} else {
|
||||
DPRINTK("ata%u: bus probe begin\n", ap->print_id);
|
||||
rc = ata_bus_probe(ap);
|
||||
DPRINTK("ata%u: bus probe end\n", ap->print_id);
|
||||
|
||||
if (rc) {
|
||||
/* FIXME: do something useful here?
|
||||
* Current libata behavior will
|
||||
* tear down everything when
|
||||
* the module is removed
|
||||
* or the h/w is unplugged.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/* in order to keep device order, we need to synchronize at this point */
|
||||
async_synchronize_cookie(cookie);
|
||||
|
||||
ata_scsi_scan_host(ap, 1);
|
||||
|
||||
}
|
||||
/**
|
||||
* ata_host_register - register initialized ATA host
|
||||
* @host: ATA host to register
|
||||
|
|
@ -5928,52 +6042,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
|
|||
DPRINTK("probe begin\n");
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
|
||||
/* probe */
|
||||
if (ap->ops->error_handler) {
|
||||
struct ata_eh_info *ehi = &ap->link.eh_info;
|
||||
unsigned long flags;
|
||||
|
||||
ata_port_probe(ap);
|
||||
|
||||
/* kick EH for boot probing */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
ehi->probe_mask |= ATA_ALL_DEVICES;
|
||||
ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
|
||||
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
|
||||
|
||||
ap->pflags &= ~ATA_PFLAG_INITIALIZING;
|
||||
ap->pflags |= ATA_PFLAG_LOADING;
|
||||
ata_port_schedule_eh(ap);
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
/* wait for EH to finish */
|
||||
ata_port_wait_eh(ap);
|
||||
} else {
|
||||
DPRINTK("ata%u: bus probe begin\n", ap->print_id);
|
||||
rc = ata_bus_probe(ap);
|
||||
DPRINTK("ata%u: bus probe end\n", ap->print_id);
|
||||
|
||||
if (rc) {
|
||||
/* FIXME: do something useful here?
|
||||
* Current libata behavior will
|
||||
* tear down everything when
|
||||
* the module is removed
|
||||
* or the h/w is unplugged.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* probes are done, now scan each port's disk(s) */
|
||||
DPRINTK("host probe begin\n");
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
struct ata_port *ap = host->ports[i];
|
||||
|
||||
ata_scsi_scan_host(ap, 1);
|
||||
async_schedule(async_port_probe, ap);
|
||||
}
|
||||
DPRINTK("probe end\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6047,8 +6118,6 @@ int ata_host_activate(struct ata_host *host, int irq,
|
|||
static void ata_port_detach(struct ata_port *ap)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ata_link *link;
|
||||
struct ata_device *dev;
|
||||
|
||||
if (!ap->ops->error_handler)
|
||||
goto skip_eh;
|
||||
|
|
@ -6056,28 +6125,15 @@ static void ata_port_detach(struct ata_port *ap)
|
|||
/* tell EH we're leaving & flush EH */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
ap->pflags |= ATA_PFLAG_UNLOADING;
|
||||
ata_port_schedule_eh(ap);
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
/* wait till EH commits suicide */
|
||||
ata_port_wait_eh(ap);
|
||||
|
||||
/* EH is now guaranteed to see UNLOADING - EH context belongs
|
||||
* to us. Restore SControl and disable all existing devices.
|
||||
*/
|
||||
__ata_port_for_each_link(link, ap) {
|
||||
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0);
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_dev_disable(dev);
|
||||
}
|
||||
/* it better be dead now */
|
||||
WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
|
||||
|
||||
/* Final freeze & EH. All in-flight commands are aborted. EH
|
||||
* will be skipped and retrials will be terminated with bad
|
||||
* target.
|
||||
*/
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
ata_port_freeze(ap); /* won't be thawed */
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
ata_port_wait_eh(ap);
|
||||
cancel_rearming_delayed_work(&ap->hotplug_task);
|
||||
|
||||
skip_eh:
|
||||
|
|
@ -6528,7 +6584,8 @@ EXPORT_SYMBOL_GPL(ata_base_port_ops);
|
|||
EXPORT_SYMBOL_GPL(sata_port_ops);
|
||||
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
|
||||
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
|
||||
EXPORT_SYMBOL_GPL(__ata_port_next_link);
|
||||
EXPORT_SYMBOL_GPL(ata_link_next);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_next);
|
||||
EXPORT_SYMBOL_GPL(ata_std_bios_param);
|
||||
EXPORT_SYMBOL_GPL(ata_host_init);
|
||||
EXPORT_SYMBOL_GPL(ata_host_alloc);
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
|
|||
|
||||
if (!dev) {
|
||||
ehi->action &= ~action;
|
||||
ata_link_for_each_dev(tdev, link)
|
||||
ata_for_each_dev(tdev, link, ALL)
|
||||
ehi->dev_action[tdev->devno] &= ~action;
|
||||
} else {
|
||||
/* doesn't make sense for port-wide EH actions */
|
||||
|
|
@ -430,7 +430,7 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
|
|||
|
||||
/* break ehi->action into ehi->dev_action */
|
||||
if (ehi->action & action) {
|
||||
ata_link_for_each_dev(tdev, link)
|
||||
ata_for_each_dev(tdev, link, ALL)
|
||||
ehi->dev_action[tdev->devno] |=
|
||||
ehi->action & action;
|
||||
ehi->action &= ~action;
|
||||
|
|
@ -491,6 +491,31 @@ enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ata_eh_unload(struct ata_port *ap)
|
||||
{
|
||||
struct ata_link *link;
|
||||
struct ata_device *dev;
|
||||
unsigned long flags;
|
||||
|
||||
/* Restore SControl IPM and SPD for the next driver and
|
||||
* disable attached devices.
|
||||
*/
|
||||
ata_for_each_link(link, ap, PMP_FIRST) {
|
||||
sata_scr_write(link, SCR_CONTROL, link->saved_scontrol & 0xff0);
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
ata_dev_disable(dev);
|
||||
}
|
||||
|
||||
/* freeze and set UNLOADED */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
ata_port_freeze(ap); /* won't be thawed */
|
||||
ap->pflags &= ~ATA_PFLAG_EH_PENDING; /* clear pending from freeze */
|
||||
ap->pflags |= ATA_PFLAG_UNLOADED;
|
||||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_error - SCSI layer error handler callback
|
||||
* @host: SCSI host on which error occurred
|
||||
|
|
@ -592,7 +617,7 @@ void ata_scsi_error(struct Scsi_Host *host)
|
|||
/* fetch & clear EH info */
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
__ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, HOST_FIRST) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
struct ata_device *dev;
|
||||
|
||||
|
|
@ -600,12 +625,9 @@ void ata_scsi_error(struct Scsi_Host *host)
|
|||
link->eh_context.i = link->eh_info;
|
||||
memset(&link->eh_info, 0, sizeof(link->eh_info));
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
int devno = dev->devno;
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ehc->saved_xfer_mode[devno] = dev->xfer_mode;
|
||||
if (ata_ncq_enabled(dev))
|
||||
ehc->saved_ncq_enabled |= 1 << devno;
|
||||
|
|
@ -621,8 +643,13 @@ void ata_scsi_error(struct Scsi_Host *host)
|
|||
/* invoke EH, skip if unloading or suspended */
|
||||
if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED)))
|
||||
ap->ops->error_handler(ap);
|
||||
else
|
||||
else {
|
||||
/* if unloading, commence suicide */
|
||||
if ((ap->pflags & ATA_PFLAG_UNLOADING) &&
|
||||
!(ap->pflags & ATA_PFLAG_UNLOADED))
|
||||
ata_eh_unload(ap);
|
||||
ata_eh_finish(ap);
|
||||
}
|
||||
|
||||
/* process port suspend request */
|
||||
ata_eh_handle_port_suspend(ap);
|
||||
|
|
@ -644,7 +671,7 @@ void ata_scsi_error(struct Scsi_Host *host)
|
|||
}
|
||||
|
||||
/* this run is complete, make sure EH info is clear */
|
||||
__ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, HOST_FIRST)
|
||||
memset(&link->eh_info, 0, sizeof(link->eh_info));
|
||||
|
||||
/* Clear host_eh_scheduled while holding ap->lock such
|
||||
|
|
@ -1025,7 +1052,7 @@ int sata_async_notification(struct ata_port *ap)
|
|||
struct ata_link *link;
|
||||
|
||||
/* check and notify ATAPI AN */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
if (!(sntf & (1 << link->pmp)))
|
||||
continue;
|
||||
|
||||
|
|
@ -2005,7 +2032,7 @@ void ata_eh_autopsy(struct ata_port *ap)
|
|||
{
|
||||
struct ata_link *link;
|
||||
|
||||
ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, EDGE)
|
||||
ata_eh_link_autopsy(link);
|
||||
|
||||
/* Handle the frigging slave link. Autopsy is done similarly
|
||||
|
|
@ -2219,7 +2246,7 @@ void ata_eh_report(struct ata_port *ap)
|
|||
{
|
||||
struct ata_link *link;
|
||||
|
||||
__ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, HOST_FIRST)
|
||||
ata_eh_link_report(link);
|
||||
}
|
||||
|
||||
|
|
@ -2230,7 +2257,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
|
|||
struct ata_device *dev;
|
||||
|
||||
if (clear_classes)
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
classes[dev->devno] = ATA_DEV_UNKNOWN;
|
||||
|
||||
return reset(link, classes, deadline);
|
||||
|
|
@ -2294,7 +2321,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|||
|
||||
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
/* If we issue an SRST then an ATA drive (not ATAPI)
|
||||
* may change configuration and be in PIO0 timing. If
|
||||
* we do a hard reset (or are coming from power on)
|
||||
|
|
@ -2355,7 +2382,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|||
"port disabled. ignoring.\n");
|
||||
ehc->i.action &= ~ATA_EH_RESET;
|
||||
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
classes[dev->devno] = ATA_DEV_NONE;
|
||||
|
||||
rc = 0;
|
||||
|
|
@ -2369,7 +2396,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|||
* bang classes and return.
|
||||
*/
|
||||
if (reset && !(ehc->i.action & ATA_EH_RESET)) {
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
classes[dev->devno] = ATA_DEV_NONE;
|
||||
rc = 0;
|
||||
goto out;
|
||||
|
|
@ -2454,7 +2481,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|||
/*
|
||||
* Post-reset processing
|
||||
*/
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
/* After the reset, the device state is PIO 0 and the
|
||||
* controller state is undefined. Reset also wakes up
|
||||
* drives from sleeping mode.
|
||||
|
|
@ -2510,7 +2537,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
|||
* can be reliably detected and retried.
|
||||
*/
|
||||
nr_unknown = 0;
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
/* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
|
||||
if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
|
||||
classes[dev->devno] = ATA_DEV_NONE;
|
||||
|
|
@ -2619,8 +2646,8 @@ static inline void ata_eh_pull_park_action(struct ata_port *ap)
|
|||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
INIT_COMPLETION(ap->park_req_pending);
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
struct ata_eh_info *ehi = &link->eh_info;
|
||||
|
||||
link->eh_context.i.dev_action[dev->devno] |=
|
||||
|
|
@ -2675,7 +2702,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
|
|||
* be done backwards such that PDIAG- is released by the slave
|
||||
* device before the master device is identified.
|
||||
*/
|
||||
ata_link_for_each_dev_reverse(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL_REVERSE) {
|
||||
unsigned int action = ata_eh_dev_action(dev);
|
||||
unsigned int readid_flags = 0;
|
||||
|
||||
|
|
@ -2744,7 +2771,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
|
|||
/* Configure new devices forward such that user doesn't see
|
||||
* device detection messages backwards.
|
||||
*/
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (!(new_mask & (1 << dev->devno)) ||
|
||||
dev->class == ATA_DEV_PMP)
|
||||
continue;
|
||||
|
|
@ -2793,10 +2820,7 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|||
int rc;
|
||||
|
||||
/* if data transfer is verified, clear DUBIOUS_XFER on ering top */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) {
|
||||
struct ata_ering_entry *ent;
|
||||
|
||||
|
|
@ -2813,14 +2837,11 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
|
|||
rc = ata_do_set_mode(link, r_failed_dev);
|
||||
|
||||
/* if transfer mode has changed, set DUBIOUS_XFER on device */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno];
|
||||
u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno));
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
if (dev->xfer_mode != saved_xfer_mode ||
|
||||
ata_ncq_enabled(dev) != saved_ncq)
|
||||
dev->flags |= ATA_DFLAG_DUBIOUS_XFER;
|
||||
|
|
@ -2881,9 +2902,8 @@ static int ata_link_nr_enabled(struct ata_link *link)
|
|||
struct ata_device *dev;
|
||||
int cnt = 0;
|
||||
|
||||
ata_link_for_each_dev(dev, link)
|
||||
if (ata_dev_enabled(dev))
|
||||
cnt++;
|
||||
ata_for_each_dev(dev, link, ENABLED)
|
||||
cnt++;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
|
@ -2892,7 +2912,7 @@ static int ata_link_nr_vacant(struct ata_link *link)
|
|||
struct ata_device *dev;
|
||||
int cnt = 0;
|
||||
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
if (dev->class == ATA_DEV_UNKNOWN)
|
||||
cnt++;
|
||||
return cnt;
|
||||
|
|
@ -2918,7 +2938,7 @@ static int ata_eh_skip_recovery(struct ata_link *link)
|
|||
return 0;
|
||||
|
||||
/* skip if class codes for all vacant slots are ATA_DEV_NONE */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (dev->class == ATA_DEV_UNKNOWN &&
|
||||
ehc->classes[dev->devno] != ATA_DEV_NONE)
|
||||
return 0;
|
||||
|
|
@ -3026,7 +3046,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
DPRINTK("ENTER\n");
|
||||
|
||||
/* prep for recovery */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
|
||||
/* re-enable link? */
|
||||
|
|
@ -3038,7 +3058,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
ata_eh_done(link, NULL, ATA_EH_ENABLE_LINK);
|
||||
}
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (link->flags & ATA_LFLAG_NO_RETRY)
|
||||
ehc->tries[dev->devno] = 1;
|
||||
else
|
||||
|
|
@ -3068,19 +3088,19 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
goto out;
|
||||
|
||||
/* prep for EH */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
|
||||
/* skip EH if possible. */
|
||||
if (ata_eh_skip_recovery(link))
|
||||
ehc->i.action = 0;
|
||||
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
|
||||
}
|
||||
|
||||
/* reset */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
|
||||
if (!(ehc->i.action & ATA_EH_RESET))
|
||||
|
|
@ -3105,8 +3125,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
ata_eh_pull_park_action(ap);
|
||||
|
||||
deadline = jiffies;
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
unsigned long tmp;
|
||||
|
||||
|
|
@ -3134,8 +3154,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
deadline = wait_for_completion_timeout(&ap->park_req_pending,
|
||||
deadline - now);
|
||||
} while (deadline);
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (!(link->eh_context.unloaded_mask &
|
||||
(1 << dev->devno)))
|
||||
continue;
|
||||
|
|
@ -3146,7 +3166,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
}
|
||||
|
||||
/* the rest */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
|
||||
/* revalidate existing devices and attach new ones */
|
||||
|
|
@ -3172,7 +3192,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
* disrupting the current users of the device.
|
||||
*/
|
||||
if (ehc->i.flags & ATA_EHI_DID_RESET) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (dev->class != ATA_DEV_ATAPI)
|
||||
continue;
|
||||
rc = atapi_eh_clear_ua(dev);
|
||||
|
|
@ -3183,7 +3203,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
|
||||
/* configure link power saving */
|
||||
if (ehc->i.action & ATA_EH_LPM)
|
||||
ata_link_for_each_dev(dev, link)
|
||||
ata_for_each_dev(dev, link, ALL)
|
||||
ata_dev_enable_pm(dev, ap->pm_policy);
|
||||
|
||||
/* this link is okay now */
|
||||
|
|
@ -3288,7 +3308,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset,
|
||||
NULL);
|
||||
if (rc) {
|
||||
ata_link_for_each_dev(dev, &ap->link)
|
||||
ata_for_each_dev(dev, &ap->link, ALL)
|
||||
ata_dev_disable(dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ static void sata_pmp_quirks(struct ata_port *ap)
|
|||
|
||||
if (vendor == 0x1095 && devid == 0x3726) {
|
||||
/* sil3726 quirks */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
/* Class code report is unreliable and SRST
|
||||
* times out under certain configurations.
|
||||
*/
|
||||
|
|
@ -336,7 +336,7 @@ static void sata_pmp_quirks(struct ata_port *ap)
|
|||
}
|
||||
} else if (vendor == 0x1095 && devid == 0x4723) {
|
||||
/* sil4723 quirks */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
/* class code report is unreliable */
|
||||
if (link->pmp < 2)
|
||||
link->flags |= ATA_LFLAG_ASSUME_ATA;
|
||||
|
|
@ -348,7 +348,7 @@ static void sata_pmp_quirks(struct ata_port *ap)
|
|||
}
|
||||
} else if (vendor == 0x1095 && devid == 0x4726) {
|
||||
/* sil4726 quirks */
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
/* Class code report is unreliable and SRST
|
||||
* times out under certain configurations.
|
||||
* Config device can be at port 0 or 5 and
|
||||
|
|
@ -450,7 +450,7 @@ int sata_pmp_attach(struct ata_device *dev)
|
|||
if (ap->ops->pmp_attach)
|
||||
ap->ops->pmp_attach(ap);
|
||||
|
||||
ata_port_for_each_link(tlink, ap)
|
||||
ata_for_each_link(tlink, ap, EDGE)
|
||||
sata_link_init_spd(tlink);
|
||||
|
||||
ata_acpi_associate_sata_port(ap);
|
||||
|
|
@ -487,7 +487,7 @@ static void sata_pmp_detach(struct ata_device *dev)
|
|||
if (ap->ops->pmp_detach)
|
||||
ap->ops->pmp_detach(ap);
|
||||
|
||||
ata_port_for_each_link(tlink, ap)
|
||||
ata_for_each_link(tlink, ap, EDGE)
|
||||
ata_eh_detach_dev(tlink->device);
|
||||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
|
@ -700,7 +700,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
|
|||
}
|
||||
|
||||
/* PMP is reset, SErrors cannot be trusted, scan all */
|
||||
ata_port_for_each_link(tlink, ap) {
|
||||
ata_for_each_link(tlink, ap, EDGE) {
|
||||
struct ata_eh_context *ehc = &tlink->eh_context;
|
||||
|
||||
ehc->i.probe_mask |= ATA_ALL_DEVICES;
|
||||
|
|
@ -768,7 +768,7 @@ static int sata_pmp_eh_handle_disabled_links(struct ata_port *ap)
|
|||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
if (!(link->flags & ATA_LFLAG_DISABLED))
|
||||
continue;
|
||||
|
||||
|
|
@ -852,7 +852,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
|
|||
int cnt, rc;
|
||||
|
||||
pmp_tries = ATA_EH_PMP_TRIES;
|
||||
ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, EDGE)
|
||||
link_tries[link->pmp] = ATA_EH_PMP_LINK_TRIES;
|
||||
|
||||
retry:
|
||||
|
|
@ -861,7 +861,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
|
|||
rc = ata_eh_recover(ap, ops->prereset, ops->softreset,
|
||||
ops->hardreset, ops->postreset, NULL);
|
||||
if (rc) {
|
||||
ata_link_for_each_dev(dev, &ap->link)
|
||||
ata_for_each_dev(dev, &ap->link, ALL)
|
||||
ata_dev_disable(dev);
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -870,7 +870,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
|
|||
return 0;
|
||||
|
||||
/* new PMP online */
|
||||
ata_port_for_each_link(link, ap)
|
||||
ata_for_each_link(link, ap, EDGE)
|
||||
link_tries[link->pmp] = ATA_EH_PMP_LINK_TRIES;
|
||||
|
||||
/* fall through */
|
||||
|
|
@ -942,7 +942,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
|
|||
}
|
||||
|
||||
cnt = 0;
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
if (!(gscr_error & (1 << link->pmp)))
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||
/* Good values for timeout and retries? Values below
|
||||
from scsi_ioctl_send_command() for default case... */
|
||||
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
|
||||
sensebuf, (10*HZ), 5, 0);
|
||||
sensebuf, (10*HZ), 5, 0, NULL);
|
||||
|
||||
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
|
||||
u8 *desc = sensebuf + 8;
|
||||
|
|
@ -603,7 +603,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|||
/* Good values for timeout and retries? Values below
|
||||
from scsi_ioctl_send_command() for default case... */
|
||||
cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
|
||||
sensebuf, (10*HZ), 5, 0);
|
||||
sensebuf, (10*HZ), 5, 0, NULL);
|
||||
|
||||
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
|
||||
u8 *desc = sensebuf + 8;
|
||||
|
|
@ -3229,12 +3229,12 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
|
|||
return;
|
||||
|
||||
repeat:
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
struct scsi_device *sdev;
|
||||
int channel = 0, id = 0;
|
||||
|
||||
if (!ata_dev_enabled(dev) || dev->sdev)
|
||||
if (dev->sdev)
|
||||
continue;
|
||||
|
||||
if (ata_is_host_link(link))
|
||||
|
|
@ -3255,9 +3255,9 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
|
|||
* failure occurred, scan would have failed silently. Check
|
||||
* whether all devices are attached.
|
||||
*/
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev) && !dev->sdev)
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
if (!dev->sdev)
|
||||
goto exit_loop;
|
||||
}
|
||||
}
|
||||
|
|
@ -3369,7 +3369,7 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
|
|||
|
||||
if (sdev) {
|
||||
ata_dev_printk(dev, KERN_INFO, "detaching (SCSI %s)\n",
|
||||
sdev->sdev_gendev.bus_id);
|
||||
dev_name(&sdev->sdev_gendev));
|
||||
|
||||
scsi_remove_device(sdev);
|
||||
scsi_device_put(sdev);
|
||||
|
|
@ -3381,7 +3381,7 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
|
|||
struct ata_port *ap = link->ap;
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
unsigned long flags;
|
||||
|
||||
if (!(dev->flags & ATA_DFLAG_DETACHED))
|
||||
|
|
@ -3496,7 +3496,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
|
|||
if (devno == SCAN_WILD_CARD) {
|
||||
struct ata_link *link;
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
struct ata_eh_info *ehi = &link->eh_info;
|
||||
ehi->probe_mask |= ATA_ALL_DEVICES;
|
||||
ehi->action |= ATA_EH_RESET;
|
||||
|
|
@ -3544,11 +3544,11 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
|||
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
struct scsi_device *sdev = dev->sdev;
|
||||
|
||||
if (!ata_dev_enabled(dev) || !sdev)
|
||||
if (!sdev)
|
||||
continue;
|
||||
if (scsi_device_get(sdev))
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ const struct ata_port_operations ata_sff_port_ops = {
|
|||
|
||||
.port_start = ata_sff_port_start,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
|
||||
|
||||
const struct ata_port_operations ata_bmdma_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
|
|
@ -77,6 +78,14 @@ const struct ata_port_operations ata_bmdma_port_ops = {
|
|||
.bmdma_stop = ata_bmdma_stop,
|
||||
.bmdma_status = ata_bmdma_status,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
|
||||
|
||||
const struct ata_port_operations ata_bmdma32_port_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
|
||||
|
||||
/**
|
||||
* ata_fill_sg - Fill PCI IDE PRD table
|
||||
|
|
@ -166,8 +175,9 @@ static void ata_fill_sg_dumb(struct ata_queued_cmd *qc)
|
|||
blen = len & 0xffff;
|
||||
ap->prd[pi].addr = cpu_to_le32(addr);
|
||||
if (blen == 0) {
|
||||
/* Some PATA chipsets like the CS5530 can't
|
||||
cope with 0x0000 meaning 64K as the spec says */
|
||||
/* Some PATA chipsets like the CS5530 can't
|
||||
cope with 0x0000 meaning 64K as the spec
|
||||
says */
|
||||
ap->prd[pi].flags_len = cpu_to_le32(0x8000);
|
||||
blen = 0x8000;
|
||||
ap->prd[++pi].addr = cpu_to_le32(addr + 0x8000);
|
||||
|
|
@ -200,6 +210,7 @@ void ata_sff_qc_prep(struct ata_queued_cmd *qc)
|
|||
|
||||
ata_fill_sg(qc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_qc_prep);
|
||||
|
||||
/**
|
||||
* ata_sff_dumb_qc_prep - Prepare taskfile for submission
|
||||
|
|
@ -217,6 +228,7 @@ void ata_sff_dumb_qc_prep(struct ata_queued_cmd *qc)
|
|||
|
||||
ata_fill_sg_dumb(qc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep);
|
||||
|
||||
/**
|
||||
* ata_sff_check_status - Read device status reg & clear interrupt
|
||||
|
|
@ -233,6 +245,7 @@ u8 ata_sff_check_status(struct ata_port *ap)
|
|||
{
|
||||
return ioread8(ap->ioaddr.status_addr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_check_status);
|
||||
|
||||
/**
|
||||
* ata_sff_altstatus - Read device alternate status reg
|
||||
|
|
@ -275,7 +288,7 @@ static u8 ata_sff_irq_status(struct ata_port *ap)
|
|||
status = ata_sff_altstatus(ap);
|
||||
/* Not us: We are busy */
|
||||
if (status & ATA_BUSY)
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
/* Clear INTRQ latch */
|
||||
status = ap->ops->sff_check_status(ap);
|
||||
|
|
@ -319,6 +332,7 @@ void ata_sff_pause(struct ata_port *ap)
|
|||
ata_sff_sync(ap);
|
||||
ndelay(400);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_pause);
|
||||
|
||||
/**
|
||||
* ata_sff_dma_pause - Pause before commencing DMA
|
||||
|
|
@ -327,7 +341,7 @@ void ata_sff_pause(struct ata_port *ap)
|
|||
* Perform I/O fencing and ensure sufficient cycle delays occur
|
||||
* for the HDMA1:0 transition
|
||||
*/
|
||||
|
||||
|
||||
void ata_sff_dma_pause(struct ata_port *ap)
|
||||
{
|
||||
if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) {
|
||||
|
|
@ -341,6 +355,7 @@ void ata_sff_dma_pause(struct ata_port *ap)
|
|||
corruption. */
|
||||
BUG();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dma_pause);
|
||||
|
||||
/**
|
||||
* ata_sff_busy_sleep - sleep until BSY clears, or timeout
|
||||
|
|
@ -396,6 +411,7 @@ int ata_sff_busy_sleep(struct ata_port *ap,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_busy_sleep);
|
||||
|
||||
static int ata_sff_check_ready(struct ata_link *link)
|
||||
{
|
||||
|
|
@ -422,6 +438,7 @@ int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline)
|
|||
{
|
||||
return ata_wait_ready(link, deadline, ata_sff_check_ready);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_wait_ready);
|
||||
|
||||
/**
|
||||
* ata_sff_dev_select - Select device 0/1 on ATA bus
|
||||
|
|
@ -449,6 +466,7 @@ void ata_sff_dev_select(struct ata_port *ap, unsigned int device)
|
|||
iowrite8(tmp, ap->ioaddr.device_addr);
|
||||
ata_sff_pause(ap); /* needed; also flushes, for mmio */
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dev_select);
|
||||
|
||||
/**
|
||||
* ata_dev_select - Select device 0/1 on ATA bus
|
||||
|
|
@ -513,6 +531,7 @@ u8 ata_sff_irq_on(struct ata_port *ap)
|
|||
|
||||
return tmp;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_irq_on);
|
||||
|
||||
/**
|
||||
* ata_sff_irq_clear - Clear PCI IDE BMDMA interrupt.
|
||||
|
|
@ -534,6 +553,7 @@ void ata_sff_irq_clear(struct ata_port *ap)
|
|||
|
||||
iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_irq_clear);
|
||||
|
||||
/**
|
||||
* ata_sff_tf_load - send taskfile registers to host controller
|
||||
|
|
@ -593,6 +613,7 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
|||
|
||||
ata_wait_idle(ap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_tf_load);
|
||||
|
||||
/**
|
||||
* ata_sff_tf_read - input device's ATA taskfile shadow registers
|
||||
|
|
@ -633,6 +654,7 @@ void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
|
|||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_tf_read);
|
||||
|
||||
/**
|
||||
* ata_sff_exec_command - issue ATA command to host controller
|
||||
|
|
@ -652,6 +674,7 @@ void ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
|
|||
iowrite8(tf->command, ap->ioaddr.command_addr);
|
||||
ata_sff_pause(ap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_exec_command);
|
||||
|
||||
/**
|
||||
* ata_tf_to_host - issue ATA taskfile to host controller
|
||||
|
|
@ -717,6 +740,53 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
|
|||
|
||||
return words << 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer);
|
||||
|
||||
/**
|
||||
* ata_sff_data_xfer32 - Transfer data by PIO
|
||||
* @dev: device to target
|
||||
* @buf: data buffer
|
||||
* @buflen: buffer length
|
||||
* @rw: read/write
|
||||
*
|
||||
* Transfer data from/to the device data register by PIO using 32bit
|
||||
* I/O operations.
|
||||
*
|
||||
* LOCKING:
|
||||
* Inherited from caller.
|
||||
*
|
||||
* RETURNS:
|
||||
* Bytes consumed.
|
||||
*/
|
||||
|
||||
unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
|
||||
unsigned int buflen, int rw)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
void __iomem *data_addr = ap->ioaddr.data_addr;
|
||||
unsigned int words = buflen >> 2;
|
||||
int slop = buflen & 3;
|
||||
|
||||
/* Transfer multiple of 4 bytes */
|
||||
if (rw == READ)
|
||||
ioread32_rep(data_addr, buf, words);
|
||||
else
|
||||
iowrite32_rep(data_addr, buf, words);
|
||||
|
||||
if (unlikely(slop)) {
|
||||
__le32 pad;
|
||||
if (rw == READ) {
|
||||
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
||||
memcpy(buf + buflen - slop, &pad, slop);
|
||||
} else {
|
||||
memcpy(&pad, buf + buflen - slop, slop);
|
||||
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
||||
}
|
||||
words++;
|
||||
}
|
||||
return words << 2;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
|
||||
|
||||
/**
|
||||
* ata_sff_data_xfer_noirq - Transfer data by PIO
|
||||
|
|
@ -746,6 +816,7 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf,
|
|||
|
||||
return consumed;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer_noirq);
|
||||
|
||||
/**
|
||||
* ata_pio_sector - Transfer a sector of data.
|
||||
|
|
@ -922,13 +993,15 @@ next_sg:
|
|||
buf = kmap_atomic(page, KM_IRQ0);
|
||||
|
||||
/* do the actual data transfer */
|
||||
consumed = ap->ops->sff_data_xfer(dev, buf + offset, count, rw);
|
||||
consumed = ap->ops->sff_data_xfer(dev, buf + offset,
|
||||
count, rw);
|
||||
|
||||
kunmap_atomic(buf, KM_IRQ0);
|
||||
local_irq_restore(flags);
|
||||
} else {
|
||||
buf = page_address(page);
|
||||
consumed = ap->ops->sff_data_xfer(dev, buf + offset, count, rw);
|
||||
consumed = ap->ops->sff_data_xfer(dev, buf + offset,
|
||||
count, rw);
|
||||
}
|
||||
|
||||
bytes -= min(bytes, consumed);
|
||||
|
|
@ -1013,18 +1086,19 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
|
|||
* RETURNS:
|
||||
* 1 if ok in workqueue, 0 otherwise.
|
||||
*/
|
||||
static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
|
||||
static inline int ata_hsm_ok_in_wq(struct ata_port *ap,
|
||||
struct ata_queued_cmd *qc)
|
||||
{
|
||||
if (qc->tf.flags & ATA_TFLAG_POLLING)
|
||||
return 1;
|
||||
|
||||
if (ap->hsm_task_state == HSM_ST_FIRST) {
|
||||
if (qc->tf.protocol == ATA_PROT_PIO &&
|
||||
(qc->tf.flags & ATA_TFLAG_WRITE))
|
||||
(qc->tf.flags & ATA_TFLAG_WRITE))
|
||||
return 1;
|
||||
|
||||
if (ata_is_atapi(qc->tf.protocol) &&
|
||||
!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
|
||||
!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1338,6 +1412,7 @@ fsm_start:
|
|||
|
||||
return poll_next;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
|
||||
|
||||
void ata_pio_task(struct work_struct *work)
|
||||
{
|
||||
|
|
@ -1507,6 +1582,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_qc_issue);
|
||||
|
||||
/**
|
||||
* ata_sff_qc_fill_rtf - fill result TF using ->sff_tf_read
|
||||
|
|
@ -1526,6 +1602,7 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
|
|||
qc->ap->ops->sff_tf_read(qc->ap, &qc->result_tf);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
|
||||
|
||||
/**
|
||||
* ata_sff_host_intr - Handle host interrupt for given (port, task)
|
||||
|
|
@ -1623,6 +1700,7 @@ idle_irq:
|
|||
#endif
|
||||
return 0; /* irq not handled */
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_host_intr);
|
||||
|
||||
/**
|
||||
* ata_sff_interrupt - Default ATA host interrupt handler
|
||||
|
|
@ -1667,6 +1745,7 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
|
|||
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_interrupt);
|
||||
|
||||
/**
|
||||
* ata_sff_freeze - Freeze SFF controller port
|
||||
|
|
@ -1695,6 +1774,7 @@ void ata_sff_freeze(struct ata_port *ap)
|
|||
|
||||
ap->ops->sff_irq_clear(ap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_freeze);
|
||||
|
||||
/**
|
||||
* ata_sff_thaw - Thaw SFF controller port
|
||||
|
|
@ -1712,6 +1792,7 @@ void ata_sff_thaw(struct ata_port *ap)
|
|||
ap->ops->sff_irq_clear(ap);
|
||||
ap->ops->sff_irq_on(ap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_thaw);
|
||||
|
||||
/**
|
||||
* ata_sff_prereset - prepare SFF link for reset
|
||||
|
|
@ -1753,6 +1834,7 @@ int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_prereset);
|
||||
|
||||
/**
|
||||
* ata_devchk - PATA device presence detection
|
||||
|
|
@ -1865,6 +1947,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
|
|||
|
||||
return class;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dev_classify);
|
||||
|
||||
/**
|
||||
* ata_sff_wait_after_reset - wait for devices to become ready after reset
|
||||
|
|
@ -1941,6 +2024,7 @@ int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_wait_after_reset);
|
||||
|
||||
static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
||||
unsigned long deadline)
|
||||
|
|
@ -2013,6 +2097,7 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
|
|||
DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_softreset);
|
||||
|
||||
/**
|
||||
* sata_sff_hardreset - reset host port via SATA phy reset
|
||||
|
|
@ -2045,6 +2130,7 @@ int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
|
|||
DPRINTK("EXIT, class=%u\n", *class);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sata_sff_hardreset);
|
||||
|
||||
/**
|
||||
* ata_sff_postreset - SFF postreset callback
|
||||
|
|
@ -2080,6 +2166,7 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
|
|||
if (ap->ioaddr.ctl_addr)
|
||||
iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_postreset);
|
||||
|
||||
/**
|
||||
* ata_sff_error_handler - Stock error handler for BMDMA controller
|
||||
|
|
@ -2152,6 +2239,7 @@ void ata_sff_error_handler(struct ata_port *ap)
|
|||
ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
|
||||
ap->ops->postreset);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_error_handler);
|
||||
|
||||
/**
|
||||
* ata_sff_post_internal_cmd - Stock post_internal_cmd for SFF controller
|
||||
|
|
@ -2174,6 +2262,7 @@ void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
|
|||
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
|
||||
|
||||
/**
|
||||
* ata_sff_port_start - Set port up for dma.
|
||||
|
|
@ -2194,6 +2283,7 @@ int ata_sff_port_start(struct ata_port *ap)
|
|||
return ata_port_start(ap);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_port_start);
|
||||
|
||||
/**
|
||||
* ata_sff_std_ports - initialize ioaddr with standard port offsets.
|
||||
|
|
@ -2219,6 +2309,7 @@ void ata_sff_std_ports(struct ata_ioports *ioaddr)
|
|||
ioaddr->status_addr = ioaddr->cmd_addr + ATA_REG_STATUS;
|
||||
ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_std_ports);
|
||||
|
||||
unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
|
||||
unsigned long xfer_mask)
|
||||
|
|
@ -2230,6 +2321,7 @@ unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
|
|||
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
|
||||
return xfer_mask;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter);
|
||||
|
||||
/**
|
||||
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
|
||||
|
|
@ -2258,6 +2350,7 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
|
|||
/* issue r/w command */
|
||||
ap->ops->sff_exec_command(ap, &qc->tf);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
|
||||
|
||||
/**
|
||||
* ata_bmdma_start - Start a PCI IDE BMDMA transaction
|
||||
|
|
@ -2290,6 +2383,7 @@ void ata_bmdma_start(struct ata_queued_cmd *qc)
|
|||
* unneccessarily delayed for MMIO
|
||||
*/
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_start);
|
||||
|
||||
/**
|
||||
* ata_bmdma_stop - Stop PCI IDE BMDMA transfer
|
||||
|
|
@ -2314,6 +2408,7 @@ void ata_bmdma_stop(struct ata_queued_cmd *qc)
|
|||
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
|
||||
ata_sff_dma_pause(ap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
|
||||
|
||||
/**
|
||||
* ata_bmdma_status - Read PCI IDE BMDMA status
|
||||
|
|
@ -2330,6 +2425,7 @@ u8 ata_bmdma_status(struct ata_port *ap)
|
|||
{
|
||||
return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_status);
|
||||
|
||||
/**
|
||||
* ata_bus_reset - reset host port and associated ATA channel
|
||||
|
|
@ -2422,6 +2518,7 @@ err_out:
|
|||
|
||||
DPRINTK("EXIT\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_bus_reset);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
|
|
@ -2449,6 +2546,7 @@ int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
|
|||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
|
||||
|
||||
/**
|
||||
* ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host
|
||||
|
|
@ -2501,11 +2599,12 @@ int ata_pci_bmdma_init(struct ata_host *host)
|
|||
host->flags |= ATA_HOST_SIMPLEX;
|
||||
|
||||
ata_port_desc(ap, "bmdma 0x%llx",
|
||||
(unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
|
||||
(unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
|
||||
|
||||
static int ata_resources_present(struct pci_dev *pdev, int port)
|
||||
{
|
||||
|
|
@ -2513,7 +2612,7 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
|
|||
|
||||
/* Check the PCI resources for this channel are enabled */
|
||||
port = port * 2;
|
||||
for (i = 0; i < 2; i ++) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (pci_resource_start(pdev, port + i) == 0 ||
|
||||
pci_resource_len(pdev, port + i) == 0)
|
||||
return 0;
|
||||
|
|
@ -2598,6 +2697,7 @@ int ata_pci_sff_init_host(struct ata_host *host)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
|
||||
|
||||
/**
|
||||
* ata_pci_sff_prepare_host - helper to prepare native PCI ATA host
|
||||
|
|
@ -2615,7 +2715,7 @@ int ata_pci_sff_init_host(struct ata_host *host)
|
|||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_pci_sff_prepare_host(struct pci_dev *pdev,
|
||||
const struct ata_port_info * const * ppi,
|
||||
const struct ata_port_info * const *ppi,
|
||||
struct ata_host **r_host)
|
||||
{
|
||||
struct ata_host *host;
|
||||
|
|
@ -2645,17 +2745,18 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev,
|
|||
*r_host = host;
|
||||
return 0;
|
||||
|
||||
err_bmdma:
|
||||
err_bmdma:
|
||||
/* This is necessary because PCI and iomap resources are
|
||||
* merged and releasing the top group won't release the
|
||||
* acquired resources if some of those have been acquired
|
||||
* before entering this function.
|
||||
*/
|
||||
pcim_iounmap_regions(pdev, 0xf);
|
||||
err_out:
|
||||
err_out:
|
||||
devres_release_group(&pdev->dev, NULL);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host);
|
||||
|
||||
/**
|
||||
* ata_pci_sff_activate_host - start SFF host, request IRQ and register it
|
||||
|
|
@ -2741,7 +2842,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
|
|||
}
|
||||
|
||||
rc = ata_host_register(host, sht);
|
||||
out:
|
||||
out:
|
||||
if (rc == 0)
|
||||
devres_remove_group(dev, NULL);
|
||||
else
|
||||
|
|
@ -2749,6 +2850,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
|
|||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
|
||||
|
||||
/**
|
||||
* ata_pci_sff_init_one - Initialize/register PCI IDE host controller
|
||||
|
|
@ -2776,7 +2878,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
|
|||
* Zero on success, negative on errno-based value on error.
|
||||
*/
|
||||
int ata_pci_sff_init_one(struct pci_dev *pdev,
|
||||
const struct ata_port_info * const * ppi,
|
||||
const struct ata_port_info * const *ppi,
|
||||
struct scsi_host_template *sht, void *host_priv)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
|
@ -2815,7 +2917,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
|
|||
|
||||
pci_set_master(pdev);
|
||||
rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
|
||||
out:
|
||||
out:
|
||||
if (rc == 0)
|
||||
devres_remove_group(&pdev->dev, NULL);
|
||||
else
|
||||
|
|
@ -2823,54 +2925,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_qc_prep);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dev_select);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_check_status);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dma_pause);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_pause);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_busy_sleep);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_wait_ready);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_tf_load);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_tf_read);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_exec_command);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_data_xfer_noirq);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_irq_on);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_irq_clear);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_qc_issue);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_host_intr);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_interrupt);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_freeze);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_thaw);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_prereset);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_dev_classify);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_wait_after_reset);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_softreset);
|
||||
EXPORT_SYMBOL_GPL(sata_sff_hardreset);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_postreset);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_error_handler);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_port_start);
|
||||
EXPORT_SYMBOL_GPL(ata_sff_std_ports);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_start);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
|
||||
EXPORT_SYMBOL_GPL(ata_bmdma_status);
|
||||
EXPORT_SYMBOL_GPL(ata_bus_reset);
|
||||
#ifdef CONFIG_PCI
|
||||
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
|
||||
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host);
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
|
||||
EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
*
|
||||
* TODO/CHECK
|
||||
* Cannot have ATAPI on both master & slave for rev < c2 (???) but
|
||||
* otherwise should do atapi DMA.
|
||||
* otherwise should do atapi DMA (For now for old we do PIO only for
|
||||
* ATAPI)
|
||||
* Review Sunblade workaround.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -33,12 +35,14 @@
|
|||
#include <linux/dmi.h>
|
||||
|
||||
#define DRV_NAME "pata_ali"
|
||||
#define DRV_VERSION "0.7.5"
|
||||
#define DRV_VERSION "0.7.8"
|
||||
|
||||
static int ali_atapi_dma = 0;
|
||||
module_param_named(atapi_dma, ali_atapi_dma, int, 0644);
|
||||
MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)");
|
||||
|
||||
static struct pci_dev *isa_bridge;
|
||||
|
||||
/*
|
||||
* Cable special cases
|
||||
*/
|
||||
|
|
@ -147,8 +151,7 @@ static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int o
|
|||
|
||||
pci_read_config_byte(pdev, pio_fifo, &fifo);
|
||||
fifo &= ~(0x0F << shift);
|
||||
if (on)
|
||||
fifo |= (on << shift);
|
||||
fifo |= (on << shift);
|
||||
pci_write_config_byte(pdev, pio_fifo, fifo);
|
||||
}
|
||||
|
||||
|
|
@ -337,6 +340,23 @@ static int ali_check_atapi_dma(struct ata_queued_cmd *qc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ali_c2_c3_postreset(struct ata_link *link, unsigned int *classes)
|
||||
{
|
||||
u8 r;
|
||||
int port_bit = 4 << link->ap->port_no;
|
||||
|
||||
/* If our bridge is an ALI 1533 then do the extra work */
|
||||
if (isa_bridge) {
|
||||
/* Tristate and re-enable the bus signals */
|
||||
pci_read_config_byte(isa_bridge, 0x58, &r);
|
||||
r &= ~port_bit;
|
||||
pci_write_config_byte(isa_bridge, 0x58, r);
|
||||
r |= port_bit;
|
||||
pci_write_config_byte(isa_bridge, 0x58, r);
|
||||
}
|
||||
ata_sff_postreset(link, classes);
|
||||
}
|
||||
|
||||
static struct scsi_host_template ali_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
};
|
||||
|
|
@ -349,10 +369,11 @@ static struct ata_port_operations ali_early_port_ops = {
|
|||
.inherits = &ata_sff_port_ops,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
.set_piomode = ali_set_piomode,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
};
|
||||
|
||||
static const struct ata_port_operations ali_dma_base_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.inherits = &ata_bmdma32_port_ops,
|
||||
.set_piomode = ali_set_piomode,
|
||||
.set_dmamode = ali_set_dmamode,
|
||||
};
|
||||
|
|
@ -377,6 +398,17 @@ static struct ata_port_operations ali_c2_port_ops = {
|
|||
.check_atapi_dma = ali_check_atapi_dma,
|
||||
.cable_detect = ali_c2_cable_detect,
|
||||
.dev_config = ali_lock_sectors,
|
||||
.postreset = ali_c2_c3_postreset,
|
||||
};
|
||||
|
||||
/*
|
||||
* Port operations for DMA capable ALi with cable detect
|
||||
*/
|
||||
static struct ata_port_operations ali_c4_port_ops = {
|
||||
.inherits = &ali_dma_base_ops,
|
||||
.check_atapi_dma = ali_check_atapi_dma,
|
||||
.cable_detect = ali_c2_cable_detect,
|
||||
.dev_config = ali_lock_sectors,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -401,27 +433,40 @@ static struct ata_port_operations ali_c5_port_ops = {
|
|||
static void ali_init_chipset(struct pci_dev *pdev)
|
||||
{
|
||||
u8 tmp;
|
||||
struct pci_dev *north, *isa_bridge;
|
||||
struct pci_dev *north;
|
||||
|
||||
/*
|
||||
* The chipset revision selects the driver operations and
|
||||
* mode data.
|
||||
*/
|
||||
|
||||
if (pdev->revision >= 0x20 && pdev->revision < 0xC2) {
|
||||
/* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
|
||||
if (pdev->revision <= 0x20) {
|
||||
pci_read_config_byte(pdev, 0x53, &tmp);
|
||||
tmp |= 0x03;
|
||||
pci_write_config_byte(pdev, 0x53, tmp);
|
||||
} else {
|
||||
pci_read_config_byte(pdev, 0x4a, &tmp);
|
||||
pci_write_config_byte(pdev, 0x4a, tmp | 0x20);
|
||||
pci_read_config_byte(pdev, 0x4B, &tmp);
|
||||
/* Clear CD-ROM DMA write bit */
|
||||
tmp &= 0x7F;
|
||||
pci_write_config_byte(pdev, 0x4B, tmp);
|
||||
} else if (pdev->revision >= 0xC2) {
|
||||
/* Enable cable detection logic */
|
||||
pci_read_config_byte(pdev, 0x4B, &tmp);
|
||||
pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
|
||||
if (pdev->revision < 0xC2)
|
||||
/* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
|
||||
/* Clear CD-ROM DMA write bit */
|
||||
tmp &= 0x7F;
|
||||
/* Cable and UDMA */
|
||||
pci_write_config_byte(pdev, 0x4B, tmp | 0x09);
|
||||
/*
|
||||
* 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 (pdev->revision >= 0xc7)
|
||||
tmp |= 0x03;
|
||||
else
|
||||
tmp |= 0x01; /* CD_ROM enable for DMA */
|
||||
pci_write_config_byte(pdev, 0x53, tmp);
|
||||
}
|
||||
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 */
|
||||
|
|
@ -431,22 +476,6 @@ static void ali_init_chipset(struct pci_dev *pdev)
|
|||
else if (pdev->revision > 0xC2 && pdev->revision < 0xC5)
|
||||
pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
|
||||
}
|
||||
if (pdev->revision >= 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 (pdev->revision <= 0x20)
|
||||
tmp &= ~0x02;
|
||||
if (pdev->revision >= 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_bmdma_clear_simplex(pdev);
|
||||
}
|
||||
|
|
@ -503,7 +532,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
.pio_mask = 0x1f,
|
||||
.mwdma_mask = 0x07,
|
||||
.udma_mask = ATA_UDMA5,
|
||||
.port_ops = &ali_c2_port_ops
|
||||
.port_ops = &ali_c4_port_ops
|
||||
};
|
||||
/* Revision 0xC5 is UDMA133 with LBA48 DMA */
|
||||
static const struct ata_port_info info_c5 = {
|
||||
|
|
@ -516,7 +545,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
|
||||
const struct ata_port_info *ppi[] = { NULL, NULL };
|
||||
u8 tmp;
|
||||
struct pci_dev *isa_bridge;
|
||||
int rc;
|
||||
|
||||
rc = pcim_enable_device(pdev);
|
||||
|
|
@ -543,14 +571,12 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
|
||||
ali_init_chipset(pdev);
|
||||
|
||||
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
|
||||
if (isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) {
|
||||
/* Are we paired with a UDMA capable chip */
|
||||
pci_read_config_byte(isa_bridge, 0x5E, &tmp);
|
||||
if ((tmp & 0x1E) == 0x12)
|
||||
ppi[0] = &info_20_udma;
|
||||
}
|
||||
pci_dev_put(isa_bridge);
|
||||
|
||||
return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
|
||||
}
|
||||
|
|
@ -590,13 +616,20 @@ static struct pci_driver ali_pci_driver = {
|
|||
|
||||
static int __init ali_init(void)
|
||||
{
|
||||
return pci_register_driver(&ali_pci_driver);
|
||||
int ret;
|
||||
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
|
||||
|
||||
ret = pci_register_driver(&ali_pci_driver);
|
||||
if (ret < 0)
|
||||
pci_dev_put(isa_bridge);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void __exit ali_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ali_pci_driver);
|
||||
pci_dev_put(isa_bridge);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_amd"
|
||||
#define DRV_VERSION "0.3.10"
|
||||
#define DRV_VERSION "0.3.11"
|
||||
|
||||
/**
|
||||
* timing_setup - shared timing computation and load
|
||||
|
|
@ -345,7 +345,7 @@ static struct scsi_host_template amd_sht = {
|
|||
};
|
||||
|
||||
static const struct ata_port_operations amd_base_port_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.inherits = &ata_bmdma32_port_ops,
|
||||
.prereset = amd_pre_reset,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -356,7 +356,6 @@ static void bfin_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
* bfin_set_dmamode - Initialize host controller PATA DMA timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: um
|
||||
* @udma: udma mode, 0 - 6
|
||||
*
|
||||
* Set UDMA mode for device.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#define DRV_VERSION "0.6.2"
|
||||
|
||||
struct hpt_clock {
|
||||
u8 xfer_speed;
|
||||
u8 xfer_mode;
|
||||
u32 timing;
|
||||
};
|
||||
|
||||
|
|
@ -189,28 +189,6 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
|
|||
return ata_bmdma_mode_filter(adev, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt36x_find_mode - reset the hpt36x bus
|
||||
* @ap: ATA port
|
||||
* @speed: transfer mode
|
||||
*
|
||||
* Return the 32bit register programming information for this channel
|
||||
* that matches the speed provided.
|
||||
*/
|
||||
|
||||
static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
|
||||
{
|
||||
struct hpt_clock *clocks = ap->host->private_data;
|
||||
|
||||
while(clocks->xfer_speed) {
|
||||
if (clocks->xfer_speed == speed)
|
||||
return clocks->timing;
|
||||
clocks++;
|
||||
}
|
||||
BUG();
|
||||
return 0xffffffffU; /* silence compiler warning */
|
||||
}
|
||||
|
||||
static int hpt36x_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
|
@ -226,6 +204,49 @@ static int hpt36x_cable_detect(struct ata_port *ap)
|
|||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev,
|
||||
u8 mode)
|
||||
{
|
||||
struct hpt_clock *clocks = ap->host->private_data;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
u32 addr2 = 0x51 + 4 * ap->port_no;
|
||||
u32 mask, reg;
|
||||
u8 fast;
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, addr2, &fast);
|
||||
if (fast & 0x80) {
|
||||
fast &= ~0x80;
|
||||
pci_write_config_byte(pdev, addr2, fast);
|
||||
}
|
||||
|
||||
/* determine timing mask and find matching clock entry */
|
||||
if (mode < XFER_MW_DMA_0)
|
||||
mask = 0xc1f8ffff;
|
||||
else if (mode < XFER_UDMA_0)
|
||||
mask = 0x303800ff;
|
||||
else
|
||||
mask = 0x30070000;
|
||||
|
||||
while (clocks->xfer_mode) {
|
||||
if (clocks->xfer_mode == mode)
|
||||
break;
|
||||
clocks++;
|
||||
}
|
||||
if (!clocks->xfer_mode)
|
||||
BUG();
|
||||
|
||||
/*
|
||||
* Combine new mode bits with old config bits and disable
|
||||
* on-chip PIO FIFO/buffer (and PIO MST mode as well) to avoid
|
||||
* problems handling I/O errors later.
|
||||
*/
|
||||
pci_read_config_dword(pdev, addr1, ®);
|
||||
reg = ((reg & ~mask) | (clocks->timing & mask)) & ~0xc0000000;
|
||||
pci_write_config_dword(pdev, addr1, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt366_set_piomode - PIO setup
|
||||
* @ap: ATA interface
|
||||
|
|
@ -236,28 +257,7 @@ static int hpt36x_cable_detect(struct ata_port *ap)
|
|||
|
||||
static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 addr1, addr2;
|
||||
u32 reg;
|
||||
u32 mode;
|
||||
u8 fast;
|
||||
|
||||
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
addr2 = 0x51 + 4 * ap->port_no;
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, addr2, &fast);
|
||||
if (fast & 0x80) {
|
||||
fast &= ~0x80;
|
||||
pci_write_config_byte(pdev, addr2, fast);
|
||||
}
|
||||
|
||||
pci_read_config_dword(pdev, addr1, ®);
|
||||
mode = hpt36x_find_mode(ap, adev->pio_mode);
|
||||
mode &= ~0x8000000; /* No FIFO in PIO */
|
||||
mode &= ~0x30070000; /* Leave config bits alone */
|
||||
reg &= 0x30070000; /* Strip timing bits */
|
||||
pci_write_config_dword(pdev, addr1, reg | mode);
|
||||
hpt366_set_mode(ap, adev, adev->pio_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -271,28 +271,7 @@ static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
|
||||
static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 addr1, addr2;
|
||||
u32 reg;
|
||||
u32 mode;
|
||||
u8 fast;
|
||||
|
||||
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
|
||||
addr2 = 0x51 + 4 * ap->port_no;
|
||||
|
||||
/* Fast interrupt prediction disable, hold off interrupt disable */
|
||||
pci_read_config_byte(pdev, addr2, &fast);
|
||||
if (fast & 0x80) {
|
||||
fast &= ~0x80;
|
||||
pci_write_config_byte(pdev, addr2, fast);
|
||||
}
|
||||
|
||||
pci_read_config_dword(pdev, addr1, ®);
|
||||
mode = hpt36x_find_mode(ap, adev->dma_mode);
|
||||
mode |= 0x8000000; /* FIFO in MWDMA or UDMA */
|
||||
mode &= ~0xC0000000; /* Leave config bits alone */
|
||||
reg &= 0xC0000000; /* Strip timing bits */
|
||||
pci_write_config_dword(pdev, addr1, reg | mode);
|
||||
hpt366_set_mode(ap, adev, adev->dma_mode);
|
||||
}
|
||||
|
||||
static struct scsi_host_template hpt36x_sht = {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_hpt3x3"
|
||||
#define DRV_VERSION "0.5.3"
|
||||
#define DRV_VERSION "0.6.1"
|
||||
|
||||
/**
|
||||
* hpt3x3_set_piomode - PIO setup
|
||||
|
|
@ -80,14 +80,48 @@ static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */
|
||||
|
||||
if (adev->dma_mode >= XFER_UDMA_0)
|
||||
r2 |= (0x10 << dn); /* Ultra mode */
|
||||
r2 |= (0x01 << dn); /* Ultra mode */
|
||||
else
|
||||
r2 |= (0x01 << dn); /* MWDMA */
|
||||
r2 |= (0x10 << dn); /* MWDMA */
|
||||
|
||||
pci_write_config_dword(pdev, 0x44, r1);
|
||||
pci_write_config_dword(pdev, 0x48, r2);
|
||||
}
|
||||
#endif /* CONFIG_PATA_HPT3X3_DMA */
|
||||
|
||||
/**
|
||||
* hpt3x3_freeze - DMA workaround
|
||||
* @ap: port to freeze
|
||||
*
|
||||
* When freezing an HPT3x3 we must stop any pending DMA before
|
||||
* writing to the control register or the chip will hang
|
||||
*/
|
||||
|
||||
static void hpt3x3_freeze(struct ata_port *ap)
|
||||
{
|
||||
void __iomem *mmio = ap->ioaddr.bmdma_addr;
|
||||
|
||||
iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ ATA_DMA_START,
|
||||
mmio + ATA_DMA_CMD);
|
||||
ata_sff_dma_pause(ap);
|
||||
ata_sff_freeze(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt3x3_bmdma_setup - DMA workaround
|
||||
* @qc: Queued command
|
||||
*
|
||||
* When issuing BMDMA we must clean up the error/active bits in
|
||||
* software on this device
|
||||
*/
|
||||
|
||||
static void hpt3x3_bmdma_setup(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
u8 r = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
r |= ATA_DMA_INTR | ATA_DMA_ERR;
|
||||
iowrite8(r, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
|
||||
return ata_bmdma_setup(qc);
|
||||
}
|
||||
|
||||
/**
|
||||
* hpt3x3_atapi_dma - ATAPI DMA check
|
||||
|
|
@ -101,18 +135,23 @@ static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PATA_HPT3X3_DMA */
|
||||
|
||||
static struct scsi_host_template hpt3x3_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
};
|
||||
|
||||
static struct ata_port_operations hpt3x3_port_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.check_atapi_dma= hpt3x3_atapi_dma,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
.set_piomode = hpt3x3_set_piomode,
|
||||
#if defined(CONFIG_PATA_HPT3X3_DMA)
|
||||
.set_dmamode = hpt3x3_set_dmamode,
|
||||
.bmdma_setup = hpt3x3_bmdma_setup,
|
||||
.check_atapi_dma= hpt3x3_atapi_dma,
|
||||
.freeze = hpt3x3_freeze,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -465,24 +465,22 @@ static int it821x_smart_set_mode(struct ata_link *link, struct ata_device **unus
|
|||
{
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->dma_mode = XFER_MW_DMA_0;
|
||||
/* We do need the right mode information for DMA or PIO
|
||||
and this comes from the current configuration flags */
|
||||
if (ata_id_has_dma(dev->id)) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for DMA\n");
|
||||
dev->xfer_mode = XFER_MW_DMA_0;
|
||||
dev->xfer_shift = ATA_SHIFT_MWDMA;
|
||||
dev->flags &= ~ATA_DFLAG_PIO;
|
||||
} else {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->dma_mode = XFER_MW_DMA_0;
|
||||
/* We do need the right mode information for DMA or PIO
|
||||
and this comes from the current configuration flags */
|
||||
if (ata_id_has_dma(dev->id)) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for DMA\n");
|
||||
dev->xfer_mode = XFER_MW_DMA_0;
|
||||
dev->xfer_shift = ATA_SHIFT_MWDMA;
|
||||
dev->flags &= ~ATA_DFLAG_PIO;
|
||||
} else {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -30,14 +30,12 @@ static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
|
|||
{
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,15 +194,12 @@ static int legacy_set_mode(struct ata_link *link, struct ata_device **unused)
|
|||
{
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
ata_dev_printk(dev, KERN_INFO,
|
||||
"configured for PIO\n");
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -641,7 +638,6 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
* qdi6580dp_set_piomode - PIO setup for dual channel
|
||||
* @ap: Port
|
||||
* @adev: Device
|
||||
* @irq: interrupt line
|
||||
*
|
||||
* In dual channel mode the 6580 has one clock per channel and we have
|
||||
* to software clockswitch in qc_issue.
|
||||
|
|
@ -1028,7 +1024,7 @@ static __init int legacy_init_one(struct legacy_probe *probe)
|
|||
/* Nothing found means we drop the port as its probably not there */
|
||||
|
||||
ret = -ENODEV;
|
||||
ata_link_for_each_dev(dev, &ap->link) {
|
||||
ata_for_each_dev(dev, &ap->link, ALL) {
|
||||
if (!ata_dev_absent(dev)) {
|
||||
legacy_host[probe->slot] = host;
|
||||
ld->platform_dev = pdev;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
|
||||
* Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
|
||||
*
|
||||
* UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
|
||||
* Domen Puncer and Tim Yamin.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
|
|
@ -17,28 +20,46 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
|
||||
#include <sysdev/bestcomm/bestcomm.h>
|
||||
#include <sysdev/bestcomm/bestcomm_priv.h>
|
||||
#include <sysdev/bestcomm/ata.h>
|
||||
|
||||
#define DRV_NAME "mpc52xx_ata"
|
||||
#define DRV_VERSION "0.1.2"
|
||||
|
||||
|
||||
/* Private structures used by the driver */
|
||||
struct mpc52xx_ata_timings {
|
||||
u32 pio1;
|
||||
u32 pio2;
|
||||
u32 mdma1;
|
||||
u32 mdma2;
|
||||
u32 udma1;
|
||||
u32 udma2;
|
||||
u32 udma3;
|
||||
u32 udma4;
|
||||
u32 udma5;
|
||||
int using_udma;
|
||||
};
|
||||
|
||||
struct mpc52xx_ata_priv {
|
||||
unsigned int ipb_period;
|
||||
struct mpc52xx_ata __iomem * ata_regs;
|
||||
struct mpc52xx_ata __iomem *ata_regs;
|
||||
phys_addr_t ata_regs_pa;
|
||||
int ata_irq;
|
||||
struct mpc52xx_ata_timings timings[2];
|
||||
int csel;
|
||||
|
||||
/* DMA */
|
||||
struct bcom_task *dmatsk;
|
||||
const struct udmaspec *udmaspec;
|
||||
const struct mdmaspec *mdmaspec;
|
||||
int mpc52xx_ata_dma_last_write;
|
||||
int waiting_for_dma;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -53,6 +74,107 @@ static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
|
|||
|
||||
#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
/* ATAPI-4 MDMA specs (in clocks) */
|
||||
struct mdmaspec {
|
||||
u32 t0M;
|
||||
u32 td;
|
||||
u32 th;
|
||||
u32 tj;
|
||||
u32 tkw;
|
||||
u32 tm;
|
||||
u32 tn;
|
||||
};
|
||||
|
||||
static const struct mdmaspec mdmaspec66[3] = {
|
||||
{ .t0M = 32, .td = 15, .th = 2, .tj = 2, .tkw = 15, .tm = 4, .tn = 1 },
|
||||
{ .t0M = 10, .td = 6, .th = 1, .tj = 1, .tkw = 4, .tm = 2, .tn = 1 },
|
||||
{ .t0M = 8, .td = 5, .th = 1, .tj = 1, .tkw = 2, .tm = 2, .tn = 1 },
|
||||
};
|
||||
|
||||
static const struct mdmaspec mdmaspec132[3] = {
|
||||
{ .t0M = 64, .td = 29, .th = 3, .tj = 3, .tkw = 29, .tm = 7, .tn = 2 },
|
||||
{ .t0M = 20, .td = 11, .th = 2, .tj = 1, .tkw = 7, .tm = 4, .tn = 1 },
|
||||
{ .t0M = 16, .td = 10, .th = 2, .tj = 1, .tkw = 4, .tm = 4, .tn = 1 },
|
||||
};
|
||||
|
||||
/* ATAPI-4 UDMA specs (in clocks) */
|
||||
struct udmaspec {
|
||||
u32 tcyc;
|
||||
u32 t2cyc;
|
||||
u32 tds;
|
||||
u32 tdh;
|
||||
u32 tdvs;
|
||||
u32 tdvh;
|
||||
u32 tfs;
|
||||
u32 tli;
|
||||
u32 tmli;
|
||||
u32 taz;
|
||||
u32 tzah;
|
||||
u32 tenv;
|
||||
u32 tsr;
|
||||
u32 trfs;
|
||||
u32 trp;
|
||||
u32 tack;
|
||||
u32 tss;
|
||||
};
|
||||
|
||||
static const struct udmaspec udmaspec66[6] = {
|
||||
{ .tcyc = 8, .t2cyc = 16, .tds = 1, .tdh = 1, .tdvs = 5, .tdvh = 1,
|
||||
.tfs = 16, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 3, .trfs = 5, .trp = 11, .tack = 2, .tss = 4,
|
||||
},
|
||||
{ .tcyc = 5, .t2cyc = 11, .tds = 1, .tdh = 1, .tdvs = 4, .tdvh = 1,
|
||||
.tfs = 14, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 2, .trfs = 5, .trp = 9, .tack = 2, .tss = 4,
|
||||
},
|
||||
{ .tcyc = 4, .t2cyc = 8, .tds = 1, .tdh = 1, .tdvs = 3, .tdvh = 1,
|
||||
.tfs = 12, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
|
||||
},
|
||||
{ .tcyc = 3, .t2cyc = 6, .tds = 1, .tdh = 1, .tdvs = 2, .tdvh = 1,
|
||||
.tfs = 9, .tli = 7, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
|
||||
},
|
||||
{ .tcyc = 2, .t2cyc = 4, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
|
||||
.tfs = 8, .tli = 8, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
|
||||
},
|
||||
{ .tcyc = 2, .t2cyc = 2, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
|
||||
.tfs = 6, .tli = 5, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 2, .trfs = 4, .trp = 6, .tack = 2, .tss = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct udmaspec udmaspec132[6] = {
|
||||
{ .tcyc = 15, .t2cyc = 31, .tds = 2, .tdh = 1, .tdvs = 10, .tdvh = 1,
|
||||
.tfs = 30, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
|
||||
.tsr = 7, .trfs = 10, .trp = 22, .tack = 3, .tss = 7,
|
||||
},
|
||||
{ .tcyc = 10, .t2cyc = 21, .tds = 2, .tdh = 1, .tdvs = 7, .tdvh = 1,
|
||||
.tfs = 27, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
|
||||
.tsr = 4, .trfs = 10, .trp = 17, .tack = 3, .tss = 7,
|
||||
},
|
||||
{ .tcyc = 6, .t2cyc = 12, .tds = 1, .tdh = 1, .tdvs = 5, .tdvh = 1,
|
||||
.tfs = 23, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
|
||||
.tsr = 3, .trfs = 8, .trp = 14, .tack = 3, .tss = 7,
|
||||
},
|
||||
{ .tcyc = 7, .t2cyc = 12, .tds = 1, .tdh = 1, .tdvs = 3, .tdvh = 1,
|
||||
.tfs = 15, .tli = 13, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
|
||||
.tsr = 3, .trfs = 8, .trp = 14, .tack = 3, .tss = 7,
|
||||
},
|
||||
{ .tcyc = 2, .t2cyc = 5, .tds = 0, .tdh = 0, .tdvs = 1, .tdvh = 1,
|
||||
.tfs = 16, .tli = 14, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
|
||||
.tsr = 2, .trfs = 7, .trp = 13, .tack = 2, .tss = 6,
|
||||
},
|
||||
{ .tcyc = 3, .t2cyc = 6, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
|
||||
.tfs = 12, .tli = 10, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
|
||||
.tsr = 3, .trfs = 7, .trp = 12, .tack = 3, .tss = 7,
|
||||
},
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
/* Bit definitions inside the registers */
|
||||
#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
|
||||
|
|
@ -66,6 +188,7 @@ static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
|
|||
#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
|
||||
|
||||
#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
|
||||
#define MPC52xx_ATA_FIFOSTAT_ERROR 0x40 /* FIFO Error */
|
||||
|
||||
#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
|
||||
#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
|
||||
|
|
@ -75,6 +198,8 @@ static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
|
|||
#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
|
||||
#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
|
||||
|
||||
#define MAX_DMA_BUFFERS 128
|
||||
#define MAX_DMA_BUFFER_SIZE 0x20000u
|
||||
|
||||
/* Structure of the hardware registers */
|
||||
struct mpc52xx_ata {
|
||||
|
|
@ -140,7 +265,6 @@ struct mpc52xx_ata {
|
|||
|
||||
|
||||
/* MPC52xx low level hw control */
|
||||
|
||||
static int
|
||||
mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
|
||||
{
|
||||
|
|
@ -148,7 +272,7 @@ mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
|
|||
unsigned int ipb_period = priv->ipb_period;
|
||||
unsigned int t0, t1, t2_8, t2_16, t2i, t4, ta;
|
||||
|
||||
if ((pio<0) || (pio>4))
|
||||
if ((pio < 0) || (pio > 4))
|
||||
return -EINVAL;
|
||||
|
||||
t0 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]);
|
||||
|
|
@ -165,6 +289,43 @@ mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpc52xx_ata_compute_mdma_timings(struct mpc52xx_ata_priv *priv, int dev,
|
||||
int speed)
|
||||
{
|
||||
struct mpc52xx_ata_timings *t = &priv->timings[dev];
|
||||
const struct mdmaspec *s = &priv->mdmaspec[speed];
|
||||
|
||||
if (speed < 0 || speed > 2)
|
||||
return -EINVAL;
|
||||
|
||||
t->mdma1 = (s->t0M << 24) | (s->td << 16) | (s->tkw << 8) | (s->tm);
|
||||
t->mdma2 = (s->th << 24) | (s->tj << 16) | (s->tn << 8);
|
||||
t->using_udma = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpc52xx_ata_compute_udma_timings(struct mpc52xx_ata_priv *priv, int dev,
|
||||
int speed)
|
||||
{
|
||||
struct mpc52xx_ata_timings *t = &priv->timings[dev];
|
||||
const struct udmaspec *s = &priv->udmaspec[speed];
|
||||
|
||||
if (speed < 0 || speed > 2)
|
||||
return -EINVAL;
|
||||
|
||||
t->udma1 = (s->t2cyc << 24) | (s->tcyc << 16) | (s->tds << 8) | s->tdh;
|
||||
t->udma2 = (s->tdvs << 24) | (s->tdvh << 16) | (s->tfs << 8) | s->tli;
|
||||
t->udma3 = (s->tmli << 24) | (s->taz << 16) | (s->tenv << 8) | s->tsr;
|
||||
t->udma4 = (s->tss << 24) | (s->trfs << 16) | (s->trp << 8) | s->tack;
|
||||
t->udma5 = (s->tzah << 24);
|
||||
t->using_udma = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
|
||||
{
|
||||
|
|
@ -173,14 +334,13 @@ mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
|
|||
|
||||
out_be32(®s->pio1, timing->pio1);
|
||||
out_be32(®s->pio2, timing->pio2);
|
||||
out_be32(®s->mdma1, 0);
|
||||
out_be32(®s->mdma2, 0);
|
||||
out_be32(®s->udma1, 0);
|
||||
out_be32(®s->udma2, 0);
|
||||
out_be32(®s->udma3, 0);
|
||||
out_be32(®s->udma4, 0);
|
||||
out_be32(®s->udma5, 0);
|
||||
|
||||
out_be32(®s->mdma1, timing->mdma1);
|
||||
out_be32(®s->mdma2, timing->mdma2);
|
||||
out_be32(®s->udma1, timing->udma1);
|
||||
out_be32(®s->udma2, timing->udma2);
|
||||
out_be32(®s->udma3, timing->udma3);
|
||||
out_be32(®s->udma4, timing->udma4);
|
||||
out_be32(®s->udma5, timing->udma5);
|
||||
priv->csel = device;
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +368,7 @@ mpc52xx_ata_hw_init(struct mpc52xx_ata_priv *priv)
|
|||
|
||||
/* Set the time slot to 1us */
|
||||
tslot = CALC_CLKCYC(priv->ipb_period, 1000000);
|
||||
out_be32(®s->share_cnt, tslot << 16 );
|
||||
out_be32(®s->share_cnt, tslot << 16);
|
||||
|
||||
/* Init timings to PIO0 */
|
||||
memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
|
||||
|
|
@ -237,13 +397,37 @@ mpc52xx_ata_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
|
||||
|
||||
if (rv) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
": Trying to select invalid PIO mode %d\n", pio);
|
||||
dev_err(ap->dev, "error: invalid PIO mode: %d\n", pio);
|
||||
return;
|
||||
}
|
||||
|
||||
mpc52xx_ata_apply_timings(priv, adev->devno);
|
||||
}
|
||||
|
||||
static void
|
||||
mpc52xx_ata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||
{
|
||||
struct mpc52xx_ata_priv *priv = ap->host->private_data;
|
||||
int rv;
|
||||
|
||||
if (adev->dma_mode >= XFER_UDMA_0) {
|
||||
int dma = adev->dma_mode - XFER_UDMA_0;
|
||||
rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma);
|
||||
} else {
|
||||
int dma = adev->dma_mode - XFER_MW_DMA_0;
|
||||
rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma);
|
||||
}
|
||||
|
||||
if (rv) {
|
||||
dev_alert(ap->dev,
|
||||
"Trying to select invalid DMA mode %d\n",
|
||||
adev->dma_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
mpc52xx_ata_apply_timings(priv, adev->devno);
|
||||
}
|
||||
|
||||
static void
|
||||
mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
|
||||
{
|
||||
|
|
@ -252,7 +436,173 @@ mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
|
|||
if (device != priv->csel)
|
||||
mpc52xx_ata_apply_timings(priv, device);
|
||||
|
||||
ata_sff_dev_select(ap,device);
|
||||
ata_sff_dev_select(ap, device);
|
||||
}
|
||||
|
||||
static int
|
||||
mpc52xx_ata_build_dmatable(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct mpc52xx_ata_priv *priv = ap->host->private_data;
|
||||
struct bcom_ata_bd *bd;
|
||||
unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE), si;
|
||||
struct scatterlist *sg;
|
||||
int count = 0;
|
||||
|
||||
if (read)
|
||||
bcom_ata_rx_prepare(priv->dmatsk);
|
||||
else
|
||||
bcom_ata_tx_prepare(priv->dmatsk);
|
||||
|
||||
for_each_sg(qc->sg, sg, qc->n_elem, si) {
|
||||
dma_addr_t cur_addr = sg_dma_address(sg);
|
||||
u32 cur_len = sg_dma_len(sg);
|
||||
|
||||
while (cur_len) {
|
||||
unsigned int tc = min(cur_len, MAX_DMA_BUFFER_SIZE);
|
||||
bd = (struct bcom_ata_bd *)
|
||||
bcom_prepare_next_buffer(priv->dmatsk);
|
||||
|
||||
if (read) {
|
||||
bd->status = tc;
|
||||
bd->src_pa = (__force u32) priv->ata_regs_pa +
|
||||
offsetof(struct mpc52xx_ata, fifo_data);
|
||||
bd->dst_pa = (__force u32) cur_addr;
|
||||
} else {
|
||||
bd->status = tc;
|
||||
bd->src_pa = (__force u32) cur_addr;
|
||||
bd->dst_pa = (__force u32) priv->ata_regs_pa +
|
||||
offsetof(struct mpc52xx_ata, fifo_data);
|
||||
}
|
||||
|
||||
bcom_submit_next_buffer(priv->dmatsk, NULL);
|
||||
|
||||
cur_addr += tc;
|
||||
cur_len -= tc;
|
||||
count++;
|
||||
|
||||
if (count > MAX_DMA_BUFFERS) {
|
||||
dev_alert(ap->dev, "dma table"
|
||||
"too small\n");
|
||||
goto use_pio_instead;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
use_pio_instead:
|
||||
bcom_ata_reset_bd(priv->dmatsk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mpc52xx_bmdma_setup(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct mpc52xx_ata_priv *priv = ap->host->private_data;
|
||||
struct mpc52xx_ata __iomem *regs = priv->ata_regs;
|
||||
|
||||
unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
|
||||
u8 dma_mode;
|
||||
|
||||
if (!mpc52xx_ata_build_dmatable(qc))
|
||||
dev_alert(ap->dev, "%s: %i, return 1?\n",
|
||||
__func__, __LINE__);
|
||||
|
||||
/* Check FIFO is OK... */
|
||||
if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
|
||||
dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
|
||||
__func__, in_8(&priv->ata_regs->fifo_status));
|
||||
|
||||
if (read) {
|
||||
dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_READ |
|
||||
MPC52xx_ATA_DMAMODE_FE;
|
||||
|
||||
/* Setup FIFO if direction changed */
|
||||
if (priv->mpc52xx_ata_dma_last_write != 0) {
|
||||
priv->mpc52xx_ata_dma_last_write = 0;
|
||||
|
||||
/* Configure FIFO with granularity to 7 */
|
||||
out_8(®s->fifo_control, 7);
|
||||
out_be16(®s->fifo_alarm, 128);
|
||||
|
||||
/* Set FIFO Reset bit (FR) */
|
||||
out_8(®s->dma_mode, MPC52xx_ATA_DMAMODE_FR);
|
||||
}
|
||||
} else {
|
||||
dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_WRITE;
|
||||
|
||||
/* Setup FIFO if direction changed */
|
||||
if (priv->mpc52xx_ata_dma_last_write != 1) {
|
||||
priv->mpc52xx_ata_dma_last_write = 1;
|
||||
|
||||
/* Configure FIFO with granularity to 4 */
|
||||
out_8(®s->fifo_control, 4);
|
||||
out_be16(®s->fifo_alarm, 128);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->timings[qc->dev->devno].using_udma)
|
||||
dma_mode |= MPC52xx_ATA_DMAMODE_UDMA;
|
||||
|
||||
out_8(®s->dma_mode, dma_mode);
|
||||
priv->waiting_for_dma = ATA_DMA_ACTIVE;
|
||||
|
||||
ata_wait_idle(ap);
|
||||
ap->ops->sff_exec_command(ap, &qc->tf);
|
||||
}
|
||||
|
||||
static void
|
||||
mpc52xx_bmdma_start(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct mpc52xx_ata_priv *priv = ap->host->private_data;
|
||||
|
||||
bcom_set_task_auto_start(priv->dmatsk->tasknum, priv->dmatsk->tasknum);
|
||||
bcom_enable(priv->dmatsk);
|
||||
}
|
||||
|
||||
static void
|
||||
mpc52xx_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct mpc52xx_ata_priv *priv = ap->host->private_data;
|
||||
|
||||
bcom_disable(priv->dmatsk);
|
||||
bcom_ata_reset_bd(priv->dmatsk);
|
||||
priv->waiting_for_dma = 0;
|
||||
|
||||
/* Check FIFO is OK... */
|
||||
if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
|
||||
dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
|
||||
__func__, in_8(&priv->ata_regs->fifo_status));
|
||||
}
|
||||
|
||||
static u8
|
||||
mpc52xx_bmdma_status(struct ata_port *ap)
|
||||
{
|
||||
struct mpc52xx_ata_priv *priv = ap->host->private_data;
|
||||
|
||||
/* Check FIFO is OK... */
|
||||
if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) {
|
||||
dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
|
||||
__func__, in_8(&priv->ata_regs->fifo_status));
|
||||
return priv->waiting_for_dma | ATA_DMA_ERR;
|
||||
}
|
||||
|
||||
return priv->waiting_for_dma;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
mpc52xx_ata_task_irq(int irq, void *vpriv)
|
||||
{
|
||||
struct mpc52xx_ata_priv *priv = vpriv;
|
||||
while (bcom_buffer_done(priv->dmatsk))
|
||||
bcom_retrieve_buffer(priv->dmatsk, NULL, NULL);
|
||||
|
||||
priv->waiting_for_dma |= ATA_DMA_INTR;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct scsi_host_template mpc52xx_ata_sht = {
|
||||
|
|
@ -262,14 +612,18 @@ static struct scsi_host_template mpc52xx_ata_sht = {
|
|||
static struct ata_port_operations mpc52xx_ata_port_ops = {
|
||||
.inherits = &ata_sff_port_ops,
|
||||
.sff_dev_select = mpc52xx_ata_dev_select,
|
||||
.cable_detect = ata_cable_40wire,
|
||||
.set_piomode = mpc52xx_ata_set_piomode,
|
||||
.post_internal_cmd = ATA_OP_NULL,
|
||||
.set_dmamode = mpc52xx_ata_set_dmamode,
|
||||
.bmdma_setup = mpc52xx_bmdma_setup,
|
||||
.bmdma_start = mpc52xx_bmdma_start,
|
||||
.bmdma_stop = mpc52xx_bmdma_stop,
|
||||
.bmdma_status = mpc52xx_bmdma_status,
|
||||
.qc_prep = ata_noop_qc_prep,
|
||||
};
|
||||
|
||||
static int __devinit
|
||||
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
|
||||
unsigned long raw_ata_regs)
|
||||
unsigned long raw_ata_regs, int mwdma_mask, int udma_mask)
|
||||
{
|
||||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
|
|
@ -281,9 +635,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
|
|||
|
||||
ap = host->ports[0];
|
||||
ap->flags |= ATA_FLAG_SLAVE_POSS;
|
||||
ap->pio_mask = 0x1f; /* Up to PIO4 */
|
||||
ap->mwdma_mask = 0x00; /* No MWDMA */
|
||||
ap->udma_mask = 0x00; /* No UDMA */
|
||||
ap->pio_mask = ATA_PIO4;
|
||||
ap->mwdma_mask = mwdma_mask;
|
||||
ap->udma_mask = udma_mask;
|
||||
ap->ops = &mpc52xx_ata_port_ops;
|
||||
host->private_data = priv;
|
||||
|
||||
|
|
@ -330,89 +684,139 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
|
|||
{
|
||||
unsigned int ipb_freq;
|
||||
struct resource res_mem;
|
||||
int ata_irq;
|
||||
int ata_irq = 0;
|
||||
struct mpc52xx_ata __iomem *ata_regs;
|
||||
struct mpc52xx_ata_priv *priv;
|
||||
int rv;
|
||||
struct mpc52xx_ata_priv *priv = NULL;
|
||||
int rv, ret, task_irq = 0;
|
||||
int mwdma_mask = 0, udma_mask = 0;
|
||||
const __be32 *prop;
|
||||
int proplen;
|
||||
struct bcom_task *dmatsk = NULL;
|
||||
|
||||
/* Get ipb frequency */
|
||||
ipb_freq = mpc52xx_find_ipb_freq(op->node);
|
||||
if (!ipb_freq) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Unable to find IPB Bus frequency\n" );
|
||||
dev_err(&op->dev, "could not determine IPB bus frequency\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Get IRQ and register */
|
||||
/* Get device base address from device tree, request the region
|
||||
* and ioremap it. */
|
||||
rv = of_address_to_resource(op->node, 0, &res_mem);
|
||||
if (rv) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while parsing device node resource\n" );
|
||||
dev_err(&op->dev, "could not determine device base address\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
ata_irq = irq_of_parse_and_map(op->node, 0);
|
||||
if (ata_irq == NO_IRQ) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while mapping the irq\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Request mem region */
|
||||
if (!devm_request_mem_region(&op->dev, res_mem.start,
|
||||
sizeof(struct mpc52xx_ata), DRV_NAME)) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while requesting mem region\n");
|
||||
rv = -EBUSY;
|
||||
goto err;
|
||||
sizeof(*ata_regs), DRV_NAME)) {
|
||||
dev_err(&op->dev, "error requesting register region\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Remap registers */
|
||||
ata_regs = devm_ioremap(&op->dev, res_mem.start,
|
||||
sizeof(struct mpc52xx_ata));
|
||||
ata_regs = devm_ioremap(&op->dev, res_mem.start, sizeof(*ata_regs));
|
||||
if (!ata_regs) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while mapping register set\n");
|
||||
dev_err(&op->dev, "error mapping device registers\n");
|
||||
rv = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* By default, all DMA modes are disabled for the MPC5200. Some
|
||||
* boards don't have the required signals routed to make DMA work.
|
||||
* Also, the MPC5200B has a silicon bug that causes data corruption
|
||||
* with UDMA if it is used at the same time as the LocalPlus bus.
|
||||
*
|
||||
* Instead of trying to guess what modes are usable, check the
|
||||
* ATA device tree node to find out what DMA modes work on the board.
|
||||
* UDMA/MWDMA modes can also be forced by adding "libata.force=<mode>"
|
||||
* to the kernel boot parameters.
|
||||
*
|
||||
* The MPC5200 ATA controller supports MWDMA modes 0, 1 and 2 and
|
||||
* UDMA modes 0, 1 and 2.
|
||||
*/
|
||||
prop = of_get_property(op->node, "mwdma-mode", &proplen);
|
||||
if ((prop) && (proplen >= 4))
|
||||
mwdma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
|
||||
prop = of_get_property(op->node, "udma-mode", &proplen);
|
||||
if ((prop) && (proplen >= 4))
|
||||
udma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
|
||||
|
||||
ata_irq = irq_of_parse_and_map(op->node, 0);
|
||||
if (ata_irq == NO_IRQ) {
|
||||
dev_err(&op->dev, "error mapping irq\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Prepare our private structure */
|
||||
priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
|
||||
GFP_ATOMIC);
|
||||
priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_ATOMIC);
|
||||
if (!priv) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while allocating private structure\n");
|
||||
dev_err(&op->dev, "error allocating private structure\n");
|
||||
rv = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
priv->ipb_period = 1000000000 / (ipb_freq / 1000);
|
||||
priv->ata_regs = ata_regs;
|
||||
priv->ata_regs_pa = res_mem.start;
|
||||
priv->ata_irq = ata_irq;
|
||||
priv->csel = -1;
|
||||
priv->mpc52xx_ata_dma_last_write = -1;
|
||||
|
||||
if (ipb_freq/1000000 == 66) {
|
||||
priv->mdmaspec = mdmaspec66;
|
||||
priv->udmaspec = udmaspec66;
|
||||
} else {
|
||||
priv->mdmaspec = mdmaspec132;
|
||||
priv->udmaspec = udmaspec132;
|
||||
}
|
||||
|
||||
/* Allocate a BestComm task for DMA */
|
||||
dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
|
||||
if (!dmatsk) {
|
||||
dev_err(&op->dev, "bestcomm initialization failed\n");
|
||||
rv = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
task_irq = bcom_get_task_irq(dmatsk);
|
||||
ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED,
|
||||
"ATA task", priv);
|
||||
if (ret) {
|
||||
dev_err(&op->dev, "error requesting DMA IRQ\n");
|
||||
goto err;
|
||||
}
|
||||
priv->dmatsk = dmatsk;
|
||||
|
||||
/* Init the hw */
|
||||
rv = mpc52xx_ata_hw_init(priv);
|
||||
if (rv) {
|
||||
printk(KERN_ERR DRV_NAME ": Error during HW init\n");
|
||||
dev_err(&op->dev, "error initializing hardware\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Register ourselves to libata */
|
||||
rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start);
|
||||
rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start,
|
||||
mwdma_mask, udma_mask);
|
||||
if (rv) {
|
||||
printk(KERN_ERR DRV_NAME ": "
|
||||
"Error while registering to ATA layer\n");
|
||||
return rv;
|
||||
dev_err(&op->dev, "error registering with ATA layer\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return 0;
|
||||
|
||||
/* Error path */
|
||||
err:
|
||||
irq_dispose_mapping(ata_irq);
|
||||
err:
|
||||
devm_release_mem_region(&op->dev, res_mem.start, sizeof(*ata_regs));
|
||||
if (ata_irq)
|
||||
irq_dispose_mapping(ata_irq);
|
||||
if (task_irq)
|
||||
irq_dispose_mapping(task_irq);
|
||||
if (dmatsk)
|
||||
bcom_ata_release(dmatsk);
|
||||
if (ata_regs)
|
||||
devm_iounmap(&op->dev, ata_regs);
|
||||
if (priv)
|
||||
devm_kfree(&op->dev, priv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -420,10 +824,23 @@ static int
|
|||
mpc52xx_ata_remove(struct of_device *op)
|
||||
{
|
||||
struct mpc52xx_ata_priv *priv;
|
||||
int task_irq;
|
||||
|
||||
/* Deregister the ATA interface */
|
||||
priv = mpc52xx_ata_remove_one(&op->dev);
|
||||
|
||||
/* Clean up DMA */
|
||||
task_irq = bcom_get_task_irq(priv->dmatsk);
|
||||
irq_dispose_mapping(task_irq);
|
||||
bcom_ata_release(priv->dmatsk);
|
||||
irq_dispose_mapping(priv->ata_irq);
|
||||
|
||||
/* Clear up IO allocations */
|
||||
devm_iounmap(&op->dev, priv->ata_regs);
|
||||
devm_release_mem_region(&op->dev, priv->ata_regs_pa,
|
||||
sizeof(*priv->ata_regs));
|
||||
devm_kfree(&op->dev, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -447,7 +864,7 @@ mpc52xx_ata_resume(struct of_device *op)
|
|||
|
||||
rv = mpc52xx_ata_hw_init(priv);
|
||||
if (rv) {
|
||||
printk(KERN_ERR DRV_NAME ": Error during HW init\n");
|
||||
dev_err(host->dev, "error initializing hardware\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -507,5 +924,4 @@ MODULE_AUTHOR("Sylvain Munaut <[email protected]>");
|
|||
MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_mpiix"
|
||||
#define DRV_VERSION "0.7.6"
|
||||
#define DRV_VERSION "0.7.7"
|
||||
|
||||
enum {
|
||||
IDETIM = 0x6C, /* IDE control register */
|
||||
|
|
@ -146,6 +146,7 @@ static struct ata_port_operations mpiix_port_ops = {
|
|||
.cable_detect = ata_cable_40wire,
|
||||
.set_piomode = mpiix_set_piomode,
|
||||
.prereset = mpiix_pre_reset,
|
||||
.sff_data_xfer = ata_sff_data_xfer32,
|
||||
};
|
||||
|
||||
static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev)
|
|||
* oldpiix_set_dmamode - Initialize host controller PATA DMA timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: Device to program
|
||||
* @isich: True if the device is an ICH and has IOCFG registers
|
||||
*
|
||||
* Set MWDMA mode for device, in host controller PCI config space.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -281,7 +281,6 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long
|
|||
* pdc2027x_set_piomode - Initialize host controller PATA PIO timings
|
||||
* @ap: Port to configure
|
||||
* @adev: um
|
||||
* @pio: PIO mode, 0 - 4
|
||||
*
|
||||
* Set PIO mode for device.
|
||||
*
|
||||
|
|
@ -326,7 +325,6 @@ static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
|||
* pdc2027x_set_dmamode - Initialize host controller PATA UDMA timings
|
||||
* @ap: Port to configure
|
||||
* @adev: um
|
||||
* @udma: udma mode, XFER_UDMA_0 to XFER_UDMA_6
|
||||
*
|
||||
* Set UDMA mode for device.
|
||||
*
|
||||
|
|
@ -406,23 +404,20 @@ static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
pdc2027x_set_piomode(ap, dev);
|
||||
|
||||
pdc2027x_set_piomode(ap, dev);
|
||||
/*
|
||||
* Enable prefetch if the device support PIO only.
|
||||
*/
|
||||
if (dev->xfer_shift == ATA_SHIFT_PIO) {
|
||||
u32 ctcr1 = ioread32(dev_mmio(ap, dev, PDC_CTCR1));
|
||||
ctcr1 |= (1 << 25);
|
||||
iowrite32(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
|
||||
|
||||
/*
|
||||
* Enable prefetch if the device support PIO only.
|
||||
*/
|
||||
if (dev->xfer_shift == ATA_SHIFT_PIO) {
|
||||
u32 ctcr1 = ioread32(dev_mmio(ap, dev, PDC_CTCR1));
|
||||
ctcr1 |= (1 << 25);
|
||||
iowrite32(ctcr1, dev_mmio(ap, dev, PDC_CTCR1));
|
||||
|
||||
PDPRINTK("Turn on prefetch\n");
|
||||
} else {
|
||||
pdc2027x_set_dmamode(ap, dev);
|
||||
}
|
||||
PDPRINTK("Turn on prefetch\n");
|
||||
} else {
|
||||
pdc2027x_set_dmamode(ap, dev);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -34,14 +34,12 @@ static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unu
|
|||
{
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
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;
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
}
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
/* 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;
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -188,7 +186,7 @@ EXPORT_SYMBOL_GPL(__pata_platform_probe);
|
|||
* A platform bus ATA device has been unplugged. Perform the needed
|
||||
* cleanup. Also called on module unload for any active devices.
|
||||
*/
|
||||
int __devexit __pata_platform_remove(struct device *dev)
|
||||
int __pata_platform_remove(struct device *dev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ static void radisys_set_piomode (struct ata_port *ap, struct ata_device *adev)
|
|||
* radisys_set_dmamode - Initialize host controller PATA DMA timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: Device to program
|
||||
* @isich: True if the device is an ICH and has IOCFG registers
|
||||
*
|
||||
* Set MWDMA mode for device, in host controller PCI config space.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -38,15 +38,13 @@ static int rz1000_set_mode(struct ata_link *link, struct ata_device **unused)
|
|||
{
|
||||
struct ata_device *dev;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (ata_dev_enabled(dev)) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
}
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
/* We don't really care */
|
||||
dev->pio_mode = XFER_PIO_0;
|
||||
dev->xfer_mode = XFER_PIO_0;
|
||||
dev->xfer_shift = ATA_SHIFT_PIO;
|
||||
dev->flags |= ATA_DFLAG_PIO;
|
||||
ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,6 @@ static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev)
|
|||
* scc_set_dmamode - Initialize host controller PATA DMA timings
|
||||
* @ap: Port whose timings we are configuring
|
||||
* @adev: um
|
||||
* @udma: udma mode, 0 - 6
|
||||
*
|
||||
* Set UDMA mode for device.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ static struct sv_cable_table cable_detect[] = {
|
|||
/**
|
||||
* serverworks_cable_detect - cable detection
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection according to the device and subvendor
|
||||
* identifications
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "pata_sil680"
|
||||
#define DRV_VERSION "0.4.8"
|
||||
#define DRV_VERSION "0.4.9"
|
||||
|
||||
#define SIL680_MMIO_BAR 5
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ static struct scsi_host_template sil680_sht = {
|
|||
};
|
||||
|
||||
static struct ata_port_operations sil680_port_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.inherits = &ata_bmdma32_port_ops,
|
||||
.cable_detect = sil680_cable_detect,
|
||||
.set_piomode = sil680_set_piomode,
|
||||
.set_dmamode = sil680_set_dmamode,
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ static int sis_133_cable_detect(struct ata_port *ap)
|
|||
/**
|
||||
* sis_66_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection on the UDMA66, UDMA100 and early UDMA133
|
||||
* SiS IDE controllers.
|
||||
|
|
|
|||
|
|
@ -1836,7 +1836,6 @@ static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled)
|
|||
/**
|
||||
* mv_err_intr - Handle error interrupts on the port
|
||||
* @ap: ATA channel to manipulate
|
||||
* @qc: affected command (non-NCQ), or NULL
|
||||
*
|
||||
* Most cases require a full reset of the chip's state machine,
|
||||
* which also performs a COMRESET.
|
||||
|
|
|
|||
|
|
@ -46,7 +46,9 @@
|
|||
#include <linux/libata.h>
|
||||
|
||||
#define DRV_NAME "sata_sil"
|
||||
#define DRV_VERSION "2.3"
|
||||
#define DRV_VERSION "2.4"
|
||||
|
||||
#define SIL_DMA_BOUNDARY 0x7fffffffUL
|
||||
|
||||
enum {
|
||||
SIL_MMIO_BAR = 5,
|
||||
|
|
@ -118,6 +120,10 @@ static void sil_dev_config(struct ata_device *dev);
|
|||
static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
|
||||
static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
|
||||
static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed);
|
||||
static void sil_qc_prep(struct ata_queued_cmd *qc);
|
||||
static void sil_bmdma_setup(struct ata_queued_cmd *qc);
|
||||
static void sil_bmdma_start(struct ata_queued_cmd *qc);
|
||||
static void sil_bmdma_stop(struct ata_queued_cmd *qc);
|
||||
static void sil_freeze(struct ata_port *ap);
|
||||
static void sil_thaw(struct ata_port *ap);
|
||||
|
||||
|
|
@ -167,13 +173,22 @@ static struct pci_driver sil_pci_driver = {
|
|||
};
|
||||
|
||||
static struct scsi_host_template sil_sht = {
|
||||
ATA_BMDMA_SHT(DRV_NAME),
|
||||
ATA_BASE_SHT(DRV_NAME),
|
||||
/** These controllers support Large Block Transfer which allows
|
||||
transfer chunks up to 2GB and which cross 64KB boundaries,
|
||||
therefore the DMA limits are more relaxed than standard ATA SFF. */
|
||||
.dma_boundary = SIL_DMA_BOUNDARY,
|
||||
.sg_tablesize = ATA_MAX_PRD
|
||||
};
|
||||
|
||||
static struct ata_port_operations sil_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.dev_config = sil_dev_config,
|
||||
.set_mode = sil_set_mode,
|
||||
.bmdma_setup = sil_bmdma_setup,
|
||||
.bmdma_start = sil_bmdma_start,
|
||||
.bmdma_stop = sil_bmdma_stop,
|
||||
.qc_prep = sil_qc_prep,
|
||||
.freeze = sil_freeze,
|
||||
.thaw = sil_thaw,
|
||||
.scr_read = sil_scr_read,
|
||||
|
|
@ -249,6 +264,83 @@ module_param(slow_down, int, 0444);
|
|||
MODULE_PARM_DESC(slow_down, "Sledgehammer used to work around random problems, by limiting commands to 15 sectors (0=off, 1=on)");
|
||||
|
||||
|
||||
static void sil_bmdma_stop(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
|
||||
void __iomem *bmdma2 = mmio_base + sil_port[ap->port_no].bmdma2;
|
||||
|
||||
/* clear start/stop bit - can safely always write 0 */
|
||||
iowrite8(0, bmdma2);
|
||||
|
||||
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
|
||||
ata_sff_dma_pause(ap);
|
||||
}
|
||||
|
||||
static void sil_bmdma_setup(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *bmdma = ap->ioaddr.bmdma_addr;
|
||||
|
||||
/* load PRD table addr. */
|
||||
iowrite32(ap->prd_dma, bmdma + ATA_DMA_TABLE_OFS);
|
||||
|
||||
/* issue r/w command */
|
||||
ap->ops->sff_exec_command(ap, &qc->tf);
|
||||
}
|
||||
|
||||
static void sil_bmdma_start(struct ata_queued_cmd *qc)
|
||||
{
|
||||
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
|
||||
struct ata_port *ap = qc->ap;
|
||||
void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
|
||||
void __iomem *bmdma2 = mmio_base + sil_port[ap->port_no].bmdma2;
|
||||
u8 dmactl = ATA_DMA_START;
|
||||
|
||||
/* set transfer direction, start host DMA transaction
|
||||
Note: For Large Block Transfer to work, the DMA must be started
|
||||
using the bmdma2 register. */
|
||||
if (!rw)
|
||||
dmactl |= ATA_DMA_WR;
|
||||
iowrite8(dmactl, bmdma2);
|
||||
}
|
||||
|
||||
/* The way God intended PCI IDE scatter/gather lists to look and behave... */
|
||||
static void sil_fill_sg(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
struct ata_port *ap = qc->ap;
|
||||
struct ata_prd *prd, *last_prd = NULL;
|
||||
unsigned int si;
|
||||
|
||||
prd = &ap->prd[0];
|
||||
for_each_sg(qc->sg, sg, qc->n_elem, si) {
|
||||
/* Note h/w doesn't support 64-bit, so we unconditionally
|
||||
* truncate dma_addr_t to u32.
|
||||
*/
|
||||
u32 addr = (u32) sg_dma_address(sg);
|
||||
u32 sg_len = sg_dma_len(sg);
|
||||
|
||||
prd->addr = cpu_to_le32(addr);
|
||||
prd->flags_len = cpu_to_le32(sg_len);
|
||||
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, sg_len);
|
||||
|
||||
last_prd = prd;
|
||||
prd++;
|
||||
}
|
||||
|
||||
if (likely(last_prd))
|
||||
last_prd->flags_len |= cpu_to_le32(ATA_PRD_EOT);
|
||||
}
|
||||
|
||||
static void sil_qc_prep(struct ata_queued_cmd *qc)
|
||||
{
|
||||
if (!(qc->flags & ATA_QCFLAG_DMAMAP))
|
||||
return;
|
||||
|
||||
sil_fill_sg(qc);
|
||||
}
|
||||
|
||||
static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
|
||||
{
|
||||
u8 cache_line = 0;
|
||||
|
|
@ -278,7 +370,7 @@ static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
ata_for_each_dev(dev, link, ALL) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
dev_mode[dev->devno] = 0; /* PIO0/1/2 */
|
||||
else if (dev->flags & ATA_DFLAG_PIO)
|
||||
|
|
|
|||
|
|
@ -51,13 +51,6 @@ struct sil24_sge {
|
|||
__le32 flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* Port multiplier
|
||||
*/
|
||||
struct sil24_port_multiplier {
|
||||
__le32 diag;
|
||||
__le32 sactive;
|
||||
};
|
||||
|
||||
enum {
|
||||
SIL24_HOST_BAR = 0,
|
||||
|
|
|
|||
Loading…
Reference in a new issue