Hi,

One issue with using S3 suspend/resume on my Tecra S1 laptop is that 
after a resume the first access to the p-ata hdd hangs the system.

Just like 6742621, but I'm using nightly 2008-10-23 bits (post snv_101).


Apparently the problem is that UDMA 5 needs to be restored for the p-ata hdd
(fujitsu 80gb),  but it isn't.


When I change the code in usr/src/uts/intel/io/dktp/controller/ata/ata_common.c
ata_set_dma_mode() to always set dma mode, s3 resume starts to work just fine.

Basically, I remove this if ():

   3819         /* Return if DMA mode is already selected */
   3820         if (((aidp->ai_validinfo & ATAC_VALIDINFO_83) &&
   3821             (aidp->ai_ultradma & ATAC_UDMA_SEL_MASK)) ||
   3822             (aidp->ai_dworddma & ATAC_MDMA_SEL_MASK))
   3823                 return (rval);


It seems the hdd's power on defaults is MWDMA 2.  The BIOS appears to
configure UDMA 5 before the OS (Solaris) is booted.

But on S3 resume,  we resume with the p-ata hdd set to MWDMA 2.  And the
ICH4-M chipset in the laptop is set to UDMA.  The above if () returns,
without setting UDMA 5 for the hdd.  On the next DMA the laptop hangs.



While looking at the ata resume code, I noticed something that appears to 
be broken:

   3523 /*
   3524  * resume the hard drive
   3525  */
   3526 static void
   3527 ata_resume_drive(ata_drv_t *ata_drvp)
   3528 {
   3529         ata_ctl_t *ata_ctlp = ata_drvp->ad_ctlp;
   3530         int drive_type;
   3531         struct ata_id id;
   3532 
   3533         ADBG_TRACE(("ata_resume_drive entered\n"));
   3534 
   3535         drive_type = ata_drive_type(ata_drvp->ad_drive_bits,
   3536             ata_ctlp->ac_iohandle1, ata_ctlp->ac_ioaddr1,
   3537             ata_ctlp->ac_iohandle2, ata_ctlp->ac_ioaddr2,
   3538             &id);
   3539         if (drive_type == ATA_DEV_NONE)
   3540                 return;
   3541 
   3542         if (!ATAPIDRV(ata_drvp)) {
   3543                 /* Reset Ultra DMA mode */
   3544                 (void) ata_set_dma_mode(ata_ctlp, ata_drvp);
   3545                 if (!ata_disk_setup_parms(ata_ctlp, ata_drvp))
   3546                         return;
   3547         } else {
   3548                 (void) atapi_init_drive(ata_drvp);

   
   
When we resume, line 3535 gets the hdd's current settings using an ata
identify command and stores the result in the local variable "id", line 3531.

But when we call ata_set_dma_mode() at line 3544, the ata_drvp pointer
still contains the ata device's configuration settings that was read during
drive attach at the initial boot  -  not the current settings at S3 resume
time that were read into the local variable "id", line 3531.

Btw, in the atapi case, line 3548, atapi_id_update() gets called which will
update the id data contained in the ata_drvp stucture before we call
ata_set_dma_mode(), so that in the atapi case ata_set_dma_mode() will work
with current configuration data of the atapi device at the time of the
s3 resume.


Isn't there a bcopy missing before line 3544, that updates the ata_id
data in the ata_drvp structure to the current values?  Or maybe pass
"&ata_drvp->ad_id" at line 3538, instead of using a local ata_id copy?
So that ata_set_dma_mode() uses the hw's settings at s3 resume time
when re-enabling dma mode...


Reply via email to