Commit 3a0eb192 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.7/libata-2020-03-29' of git://git.kernel.dk/linux-block

Pull libata updates from Jens Axboe:

 - Series from Bart, making the libata code smaller on PATA only setups.
   This is useful for smaller/embedded use cases, and will help us move
   some of those off drivers/ide.

 - Kill unused BPRINTK() (Hannes)

 - Add various Comet Lake ahci PCI ids (Kai-Heng, Mika)

 - Fix for a double scsi_host_put() in error handling (John)

 - Use scnprintf (Takashi)

 - Assign OF node to the SCSI device (Linus Walleij)

* tag 'for-5.7/libata-2020-03-29' of git://git.kernel.dk/linux-block: (36 commits)
  ata: make "libata.force" kernel parameter optional
  ata: move ata_eh_analyze_ncq_error() & co. to libata-sata.c
  ata: start separating SATA specific code from libata-eh.c
  ata: move ata_sas_*() to libata-sata.c
  ata: start separating SATA specific code from libata-scsi.c
  ata: move sata_deb_timing_*() to libata-sata.c
  ata: move ata_qc_complete_multiple() to libata-sata.c
  ata: move sata_link_hardreset() to libata-sata.c
  ata: move sata_link_{debounce,resume}() to libata-sata.c
  ata: move *sata_set_spd*() to libata-sata.c
  ata: move sata_scr_*() to libata-sata.c
  ata: start separating SATA specific code from libata-core.c
  ata: let compiler optimize out ata_eh_set_lpm() on non-SATA hosts
  ata: let compiler optimize out ata_dev_config_ncq() on non-SATA hosts
  ata: add CONFIG_SATA_HOST=n version of ata_ncq_enabled()
  ata: separate PATA timings code from libata-core.c
  ata: fix CodingStyle issues in PATA timings code
  ata: remove EXPORT_SYMBOL_GPL()s not used by modules
  ata: move EXPORT_SYMBOL_GPL()s close to exported code
  ata: optimize ata_scsi_rbuf[] size
  ...
