Skip to content

Commit

Permalink
ata: move sata_link_hardreset() to libata-sata.c
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
bzolnier authored and axboe committed Mar 26, 2020
1 parent 9d3158f commit 78c97c8
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 124 deletions.
113 changes: 0 additions & 113 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
115 changes: 114 additions & 1 deletion drivers/ata/libata-sata.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
7 changes: 0 additions & 7 deletions drivers/ata/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
16 changes: 13 additions & 3 deletions include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit 78c97c8

Please sign in to comment.