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:

committed by
Jens Axboe

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);
|
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
|
* sata_std_hardreset - COMRESET w/o waiting or classification
|
||||||
* @link: link to reset
|
* @link: link to reset
|
||||||
|
@@ -449,7 +449,7 @@ static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
|
|||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 1 if SATA spd configuration is needed, 0 otherwise.
|
* 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;
|
u32 scontrol;
|
||||||
|
|
||||||
@@ -490,6 +490,119 @@ int sata_set_spd(struct ata_link *link)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sata_set_spd);
|
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
|
* ata_slave_link_init - initialize slave link
|
||||||
* @ap: port to initialize slave link for
|
* @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)
|
#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 */
|
/* 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;
|
||||||
|
@@ -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_std_prereset(struct ata_link *link, unsigned long deadline);
|
||||||
extern int ata_wait_after_reset(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));
|
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,
|
extern int sata_std_hardreset(struct ata_link *link, unsigned int *class,
|
||||||
unsigned long deadline);
|
unsigned long deadline);
|
||||||
extern void ata_std_postreset(struct ata_link *link, unsigned int *classes);
|
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(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_scr_write_flush(struct ata_link *link, int reg, u32 val);
|
||||||
extern int sata_set_spd(struct ata_link *link);
|
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,
|
extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
||||||
unsigned long deadline);
|
unsigned long deadline);
|
||||||
#else
|
#else
|
||||||
@@ -1207,6 +1207,16 @@ static inline int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
static inline int sata_set_spd(struct ata_link *link) { 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,
|
static inline int sata_link_resume(struct ata_link *link,
|
||||||
const unsigned long *params,
|
const unsigned long *params,
|
||||||
unsigned long deadline)
|
unsigned long deadline)
|
||||||
|
Reference in New Issue
Block a user