Date: Tue, 2 Sep 2003 00:56:46 +0900 From: Hiroyuki Aizu <eyes@navi.org> To: freebsd-current@freebsd.org Subject: Re: ATAng suspend/resume support broken Message-ID: <20030902005646.7f9cc963.eyes@navi.org> In-Reply-To: <20030828215209.T41901@root.org> References: <20030828215209.T41901@root.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi.
On Thu, 28 Aug 2003 21:57:24 -0700 (PDT)
Nate Lawson <nate@root.org> wrote:
> With today's ATAng, I can suspend my laptop but when I resume, the system
> hangs. I'll try to get the exact dmesg with a serial console since
> syscons gets screwed up by resuming (this is normal behavior). In any
> case, my laptop hangs with the drive light on while trying to reset the
> ata controller. I can't enter DDB. By reverting just the ATAng commit to
> 2003/08/23, suspend and resume work well. Here is my dmesg from a working
> suspend/resume...
>
> -Nate
My laptop has same behavior. So I compare ATAng with ATAold and solve this
problem. I found re-init routine must necessary at wakeup.
I made patches and attach to this mail.
These three are patches for re-init. At least, this works for my machine.
ata-all.c.diff
ata-all.h.diff
ata-disk.c.diff
And I make one more patch "ata-lowlevel.c.diff".
The Reason is ATAng code fonund ghost device on slave at resume time like this.
ad1: 8994829560181951MB <\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-
%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-%\M^?\M-
%\M^?\M-%\M^?\M-%\M^?\M-%> [676635847171814/165/165] at ata0-slave UDMA66
Mysteriously, ATAold and ATAng code using variable "ostat[01]" that save status
before reset channel. I'm not familier with ATA, so maybe I'm
misunderstanding.
Please consider these patches.
At last, I can sleep (-.-)
--
Hiroyuki Aizu
[-- Attachment #2 --]
--- ata-all.c.orig Mon Sep 1 22:22:19 2003
+++ ata-all.c Tue Sep 2 00:16:29 2003
@@ -257,6 +257,13 @@
if ((newdev & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) &&
ch->device[SLAVE].attach)
ch->device[SLAVE].attach(&ch->device[SLAVE]);
+ } else {
+ if ((ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) &&
+ ch->device[MASTER].reinit)
+ ch->device[MASTER].reinit(&ch->device[MASTER]);
+ if ((ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) &&
+ ch->device[SLAVE].reinit)
+ ch->device[SLAVE].reinit(&ch->device[SLAVE]);
}
#ifdef DEV_ATAPICAM
atapi_cam_reinit_bus(ch);
[-- Attachment #3 --]
--- ata-all.h.orig Mon Aug 25 20:13:04 2003
+++ ata-all.h Tue Sep 2 00:15:14 2003
@@ -218,6 +218,7 @@
void *softc; /* ptr to softc for device */
void (*attach)(struct ata_device *atadev);
void (*detach)(struct ata_device *atadev);
+ void (*reinit)(struct ata_device *atadev);
void (*start)(struct ata_device *atadev);
int flags;
#define ATA_D_USE_CHS 0x0001
[-- Attachment #4 --]
--- ata-disk.c.orig Mon Aug 25 18:01:49 2003
+++ ata-disk.c Tue Sep 2 00:15:31 2003
@@ -55,6 +55,7 @@
/* prototypes */
static void ad_detach(struct ata_device *);
+static void ad_reinit(struct ata_device *);
static void ad_start(struct ata_device *);
static void ad_done(struct ata_request *);
static disk_open_t adopen;
@@ -152,6 +153,7 @@
/* setup the function ptrs */
atadev->detach = ad_detach;
+ atadev->reinit = ad_reinit;
atadev->start = ad_start;
atadev->softc = adp;
@@ -202,6 +204,19 @@
atadev->softc = NULL;
atadev->flags = 0;
free(adp, M_AD);
+}
+
+static void
+ad_reinit(struct ata_device *atadev)
+{
+ struct ad_softc *adp = atadev->softc;
+
+ ata_controlcmd(atadev, ATA_SET_MULTI, 0, 0, (adp->max_iosize / DEV_BSIZE));
+
+ if (ata_dma && atadev->channel->dma)
+ atadev->setmode(atadev, ATA_DMA_MAX);
+ else
+ atadev->setmode(atadev, ATA_PIO_MAX);
}
static int
[-- Attachment #5 --]
--- ata-lowlevel.c.orig Mon Sep 1 20:13:21 2003
+++ ata-lowlevel.c Tue Sep 2 00:15:20 2003
@@ -591,7 +591,7 @@
if (!mask)
return;
- if (mask & 0x01 && ostat0 != 0x00 &&
+ if (mask & 0x01 && stat0 != 0x00 &&
!(ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER))) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
DELAY(10);
@@ -604,7 +604,7 @@
if (err != 0x58 && lsb == 0xa5)
ch->devices |= ATA_ATA_MASTER;
}
- if (mask & 0x02 && ostat1 != 0x00 &&
+ if (mask & 0x02 && stat1 != 0x00 &&
!(ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE))) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
DELAY(10);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030902005646.7f9cc963.eyes>
