Merge branch 'for-3.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata fixes from Tejun Heo: "There's one interseting commit - "libata, freezer: avoid block device removal while system is frozen". It's an ugly hack working around a deadlock condition between driver core resume and block layer device removal paths through freezer which was made more reproducible by writeback being converted to workqueue some releases ago. The bug has nothing to do with libata but it's just an workaround which is easy to backport. After discussion, Rafael and I seem to agree that we don't really need kernel freezables - both kthread and workqueue. There are few specific workqueues which constitute PM operations and require freezing, which will be converted to use workqueue_set_max_active() instead. All other kernel freezer uses are planned to be removed, followed by the removal of kthread and workqueue freezer support, hopefully. Others are device-specific fixes. The most notable is the addition of NO_NCQ_TRIM which is used to disable queued TRIM commands to Micro M500 SSDs which otherwise suffers data corruption" * 'for-3.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: libata, freezer: avoid block device removal while system is frozen libata: implement ATA_HORKAGE_NO_NCQ_TRIM and apply it to Micro M500 SSDs libata: disable a disk via libata.force params ahci: bail out on ICH6 before using AHCI BAR ahci: imx: Explicitly clear IMX6Q_GPR13_SATA_MPLL_CLK_EN libata: add ATA_HORKAGE_BROKEN_FPDMA_AA quirk for Seagate Momentus SpinPoint M8
This commit is contained in:
Коммит
4b69316ede
|
@ -1529,6 +1529,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
|
||||
* atapi_dmadir: Enable ATAPI DMADIR bridge support
|
||||
|
||||
* disable: Disable this device.
|
||||
|
||||
If there are multiple matching configurations changing
|
||||
the same attribute, the last one is used.
|
||||
|
||||
|
|
|
@ -1238,15 +1238,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* AHCI controllers often implement SFF compatible interface.
|
||||
* Grab all PCI BARs just in case.
|
||||
*/
|
||||
rc = pcim_iomap_regions_request_all(pdev, 1 << ahci_pci_bar, DRV_NAME);
|
||||
if (rc == -EBUSY)
|
||||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
(pdev->device == 0x2652 || pdev->device == 0x2653)) {
|
||||
u8 map;
|
||||
|
@ -1263,6 +1254,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
}
|
||||
}
|
||||
|
||||
/* AHCI controllers often implement SFF compatible interface.
|
||||
* Grab all PCI BARs just in case.
|
||||
*/
|
||||
rc = pcim_iomap_regions_request_all(pdev, 1 << ahci_pci_bar, DRV_NAME);
|
||||
if (rc == -EBUSY)
|
||||
pcim_pin_device(pdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
|
||||
if (!hpriv)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -113,7 +113,7 @@ static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
|
|||
/*
|
||||
* set PHY Paremeters, two steps to configure the GPR13,
|
||||
* one write for rest of parameters, mask of first write
|
||||
* is 0x07fffffd, and the other one write for setting
|
||||
* is 0x07ffffff, and the other one write for setting
|
||||
* the mpll_clk_en.
|
||||
*/
|
||||
regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK
|
||||
|
@ -124,6 +124,7 @@ static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
|
|||
| IMX6Q_GPR13_SATA_TX_ATTEN_MASK
|
||||
| IMX6Q_GPR13_SATA_TX_BOOST_MASK
|
||||
| IMX6Q_GPR13_SATA_TX_LVL_MASK
|
||||
| IMX6Q_GPR13_SATA_MPLL_CLK_EN
|
||||
| IMX6Q_GPR13_SATA_TX_EDGE_RATE
|
||||
, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB
|
||||
| IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M
|
||||
|
|
|
@ -2149,9 +2149,16 @@ static int ata_dev_config_ncq(struct ata_device *dev,
|
|||
"failed to get NCQ Send/Recv Log Emask 0x%x\n",
|
||||
err_mask);
|
||||
} else {
|
||||
u8 *cmds = dev->ncq_send_recv_cmds;
|
||||
|
||||
dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
|
||||
memcpy(dev->ncq_send_recv_cmds, ap->sector_buf,
|
||||
ATA_LOG_NCQ_SEND_RECV_SIZE);
|
||||
memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE);
|
||||
|
||||
if (dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM) {
|
||||
ata_dev_dbg(dev, "disabling queued TRIM support\n");
|
||||
cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] &=
|
||||
~ATA_LOG_NCQ_SEND_RECV_DSM_TRIM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4156,6 +4163,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|||
{ "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ |
|
||||
ATA_HORKAGE_FIRMWARE_WARN },
|
||||
|
||||
/* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */
|
||||
{ "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA },
|
||||
|
||||
/* Blacklist entries taken from Silicon Image 3124/3132
|
||||
Windows driver .inf file - also several Linux problem reports */
|
||||
{ "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
|
||||
|
@ -4202,6 +4212,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|||
{ "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER },
|
||||
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
|
||||
|
||||
/* devices that don't properly handle queued TRIM commands */
|
||||
{ "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT???M500SSD1", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
|
||||
/* End Marker */
|
||||
{ }
|
||||
};
|
||||
|
@ -6519,6 +6533,7 @@ static int __init ata_parse_force_one(char **cur,
|
|||
{ "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
|
||||
{ "rstonce", .lflags = ATA_LFLAG_RST_ONCE },
|
||||
{ "atapi_dmadir", .horkage_on = ATA_HORKAGE_ATAPI_DMADIR },
|
||||
{ "disable", .horkage_on = ATA_HORKAGE_DISABLE },
|
||||
};
|
||||
char *start = *cur, *p = *cur;
|
||||
char *id, *val, *endp;
|
||||
|
|
|
@ -3872,6 +3872,27 @@ void ata_scsi_hotplug(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - UGLY HACK
|
||||
*
|
||||
* The block layer suspend/resume path is fundamentally broken due
|
||||
* to freezable kthreads and workqueue and may deadlock if a block
|
||||
* device gets removed while resume is in progress. I don't know
|
||||
* what the solution is short of removing freezable kthreads and
|
||||
* workqueues altogether.
|
||||
*
|
||||
* The following is an ugly hack to avoid kicking off device
|
||||
* removal while freezer is active. This is a joke but does avoid
|
||||
* this particular deadlock scenario.
|
||||
*
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=62801
|
||||
* http://marc.info/?l=linux-kernel&m=138695698516487
|
||||
*/
|
||||
#ifdef CONFIG_FREEZER
|
||||
while (pm_freezing)
|
||||
msleep(10);
|
||||
#endif
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
mutex_lock(&ap->scsi_scan_mutex);
|
||||
|
||||
|
|
|
@ -418,6 +418,7 @@ enum {
|
|||
ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */
|
||||
ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */
|
||||
ATA_HORKAGE_ATAPI_DMADIR = (1 << 18), /* device requires dmadir */
|
||||
ATA_HORKAGE_NO_NCQ_TRIM = (1 << 19), /* don't use queued TRIM */
|
||||
|
||||
/* DMA mask for user DMA control: User visible values; DO NOT
|
||||
renumber */
|
||||
|
|
|
@ -19,6 +19,12 @@ EXPORT_SYMBOL(system_freezing_cnt);
|
|||
bool pm_freezing;
|
||||
bool pm_nosig_freezing;
|
||||
|
||||
/*
|
||||
* Temporary export for the deadlock workaround in ata_scsi_hotplug().
|
||||
* Remove once the hack becomes unnecessary.
|
||||
*/
|
||||
EXPORT_SYMBOL_GPL(pm_freezing);
|
||||
|
||||
/* protects freezing and frozen transitions */
|
||||
static DEFINE_SPINLOCK(freezer_lock);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче