mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 00:24:12 +08:00
libata: separate out ata_std_prereset() from ata_sff_prereset()
Separate out generic ATA portion from ata_sff_prereset() into ata_std_prereset() and implement ata_sff_prereset() using the std version. Waiting for device readiness is the only SFF specific part. ata_base_port_ops now has ata_std_prereset() for its prereset and ata_sff_port_ops overrides it to ata_sff_prereset(). This change can affect pdc_adma, ahci, sata_fsl and sata_sil24. pdc_adma implements its own prereset using ata_sff_prereset() and the rest has hardreset and thus are unaffected by this change. This change reflects real world situation. There is no generic way to wait for device readiness for non-SFF controllers and some of them don't have any mechanism for that. Non-sff drivers which don't have hardreset should wrap ata_std_prereset() and wait for device readiness itself but there's no such driver now and isn't likely to be popular in the future either. Signed-off-by: Tejun Heo <htejun@gmail.com>
This commit is contained in:
parent
288623a06c
commit
0aa1113d54
@ -74,7 +74,7 @@ const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
|
||||
const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };
|
||||
|
||||
const struct ata_port_operations ata_base_port_ops = {
|
||||
.prereset = ata_sff_prereset,
|
||||
.prereset = ata_std_prereset,
|
||||
.hardreset = sata_sff_hardreset,
|
||||
.postreset = ata_sff_postreset,
|
||||
.error_handler = ata_std_error_handler,
|
||||
@ -3416,7 +3416,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_sff_prereset - prepare for reset
|
||||
* ata_std_prereset - prepare for reset
|
||||
* @link: ATA link to be reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
@ -3432,7 +3432,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
|
||||
int ata_std_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
@ -3452,16 +3452,6 @@ int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
|
||||
"link for reset (errno=%d)\n", rc);
|
||||
}
|
||||
|
||||
/* wait for !BSY if we don't know that no device is attached */
|
||||
if (!ata_link_offline(link)) {
|
||||
rc = ata_sff_wait_ready(ap, deadline);
|
||||
if (rc && rc != -ENODEV) {
|
||||
ata_link_printk(link, KERN_WARNING, "device not ready "
|
||||
"(errno=%d), forcing hardreset\n", rc);
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6104,6 +6094,7 @@ EXPORT_SYMBOL_GPL(ata_dev_disable);
|
||||
EXPORT_SYMBOL_GPL(sata_set_spd);
|
||||
EXPORT_SYMBOL_GPL(sata_link_debounce);
|
||||
EXPORT_SYMBOL_GPL(sata_link_resume);
|
||||
EXPORT_SYMBOL_GPL(ata_std_prereset);
|
||||
EXPORT_SYMBOL_GPL(sata_link_hardreset);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_classify);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_pair);
|
||||
|
@ -47,6 +47,7 @@ const struct ata_port_operations ata_sff_port_ops = {
|
||||
|
||||
.freeze = ata_sff_freeze,
|
||||
.thaw = ata_sff_thaw,
|
||||
.prereset = ata_sff_prereset,
|
||||
.softreset = ata_sff_softreset,
|
||||
.error_handler = ata_sff_error_handler,
|
||||
.post_internal_cmd = ata_sff_post_internal_cmd,
|
||||
@ -1606,6 +1607,48 @@ void ata_sff_thaw(struct ata_port *ap)
|
||||
ap->ops->sff_irq_on(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_sff_prereset - prepare SFF link for reset
|
||||
* @link: SFF link to be reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* SFF link @link is about to be reset. Initialize it. It first
|
||||
* calls ata_std_prereset() and wait for !BSY if the port is
|
||||
* being softreset.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
|
||||
{
|
||||
struct ata_port *ap = link->ap;
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
int rc;
|
||||
|
||||
rc = ata_std_prereset(link, deadline);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* if we're about to do hardreset, nothing more to do */
|
||||
if (ehc->i.action & ATA_EH_HARDRESET)
|
||||
return 0;
|
||||
|
||||
/* wait for !BSY if we don't know that no device is attached */
|
||||
if (!ata_link_offline(link)) {
|
||||
rc = ata_sff_wait_ready(ap, deadline);
|
||||
if (rc && rc != -ENODEV) {
|
||||
ata_link_printk(link, KERN_WARNING, "device not ready "
|
||||
"(errno=%d), forcing hardreset\n", rc);
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_devchk - PATA device presence detection
|
||||
* @ap: ATA channel to examine
|
||||
|
@ -824,6 +824,7 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
|
||||
extern void sata_print_link_status(struct ata_link *link);
|
||||
extern void ata_port_probe(struct ata_port *);
|
||||
extern int sata_set_spd(struct ata_link *link);
|
||||
extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user