u16 heads, u16 sectors);
static unsigned int ata_dev_set_xfermode(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;
static struct workqueue_struct *ata_wq;
void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
unsigned long delay)
{
- int rc;
-
- if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK)
- return;
-
PREPARE_DELAYED_WORK(&ap->port_task, fn);
ap->port_task_data = data;
- rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
-
- /* rc == 0 means that another user is using port task */
- WARN_ON(rc == 0);
+ /* may fail if ata_port_flush_task() in progress */
+ queue_delayed_work(ata_wq, &ap->port_task, delay);
}
/**
*/
void ata_port_flush_task(struct ata_port *ap)
{
- unsigned long flags;
-
DPRINTK("ENTER\n");
- spin_lock_irqsave(ap->lock, flags);
- 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);
+ cancel_rearming_delayed_work(&ap->port_task);
if (ata_msg_ctl(ap))
ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
desc[0] = '\0';
return;
}
- if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
+ if (dev->horkage & ATA_HORKAGE_NONCQ) {
snprintf(desc, desc_sz, "NCQ (not used)");
return;
}
if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
+ /* set horkage */
+ dev->horkage |= ata_dev_blacklisted(dev);
+
/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
if (rc)
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);
if ((slave_possible) && (err != 0x81))
ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
- /* re-enable interrupts */
- ap->ops->irq_on(ap);
-
/* is double-select really necessary? */
if (ap->device[1].class != ATA_DEV_NONE)
ap->ops->dev_select(ap, 1);
if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
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? */
if (classes[0] != ATA_DEV_NONE)
ap->ops->dev_select(ap, 1);
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
{ "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
+ { "IOMEGA ZIP 250 ATAPI Floppy",
+ NULL, ATA_HORKAGE_NODMA },
/* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
{ "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
/* NCQ is broken */
{ "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
+ { "Maxtor 6B200M0", "BANC1BM0", 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 */
{ "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ },
/* Blacklist entries taken from Silicon Image 3124/3132
{ "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
{ "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
{ "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
+ { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
/* Devices with NCQ limits */
{ }
};
-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_rev[ATA_ID_FW_REV_LEN + 1];
if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
(dev->flags & ATA_DFLAG_CDB_INTR))
return 1;
- return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
+ return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
}
/**
spin_unlock_irqrestore(ap->lock, flags);
ata_port_wait_eh(ap);
-
- /* 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);
+ cancel_rearming_delayed_work(&ap->hotplug_task);
skip_eh:
/* remove the associated SCSI host */
EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string);
EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
-EXPORT_SYMBOL_GPL(ata_device_blacklisted);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
#ifdef CONFIG_PCI
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_prepare_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_prepare_sff_host);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
#ifdef CONFIG_PM