mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-11 07:39:47 +00:00
ata: move sata_link_hardreset() to libata-sata.c
* move sata_link_hardreset() to libata-sata.c * add static inline for CONFIG_SATA_HOST=n case * make sata_set_spd_needed() static Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32724 572 40 33336 8238 drivers/ata/libata-core.o after: 32559 572 40 33171 8193 drivers/ata/libata-core.o Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
9d3158f5cb
commit
78c97c80d7
@ -3531,119 +3531,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_std_prereset);
|
||||
|
||||
/**
|
||||
* sata_link_hardreset - reset link via SATA phy reset
|
||||
* @link: link to reset
|
||||
* @timing: timing parameters { interval, duration, timeout } in msec
|
||||
* @deadline: deadline jiffies for the operation
|
||||
* @online: optional out parameter indicating link onlineness
|
||||
* @check_ready: optional callback to check link readiness
|
||||
*
|
||||
* SATA phy-reset @link using DET bits of SControl register.
|
||||
* After hardreset, link readiness is waited upon using
|
||||
* ata_wait_ready() if @check_ready is specified. LLDs are
|
||||
* allowed to not specify @check_ready and wait itself after this
|
||||
* function returns. Device classification is LLD's
|
||||
* responsibility.
|
||||
*
|
||||
* *@online is set to one iff reset succeeded and @link is online
|
||||
* after reset.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
|
||||
unsigned long deadline,
|
||||
bool *online, int (*check_ready)(struct ata_link *))
|
||||
{
|
||||
u32 scontrol;
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
if (online)
|
||||
*online = false;
|
||||
|
||||
if (sata_set_spd_needed(link)) {
|
||||
/* SATA spec says nothing about how to reconfigure
|
||||
* spd. To be on the safe side, turn off phy during
|
||||
* reconfiguration. This works for at least ICH7 AHCI
|
||||
* and Sil3124.
|
||||
*/
|
||||
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
||||
goto out;
|
||||
|
||||
scontrol = (scontrol & 0x0f0) | 0x304;
|
||||
|
||||
if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
|
||||
goto out;
|
||||
|
||||
sata_set_spd(link);
|
||||
}
|
||||
|
||||
/* issue phy wake/reset */
|
||||
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
||||
goto out;
|
||||
|
||||
scontrol = (scontrol & 0x0f0) | 0x301;
|
||||
|
||||
if ((rc = sata_scr_write_flush(link, SCR_CONTROL, scontrol)))
|
||||
goto out;
|
||||
|
||||
/* Couldn't find anything in SATA I/II specs, but AHCI-1.1
|
||||
* 10.4.2 says at least 1 ms.
|
||||
*/
|
||||
ata_msleep(link->ap, 1);
|
||||
|
||||
/* bring link back */
|
||||
rc = sata_link_resume(link, timing, deadline);
|
||||
if (rc)
|
||||
goto out;
|
||||
/* if link is offline nothing more to do */
|
||||
if (ata_phys_link_offline(link))
|
||||
goto out;
|
||||
|
||||
/* Link is online. From this point, -ENODEV too is an error. */
|
||||
if (online)
|
||||
*online = true;
|
||||
|
||||
if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) {
|
||||
/* If PMP is supported, we have to do follow-up SRST.
|
||||
* Some PMPs don't send D2H Reg FIS after hardreset if
|
||||
* the first port is empty. Wait only for
|
||||
* ATA_TMOUT_PMP_SRST_WAIT.
|
||||
*/
|
||||
if (check_ready) {
|
||||
unsigned long pmp_deadline;
|
||||
|
||||
pmp_deadline = ata_deadline(jiffies,
|
||||
ATA_TMOUT_PMP_SRST_WAIT);
|
||||
if (time_after(pmp_deadline, deadline))
|
||||
pmp_deadline = deadline;
|
||||
ata_wait_ready(link, pmp_deadline, check_ready);
|
||||
}
|
||||
rc = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
if (check_ready)
|
||||
rc = ata_wait_ready(link, deadline, check_ready);
|
||||
out:
|
||||
if (rc && rc != -EAGAIN) {
|
||||
/* online is set iff link is online && reset succeeded */
|
||||
if (online)
|
||||
*online = false;
|
||||
ata_link_err(link, "COMRESET failed (errno=%d)\n", rc);
|
||||
}
|
||||
DPRINTK("EXIT, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sata_link_hardreset);
|
||||
|
||||
/**
|
||||
* sata_std_hardreset - COMRESET w/o waiting or classification
|
||||
* @link: link to reset
|
||||
|
@ -449,7 +449,7 @@ static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
|
||||
* RETURNS:
|
||||
* 1 if SATA spd configuration is needed, 0 otherwise.
|
||||
*/
|
||||
int sata_set_spd_needed(struct ata_link *link)
|
||||
static int sata_set_spd_needed(struct ata_link *link)
|
||||
{
|
||||
u32 scontrol;
|
||||
|
||||
@ -490,6 +490,119 @@ int sata_set_spd(struct ata_link *link)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sata_set_spd);
|
||||
|
||||
/**
|
||||
* sata_link_hardreset - reset link via SATA phy reset
|
||||
* @link: link to reset
|
||||
* @timing: timing parameters { interval, duration, timeout } in msec
|
||||
* @deadline: deadline jiffies for the operation
|
||||
* @online: optional out parameter indicating link onlineness
|
||||
* @check_ready: optional callback to check link readiness
|
||||
*
|
||||
* SATA phy-reset @link using DET bits of SControl register.
|
||||
* After hardreset, link readiness is waited upon using
|
||||
* ata_wait_ready() if @check_ready is specified. LLDs are
|
||||
* allowed to not specify @check_ready and wait itself after this
|
||||
* function returns. Device classification is LLD's
|
||||
* responsibility.
|
||||
*
|
||||
* *@online is set to one iff reset succeeded and @link is online
|
||||
* after reset.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
|
||||
unsigned long deadline,
|
||||
bool *online, int (*check_ready)(struct ata_link *))
|
||||
{
|
||||
u32 scontrol;
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
||||
if (online)
|
||||
*online = false;
|
||||
|
||||
if (sata_set_spd_needed(link)) {
|
||||
/* SATA spec says nothing about how to reconfigure
|
||||
* spd. To be on the safe side, turn off phy during
|
||||
* reconfiguration. This works for at least ICH7 AHCI
|
||||
* and Sil3124.
|
||||
*/
|
||||
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
||||
goto out;
|
||||
|
||||
scontrol = (scontrol & 0x0f0) | 0x304;
|
||||
|
||||
if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
|
||||
goto out;
|
||||
|
||||
sata_set_spd(link);
|
||||
}
|
||||
|
||||
/* issue phy wake/reset */
|
||||
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
||||
goto out;
|
||||
|
||||
scontrol = (scontrol & 0x0f0) | 0x301;
|
||||
|
||||
if ((rc = sata_scr_write_flush(link, SCR_CONTROL, scontrol)))
|
||||
goto out;
|
||||
|
||||
/* Couldn't find anything in SATA I/II specs, but AHCI-1.1
|
||||
* 10.4.2 says at least 1 ms.
|
||||
*/
|
||||
ata_msleep(link->ap, 1);
|
||||
|
||||
/* bring link back */
|
||||
rc = sata_link_resume(link, timing, deadline);
|
||||
if (rc)
|
||||
goto out;
|
||||
/* if link is offline nothing more to do */
|
||||
if (ata_phys_link_offline(link))
|
||||
goto out;
|
||||
|
||||
/* Link is online. From this point, -ENODEV too is an error. */
|
||||
if (online)
|
||||
*online = true;
|
||||
|
||||
if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) {
|
||||
/* If PMP is supported, we have to do follow-up SRST.
|
||||
* Some PMPs don't send D2H Reg FIS after hardreset if
|
||||
* the first port is empty. Wait only for
|
||||
* ATA_TMOUT_PMP_SRST_WAIT.
|
||||
*/
|
||||
if (check_ready) {
|
||||
unsigned long pmp_deadline;
|
||||
|
||||
pmp_deadline = ata_deadline(jiffies,
|
||||
ATA_TMOUT_PMP_SRST_WAIT);
|
||||
if (time_after(pmp_deadline, deadline))
|
||||
pmp_deadline = deadline;
|
||||
ata_wait_ready(link, pmp_deadline, check_ready);
|
||||
}
|
||||
rc = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
if (check_ready)
|
||||
rc = ata_wait_ready(link, deadline, check_ready);
|
||||
out:
|
||||
if (rc && rc != -EAGAIN) {
|
||||
/* online is set iff link is online && reset succeeded */
|
||||
if (online)
|
||||
*online = false;
|
||||
ata_link_err(link, "COMRESET failed (errno=%d)\n", rc);
|
||||
}
|
||||
DPRINTK("EXIT, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sata_link_hardreset);
|
||||
|
||||
/**
|
||||
* ata_slave_link_init - initialize slave link
|
||||
* @ap: port to initialize slave link for
|
||||
|
@ -87,13 +87,6 @@ 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)
|
||||
|
||||
/* libata-sata.c */
|
||||
#ifdef CONFIG_SATA_HOST
|
||||
int sata_set_spd_needed(struct ata_link *link);
|
||||
#else
|
||||
static inline int sata_set_spd_needed(struct ata_link *link) { return 1; }
|
||||
#endif
|
||||
|
||||
/* libata-acpi.c */
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
extern unsigned int ata_acpi_gtf_filter;
|
||||
|
@ -1077,9 +1077,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
|
||||
extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
|
||||
extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
|
||||
int (*check_ready)(struct ata_link *link));
|
||||
extern int sata_link_hardreset(struct ata_link *link,
|
||||
const unsigned long *timing, unsigned long deadline,
|
||||
bool *online, int (*check_ready)(struct ata_link *));
|
||||
extern int sata_std_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
extern void ata_std_postreset(struct ata_link *link, unsigned int *classes);
|
||||
@ -1190,6 +1187,9 @@ extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
|
||||
extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
|
||||
extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val);
|
||||
extern int sata_set_spd(struct ata_link *link);
|
||||
extern int sata_link_hardreset(struct ata_link *link,
|
||||
const unsigned long *timing, unsigned long deadline,
|
||||
bool *online, int (*check_ready)(struct ata_link *));
|
||||
extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
||||
unsigned long deadline);
|
||||
#else
|
||||
@ -1207,6 +1207,16 @@ static inline int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int sata_set_spd(struct ata_link *link) { return -EOPNOTSUPP; }
|
||||
static inline int sata_link_hardreset(struct ata_link *link,
|
||||
const unsigned long *timing,
|
||||
unsigned long deadline,
|
||||
bool *online,
|
||||
int (*check_ready)(struct ata_link *))
|
||||
{
|
||||
if (online)
|
||||
*online = false;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int sata_link_resume(struct ata_link *link,
|
||||
const unsigned long *params,
|
||||
unsigned long deadline)
|
||||
|
Loading…
x
Reference in New Issue
Block a user