ata: move sata_link_{debounce,resume}() to libata-sata.c
* move sata_link_{debounce,resume}() to libata-sata.c * add static inline for CONFIG_SATA_HOST=n case (only one, for sata_link_resume() is needed) Code size savings on m68k arch using (modified) atari_defconfig: text data bss dec hex filename before: 32816 572 40 33428 8294 drivers/ata/libata-core.o after: 32724 572 40 33336 8238 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
ab4117cf24
commit
9d3158f5cb
|
@ -3485,144 +3485,6 @@ int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ata_wait_after_reset);
|
EXPORT_SYMBOL_GPL(ata_wait_after_reset);
|
||||||
|
|
||||||
/**
|
|
||||||
* sata_link_debounce - debounce SATA phy status
|
|
||||||
* @link: ATA link to debounce SATA phy status for
|
|
||||||
* @params: timing parameters { interval, duration, timeout } in msec
|
|
||||||
* @deadline: deadline jiffies for the operation
|
|
||||||
*
|
|
||||||
* Make sure SStatus of @link reaches stable state, determined by
|
|
||||||
* holding the same value where DET is not 1 for @duration polled
|
|
||||||
* every @interval, before @timeout. Timeout constraints the
|
|
||||||
* beginning of the stable state. Because DET gets stuck at 1 on
|
|
||||||
* some controllers after hot unplugging, this functions waits
|
|
||||||
* until timeout then returns 0 if DET is stable at 1.
|
|
||||||
*
|
|
||||||
* @timeout is further limited by @deadline. The sooner of the
|
|
||||||
* two is used.
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
* Kernel thread context (may sleep)
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 on success, -errno on failure.
|
|
||||||
*/
|
|
||||||
int sata_link_debounce(struct ata_link *link, const unsigned long *params,
|
|
||||||
unsigned long deadline)
|
|
||||||
{
|
|
||||||
unsigned long interval = params[0];
|
|
||||||
unsigned long duration = params[1];
|
|
||||||
unsigned long last_jiffies, t;
|
|
||||||
u32 last, cur;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
t = ata_deadline(jiffies, params[2]);
|
|
||||||
if (time_before(t, deadline))
|
|
||||||
deadline = t;
|
|
||||||
|
|
||||||
if ((rc = sata_scr_read(link, SCR_STATUS, &cur)))
|
|
||||||
return rc;
|
|
||||||
cur &= 0xf;
|
|
||||||
|
|
||||||
last = cur;
|
|
||||||
last_jiffies = jiffies;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
ata_msleep(link->ap, interval);
|
|
||||||
if ((rc = sata_scr_read(link, SCR_STATUS, &cur)))
|
|
||||||
return rc;
|
|
||||||
cur &= 0xf;
|
|
||||||
|
|
||||||
/* DET stable? */
|
|
||||||
if (cur == last) {
|
|
||||||
if (cur == 1 && time_before(jiffies, deadline))
|
|
||||||
continue;
|
|
||||||
if (time_after(jiffies,
|
|
||||||
ata_deadline(last_jiffies, duration)))
|
|
||||||
return 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unstable, start over */
|
|
||||||
last = cur;
|
|
||||||
last_jiffies = jiffies;
|
|
||||||
|
|
||||||
/* Check deadline. If debouncing failed, return
|
|
||||||
* -EPIPE to tell upper layer to lower link speed.
|
|
||||||
*/
|
|
||||||
if (time_after(jiffies, deadline))
|
|
||||||
return -EPIPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(sata_link_debounce);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sata_link_resume - resume SATA link
|
|
||||||
* @link: ATA link to resume SATA
|
|
||||||
* @params: timing parameters { interval, duration, timeout } in msec
|
|
||||||
* @deadline: deadline jiffies for the operation
|
|
||||||
*
|
|
||||||
* Resume SATA phy @link and debounce it.
|
|
||||||
*
|
|
||||||
* LOCKING:
|
|
||||||
* Kernel thread context (may sleep)
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 on success, -errno on failure.
|
|
||||||
*/
|
|
||||||
int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
|
||||||
unsigned long deadline)
|
|
||||||
{
|
|
||||||
int tries = ATA_LINK_RESUME_TRIES;
|
|
||||||
u32 scontrol, serror;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Writes to SControl sometimes get ignored under certain
|
|
||||||
* controllers (ata_piix SIDPR). Make sure DET actually is
|
|
||||||
* cleared.
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
scontrol = (scontrol & 0x0f0) | 0x300;
|
|
||||||
if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
|
|
||||||
return rc;
|
|
||||||
/*
|
|
||||||
* Some PHYs react badly if SStatus is pounded
|
|
||||||
* immediately after resuming. Delay 200ms before
|
|
||||||
* debouncing.
|
|
||||||
*/
|
|
||||||
if (!(link->flags & ATA_LFLAG_NO_DB_DELAY))
|
|
||||||
ata_msleep(link->ap, 200);
|
|
||||||
|
|
||||||
/* is SControl restored correctly? */
|
|
||||||
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
|
||||||
return rc;
|
|
||||||
} while ((scontrol & 0xf0f) != 0x300 && --tries);
|
|
||||||
|
|
||||||
if ((scontrol & 0xf0f) != 0x300) {
|
|
||||||
ata_link_warn(link, "failed to resume link (SControl %X)\n",
|
|
||||||
scontrol);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tries < ATA_LINK_RESUME_TRIES)
|
|
||||||
ata_link_warn(link, "link resume succeeded after %d retries\n",
|
|
||||||
ATA_LINK_RESUME_TRIES - tries);
|
|
||||||
|
|
||||||
if ((rc = sata_link_debounce(link, params, deadline)))
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* clear SError, some PHYs require this even for SRST to work */
|
|
||||||
if (!(rc = sata_scr_read(link, SCR_ERROR, &serror)))
|
|
||||||
rc = sata_scr_write(link, SCR_ERROR, serror);
|
|
||||||
|
|
||||||
return rc != -EINVAL ? rc : 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(sata_link_resume);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_std_prereset - prepare for reset
|
* ata_std_prereset - prepare for reset
|
||||||
* @link: ATA link to be reset
|
* @link: ATA link to be reset
|
||||||
|
|
|
@ -196,6 +196,144 @@ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ata_tf_from_fis);
|
EXPORT_SYMBOL_GPL(ata_tf_from_fis);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sata_link_debounce - debounce SATA phy status
|
||||||
|
* @link: ATA link to debounce SATA phy status for
|
||||||
|
* @params: timing parameters { interval, duration, timeout } in msec
|
||||||
|
* @deadline: deadline jiffies for the operation
|
||||||
|
*
|
||||||
|
* Make sure SStatus of @link reaches stable state, determined by
|
||||||
|
* holding the same value where DET is not 1 for @duration polled
|
||||||
|
* every @interval, before @timeout. Timeout constraints the
|
||||||
|
* beginning of the stable state. Because DET gets stuck at 1 on
|
||||||
|
* some controllers after hot unplugging, this functions waits
|
||||||
|
* until timeout then returns 0 if DET is stable at 1.
|
||||||
|
*
|
||||||
|
* @timeout is further limited by @deadline. The sooner of the
|
||||||
|
* two is used.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Kernel thread context (may sleep)
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* 0 on success, -errno on failure.
|
||||||
|
*/
|
||||||
|
int sata_link_debounce(struct ata_link *link, const unsigned long *params,
|
||||||
|
unsigned long deadline)
|
||||||
|
{
|
||||||
|
unsigned long interval = params[0];
|
||||||
|
unsigned long duration = params[1];
|
||||||
|
unsigned long last_jiffies, t;
|
||||||
|
u32 last, cur;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
t = ata_deadline(jiffies, params[2]);
|
||||||
|
if (time_before(t, deadline))
|
||||||
|
deadline = t;
|
||||||
|
|
||||||
|
if ((rc = sata_scr_read(link, SCR_STATUS, &cur)))
|
||||||
|
return rc;
|
||||||
|
cur &= 0xf;
|
||||||
|
|
||||||
|
last = cur;
|
||||||
|
last_jiffies = jiffies;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ata_msleep(link->ap, interval);
|
||||||
|
if ((rc = sata_scr_read(link, SCR_STATUS, &cur)))
|
||||||
|
return rc;
|
||||||
|
cur &= 0xf;
|
||||||
|
|
||||||
|
/* DET stable? */
|
||||||
|
if (cur == last) {
|
||||||
|
if (cur == 1 && time_before(jiffies, deadline))
|
||||||
|
continue;
|
||||||
|
if (time_after(jiffies,
|
||||||
|
ata_deadline(last_jiffies, duration)))
|
||||||
|
return 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unstable, start over */
|
||||||
|
last = cur;
|
||||||
|
last_jiffies = jiffies;
|
||||||
|
|
||||||
|
/* Check deadline. If debouncing failed, return
|
||||||
|
* -EPIPE to tell upper layer to lower link speed.
|
||||||
|
*/
|
||||||
|
if (time_after(jiffies, deadline))
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(sata_link_debounce);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sata_link_resume - resume SATA link
|
||||||
|
* @link: ATA link to resume SATA
|
||||||
|
* @params: timing parameters { interval, duration, timeout } in msec
|
||||||
|
* @deadline: deadline jiffies for the operation
|
||||||
|
*
|
||||||
|
* Resume SATA phy @link and debounce it.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Kernel thread context (may sleep)
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* 0 on success, -errno on failure.
|
||||||
|
*/
|
||||||
|
int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
||||||
|
unsigned long deadline)
|
||||||
|
{
|
||||||
|
int tries = ATA_LINK_RESUME_TRIES;
|
||||||
|
u32 scontrol, serror;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Writes to SControl sometimes get ignored under certain
|
||||||
|
* controllers (ata_piix SIDPR). Make sure DET actually is
|
||||||
|
* cleared.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
scontrol = (scontrol & 0x0f0) | 0x300;
|
||||||
|
if ((rc = sata_scr_write(link, SCR_CONTROL, scontrol)))
|
||||||
|
return rc;
|
||||||
|
/*
|
||||||
|
* Some PHYs react badly if SStatus is pounded
|
||||||
|
* immediately after resuming. Delay 200ms before
|
||||||
|
* debouncing.
|
||||||
|
*/
|
||||||
|
if (!(link->flags & ATA_LFLAG_NO_DB_DELAY))
|
||||||
|
ata_msleep(link->ap, 200);
|
||||||
|
|
||||||
|
/* is SControl restored correctly? */
|
||||||
|
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
|
||||||
|
return rc;
|
||||||
|
} while ((scontrol & 0xf0f) != 0x300 && --tries);
|
||||||
|
|
||||||
|
if ((scontrol & 0xf0f) != 0x300) {
|
||||||
|
ata_link_warn(link, "failed to resume link (SControl %X)\n",
|
||||||
|
scontrol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tries < ATA_LINK_RESUME_TRIES)
|
||||||
|
ata_link_warn(link, "link resume succeeded after %d retries\n",
|
||||||
|
ATA_LINK_RESUME_TRIES - tries);
|
||||||
|
|
||||||
|
if ((rc = sata_link_debounce(link, params, deadline)))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* clear SError, some PHYs require this even for SRST to work */
|
||||||
|
if (!(rc = sata_scr_read(link, SCR_ERROR, &serror)))
|
||||||
|
rc = sata_scr_write(link, SCR_ERROR, serror);
|
||||||
|
|
||||||
|
return rc != -EINVAL ? rc : 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(sata_link_resume);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sata_link_scr_lpm - manipulate SControl IPM and SPM fields
|
* sata_link_scr_lpm - manipulate SControl IPM and SPM fields
|
||||||
* @link: ATA link to manipulate SControl for
|
* @link: ATA link to manipulate SControl for
|
||||||
|
|
|
@ -1077,10 +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_debounce(struct ata_link *link,
|
|
||||||
const unsigned long *params, unsigned long deadline);
|
|
||||||
extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
|
||||||
unsigned long deadline);
|
|
||||||
extern int sata_link_hardreset(struct ata_link *link,
|
extern int sata_link_hardreset(struct ata_link *link,
|
||||||
const unsigned long *timing, unsigned long deadline,
|
const unsigned long *timing, unsigned long deadline,
|
||||||
bool *online, int (*check_ready)(struct ata_link *));
|
bool *online, int (*check_ready)(struct ata_link *));
|
||||||
|
@ -1194,6 +1190,8 @@ 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_resume(struct ata_link *link, const unsigned long *params,
|
||||||
|
unsigned long deadline);
|
||||||
#else
|
#else
|
||||||
static inline int sata_scr_valid(struct ata_link *link) { return 0; }
|
static inline int sata_scr_valid(struct ata_link *link) { return 0; }
|
||||||
static inline int sata_scr_read(struct ata_link *link, int reg, u32 *val)
|
static inline int sata_scr_read(struct ata_link *link, int reg, u32 *val)
|
||||||
|
@ -1209,7 +1207,15 @@ 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_resume(struct ata_link *link,
|
||||||
|
const unsigned long *params,
|
||||||
|
unsigned long deadline)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
extern int sata_link_debounce(struct ata_link *link,
|
||||||
|
const unsigned long *params, unsigned long deadline);
|
||||||
extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
||||||
bool spm_wakeup);
|
bool spm_wakeup);
|
||||||
extern int ata_slave_link_init(struct ata_port *ap);
|
extern int ata_slave_link_init(struct ata_port *ap);
|
||||||
|
|
Loading…
Reference in New Issue