Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev: (21 commits) libata: remove irq_on from ata_bus_reset() and ata_std_postreset() ata_piix: kill incorrect invalid map value warning libata: add another Maxtor drive with broken NCQ to the list [libata] sata_mv: Fix and clean up per-chip-generation tests [libata] sata_mv: Convert to new exception handling (EH) infrastructure [libata] sata_mv: minor bug fixes, enhancements, and cleanups (prep for new EH) [libata] sata_mv: Minor cleanups and renaming, preparing for new EH & NCQ libata-link: add PMP related ATA constants libata-link: separate out ata_eh_handle_dev_fail() pata_hpt3x3: fix DMA Kconfig option to actually have a hope of working Add Hitachi HDS7250SASUN500G 0621KTAWSD to NCQ blacklist pata_scc.c: Workaround for errata A308 libata: add FUJITSU MHV2080BH to NCQ blacklist pata_hpt3x3: major reworking and testing libata: clean up horkage handling libata: quirk IOMEGA ZIP 250 ATAPI FLOPPY libata: simplify PCI legacy SFF host handling pata_mpc52xx: suspend/resume support sata_promise: SATA hotplug support, take 2 pata_sis: FIFO whack ...
This commit is contained in:
commit
57399ec907
|
@ -309,7 +309,7 @@ config PATA_HPT3X2N
|
||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
config PATA_HPT3X3
|
config PATA_HPT3X3
|
||||||
tristate "HPT 343/363 PATA support (Experimental)"
|
tristate "HPT 343/363 PATA support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
help
|
help
|
||||||
This option enables support for the HPT 343/363
|
This option enables support for the HPT 343/363
|
||||||
|
@ -317,6 +317,14 @@ config PATA_HPT3X3
|
||||||
|
|
||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
|
config PATA_HPT3X3_DMA
|
||||||
|
bool "HPT 343/363 DMA support (Experimental)"
|
||||||
|
depends on PATA_HPT3X3
|
||||||
|
help
|
||||||
|
This option enables DMA support for the HPT343/363
|
||||||
|
controllers. Enable with care as there are still some
|
||||||
|
problems with DMA on this chipset.
|
||||||
|
|
||||||
config PATA_ISAPNP
|
config PATA_ISAPNP
|
||||||
tristate "ISA Plug and Play PATA support (Experimental)"
|
tristate "ISA Plug and Play PATA support (Experimental)"
|
||||||
depends on EXPERIMENTAL && ISAPNP
|
depends on EXPERIMENTAL && ISAPNP
|
||||||
|
|
|
@ -414,7 +414,7 @@ static const struct piix_map_db ich6m_map_db = {
|
||||||
*/
|
*/
|
||||||
.map = {
|
.map = {
|
||||||
/* PM PS SM SS MAP */
|
/* PM PS SM SS MAP */
|
||||||
{ P0, P2, RV, RV }, /* 00b */
|
{ P0, P2, NA, NA }, /* 00b */
|
||||||
{ IDE, IDE, P1, P3 }, /* 01b */
|
{ IDE, IDE, P1, P3 }, /* 01b */
|
||||||
{ P0, P2, IDE, IDE }, /* 10b */
|
{ P0, P2, IDE, IDE }, /* 10b */
|
||||||
{ RV, RV, RV, RV },
|
{ RV, RV, RV, RV },
|
||||||
|
|
|
@ -71,6 +71,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
|
||||||
u16 heads, u16 sectors);
|
u16 heads, u16 sectors);
|
||||||
static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
|
static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
|
||||||
static void ata_dev_xfermask(struct ata_device *dev);
|
static void ata_dev_xfermask(struct ata_device *dev);
|
||||||
|
static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
|
||||||
|
|
||||||
unsigned int ata_print_id = 1;
|
unsigned int ata_print_id = 1;
|
||||||
static struct workqueue_struct *ata_wq;
|
static struct workqueue_struct *ata_wq;
|
||||||
|
@ -1283,18 +1284,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
|
||||||
void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
|
void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
|
||||||
unsigned long delay)
|
unsigned long delay)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PREPARE_DELAYED_WORK(&ap->port_task, fn);
|
PREPARE_DELAYED_WORK(&ap->port_task, fn);
|
||||||
ap->port_task_data = data;
|
ap->port_task_data = data;
|
||||||
|
|
||||||
rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
|
/* may fail if ata_port_flush_task() in progress */
|
||||||
|
queue_delayed_work(ata_wq, &ap->port_task, delay);
|
||||||
/* rc == 0 means that another user is using port task */
|
|
||||||
WARN_ON(rc == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1309,32 +1303,9 @@ void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
|
||||||
*/
|
*/
|
||||||
void ata_port_flush_task(struct ata_port *ap)
|
void ata_port_flush_task(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
DPRINTK("ENTER\n");
|
DPRINTK("ENTER\n");
|
||||||
|
|
||||||
spin_lock_irqsave(ap->lock, flags);
|
cancel_rearming_delayed_work(&ap->port_task);
|
||||||
ap->pflags |= ATA_PFLAG_FLUSH_PORT_TASK;
|
|
||||||
spin_unlock_irqrestore(ap->lock, flags);
|
|
||||||
|
|
||||||
DPRINTK("flush #1\n");
|
|
||||||
cancel_work_sync(&ap->port_task.work); /* akpm: seems unneeded */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* At this point, if a task is running, it's guaranteed to see
|
|
||||||
* the FLUSH flag; thus, it will never queue pio tasks again.
|
|
||||||
* Cancel and flush.
|
|
||||||
*/
|
|
||||||
if (!cancel_delayed_work(&ap->port_task)) {
|
|
||||||
if (ata_msg_ctl(ap))
|
|
||||||
ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
cancel_work_sync(&ap->port_task.work);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(ap->lock, flags);
|
|
||||||
ap->pflags &= ~ATA_PFLAG_FLUSH_PORT_TASK;
|
|
||||||
spin_unlock_irqrestore(ap->lock, flags);
|
|
||||||
|
|
||||||
if (ata_msg_ctl(ap))
|
if (ata_msg_ctl(ap))
|
||||||
ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
|
ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
|
||||||
|
@ -1814,7 +1785,7 @@ static void ata_dev_config_ncq(struct ata_device *dev,
|
||||||
desc[0] = '\0';
|
desc[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
|
if (dev->horkage & ATA_HORKAGE_NONCQ) {
|
||||||
snprintf(desc, desc_sz, "NCQ (not used)");
|
snprintf(desc, desc_sz, "NCQ (not used)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1863,6 +1834,9 @@ int ata_dev_configure(struct ata_device *dev)
|
||||||
if (ata_msg_probe(ap))
|
if (ata_msg_probe(ap))
|
||||||
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
|
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
|
||||||
|
|
||||||
|
/* set horkage */
|
||||||
|
dev->horkage |= ata_dev_blacklisted(dev);
|
||||||
|
|
||||||
/* let ACPI work its magic */
|
/* let ACPI work its magic */
|
||||||
rc = ata_acpi_on_devcfg(dev);
|
rc = ata_acpi_on_devcfg(dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -2038,7 +2012,7 @@ int ata_dev_configure(struct ata_device *dev)
|
||||||
dev->max_sectors = ATA_MAX_SECTORS;
|
dev->max_sectors = ATA_MAX_SECTORS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128)
|
if (dev->horkage & ATA_HORKAGE_MAX_SEC_128)
|
||||||
dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
|
dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
|
||||||
dev->max_sectors);
|
dev->max_sectors);
|
||||||
|
|
||||||
|
@ -3190,9 +3164,6 @@ void ata_bus_reset(struct ata_port *ap)
|
||||||
if ((slave_possible) && (err != 0x81))
|
if ((slave_possible) && (err != 0x81))
|
||||||
ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
|
ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
|
||||||
|
|
||||||
/* re-enable interrupts */
|
|
||||||
ap->ops->irq_on(ap);
|
|
||||||
|
|
||||||
/* is double-select really necessary? */
|
/* is double-select really necessary? */
|
||||||
if (ap->device[1].class != ATA_DEV_NONE)
|
if (ap->device[1].class != ATA_DEV_NONE)
|
||||||
ap->ops->dev_select(ap, 1);
|
ap->ops->dev_select(ap, 1);
|
||||||
|
@ -3577,10 +3548,6 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
|
||||||
if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
|
if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
|
||||||
sata_scr_write(ap, SCR_ERROR, serror);
|
sata_scr_write(ap, SCR_ERROR, serror);
|
||||||
|
|
||||||
/* re-enable interrupts */
|
|
||||||
if (!ap->ops->error_handler)
|
|
||||||
ap->ops->irq_on(ap);
|
|
||||||
|
|
||||||
/* is double-select really necessary? */
|
/* is double-select really necessary? */
|
||||||
if (classes[0] != ATA_DEV_NONE)
|
if (classes[0] != ATA_DEV_NONE)
|
||||||
ap->ops->dev_select(ap, 1);
|
ap->ops->dev_select(ap, 1);
|
||||||
|
@ -3770,6 +3737,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||||
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
|
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
|
||||||
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
|
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
|
||||||
{ "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
|
{ "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
|
||||||
|
{ "IOMEGA ZIP 250 ATAPI Floppy",
|
||||||
|
NULL, ATA_HORKAGE_NODMA },
|
||||||
|
|
||||||
/* Weird ATAPI devices */
|
/* Weird ATAPI devices */
|
||||||
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
|
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
|
||||||
|
@ -3783,7 +3752,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||||
{ "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
|
{ "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
|
||||||
/* NCQ is broken */
|
/* NCQ is broken */
|
||||||
{ "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
|
{ "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
|
||||||
|
{ "Maxtor 6B200M0", "BANC1BM0", ATA_HORKAGE_NONCQ },
|
||||||
{ "Maxtor 6B200M0", "BANC1B10", ATA_HORKAGE_NONCQ },
|
{ "Maxtor 6B200M0", "BANC1B10", ATA_HORKAGE_NONCQ },
|
||||||
|
{ "HITACHI HDS7250SASUN500G 0621KTAWSD", "K2AOAJ0AHITACHI",
|
||||||
|
ATA_HORKAGE_NONCQ },
|
||||||
/* NCQ hard hangs device under heavier load, needs hard power cycle */
|
/* NCQ hard hangs device under heavier load, needs hard power cycle */
|
||||||
{ "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ },
|
{ "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ },
|
||||||
/* Blacklist entries taken from Silicon Image 3124/3132
|
/* Blacklist entries taken from Silicon Image 3124/3132
|
||||||
|
@ -3796,6 +3768,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||||
{ "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
|
{ "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
|
||||||
{ "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
|
{ "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
|
||||||
{ "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
|
{ "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
|
||||||
|
{ "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
|
||||||
|
|
||||||
/* Devices with NCQ limits */
|
/* Devices with NCQ limits */
|
||||||
|
|
||||||
|
@ -3803,7 +3776,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long ata_device_blacklisted(const struct ata_device *dev)
|
static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
|
||||||
{
|
{
|
||||||
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||||
unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
|
unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
|
||||||
|
@ -3833,7 +3806,7 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
|
||||||
if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
|
if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
|
||||||
(dev->flags & ATA_DFLAG_CDB_INTR))
|
(dev->flags & ATA_DFLAG_CDB_INTR))
|
||||||
return 1;
|
return 1;
|
||||||
return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
|
return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6557,13 +6530,7 @@ void ata_port_detach(struct ata_port *ap)
|
||||||
spin_unlock_irqrestore(ap->lock, flags);
|
spin_unlock_irqrestore(ap->lock, flags);
|
||||||
|
|
||||||
ata_port_wait_eh(ap);
|
ata_port_wait_eh(ap);
|
||||||
|
cancel_rearming_delayed_work(&ap->hotplug_task);
|
||||||
/* Flush hotplug task. The sequence is similar to
|
|
||||||
* ata_port_flush_task().
|
|
||||||
*/
|
|
||||||
cancel_work_sync(&ap->hotplug_task.work); /* akpm: why? */
|
|
||||||
cancel_delayed_work(&ap->hotplug_task);
|
|
||||||
cancel_work_sync(&ap->hotplug_task.work);
|
|
||||||
|
|
||||||
skip_eh:
|
skip_eh:
|
||||||
/* remove the associated SCSI host */
|
/* remove the associated SCSI host */
|
||||||
|
@ -6952,7 +6919,6 @@ EXPORT_SYMBOL_GPL(ata_host_resume);
|
||||||
EXPORT_SYMBOL_GPL(ata_id_string);
|
EXPORT_SYMBOL_GPL(ata_id_string);
|
||||||
EXPORT_SYMBOL_GPL(ata_id_c_string);
|
EXPORT_SYMBOL_GPL(ata_id_c_string);
|
||||||
EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
|
EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
|
||||||
EXPORT_SYMBOL_GPL(ata_device_blacklisted);
|
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
|
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
|
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
|
||||||
|
@ -6961,9 +6927,9 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
EXPORT_SYMBOL_GPL(pci_test_config_bits);
|
EXPORT_SYMBOL_GPL(pci_test_config_bits);
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
|
EXPORT_SYMBOL_GPL(ata_pci_init_sff_host);
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
|
EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
|
EXPORT_SYMBOL_GPL(ata_pci_prepare_sff_host);
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_init_one);
|
EXPORT_SYMBOL_GPL(ata_pci_init_one);
|
||||||
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
|
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
|
@ -1897,6 +1897,57 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)
|
||||||
|
{
|
||||||
|
struct ata_port *ap = dev->ap;
|
||||||
|
struct ata_eh_context *ehc = &ap->eh_context;
|
||||||
|
|
||||||
|
ehc->tries[dev->devno]--;
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case -ENODEV:
|
||||||
|
/* device missing or wrong IDENTIFY data, schedule probing */
|
||||||
|
ehc->i.probe_mask |= (1 << dev->devno);
|
||||||
|
case -EINVAL:
|
||||||
|
/* give it just one more chance */
|
||||||
|
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
|
||||||
|
case -EIO:
|
||||||
|
if (ehc->tries[dev->devno] == 1) {
|
||||||
|
/* This is the last chance, better to slow
|
||||||
|
* down than lose it.
|
||||||
|
*/
|
||||||
|
sata_down_spd_limit(ap);
|
||||||
|
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
|
||||||
|
/* disable device if it has used up all its chances */
|
||||||
|
ata_dev_disable(dev);
|
||||||
|
|
||||||
|
/* detach if offline */
|
||||||
|
if (ata_port_offline(ap))
|
||||||
|
ata_eh_detach_dev(dev);
|
||||||
|
|
||||||
|
/* probe if requested */
|
||||||
|
if ((ehc->i.probe_mask & (1 << dev->devno)) &&
|
||||||
|
!(ehc->did_probe_mask & (1 << dev->devno))) {
|
||||||
|
ata_eh_detach_dev(dev);
|
||||||
|
ata_dev_init(dev);
|
||||||
|
|
||||||
|
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
|
||||||
|
ehc->did_probe_mask |= (1 << dev->devno);
|
||||||
|
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* soft didn't work? be haaaaard */
|
||||||
|
if (ehc->i.flags & ATA_EHI_DID_RESET)
|
||||||
|
ehc->i.action |= ATA_EH_HARDRESET;
|
||||||
|
else
|
||||||
|
ehc->i.action |= ATA_EH_SOFTRESET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_eh_recover - recover host port after error
|
* ata_eh_recover - recover host port after error
|
||||||
* @ap: host port to recover
|
* @ap: host port to recover
|
||||||
|
@ -1997,50 +2048,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
dev_fail:
|
dev_fail:
|
||||||
ehc->tries[dev->devno]--;
|
ata_eh_handle_dev_fail(dev, rc);
|
||||||
|
|
||||||
switch (rc) {
|
|
||||||
case -ENODEV:
|
|
||||||
/* device missing or wrong IDENTIFY data, schedule probing */
|
|
||||||
ehc->i.probe_mask |= (1 << dev->devno);
|
|
||||||
case -EINVAL:
|
|
||||||
/* give it just one more chance */
|
|
||||||
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
|
|
||||||
case -EIO:
|
|
||||||
if (ehc->tries[dev->devno] == 1) {
|
|
||||||
/* This is the last chance, better to slow
|
|
||||||
* down than lose it.
|
|
||||||
*/
|
|
||||||
sata_down_spd_limit(ap);
|
|
||||||
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
|
|
||||||
/* disable device if it has used up all its chances */
|
|
||||||
ata_dev_disable(dev);
|
|
||||||
|
|
||||||
/* detach if offline */
|
|
||||||
if (ata_port_offline(ap))
|
|
||||||
ata_eh_detach_dev(dev);
|
|
||||||
|
|
||||||
/* probe if requested */
|
|
||||||
if ((ehc->i.probe_mask & (1 << dev->devno)) &&
|
|
||||||
!(ehc->did_probe_mask & (1 << dev->devno))) {
|
|
||||||
ata_eh_detach_dev(dev);
|
|
||||||
ata_dev_init(dev);
|
|
||||||
|
|
||||||
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
|
|
||||||
ehc->did_probe_mask |= (1 << dev->devno);
|
|
||||||
ehc->i.action |= ATA_EH_SOFTRESET;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* soft didn't work? be haaaaard */
|
|
||||||
if (ehc->i.flags & ATA_EHI_DID_RESET)
|
|
||||||
ehc->i.action |= ATA_EH_HARDRESET;
|
|
||||||
else
|
|
||||||
ehc->i.action |= ATA_EH_SOFTRESET;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ata_port_nr_enabled(ap)) {
|
if (ata_port_nr_enabled(ap)) {
|
||||||
ata_port_printk(ap, KERN_WARNING, "failed to recover some "
|
ata_port_printk(ap, KERN_WARNING, "failed to recover some "
|
||||||
|
|
|
@ -604,13 +604,17 @@ int ata_pci_init_bmdma(struct ata_host *host)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_pci_init_native_host - acquire native ATA resources and init host
|
* ata_pci_init_sff_host - acquire native PCI ATA resources and init host
|
||||||
* @host: target ATA host
|
* @host: target ATA host
|
||||||
*
|
*
|
||||||
* Acquire native PCI ATA resources for @host and initialize the
|
* Acquire native PCI ATA resources for @host and initialize the
|
||||||
* first two ports of @host accordingly. Ports marked dummy are
|
* first two ports of @host accordingly. Ports marked dummy are
|
||||||
* skipped and allocation failure makes the port dummy.
|
* skipped and allocation failure makes the port dummy.
|
||||||
*
|
*
|
||||||
|
* Note that native PCI resources are valid even for legacy hosts
|
||||||
|
* as we fix up pdev resources array early in boot, so this
|
||||||
|
* function can be used for both native and legacy SFF hosts.
|
||||||
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Inherited from calling layer (may sleep).
|
* Inherited from calling layer (may sleep).
|
||||||
*
|
*
|
||||||
|
@ -618,7 +622,7 @@ int ata_pci_init_bmdma(struct ata_host *host)
|
||||||
* 0 if at least one port is initialized, -ENODEV if no port is
|
* 0 if at least one port is initialized, -ENODEV if no port is
|
||||||
* available.
|
* available.
|
||||||
*/
|
*/
|
||||||
int ata_pci_init_native_host(struct ata_host *host)
|
int ata_pci_init_sff_host(struct ata_host *host)
|
||||||
{
|
{
|
||||||
struct device *gdev = host->dev;
|
struct device *gdev = host->dev;
|
||||||
struct pci_dev *pdev = to_pci_dev(gdev);
|
struct pci_dev *pdev = to_pci_dev(gdev);
|
||||||
|
@ -673,7 +677,7 @@ int ata_pci_init_native_host(struct ata_host *host)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_pci_prepare_native_host - helper to prepare native PCI ATA host
|
* ata_pci_prepare_sff_host - helper to prepare native PCI ATA host
|
||||||
* @pdev: target PCI device
|
* @pdev: target PCI device
|
||||||
* @ppi: array of port_info, must be enough for two ports
|
* @ppi: array of port_info, must be enough for two ports
|
||||||
* @r_host: out argument for the initialized ATA host
|
* @r_host: out argument for the initialized ATA host
|
||||||
|
@ -687,9 +691,9 @@ int ata_pci_init_native_host(struct ata_host *host)
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 0 on success, -errno otherwise.
|
* 0 on success, -errno otherwise.
|
||||||
*/
|
*/
|
||||||
int ata_pci_prepare_native_host(struct pci_dev *pdev,
|
int ata_pci_prepare_sff_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 **r_host)
|
||||||
{
|
{
|
||||||
struct ata_host *host;
|
struct ata_host *host;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -705,7 +709,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ata_pci_init_native_host(host);
|
rc = ata_pci_init_sff_host(host);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
|
@ -730,221 +734,6 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ata_legacy_devres {
|
|
||||||
unsigned int mask;
|
|
||||||
unsigned long cmd_port[2];
|
|
||||||
void __iomem * cmd_addr[2];
|
|
||||||
void __iomem * ctl_addr[2];
|
|
||||||
unsigned int irq[2];
|
|
||||||
void * irq_dev_id[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (!legacy_dr->irq[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
|
|
||||||
legacy_dr->irq[i] = 0;
|
|
||||||
legacy_dr->irq_dev_id[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ata_legacy_release(struct device *gdev, void *res)
|
|
||||||
{
|
|
||||||
struct ata_legacy_devres *this = res;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
ata_legacy_free_irqs(this);
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (this->cmd_addr[i])
|
|
||||||
ioport_unmap(this->cmd_addr[i]);
|
|
||||||
if (this->ctl_addr[i])
|
|
||||||
ioport_unmap(this->ctl_addr[i]);
|
|
||||||
if (this->cmd_port[i])
|
|
||||||
release_region(this->cmd_port[i], 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ata_init_legacy_port(struct ata_port *ap,
|
|
||||||
struct ata_legacy_devres *legacy_dr)
|
|
||||||
{
|
|
||||||
struct ata_host *host = ap->host;
|
|
||||||
int port_no = ap->port_no;
|
|
||||||
unsigned long cmd_port, ctl_port;
|
|
||||||
|
|
||||||
if (port_no == 0) {
|
|
||||||
cmd_port = ATA_PRIMARY_CMD;
|
|
||||||
ctl_port = ATA_PRIMARY_CTL;
|
|
||||||
} else {
|
|
||||||
cmd_port = ATA_SECONDARY_CMD;
|
|
||||||
ctl_port = ATA_SECONDARY_CTL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* request cmd_port */
|
|
||||||
if (request_region(cmd_port, 8, "libata"))
|
|
||||||
legacy_dr->cmd_port[port_no] = cmd_port;
|
|
||||||
else {
|
|
||||||
dev_printk(KERN_WARNING, host->dev,
|
|
||||||
"0x%0lX IDE port busy\n", cmd_port);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iomap cmd and ctl ports */
|
|
||||||
legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
|
|
||||||
legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
|
|
||||||
if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) {
|
|
||||||
dev_printk(KERN_WARNING, host->dev,
|
|
||||||
"failed to map cmd/ctl ports\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init IO addresses */
|
|
||||||
ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
|
|
||||||
ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
|
|
||||||
ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
|
|
||||||
ata_std_ports(&ap->ioaddr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ata_init_legacy_host - acquire legacy ATA resources and init ATA host
|
|
||||||
* @host: target ATA host
|
|
||||||
* @was_busy: out parameter, indicates whether any port was busy
|
|
||||||
*
|
|
||||||
* Acquire legacy ATA resources for the first two ports of @host
|
|
||||||
* and initialize it accordingly. Ports marked dummy are skipped
|
|
||||||
* and resource acquistion failure makes the port dummy.
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
* Inherited from calling layer (may sleep).
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 if at least one port is initialized, -ENODEV if no port is
|
|
||||||
* available.
|
|
||||||
*/
|
|
||||||
static int ata_init_legacy_host(struct ata_host *host, int *was_busy)
|
|
||||||
{
|
|
||||||
struct device *gdev = host->dev;
|
|
||||||
struct ata_legacy_devres *legacy_dr;
|
|
||||||
int i, rc;
|
|
||||||
|
|
||||||
if (!devres_open_group(gdev, NULL, GFP_KERNEL))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rc = -ENOMEM;
|
|
||||||
legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!legacy_dr)
|
|
||||||
goto err_out;
|
|
||||||
devres_add(gdev, legacy_dr);
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (ata_port_is_dummy(host->ports[i]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
rc = ata_init_legacy_port(host->ports[i], legacy_dr);
|
|
||||||
if (rc == 0)
|
|
||||||
legacy_dr->mask |= 1 << i;
|
|
||||||
else {
|
|
||||||
if (rc == -EBUSY)
|
|
||||||
(*was_busy)++;
|
|
||||||
host->ports[i]->ops = &ata_dummy_port_ops;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!legacy_dr->mask) {
|
|
||||||
dev_printk(KERN_ERR, gdev, "no available legacy port\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
devres_remove_group(gdev, NULL);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
devres_release_group(gdev, NULL);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ata_request_legacy_irqs - request legacy ATA IRQs
|
|
||||||
* @host: target ATA host
|
|
||||||
* @handler: array of IRQ handlers
|
|
||||||
* @irq_flags: array of IRQ flags
|
|
||||||
* @dev_id: array of IRQ dev_ids
|
|
||||||
*
|
|
||||||
* Request legacy IRQs for non-dummy legacy ports in @host. All
|
|
||||||
* IRQ parameters are passed as array to allow ports to have
|
|
||||||
* separate IRQ handlers.
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
* Inherited from calling layer (may sleep).
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 on success, -errno otherwise.
|
|
||||||
*/
|
|
||||||
static int ata_request_legacy_irqs(struct ata_host *host,
|
|
||||||
irq_handler_t const *handler,
|
|
||||||
const unsigned int *irq_flags,
|
|
||||||
void * const *dev_id)
|
|
||||||
{
|
|
||||||
struct device *gdev = host->dev;
|
|
||||||
struct ata_legacy_devres *legacy_dr;
|
|
||||||
int i, rc;
|
|
||||||
|
|
||||||
legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
|
|
||||||
BUG_ON(!legacy_dr);
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
unsigned int irq;
|
|
||||||
|
|
||||||
/* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
|
|
||||||
if (i == 0)
|
|
||||||
irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
|
|
||||||
else
|
|
||||||
irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
|
|
||||||
|
|
||||||
if (!(legacy_dr->mask & (1 << i)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!handler[i]) {
|
|
||||||
dev_printk(KERN_ERR, gdev,
|
|
||||||
"NULL handler specified for port %d\n", i);
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
|
|
||||||
dev_id[i]);
|
|
||||||
if (rc) {
|
|
||||||
dev_printk(KERN_ERR, gdev,
|
|
||||||
"irq %u request failed (errno=%d)\n", irq, rc);
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* record irq allocation in legacy_dr */
|
|
||||||
legacy_dr->irq[i] = irq;
|
|
||||||
legacy_dr->irq_dev_id[i] = dev_id[i];
|
|
||||||
|
|
||||||
/* only used to print info */
|
|
||||||
if (i == 0)
|
|
||||||
host->irq = irq;
|
|
||||||
else
|
|
||||||
host->irq2 = irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
ata_legacy_free_irqs(legacy_dr);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_pci_init_one - Initialize/register PCI IDE host controller
|
* ata_pci_init_one - Initialize/register PCI IDE host controller
|
||||||
* @pdev: Controller to be initialized
|
* @pdev: Controller to be initialized
|
||||||
|
@ -1029,35 +818,11 @@ int ata_pci_init_one(struct pci_dev *pdev,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alloc and init host */
|
/* prepare host */
|
||||||
host = ata_host_alloc_pinfo(dev, ppi, 2);
|
rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
|
||||||
if (!host) {
|
if (rc)
|
||||||
dev_printk(KERN_ERR, &pdev->dev,
|
|
||||||
"failed to allocate ATA host\n");
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
|
||||||
|
|
||||||
if (!legacy_mode) {
|
|
||||||
rc = ata_pci_init_native_host(host);
|
|
||||||
if (rc)
|
|
||||||
goto err_out;
|
|
||||||
} else {
|
|
||||||
int was_busy = 0;
|
|
||||||
|
|
||||||
rc = ata_init_legacy_host(host, &was_busy);
|
|
||||||
if (was_busy)
|
|
||||||
pcim_pin_device(pdev);
|
|
||||||
if (rc)
|
|
||||||
goto err_out;
|
|
||||||
|
|
||||||
/* request respective PCI regions, may fail */
|
|
||||||
rc = pci_request_region(pdev, 1, DRV_NAME);
|
|
||||||
rc = pci_request_region(pdev, 3, DRV_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init BMDMA, may fail */
|
|
||||||
ata_pci_init_bmdma(host);
|
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
|
|
||||||
/* start host and request IRQ */
|
/* start host and request IRQ */
|
||||||
|
@ -1068,17 +833,28 @@ int ata_pci_init_one(struct pci_dev *pdev,
|
||||||
if (!legacy_mode) {
|
if (!legacy_mode) {
|
||||||
rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
|
rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
|
||||||
IRQF_SHARED, DRV_NAME, host);
|
IRQF_SHARED, DRV_NAME, host);
|
||||||
|
if (rc)
|
||||||
|
goto err_out;
|
||||||
host->irq = pdev->irq;
|
host->irq = pdev->irq;
|
||||||
} else {
|
} else {
|
||||||
irq_handler_t handler[2] = { host->ops->irq_handler,
|
if (!ata_port_is_dummy(host->ports[0])) {
|
||||||
host->ops->irq_handler };
|
host->irq = ATA_PRIMARY_IRQ(pdev);
|
||||||
unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
|
rc = devm_request_irq(dev, host->irq,
|
||||||
void *dev_id[2] = { host, host };
|
pi->port_ops->irq_handler,
|
||||||
|
IRQF_SHARED, DRV_NAME, host);
|
||||||
|
if (rc)
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
|
if (!ata_port_is_dummy(host->ports[1])) {
|
||||||
|
host->irq2 = ATA_SECONDARY_IRQ(pdev);
|
||||||
|
rc = devm_request_irq(dev, host->irq2,
|
||||||
|
pi->port_ops->irq_handler,
|
||||||
|
IRQF_SHARED, DRV_NAME, host);
|
||||||
|
if (rc)
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rc)
|
|
||||||
goto err_out;
|
|
||||||
|
|
||||||
/* register */
|
/* register */
|
||||||
rc = ata_host_register(host, pi->sht);
|
rc = ata_host_register(host, pi->sht);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <linux/libata.h>
|
#include <linux/libata.h>
|
||||||
|
|
||||||
#define DRV_NAME "pata_hpt3x3"
|
#define DRV_NAME "pata_hpt3x3"
|
||||||
#define DRV_VERSION "0.4.3"
|
#define DRV_VERSION "0.5.3"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hpt3x3_set_piomode - PIO setup
|
* hpt3x3_set_piomode - PIO setup
|
||||||
|
@ -52,6 +52,7 @@ static void hpt3x3_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||||
pci_write_config_dword(pdev, 0x48, r2);
|
pci_write_config_dword(pdev, 0x48, r2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PATA_HPT3X3_DMA)
|
||||||
/**
|
/**
|
||||||
* hpt3x3_set_dmamode - DMA timing setup
|
* hpt3x3_set_dmamode - DMA timing setup
|
||||||
* @ap: ATA interface
|
* @ap: ATA interface
|
||||||
|
@ -59,6 +60,9 @@ static void hpt3x3_set_piomode(struct ata_port *ap, struct ata_device *adev)
|
||||||
*
|
*
|
||||||
* Set up the channel for MWDMA or UDMA modes. Much the same as with
|
* Set up the channel for MWDMA or UDMA modes. Much the same as with
|
||||||
* PIO, load the mode number and then set MWDMA or UDMA flag.
|
* PIO, load the mode number and then set MWDMA or UDMA flag.
|
||||||
|
*
|
||||||
|
* 0x44 : bit 0-2 master mode, 3-5 slave mode, etc
|
||||||
|
* 0x48 : bit 4/0 DMA/UDMA bit 5/1 for slave etc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||||
|
@ -76,13 +80,26 @@ static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
||||||
r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */
|
r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */
|
||||||
|
|
||||||
if (adev->dma_mode >= XFER_UDMA_0)
|
if (adev->dma_mode >= XFER_UDMA_0)
|
||||||
r2 |= 0x01 << dn; /* Ultra mode */
|
r2 |= (0x10 << dn); /* Ultra mode */
|
||||||
else
|
else
|
||||||
r2 |= 0x10 << dn; /* MWDMA */
|
r2 |= (0x01 << dn); /* MWDMA */
|
||||||
|
|
||||||
pci_write_config_dword(pdev, 0x44, r1);
|
pci_write_config_dword(pdev, 0x44, r1);
|
||||||
pci_write_config_dword(pdev, 0x48, r2);
|
pci_write_config_dword(pdev, 0x48, r2);
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_PATA_HPT3X3_DMA */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hpt3x3_atapi_dma - ATAPI DMA check
|
||||||
|
* @qc: Queued command
|
||||||
|
*
|
||||||
|
* Just say no - we don't do ATAPI DMA
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static struct scsi_host_template hpt3x3_sht = {
|
static struct scsi_host_template hpt3x3_sht = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
|
@ -105,7 +122,9 @@ static struct scsi_host_template hpt3x3_sht = {
|
||||||
static struct ata_port_operations hpt3x3_port_ops = {
|
static struct ata_port_operations hpt3x3_port_ops = {
|
||||||
.port_disable = ata_port_disable,
|
.port_disable = ata_port_disable,
|
||||||
.set_piomode = hpt3x3_set_piomode,
|
.set_piomode = hpt3x3_set_piomode,
|
||||||
|
#if defined(CONFIG_PATA_HPT3X3_DMA)
|
||||||
.set_dmamode = hpt3x3_set_dmamode,
|
.set_dmamode = hpt3x3_set_dmamode,
|
||||||
|
#endif
|
||||||
.mode_filter = ata_pci_default_filter,
|
.mode_filter = ata_pci_default_filter,
|
||||||
|
|
||||||
.tf_load = ata_tf_load,
|
.tf_load = ata_tf_load,
|
||||||
|
@ -124,6 +143,7 @@ static struct ata_port_operations hpt3x3_port_ops = {
|
||||||
.bmdma_start = ata_bmdma_start,
|
.bmdma_start = ata_bmdma_start,
|
||||||
.bmdma_stop = ata_bmdma_stop,
|
.bmdma_stop = ata_bmdma_stop,
|
||||||
.bmdma_status = ata_bmdma_status,
|
.bmdma_status = ata_bmdma_status,
|
||||||
|
.check_atapi_dma= hpt3x3_atapi_dma,
|
||||||
|
|
||||||
.qc_prep = ata_qc_prep,
|
.qc_prep = ata_qc_prep,
|
||||||
.qc_issue = ata_qc_issue_prot,
|
.qc_issue = ata_qc_issue_prot,
|
||||||
|
@ -158,32 +178,79 @@ static void hpt3x3_init_chipset(struct pci_dev *dev)
|
||||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
|
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hpt3x3_init_one - Initialise an HPT343/363
|
* hpt3x3_init_one - Initialise an HPT343/363
|
||||||
* @dev: PCI device
|
* @pdev: PCI device
|
||||||
* @id: Entry in match table
|
* @id: Entry in match table
|
||||||
*
|
*
|
||||||
* Perform basic initialisation. The chip has a quirk that it won't
|
* Perform basic initialisation. We set the device up so we access all
|
||||||
* function unless it is at XX00. The old ATA driver touched this up
|
* ports via BAR4. This is neccessary to work around errata.
|
||||||
* but we leave it for pci quirks to do properly.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
|
static int printed_version;
|
||||||
static const struct ata_port_info info = {
|
static const struct ata_port_info info = {
|
||||||
.sht = &hpt3x3_sht,
|
.sht = &hpt3x3_sht,
|
||||||
.flags = ATA_FLAG_SLAVE_POSS,
|
.flags = ATA_FLAG_SLAVE_POSS,
|
||||||
.pio_mask = 0x1f,
|
.pio_mask = 0x1f,
|
||||||
|
#if defined(CONFIG_PATA_HPT3X3_DMA)
|
||||||
|
/* Further debug needed */
|
||||||
.mwdma_mask = 0x07,
|
.mwdma_mask = 0x07,
|
||||||
.udma_mask = 0x07,
|
.udma_mask = 0x07,
|
||||||
|
#endif
|
||||||
.port_ops = &hpt3x3_port_ops
|
.port_ops = &hpt3x3_port_ops
|
||||||
};
|
};
|
||||||
|
/* Register offsets of taskfiles in BAR4 area */
|
||||||
|
static const u8 offset_cmd[2] = { 0x20, 0x28 };
|
||||||
|
static const u8 offset_ctl[2] = { 0x36, 0x3E };
|
||||||
const struct ata_port_info *ppi[] = { &info, NULL };
|
const struct ata_port_info *ppi[] = { &info, NULL };
|
||||||
|
struct ata_host *host;
|
||||||
|
int i, rc;
|
||||||
|
void __iomem *base;
|
||||||
|
|
||||||
hpt3x3_init_chipset(dev);
|
hpt3x3_init_chipset(pdev);
|
||||||
/* Now kick off ATA set up */
|
|
||||||
return ata_pci_init_one(dev, ppi);
|
if (!printed_version++)
|
||||||
|
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
||||||
|
|
||||||
|
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
|
||||||
|
if (!host)
|
||||||
|
return -ENOMEM;
|
||||||
|
/* acquire resources and fill host */
|
||||||
|
rc = pcim_enable_device(pdev);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* Everything is relative to BAR4 if we set up this way */
|
||||||
|
rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
|
||||||
|
if (rc == -EBUSY)
|
||||||
|
pcim_pin_device(pdev);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
host->iomap = pcim_iomap_table(pdev);
|
||||||
|
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
base = host->iomap[4]; /* Bus mastering base */
|
||||||
|
|
||||||
|
for (i = 0; i < host->n_ports; i++) {
|
||||||
|
struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
|
||||||
|
|
||||||
|
ioaddr->cmd_addr = base + offset_cmd[i];
|
||||||
|
ioaddr->altstatus_addr =
|
||||||
|
ioaddr->ctl_addr = base + offset_ctl[i];
|
||||||
|
ioaddr->scr_addr = NULL;
|
||||||
|
ata_std_ports(ioaddr);
|
||||||
|
ioaddr->bmdma_addr = base + 8 * i;
|
||||||
|
}
|
||||||
|
pci_set_master(pdev);
|
||||||
|
return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
|
||||||
|
&hpt3x3_sht);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
|
@ -467,13 +467,27 @@ mpc52xx_ata_remove(struct of_device *op)
|
||||||
static int
|
static int
|
||||||
mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
|
mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
|
||||||
{
|
{
|
||||||
return 0; /* FIXME : What to do here ? */
|
struct ata_host *host = dev_get_drvdata(&op->dev);
|
||||||
|
|
||||||
|
return ata_host_suspend(host, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mpc52xx_ata_resume(struct of_device *op)
|
mpc52xx_ata_resume(struct of_device *op)
|
||||||
{
|
{
|
||||||
return 0; /* FIXME : What to do here ? */
|
struct ata_host *host = dev_get_drvdata(&op->dev);
|
||||||
|
struct mpc52xx_ata_priv *priv = host->private_data;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = mpc52xx_ata_hw_init(priv);
|
||||||
|
if (rv) {
|
||||||
|
printk(KERN_ERR DRV_NAME ": Error during HW init\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
ata_host_resume(host);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -238,6 +238,12 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
|
||||||
else
|
else
|
||||||
offset = 0; /* 100MHz */
|
offset = 0; /* 100MHz */
|
||||||
|
|
||||||
|
/* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
|
||||||
|
if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) {
|
||||||
|
printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
|
||||||
|
speed = XFER_UDMA_4;
|
||||||
|
}
|
||||||
|
|
||||||
if (speed >= XFER_UDMA_0)
|
if (speed >= XFER_UDMA_0)
|
||||||
idx = speed - XFER_UDMA_0;
|
idx = speed - XFER_UDMA_0;
|
||||||
else
|
else
|
||||||
|
@ -724,22 +730,36 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
|
||||||
|
|
||||||
static u8 scc_bmdma_status (struct ata_port *ap)
|
static u8 scc_bmdma_status (struct ata_port *ap)
|
||||||
{
|
{
|
||||||
u8 host_stat;
|
|
||||||
void __iomem *mmio = ap->ioaddr.bmdma_addr;
|
void __iomem *mmio = ap->ioaddr.bmdma_addr;
|
||||||
|
u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
|
||||||
|
u32 int_status = in_be32(mmio + SCC_DMA_INTST);
|
||||||
|
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
|
||||||
|
static int retry = 0;
|
||||||
|
|
||||||
host_stat = in_be32(mmio + SCC_DMA_STATUS);
|
/* return if IOS_SS is cleared */
|
||||||
|
if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START))
|
||||||
|
return host_stat;
|
||||||
|
|
||||||
/* Workaround for PTERADD: emulate DMA_INTR when
|
/* errata A252,A308 workaround: Step4 */
|
||||||
* - IDE_STATUS[ERR] = 1
|
if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ)
|
||||||
* - INT_STATUS[INTRQ] = 1
|
return (host_stat | ATA_DMA_INTR);
|
||||||
* - DMA_STATUS[IORACTA] = 1
|
|
||||||
*/
|
/* errata A308 workaround Step5 */
|
||||||
if (!(host_stat & ATA_DMA_INTR)) {
|
if (int_status & INTSTS_IOIRQS) {
|
||||||
u32 int_status = in_be32(mmio + SCC_DMA_INTST);
|
host_stat |= ATA_DMA_INTR;
|
||||||
if (ata_altstatus(ap) & ATA_ERR &&
|
|
||||||
int_status & INTSTS_INTRQ &&
|
/* We don't check ATAPI DMA because it is limited to UDMA4 */
|
||||||
host_stat & ATA_DMA_ACTIVE)
|
if ((qc->tf.protocol == ATA_PROT_DMA &&
|
||||||
host_stat |= ATA_DMA_INTR;
|
qc->dev->xfer_mode > XFER_UDMA_4)) {
|
||||||
|
if (!(int_status & INTSTS_ACTEINT)) {
|
||||||
|
printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n",
|
||||||
|
ap->print_id, retry);
|
||||||
|
host_stat |= ATA_DMA_ERR;
|
||||||
|
if (retry++)
|
||||||
|
ap->udma_mask >>= 1;
|
||||||
|
} else
|
||||||
|
retry = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return host_stat;
|
return host_stat;
|
||||||
|
@ -892,10 +912,6 @@ static void scc_std_postreset (struct ata_port *ap, unsigned int *classes)
|
||||||
{
|
{
|
||||||
DPRINTK("ENTER\n");
|
DPRINTK("ENTER\n");
|
||||||
|
|
||||||
/* re-enable interrupts */
|
|
||||||
if (!ap->ops->error_handler)
|
|
||||||
ap->ops->irq_on(ap);
|
|
||||||
|
|
||||||
/* is double-select really necessary? */
|
/* is double-select really necessary? */
|
||||||
if (classes[0] != ATA_DEV_NONE)
|
if (classes[0] != ATA_DEV_NONE)
|
||||||
ap->ops->dev_select(ap, 1);
|
ap->ops->dev_select(ap, 1);
|
||||||
|
|
|
@ -149,6 +149,9 @@ static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||||
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
|
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* Clear the FIFO settings. We can't enable the FIFO until
|
||||||
|
we know we are poking at a disk */
|
||||||
|
pci_write_config_byte(pdev, 0x4B, 0);
|
||||||
return ata_std_prereset(ap, deadline);
|
return ata_std_prereset(ap, deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1560,7 +1560,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
}
|
}
|
||||||
|
|
||||||
ppi[0] = &nv_port_info[type];
|
ppi[0] = &nv_port_info[type];
|
||||||
rc = ata_pci_prepare_native_host(pdev, ppi, &host);
|
rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include "sata_promise.h"
|
#include "sata_promise.h"
|
||||||
|
|
||||||
#define DRV_NAME "sata_promise"
|
#define DRV_NAME "sata_promise"
|
||||||
#define DRV_VERSION "2.08"
|
#define DRV_VERSION "2.09"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PDC_MAX_PORTS = 4,
|
PDC_MAX_PORTS = 4,
|
||||||
|
@ -716,6 +716,9 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
|
||||||
unsigned int i, tmp;
|
unsigned int i, tmp;
|
||||||
unsigned int handled = 0;
|
unsigned int handled = 0;
|
||||||
void __iomem *mmio_base;
|
void __iomem *mmio_base;
|
||||||
|
unsigned int hotplug_offset, ata_no;
|
||||||
|
u32 hotplug_status;
|
||||||
|
int is_sataii_tx4;
|
||||||
|
|
||||||
VPRINTK("ENTER\n");
|
VPRINTK("ENTER\n");
|
||||||
|
|
||||||
|
@ -726,10 +729,20 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
|
||||||
|
|
||||||
mmio_base = host->iomap[PDC_MMIO_BAR];
|
mmio_base = host->iomap[PDC_MMIO_BAR];
|
||||||
|
|
||||||
|
/* read and clear hotplug flags for all ports */
|
||||||
|
if (host->ports[0]->flags & PDC_FLAG_GEN_II)
|
||||||
|
hotplug_offset = PDC2_SATA_PLUG_CSR;
|
||||||
|
else
|
||||||
|
hotplug_offset = PDC_SATA_PLUG_CSR;
|
||||||
|
hotplug_status = readl(mmio_base + hotplug_offset);
|
||||||
|
if (hotplug_status & 0xff)
|
||||||
|
writel(hotplug_status | 0xff, mmio_base + hotplug_offset);
|
||||||
|
hotplug_status &= 0xff; /* clear uninteresting bits */
|
||||||
|
|
||||||
/* reading should also clear interrupts */
|
/* reading should also clear interrupts */
|
||||||
mask = readl(mmio_base + PDC_INT_SEQMASK);
|
mask = readl(mmio_base + PDC_INT_SEQMASK);
|
||||||
|
|
||||||
if (mask == 0xffffffff) {
|
if (mask == 0xffffffff && hotplug_status == 0) {
|
||||||
VPRINTK("QUICK EXIT 2\n");
|
VPRINTK("QUICK EXIT 2\n");
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
@ -737,16 +750,34 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
|
||||||
spin_lock(&host->lock);
|
spin_lock(&host->lock);
|
||||||
|
|
||||||
mask &= 0xffff; /* only 16 tags possible */
|
mask &= 0xffff; /* only 16 tags possible */
|
||||||
if (!mask) {
|
if (mask == 0 && hotplug_status == 0) {
|
||||||
VPRINTK("QUICK EXIT 3\n");
|
VPRINTK("QUICK EXIT 3\n");
|
||||||
goto done_irq;
|
goto done_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(mask, mmio_base + PDC_INT_SEQMASK);
|
writel(mask, mmio_base + PDC_INT_SEQMASK);
|
||||||
|
|
||||||
|
is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags);
|
||||||
|
|
||||||
for (i = 0; i < host->n_ports; i++) {
|
for (i = 0; i < host->n_ports; i++) {
|
||||||
VPRINTK("port %u\n", i);
|
VPRINTK("port %u\n", i);
|
||||||
ap = host->ports[i];
|
ap = host->ports[i];
|
||||||
|
|
||||||
|
/* check for a plug or unplug event */
|
||||||
|
ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
|
||||||
|
tmp = hotplug_status & (0x11 << ata_no);
|
||||||
|
if (tmp && ap &&
|
||||||
|
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||||
|
struct ata_eh_info *ehi = &ap->eh_info;
|
||||||
|
ata_ehi_clear_desc(ehi);
|
||||||
|
ata_ehi_hotplugged(ehi);
|
||||||
|
ata_ehi_push_desc(ehi, "hotplug_status %#x", tmp);
|
||||||
|
ata_port_freeze(ap);
|
||||||
|
++handled;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for a packet interrupt */
|
||||||
tmp = mask & (1 << (i + 1));
|
tmp = mask & (1 << (i + 1));
|
||||||
if (tmp && ap &&
|
if (tmp && ap &&
|
||||||
!(ap->flags & ATA_FLAG_DISABLED)) {
|
!(ap->flags & ATA_FLAG_DISABLED)) {
|
||||||
|
@ -902,9 +933,9 @@ static void pdc_host_init(struct ata_host *host)
|
||||||
tmp = readl(mmio + hotplug_offset);
|
tmp = readl(mmio + hotplug_offset);
|
||||||
writel(tmp | 0xff, mmio + hotplug_offset);
|
writel(tmp | 0xff, mmio + hotplug_offset);
|
||||||
|
|
||||||
/* mask plug/unplug ints */
|
/* unmask plug/unplug ints */
|
||||||
tmp = readl(mmio + hotplug_offset);
|
tmp = readl(mmio + hotplug_offset);
|
||||||
writel(tmp | 0xff0000, mmio + hotplug_offset);
|
writel(tmp & ~0xff0000, mmio + hotplug_offset);
|
||||||
|
|
||||||
/* don't initialise TBG or SLEW on 2nd generation chips */
|
/* don't initialise TBG or SLEW on 2nd generation chips */
|
||||||
if (is_gen2)
|
if (is_gen2)
|
||||||
|
|
|
@ -334,7 +334,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ata_pci_prepare_native_host(pdev, ppi, &host);
|
rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
host->private_data = hpriv;
|
host->private_data = hpriv;
|
||||||
|
|
||||||
/* the first two ports are standard SFF */
|
/* the first two ports are standard SFF */
|
||||||
rc = ata_pci_init_native_host(host);
|
rc = ata_pci_init_sff_host(host);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
|
@ -412,7 +412,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
|
||||||
struct ata_host *host;
|
struct ata_host *host;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ata_pci_prepare_native_host(pdev, ppi, &host);
|
rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
*r_host = host;
|
*r_host = host;
|
||||||
|
|
|
@ -164,6 +164,8 @@ enum {
|
||||||
ATA_CMD_SET_MAX = 0xF9,
|
ATA_CMD_SET_MAX = 0xF9,
|
||||||
ATA_CMD_SET_MAX_EXT = 0x37,
|
ATA_CMD_SET_MAX_EXT = 0x37,
|
||||||
ATA_CMD_READ_LOG_EXT = 0x2f,
|
ATA_CMD_READ_LOG_EXT = 0x2f,
|
||||||
|
ATA_CMD_PMP_READ = 0xE4,
|
||||||
|
ATA_CMD_PMP_WRITE = 0xE8,
|
||||||
|
|
||||||
/* READ_LOG_EXT pages */
|
/* READ_LOG_EXT pages */
|
||||||
ATA_LOG_SATA_NCQ = 0x10,
|
ATA_LOG_SATA_NCQ = 0x10,
|
||||||
|
@ -212,6 +214,28 @@ enum {
|
||||||
0=to device, 1=to host */
|
0=to device, 1=to host */
|
||||||
ATAPI_CDB_LEN = 16,
|
ATAPI_CDB_LEN = 16,
|
||||||
|
|
||||||
|
/* PMP stuff */
|
||||||
|
SATA_PMP_MAX_PORTS = 15,
|
||||||
|
SATA_PMP_CTRL_PORT = 15,
|
||||||
|
|
||||||
|
SATA_PMP_GSCR_DWORDS = 128,
|
||||||
|
SATA_PMP_GSCR_PROD_ID = 0,
|
||||||
|
SATA_PMP_GSCR_REV = 1,
|
||||||
|
SATA_PMP_GSCR_PORT_INFO = 2,
|
||||||
|
SATA_PMP_GSCR_ERROR = 32,
|
||||||
|
SATA_PMP_GSCR_ERROR_EN = 33,
|
||||||
|
SATA_PMP_GSCR_FEAT = 64,
|
||||||
|
SATA_PMP_GSCR_FEAT_EN = 96,
|
||||||
|
|
||||||
|
SATA_PMP_PSCR_STATUS = 0,
|
||||||
|
SATA_PMP_PSCR_ERROR = 1,
|
||||||
|
SATA_PMP_PSCR_CONTROL = 2,
|
||||||
|
|
||||||
|
SATA_PMP_FEAT_BIST = (1 << 0),
|
||||||
|
SATA_PMP_FEAT_PMREQ = (1 << 1),
|
||||||
|
SATA_PMP_FEAT_DYNSSC = (1 << 2),
|
||||||
|
SATA_PMP_FEAT_NOTIFY = (1 << 3),
|
||||||
|
|
||||||
/* cable types */
|
/* cable types */
|
||||||
ATA_CBL_NONE = 0,
|
ATA_CBL_NONE = 0,
|
||||||
ATA_CBL_PATA40 = 1,
|
ATA_CBL_PATA40 = 1,
|
||||||
|
@ -418,4 +442,9 @@ static inline int lba_48_ok(u64 block, u32 n_block)
|
||||||
return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
|
return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define sata_pmp_gscr_vendor(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
|
||||||
|
#define sata_pmp_gscr_devid(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16)
|
||||||
|
#define sata_pmp_gscr_rev(gscr) (((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff)
|
||||||
|
#define sata_pmp_gscr_ports(gscr) ((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf)
|
||||||
|
|
||||||
#endif /* __LINUX_ATA_H__ */
|
#endif /* __LINUX_ATA_H__ */
|
||||||
|
|
|
@ -196,7 +196,6 @@ enum {
|
||||||
ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */
|
ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */
|
||||||
ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */
|
ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */
|
||||||
|
|
||||||
ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
|
|
||||||
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
|
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
|
||||||
ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
|
ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
|
||||||
ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */
|
ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */
|
||||||
|
@ -435,6 +434,7 @@ struct ata_device {
|
||||||
struct ata_port *ap;
|
struct ata_port *ap;
|
||||||
unsigned int devno; /* 0 or 1 */
|
unsigned int devno; /* 0 or 1 */
|
||||||
unsigned long flags; /* ATA_DFLAG_xxx */
|
unsigned long flags; /* ATA_DFLAG_xxx */
|
||||||
|
unsigned int horkage; /* List of broken features */
|
||||||
struct scsi_device *sdev; /* attached SCSI device */
|
struct scsi_device *sdev; /* attached SCSI device */
|
||||||
#ifdef CONFIG_ATA_ACPI
|
#ifdef CONFIG_ATA_ACPI
|
||||||
acpi_handle acpi_handle;
|
acpi_handle acpi_handle;
|
||||||
|
@ -466,7 +466,6 @@ struct ata_device {
|
||||||
/* error history */
|
/* error history */
|
||||||
struct ata_ering ering;
|
struct ata_ering ering;
|
||||||
int spdn_cnt;
|
int spdn_cnt;
|
||||||
unsigned int horkage; /* List of broken features */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Offset into struct ata_device. Fields above it are maintained
|
/* Offset into struct ata_device. Fields above it are maintained
|
||||||
|
@ -794,7 +793,6 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
|
||||||
extern void ata_id_c_string(const u16 *id, unsigned char *s,
|
extern void ata_id_c_string(const u16 *id, unsigned char *s,
|
||||||
unsigned int ofs, unsigned int len);
|
unsigned int ofs, unsigned int len);
|
||||||
extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown);
|
extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown);
|
||||||
extern unsigned long ata_device_blacklisted(const struct ata_device *dev);
|
|
||||||
extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
|
extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
|
||||||
extern void ata_bmdma_start (struct ata_queued_cmd *qc);
|
extern void ata_bmdma_start (struct ata_queued_cmd *qc);
|
||||||
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
|
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
|
||||||
|
@ -871,11 +869,11 @@ struct pci_bits {
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int ata_pci_init_native_host(struct ata_host *host);
|
extern int ata_pci_init_sff_host(struct ata_host *host);
|
||||||
extern int ata_pci_init_bmdma(struct ata_host *host);
|
extern int ata_pci_init_bmdma(struct ata_host *host);
|
||||||
extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
|
extern int ata_pci_prepare_sff_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 **r_host);
|
||||||
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
|
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
|
||||||
extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
|
extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
|
|
Loading…
Reference in New Issue