parents c03cb664 bf89b0bf
This diff is collapsed.
...@@ -123,7 +123,9 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o ...@@ -123,7 +123,9 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-y := libata-core.o libata-scsi.o libata-eh.o \ libata-y := libata-core.o libata-scsi.o libata-eh.o \
libata-transport.o libata-trace.o libata-transport.o libata-trace.o
libata-$(CONFIG_SATA_HOST) += libata-sata.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o libata-$(CONFIG_SATA_ZPODD) += libata-zpodd.o
libata-$(CONFIG_PATA_TIMINGS) += libata-pata-timings.o
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
enum { enum {
AHCI_PCI_BAR_STA2X11 = 0, AHCI_PCI_BAR_STA2X11 = 0,
AHCI_PCI_BAR_CAVIUM = 0, AHCI_PCI_BAR_CAVIUM = 0,
AHCI_PCI_BAR_LOONGSON = 0,
AHCI_PCI_BAR_ENMOTUS = 2, AHCI_PCI_BAR_ENMOTUS = 2,
AHCI_PCI_BAR_CAVIUM_GEN5 = 4, AHCI_PCI_BAR_CAVIUM_GEN5 = 4,
AHCI_PCI_BAR_STANDARD = 5, AHCI_PCI_BAR_STANDARD = 5,
...@@ -245,6 +246,7 @@ static const struct ata_port_info ahci_port_info[] = { ...@@ -245,6 +246,7 @@ static const struct ata_port_info ahci_port_info[] = {
static const struct pci_device_id ahci_pci_tbl[] = { static const struct pci_device_id ahci_pci_tbl[] = {
/* Intel */ /* Intel */
{ PCI_VDEVICE(INTEL, 0x06d6), board_ahci }, /* Comet Lake PCH-H RAID */
{ PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */ { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
{ PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */ { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
{ PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
...@@ -401,6 +403,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -401,6 +403,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
{ PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */
{ PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */
{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
...@@ -589,6 +593,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -589,6 +593,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Enmotus */ /* Enmotus */
{ PCI_DEVICE(0x1c44, 0x8000), board_ahci }, { PCI_DEVICE(0x1c44, 0x8000), board_ahci },
/* Loongson */
{ PCI_VDEVICE(LOONGSON, 0x7a08), board_ahci },
/* Generic, PCI class code for AHCI */ /* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
...@@ -1680,6 +1687,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1680,6 +1687,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM; ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
if (pdev->device == 0xa084) if (pdev->device == 0xa084)
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM_GEN5; ahci_pci_bar = AHCI_PCI_BAR_CAVIUM_GEN5;
} else if (pdev->vendor == PCI_VENDOR_ID_LOONGSON) {
if (pdev->device == 0x7a08)
ahci_pci_bar = AHCI_PCI_BAR_LOONGSON;
} }
/* acquire resources */ /* acquire resources */
......
This diff is collapsed.
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
/* /*
* libata-eh.c - libata error handling * libata-eh.c - libata error handling
* *
* Maintained by: Tejun Heo <tj@kernel.org>
* Please ALWAYS copy linux-ide@vger.kernel.org
* on emails.
*
* Copyright 2006 Tejun Heo <htejun@gmail.com> * Copyright 2006 Tejun Heo <htejun@gmail.com>
* *
* libata documentation is available via 'make {ps|pdf}docs', * libata documentation is available via 'make {ps|pdf}docs',
...@@ -184,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) ...@@ -184,6 +180,7 @@ void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
__ata_ehi_pushv_desc(ehi, fmt, args); __ata_ehi_pushv_desc(ehi, fmt, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
/** /**
* ata_ehi_push_desc - push error description with separator * ata_ehi_push_desc - push error description with separator
...@@ -207,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) ...@@ -207,6 +204,7 @@ void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
__ata_ehi_pushv_desc(ehi, fmt, args); __ata_ehi_pushv_desc(ehi, fmt, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
/** /**
* ata_ehi_clear_desc - clean error description * ata_ehi_clear_desc - clean error description
...@@ -222,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi) ...@@ -222,6 +220,7 @@ void ata_ehi_clear_desc(struct ata_eh_info *ehi)
ehi->desc[0] = '\0'; ehi->desc[0] = '\0';
ehi->desc_len = 0; ehi->desc_len = 0;
} }
EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
/** /**
* ata_port_desc - append port description * ata_port_desc - append port description
...@@ -249,9 +248,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...) ...@@ -249,9 +248,9 @@ void ata_port_desc(struct ata_port *ap, const char *fmt, ...)
__ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args); __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args);
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(ata_port_desc);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/** /**
* ata_port_pbar_desc - append PCI BAR description * ata_port_pbar_desc - append PCI BAR description
* @ap: target ATA port * @ap: target ATA port
...@@ -288,7 +287,7 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, ...@@ -288,7 +287,7 @@ void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
ata_port_desc(ap, "%s 0x%llx", name, ata_port_desc(ap, "%s 0x%llx", name,
start + (unsigned long long)offset); start + (unsigned long long)offset);
} }
EXPORT_SYMBOL_GPL(ata_port_pbar_desc);
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
static int ata_lookup_timeout_table(u8 cmd) static int ata_lookup_timeout_table(u8 cmd)
...@@ -973,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap) ...@@ -973,6 +972,7 @@ void ata_port_schedule_eh(struct ata_port *ap)
/* see: ata_std_sched_eh, unless you know better */ /* see: ata_std_sched_eh, unless you know better */
ap->ops->sched_eh(ap); ap->ops->sched_eh(ap);
} }
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
{ {
...@@ -1015,6 +1015,7 @@ int ata_link_abort(struct ata_link *link) ...@@ -1015,6 +1015,7 @@ int ata_link_abort(struct ata_link *link)
{ {
return ata_do_link_abort(link->ap, link); return ata_do_link_abort(link->ap, link);
} }
EXPORT_SYMBOL_GPL(ata_link_abort);
/** /**
* ata_port_abort - abort all qc's on the port * ata_port_abort - abort all qc's on the port
...@@ -1032,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap) ...@@ -1032,6 +1033,7 @@ int ata_port_abort(struct ata_port *ap)
{ {
return ata_do_link_abort(ap, NULL); return ata_do_link_abort(ap, NULL);
} }
EXPORT_SYMBOL_GPL(ata_port_abort);
/** /**
* __ata_port_freeze - freeze port * __ata_port_freeze - freeze port
...@@ -1088,79 +1090,7 @@ int ata_port_freeze(struct ata_port *ap) ...@@ -1088,79 +1090,7 @@ int ata_port_freeze(struct ata_port *ap)
return nr_aborted; return nr_aborted;
} }
EXPORT_SYMBOL_GPL(ata_port_freeze);
/**
* sata_async_notification - SATA async notification handler
* @ap: ATA port where async notification is received
*
* Handler to be called when async notification via SDB FIS is
* received. This function schedules EH if necessary.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*
* RETURNS:
* 1 if EH is scheduled, 0 otherwise.
*/
int sata_async_notification(struct ata_port *ap)
{
u32 sntf;
int rc;
if (!(ap->flags & ATA_FLAG_AN))
return 0;
rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf);
if (rc == 0)
sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf);
if (!sata_pmp_attached(ap) || rc) {
/* PMP is not attached or SNTF is not available */
if (!sata_pmp_attached(ap)) {
/* PMP is not attached. Check whether ATAPI
* AN is configured. If so, notify media
* change.
*/
struct ata_device *dev = ap->link.device;
if ((dev->class == ATA_DEV_ATAPI) &&
(dev->flags & ATA_DFLAG_AN))
ata_scsi_media_change_notify(dev);
return 0;
} else {
/* PMP is attached but SNTF is not available.
* ATAPI async media change notification is
* not used. The PMP must be reporting PHY
* status change, schedule EH.
*/
ata_port_schedule_eh(ap);
return 1;
}
} else {
/* PMP is attached and SNTF is available */
struct ata_link *link;
/* check and notify ATAPI AN */
ata_for_each_link(link, ap, EDGE) {
if (!(sntf & (1 << link->pmp)))
continue;
if ((link->device->class == ATA_DEV_ATAPI) &&
(link->device->flags & ATA_DFLAG_AN))
ata_scsi_media_change_notify(link->device);
}
/* If PMP is reporting that PHY status of some
* downstream ports has changed, schedule EH.
*/
if (sntf & (1 << SATA_PMP_CTRL_PORT)) {
ata_port_schedule_eh(ap);
return 1;
}
return 0;
}
}
/** /**
* ata_eh_freeze_port - EH helper to freeze port * ata_eh_freeze_port - EH helper to freeze port
...@@ -1182,6 +1112,7 @@ void ata_eh_freeze_port(struct ata_port *ap) ...@@ -1182,6 +1112,7 @@ void ata_eh_freeze_port(struct ata_port *ap)
__ata_port_freeze(ap); __ata_port_freeze(ap);
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
} }
EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
/** /**
* ata_port_thaw_port - EH helper to thaw port * ata_port_thaw_port - EH helper to thaw port
...@@ -1289,6 +1220,7 @@ void ata_dev_disable(struct ata_device *dev) ...@@ -1289,6 +1220,7 @@ void ata_dev_disable(struct ata_device *dev)
*/ */
ata_ering_clear(&dev->ering); ata_ering_clear(&dev->ering);
} }
EXPORT_SYMBOL_GPL(ata_dev_disable);
/** /**
* ata_eh_detach_dev - detach ATA device * ata_eh_detach_dev - detach ATA device
...@@ -1419,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask) ...@@ -1419,62 +1351,6 @@ static const char *ata_err_string(unsigned int err_mask)
return "unknown error"; return "unknown error";
} }
/**
* ata_eh_read_log_10h - Read log page 10h for NCQ error details
* @dev: Device to read log page 10h from
* @tag: Resulting tag of the failed command
* @tf: Resulting taskfile registers of the failed command
*
* Read log page 10h to obtain NCQ error details and clear error
* condition.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* 0 on success, -errno otherwise.
*/
static int ata_eh_read_log_10h(struct ata_device *dev,
int *tag, struct ata_taskfile *tf)
{
u8 *buf = dev->link->ap->sector_buf;
unsigned int err_mask;
u8 csum;
int i;
err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1);
if (err_mask)
return -EIO;
csum = 0;
for (i = 0; i < ATA_SECT_SIZE; i++)
csum += buf[i];
if (csum)
ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n",
csum);
if (buf[0] & 0x80)
return -ENOENT;
*tag = buf[0] & 0x1f;
tf->command = buf[2];
tf->feature = buf[3];
tf->lbal = buf[4];
tf->lbam = buf[5];
tf->lbah = buf[6];
tf->device = buf[7];
tf->hob_lbal = buf[8];
tf->hob_lbam = buf[9];
tf->hob_lbah = buf[10];
tf->nsect = buf[12];
tf->hob_nsect = buf[13];
if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id))
tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
return 0;
}
/** /**
* atapi_eh_tur - perform ATAPI TEST_UNIT_READY * atapi_eh_tur - perform ATAPI TEST_UNIT_READY
* @dev: target ATAPI device * @dev: target ATAPI device
...@@ -1658,80 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link) ...@@ -1658,80 +1534,6 @@ static void ata_eh_analyze_serror(struct ata_link *link)
ehc->i.action |= action; ehc->i.action |= action;
} }
/**
* ata_eh_analyze_ncq_error - analyze NCQ error
* @link: ATA link to analyze NCQ error for
*
* Read log page 10h, determine the offending qc and acquire
* error status TF. For NCQ device errors, all LLDDs have to do
* is setting AC_ERR_DEV in ehi->err_mask. This function takes
* care of the rest.
*
* LOCKING:
* Kernel thread context (may sleep).
*/
void ata_eh_analyze_ncq_error(struct ata_link *link)
{
struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev = link->device;
struct ata_queued_cmd *qc;
struct ata_taskfile tf;
int tag, rc;
/* if frozen, we can't do much */
if (ap->pflags & ATA_PFLAG_FROZEN)
return;
/* is it NCQ device error? */
if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV))
return;
/* has LLDD analyzed already? */
ata_qc_for_each_raw(ap, qc, tag) {
if (!(qc->flags & ATA_QCFLAG_FAILED))
continue;
if (qc->err_mask)
return;
}
/* okay, this error is ours */
memset(&tf, 0, sizeof(tf));
rc = ata_eh_read_log_10h(dev, &tag, &tf);
if (rc) {
ata_link_err(link, "failed to read log page 10h (errno=%d)\n",
rc);
return;
}
if (!(link->sactive & (1 << tag))) {
ata_link_err(link, "log page 10h reported inactive tag %d\n",
tag);
return;
}
/* we've got the perpetrator, condemn it */
qc = __ata_qc_from_tag(ap, tag);
memcpy(&qc->result_tf, &tf, sizeof(tf));
qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
if (dev->class == ATA_DEV_ZAC &&
((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) {
char sense_key, asc, ascq;
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
ascq = qc->result_tf.auxiliary & 0xff;
ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
ata_scsi_set_sense_information(dev, qc->scsicmd,
&qc->result_tf);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
}
ehc->i.err_mask &= ~AC_ERR_DEV;
}
/** /**
* ata_eh_analyze_tf - analyze taskfile of a failed qc * ata_eh_analyze_tf - analyze taskfile of a failed qc
* @qc: qc to analyze * @qc: qc to analyze
...@@ -3436,7 +3238,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, ...@@ -3436,7 +3238,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
int rc; int rc;
/* if the link or host doesn't do LPM, noop */ /* if the link or host doesn't do LPM, noop */
if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) if (!IS_ENABLED(CONFIG_SATA_HOST) ||
(link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm))
return 0; return 0;
/* /*
...@@ -4052,6 +3855,7 @@ void ata_std_error_handler(struct ata_port *ap) ...@@ -4052,6 +3855,7 @@ void ata_std_error_handler(struct ata_port *ap)
ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
} }
EXPORT_SYMBOL_GPL(ata_std_error_handler);
#ifdef CONFIG_PM #ifdef CONFIG_PM
/** /**
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Helper library for PATA timings
*
* Copyright 2003-2004 Red Hat, Inc. All rights reserved.
* Copyright 2003-2004 Jeff Garzik
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/libata.h>
/*
* This mode timing computation functionality is ported over from
* drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik
*/
/*
* PIO 0-4, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
* These were taken from ATA/ATAPI-6 standard, rev 0a, except
* for UDMA6, which is currently supported only by Maxtor drives.
*
* For PIO 5/6 MWDMA 3/4 see the CFA specification 3.0.
*/
static const struct ata_timing ata_timing[] = {
/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 0, 960, 0 }, */
{ XFER_PIO_0, 70, 290, 240, 600, 165, 150, 0, 600, 0 },
{ XFER_PIO_1, 50, 290, 93, 383, 125, 100, 0, 383, 0 },
{ XFER_PIO_2, 30, 290, 40, 330, 100, 90, 0, 240, 0 },
{ XFER_PIO_3, 30, 80, 70, 180, 80, 70, 0, 180, 0 },
{ XFER_PIO_4, 25, 70, 25, 120, 70, 25, 0, 120, 0 },
{ XFER_PIO_5, 15, 65, 25, 100, 65, 25, 0, 100, 0 },
{ XFER_PIO_6, 10, 55, 20, 80, 55, 20, 0, 80, 0 },
{ XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 50, 960, 0 },
{ XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 30, 480, 0 },
{ XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 20, 240, 0 },
{ XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 20, 480, 0 },
{ XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 5, 150, 0 },
{ XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 5, 120, 0 },
{ XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 5, 100, 0 },
{ XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 5, 80, 0 },
/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 0, 150 }, */
{ XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 0, 120 },
{ XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 0, 80 },
{ XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 0, 60 },
{ XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 0, 45 },
{ XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 0, 30 },
{ XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
{ XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
{ 0xFF }
};
#define ENOUGH(v, unit) (((v)-1)/(unit)+1)
#define EZ(v, unit) ((v)?ENOUGH(((v) * 1000), unit):0)
static void ata_timing_quantize(const struct ata_timing *t,
struct ata_timing *q, int T, int UT)
{
q->setup = EZ(t->setup, T);
q->act8b = EZ(t->act8b, T);
q->rec8b = EZ(t->rec8b, T);
q->cyc8b = EZ(t->cyc8b, T);
q->active = EZ(t->active, T);
q->recover = EZ(t->recover, T);
q->dmack_hold = EZ(t->dmack_hold, T);
q->cycle = EZ(t->cycle, T);
q->udma = EZ(t->udma, UT);
}
void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
struct ata_timing *m, unsigned int what)
{
if (what & ATA_TIMING_SETUP)
m->setup = max(a->setup, b->setup);
if (what & ATA_TIMING_ACT8B)
m->act8b = max(a->act8b, b->act8b);
if (what & ATA_TIMING_REC8B)
m->rec8b = max(a->rec8b, b->rec8b);
if (what & ATA_TIMING_CYC8B)
m->cyc8b = max(a->cyc8b, b->cyc8b);
if (what & ATA_TIMING_ACTIVE)
m->active = max(a->active, b->active);
if (what & ATA_TIMING_RECOVER)
m->recover = max(a->recover, b->recover);
if (what & ATA_TIMING_DMACK_HOLD)
m->dmack_hold = max(a->dmack_hold, b->dmack_hold);
if (what & ATA_TIMING_CYCLE)
m->cycle = max(a->cycle, b->cycle);
if (what & ATA_TIMING_UDMA)
m->udma = max(a->udma, b->udma);
}
EXPORT_SYMBOL_GPL(ata_timing_merge);
const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
{
const struct ata_timing *t = ata_timing;
while (xfer_mode > t->mode)
t++;
if (xfer_mode == t->mode)
return t;
WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n",
__func__, xfer_mode);
return NULL;
}
EXPORT_SYMBOL_GPL(ata_timing_find_mode);
int ata_timing_compute(struct ata_device *adev, unsigned short speed,
struct ata_timing *t, int T, int UT)
{
const u16 *id = adev->id;
const struct ata_timing *s;
struct ata_timing p;
/*
* Find the mode.
*/
s = ata_timing_find_mode(speed);
if (!s)
return -EINVAL;
memcpy(t, s, sizeof(*s));
/*
* If the drive is an EIDE drive, it can tell us it needs extended
* PIO/MW_DMA cycle timing.
*/
if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */
memset(&p, 0, sizeof(p));
if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) {
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
else if ((speed <= XFER_PIO_4) ||
(speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
} else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
p.cycle = id[ATA_ID_EIDE_DMA_MIN];
ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B);
}
/*
* Convert the timing to bus clock counts.
*/
ata_timing_quantize(t, t, T, UT);
/*
* Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
* S.M.A.R.T * and some other commands. We have to ensure that the
* DMA cycle timing is slower/equal than the fastest PIO timing.
*/
if (speed > XFER_PIO_6) {
ata_timing_compute(adev, adev->pio_mode, &p, T, UT);
ata_timing_merge(&p, t, t, ATA_TIMING_ALL);
}
/*
* Lengthen active & recovery time so that cycle time is correct.
*/
if (t->act8b + t->rec8b < t->cyc8b) {
t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
t->rec8b = t->cyc8b - t->act8b;
}
if (t->active + t->recover < t->cycle) {
t->active += (t->cycle - (t->active + t->recover)) / 2;
t->recover = t->cycle - t->active;
}
/*
* In a few cases quantisation may produce enough errors to
* leave t->cycle too low for the sum of active and recovery
* if so we must correct this.
*/
if (t->active + t->recover > t->cycle)
t->cycle = t->active + t->recover;
return 0;
}
EXPORT_SYMBOL_GPL(ata_timing_compute);
This diff is collapsed.
This diff is collapsed.
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
/* /*
* libata-sff.c - helper library for PCI IDE BMDMA * libata-sff.c - helper library for PCI IDE BMDMA
* *
* Maintained by: Tejun Heo <tj@kernel.org>
* Please ALWAYS copy linux-ide@vger.kernel.org
* on emails.
*
* Copyright 2003-2006 Red Hat, Inc. All rights reserved. * Copyright 2003-2006 Red Hat, Inc. All rights reserved.
* Copyright 2003-2006 Jeff Garzik * Copyright 2003-2006 Jeff Garzik
* *
......
...@@ -208,7 +208,7 @@ show_ata_port_##name(struct device *dev, \ ...@@ -208,7 +208,7 @@ show_ata_port_##name(struct device *dev, \
{ \ { \
struct ata_port *ap = transport_class_to_port(dev); \ struct ata_port *ap = transport_class_to_port(dev); \
\ \
return snprintf(buf, 20, format_string, cast ap->field); \ return scnprintf(buf, 20, format_string, cast ap->field); \
} }
#define ata_port_simple_attr(field, name, format_string, type) \ #define ata_port_simple_attr(field, name, format_string, type) \
...@@ -479,7 +479,7 @@ show_ata_dev_##field(struct device *dev, \ ...@@ -479,7 +479,7 @@ show_ata_dev_##field(struct device *dev, \
{ \ { \
struct ata_device *ata_dev = transport_class_to_dev(dev); \ struct ata_device *ata_dev = transport_class_to_dev(dev); \
\ \
return snprintf(buf, 20, format_string, cast ata_dev->field); \ return scnprintf(buf, 20, format_string, cast ata_dev->field); \
} }
#define ata_dev_simple_attr(field, format_string, type) \ #define ata_dev_simple_attr(field, format_string, type) \
...@@ -533,7 +533,7 @@ show_ata_dev_id(struct device *dev, ...@@ -533,7 +533,7 @@ show_ata_dev_id(struct device *dev,
if (ata_dev->class == ATA_DEV_PMP) if (ata_dev->class == ATA_DEV_PMP)
return 0; return 0;
for(i=0;i<ATA_ID_WORDS;i++) { for(i=0;i<ATA_ID_WORDS;i++) {
written += snprintf(buf+written, 20, "%04x%c", written += scnprintf(buf+written, 20, "%04x%c",
ata_dev->id[i], ata_dev->id[i],
((i+1) & 7) ? ' ' : '\n'); ((i+1) & 7) ? ' ' : '\n');
} }
...@@ -552,7 +552,7 @@ show_ata_dev_gscr(struct device *dev, ...@@ -552,7 +552,7 @@ show_ata_dev_gscr(struct device *dev,
if (ata_dev->class != ATA_DEV_PMP) if (ata_dev->class != ATA_DEV_PMP)
return 0; return 0;
for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) { for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) {
written += snprintf(buf+written, 20, "%08x%c", written += scnprintf(buf+written, 20, "%08x%c",
ata_dev->gscr[i], ata_dev->gscr[i],
((i+1) & 3) ? ' ' : '\n'); ((i+1) & 3) ? ' ' : '\n');
} }
...@@ -581,7 +581,7 @@ show_ata_dev_trim(struct device *dev, ...@@ -581,7 +581,7 @@ show_ata_dev_trim(struct device *dev,
else else
mode = "unqueued"; mode = "unqueued";
return snprintf(buf, 20, "%s\n", mode); return scnprintf(buf, 20, "%s\n", mode);
} }
static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL); static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL);
......
...@@ -37,7 +37,11 @@ extern int libata_noacpi; ...@@ -37,7 +37,11 @@ extern int libata_noacpi;
extern int libata_allow_tpm; extern int libata_allow_tpm;
extern const struct device_type ata_port_type; extern const struct device_type ata_port_type;
extern struct ata_link *ata_dev_phys_link(struct ata_device *dev); extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
#ifdef CONFIG_ATA_FORCE
extern void ata_force_cbl(struct ata_port *ap); extern void ata_force_cbl(struct ata_port *ap);
#else
static inline void ata_force_cbl(struct ata_port *ap) { }
#endif
extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag);
...@@ -87,6 +91,18 @@ extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, ...@@ -87,6 +91,18 @@ extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
#define to_ata_port(d) container_of(d, struct ata_port, tdev) #define to_ata_port(d) container_of(d, struct ata_port, tdev)
/* libata-sata.c */
#ifdef CONFIG_SATA_HOST
int ata_sas_allocate_tag(struct ata_port *ap);
void ata_sas_free_tag(unsigned int tag, struct ata_port *ap);
#else
static inline int ata_sas_allocate_tag(struct ata_port *ap)
{
return -EOPNOTSUPP;
}
static inline void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) { }
#endif
/* libata-acpi.c */ /* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
extern unsigned int ata_acpi_gtf_filter; extern unsigned int ata_acpi_gtf_filter;
...@@ -112,6 +128,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} ...@@ -112,6 +128,8 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {}
#endif #endif
/* libata-scsi.c */ /* libata-scsi.c */
extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
extern int ata_scsi_add_hosts(struct ata_host *host, extern int ata_scsi_add_hosts(struct ata_host *host,
struct scsi_host_template *sht); struct scsi_host_template *sht);
extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
...@@ -128,9 +146,10 @@ extern void ata_scsi_dev_rescan(struct work_struct *work); ...@@ -128,9 +146,10 @@ extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap); extern int ata_bus_probe(struct ata_port *ap);
extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, u64 lun); unsigned int id, u64 lun);
int ata_sas_allocate_tag(struct ata_port *ap); void ata_scsi_sdev_config(struct scsi_device *sdev);
void ata_sas_free_tag(unsigned int tag, struct ata_port *ap); int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev);
void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd);
int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev);
/* libata-eh.c */ /* libata-eh.c */
extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd); extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
......
...@@ -157,7 +157,6 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class, ...@@ -157,7 +157,6 @@ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
static void pdc_error_handler(struct ata_port *ap); static void pdc_error_handler(struct ata_port *ap);
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
static int pdc_pata_cable_detect(struct ata_port *ap); static int pdc_pata_cable_detect(struct ata_port *ap);
static int pdc_sata_cable_detect(struct ata_port *ap);
static struct scsi_host_template pdc_ata_sht = { static struct scsi_host_template pdc_ata_sht = {
ATA_BASE_SHT(DRV_NAME), ATA_BASE_SHT(DRV_NAME),
...@@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = { ...@@ -183,7 +182,7 @@ static const struct ata_port_operations pdc_common_ops = {
static struct ata_port_operations pdc_sata_ops = { static struct ata_port_operations pdc_sata_ops = {
.inherits = &pdc_common_ops, .inherits = &pdc_common_ops,
.cable_detect = pdc_sata_cable_detect, .cable_detect = ata_cable_sata,
.freeze = pdc_sata_freeze, .freeze = pdc_sata_freeze,
.thaw = pdc_sata_thaw, .thaw = pdc_sata_thaw,
.scr_read = pdc_sata_scr_read, .scr_read = pdc_sata_scr_read,
...@@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap) ...@@ -459,11 +458,6 @@ static int pdc_pata_cable_detect(struct ata_port *ap)
return ATA_CBL_PATA80; return ATA_CBL_PATA80;
} }
static int pdc_sata_cable_detect(struct ata_port *ap)
{
return ATA_CBL_SATA;
}
static int pdc_sata_scr_read(struct ata_link *link, static int pdc_sata_scr_read(struct ata_link *link,
unsigned int sc_reg, u32 *val) unsigned int sc_reg, u32 *val)
{ {
......
...@@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO ...@@ -989,6 +989,7 @@ config SCSI_SYM53C8XX_MMIO
config SCSI_IPR config SCSI_IPR
tristate "IBM Power Linux RAID adapter support" tristate "IBM Power Linux RAID adapter support"
depends on PCI && SCSI && ATA depends on PCI && SCSI && ATA
select SATA_HOST
select FW_LOADER select FW_LOADER
select IRQ_POLL select IRQ_POLL
select SGL_ALLOC select SGL_ALLOC
......
...@@ -19,6 +19,7 @@ config SCSI_SAS_ATA ...@@ -19,6 +19,7 @@ config SCSI_SAS_ATA
bool "ATA support for libsas (requires libata)" bool "ATA support for libsas (requires libata)"
depends on SCSI_SAS_LIBSAS depends on SCSI_SAS_LIBSAS
depends on ATA = y || ATA = SCSI_SAS_LIBSAS depends on ATA = y || ATA = SCSI_SAS_LIBSAS
select SATA_HOST
help help
Builds in ATA support into libsas. Will necessitate Builds in ATA support into libsas. Will necessitate
the loading of libata along with libsas. the loading of libata along with libsas.
......
This diff is collapsed.
...@@ -148,6 +148,8 @@ ...@@ -148,6 +148,8 @@
/* Vendors and devices. Sort key: vendor first, device next. */ /* Vendors and devices. Sort key: vendor first, device next. */
#define PCI_VENDOR_ID_LOONGSON 0x0014
#define PCI_VENDOR_ID_TTTECH 0x0357 #define PCI_VENDOR_ID_TTTECH 0x0357
#define PCI_DEVICE_ID_TTTECH_MC322 0x000a #define PCI_DEVICE_ID_TTTECH_MC322 0x000a
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment