Thanks again for the help, but, I could use a little more instruction... I've figured out how to apply the patch to the source, and compiled the libata-pmp, and libata-eh modules(/drivers/ata), but, I cannot figure out what to do from here. The libata-pmp driver/module does not seem to be loaded on my system to begin with...maybe this was part of my problem. On Sat, Oct 8, 2011 at 1:25 PM, Michael Ihrcke <mihrcke@xxxxxxxxx> wrote: > Thank you... > > Will this require a complete kernel recompile? > Or is there an easier way to include this patch? > > I have little to no experience with working with patches at this level. > I've been doing research on how to use this patch, and I'm close, but, I'm not > sure if I need to attack compiling a kernel, or if I can somehow just patch > libata or something like that? > > Thank you, > Mike > > On Thu, Oct 6, 2011 at 12:48 AM, Gwendal Grignou <gwendal@xxxxxxxxxx> wrote: >> >> I think I know what is going on. One of your disks at least is slow to >> spinup. Due to a bug/feature in silicon image disk controller and pmp, >> at bring up we can not issue a SOFT_RESET and wait for the disk to >> spinup and then continue. >> That why we set ATA_LFLAG_NO_SRST in sata_pmp_quirks(). >> So what happen is we go into a function that issue identify, but we >> fail, the disk is not ready [it is spinning up], so we retry. >> 3 times. >> >> From the first hard reset: 12888.470385, to the time you got the final >> error: 12901.397305 ~ 12.9s >> In the second case, your controller can send SOFT_RESET and wait for >> the device to respond. >> Time for the disk to spinup: >> 28010.630028 - 27997.097116 ~ 13.5s >> As you can see, you are borderline with the PMP, but the controller >> did not "wait" enough in the first case. >> Given the spinup time varies with drive, age, time since last >> spin-up..., it may work one day and fail the next. >> To work around the problem, I have a patch that consist of allowing >> the silicon image control to send a reset, but if it fails, we spin >> for a fixed amount of time and retry. This is not very nice, it is a >> better design to wait for event that waiting a fixed amount of time. >> You may have to alter ATA_LFLAG_WAIT_SRST to use the first bit available. >> >> Can you try with the following patch? >> >> Thanks, >> Gwendal. >> >> diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c >> index 228740f..b98b02d 100644 >> --- a/drivers/ata/libata-eh.c >> +++ b/drivers/ata/libata-eh.c >> @@ -2798,7 +2798,14 @@ int ata_eh_reset(struct ata_link *link, int classify, >> sata_scr_read(link, SCR_STATUS, &sstatus)) >> rc = -ERESTART; >> >> - if (rc == -ERESTART || try >= max_tries) >> + if (try >= max_tries) >> + goto out; >> + >> + /* Some PMP will not serve SRST until the disk is spunup, >> + * if the controller can not wait for the PMP to acknowledge the frame, >> + * wait here */ >> + if (rc == -ERESTART && >> + !((lflags & ATA_LFLAG_WAIT_SRST) && (reset == softreset))) >> goto out; >> >> now = jiffies; >> @@ -2813,6 +2820,8 @@ int ata_eh_reset(struct ata_link *link, int classify, >> delta = schedule_timeout_uninterruptible(delta); >> } >> >> + if (rc == -ERESTART) >> + goto out; >> if (try == max_tries - 1) { >> sata_down_spd_limit(link, 0); >> if (slave) >> diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c >> index 00305f4..d21ad7d 100644 >> --- a/drivers/ata/libata-pmp.c >> +++ b/drivers/ata/libata-pmp.c >> @@ -325,13 +351,11 @@ static void sata_pmp_quirks(struct ata_port *ap) >> if (vendor == 0x1095 && devid == 0x3726) { >> /* sil3726 quirks */ >> ata_for_each_link(link, ap, EDGE) { >> - /* Class code report is unreliable and SRST >> - * times out under certain configurations. >> - */ >> + /* Class code report is unreliable */ >> + /* PMP does not forward SRST until the drive spins up */ >> if (link->pmp < 5) >> - link->flags |= ATA_LFLAG_NO_SRST | >> - ATA_LFLAG_ASSUME_ATA; >> - >> + link->flags |= ATA_LFLAG_ASSUME_ATA | >> + ATA_LFLAG_WAIT_SRST; >> /* port 5 is for SEMB device and it doesn't like SRST */ >> if (link->pmp == 5) >> link->flags |= ATA_LFLAG_NO_SRST | >> diff --git a/include/linux/libata.h b/include/linux/libata.h >> index b2f2003..3a18caa 100644 >> --- a/include/linux/libata.h >> +++ b/include/linux/libata.h >> @@ -172,6 +172,7 @@ enum { >> ATA_LFLAG_NO_RETRY = (1 << 5), /* don't retry this link */ >> ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */ >> ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ >> + ATA_LFLAG_WAIT_SRST = (1 << 8), /* add delay when SRST fails */ >> >> /* struct ata_port flags */ >> ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ >> >> > -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html