Skip to content

Commit

Permalink
libata: implement no[hs]rst force params
Browse files Browse the repository at this point in the history
Implement force params nohrst, nosrst and norst.  This is to work
around reset related problems and ease debugging.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Aug 22, 2008
1 parent 6a55617 commit 05944bd
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
3 changes: 3 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file

* [no]ncq: Turn on or off NCQ.

* nohrst, nosrst, norst: suppress hard, soft
and both resets.

If there are multiple matching configurations changing
the same attribute, the last one is used.

Expand Down
46 changes: 30 additions & 16 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ struct ata_force_param {
unsigned long xfer_mask;
unsigned int horkage_on;
unsigned int horkage_off;
unsigned int lflags;
};

struct ata_force_ent {
Expand Down Expand Up @@ -196,22 +197,23 @@ void ata_force_cbl(struct ata_port *ap)
}

/**
* ata_force_spd_limit - force SATA spd limit according to libata.force
* ata_force_link_limits - force link limits according to libata.force
* @link: ATA link of interest
*
* Force SATA spd limit according to libata.force and whine about
* it. When only the port part is specified (e.g. 1:), the limit
* applies to all links connected to both the host link and all
* fan-out ports connected via PMP. If the device part is
* specified as 0 (e.g. 1.00:), it specifies the first fan-out
* link not the host link. Device number 15 always points to the
* host link whether PMP is attached or not.
* Force link flags and SATA spd limit according to libata.force
* and whine about it. When only the port part is specified
* (e.g. 1:), the limit applies to all links connected to both
* the host link and all fan-out ports connected via PMP. If the
* device part is specified as 0 (e.g. 1.00:), it specifies the
* first fan-out link not the host link. Device number 15 always
* points to the host link whether PMP is attached or not.
*
* LOCKING:
* EH context.
*/
static void ata_force_spd_limit(struct ata_link *link)
static void ata_force_link_limits(struct ata_link *link)
{
bool did_spd = false;
int linkno, i;

if (ata_is_host_link(link))
Expand All @@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
if (fe->device != -1 && fe->device != linkno)
continue;

if (!fe->param.spd_limit)
continue;
/* only honor the first spd limit */
if (!did_spd && fe->param.spd_limit) {
link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
ata_link_printk(link, KERN_NOTICE,
"FORCE: PHY spd limit set to %s\n",
fe->param.name);
did_spd = true;
}

link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
ata_link_printk(link, KERN_NOTICE,
"FORCE: PHY spd limit set to %s\n", fe->param.name);
return;
/* let lflags stack */
if (fe->param.lflags) {
link->flags |= fe->param.lflags;
ata_link_printk(link, KERN_NOTICE,
"FORCE: link flag 0x%x forced -> 0x%x\n",
fe->param.lflags, link->flags);
}
}
}

Expand Down Expand Up @@ -5200,7 +5211,7 @@ int sata_link_init_spd(struct ata_link *link)
if (spd)
link->hw_sata_spd_limit &= (1 << spd) - 1;

ata_force_spd_limit(link);
ata_force_link_limits(link);

link->sata_spd_limit = link->hw_sata_spd_limit;

Expand Down Expand Up @@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
{ "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
{ "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
{ "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
{ "nohrst", .lflags = ATA_LFLAG_NO_HRST },
{ "nosrst", .lflags = ATA_LFLAG_NO_SRST },
{ "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
};
char *start = *cur, *p = *cur;
char *id, *val, *endp;
Expand Down
4 changes: 4 additions & 0 deletions drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -2210,6 +2210,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
*/
while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
max_tries++;
if (link->flags & ATA_LFLAG_NO_HRST)
hardreset = NULL;
if (link->flags & ATA_LFLAG_NO_SRST)
softreset = NULL;

now = jiffies;
deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
Expand Down
1 change: 1 addition & 0 deletions include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ enum {
ATA_DEV_NONE = 9, /* no device */

/* struct ata_link flags */
ATA_LFLAG_NO_HRST = (1 << 1), /* avoid hardreset */
ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */
Expand Down

0 comments on commit 05944bd

Please sign in to comment.