Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 127705
b: refs/heads/master
c: 2852bcf
h: refs/heads/master
i:
  127703: 4cd304e
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Jan 8, 2009
1 parent 68137b9 commit 5555824
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fc80902fdf4219a81eccca4a06259c4b56812ba5
refs/heads/master: 2852bcf7c12d3027c5d10f4f5ca5fada24ce8088
49 changes: 34 additions & 15 deletions trunk/drivers/ata/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
Expand Down Expand Up @@ -1350,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[] = {
{
Expand All @@ -1367,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;
Expand All @@ -1376,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));
}
}

Expand Down Expand Up @@ -1430,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.
Expand All @@ -1441,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]);
Expand All @@ -1463,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.
Expand All @@ -1488,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;
Expand Down

0 comments on commit 5555824

Please sign in to comment.