Subject: Re: wd2500 drive not properly detected by ahci driver
To: Manuel Bouyer <bouyer@antioche.eu.org>
From: Stephen Degler <sdegler@degler.net>
List: port-amd64
Date: 08/25/2007 16:01:04
This is a multi-part message in MIME format.
--------------090805020506090209040102
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Manuel Bouyer wrote:
So I've finally gotten back to this and done some more research:
Simply retrying the identify command seems to work fine, although the
first command always seems to fail.
The attached patch causes the command to succeed, although I'm certainly
not suggesting that it is the correct fix.
The first command always fails on the wd2500 drive.
Given that the same drive works fine if I set the controller mode to be
ide rather than ahci in the BIOS (causing it to attach via ixpide), I'm
wondering what the differences are in the code paths. One thing I'm
curious about is that the drive or controller doesn't seem to get reset
as part of the probe/attach. I see the phy gets reset, but I wonder if
some analog of the reset performed in wdcprobe1 needs to happen as well
for the drive to be happy.
skd
> Hi,
>
> On Wed, Jun 20, 2007 at 10:19:26AM +0200, Frank van der Linden wrote:
>
>> Stephen Degler wrote:
>>
>>> This is on an amd64 4600 x2 w/ AMD690G northbridge and SB600 south
>>> bridge.
>>>
>>> Some debuggins is turned on, Reads work ok as far as I can tell.
>>>
>>> ahcisata0 port 0: device present, speed: 1.5Gb/s
>>> wd0 at atabus0 drive 0wdattach
>>> ahcisata0 port 1: device present, speed: 1.5Gb/s
>>> : <ST506>
>>> wd0: drive supports 1-sector PIO transfers, chs addressing
>>> wd0: 69632 KB, 1024 cyl, 8 head, 17 sec, 512 bytes/sect x 139264 sectors
>>> wd0: atap_dmatiming_mimi=0, atap_dmatiming_recom=0
>>> dk0 at wd0: wd0e
>>> dk0: 488397105 blocks at 63, type: lfs
>>> wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 6 (Ultra/133)
>>> wd0(ahcisata0:0:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 6
>>> (Ultra/133) (
>>> using DMA)
>>> wd1 at atabus1 drive 0wdattach
>>> : <ST3160023AS>
>>> wd1: quirks 2<FORCE_LBA48>
>>> wd1: drive supports 16-sector PIO transfers, LBA48 addressing
>>> wd1: 149 GB, 310101 cyl, 16 head, 63 sec, 512 bytes/sect x 312581808
>>> sectors
>>> wd1: atap_dmatiming_mimi=120, atap_dmatiming_recom=120
>>>
>>> skd
>>>
>> I've seen that problem too. Asus P5B-V board (Intel 965), on-board SATA
>> enabled as AHCI. The controller has 6 channels, but only channels 0,1,4
>> and 5 are used.
>>
>> wd0 at atabus3 drive 0: <WDC WD740GD-00FLA0>
>> wd0: drive supports 16-sector PIO transfers, LBA48 addressing
>> wd0: 70911 MB, 144073 cyl, 16 head, 63 sec, 512 bytes/sect x 145226112
>> sectors
>> wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 6 (Ultra/133)
>> wd0(ahcisata1:0:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 6
>> (Ultra/133) (
>> using DMA)
>> wd1 at atabus4 drive 0: <WDC WD740GD-00FLA0>
>> wd1: drive supports 16-sector PIO transfers, LBA48 addressing
>> wd1: 70911 MB, 144073 cyl, 16 head, 63 sec, 512 bytes/sect x 145226112
>> sectors
>> wd1: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 6 (Ultra/133)
>> wd1(ahcisata1:1:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 6
>> (Ultra/133) (
>> using DMA)
>> wd2 at atabus5 drive 0: <ST506>
>> wd2: drive supports 1-sector PIO transfers, chs addressing
>> wd2: 69632 KB, 1024 cyl, 8 head, 17 sec, 512 bytes/sect x 139264 sectors
>> wd2(ahcisata1:4:0): using PIO mode 0
>> wd3 at atabus6 drive 0: <ST506>
>> wd3: drive supports 1-sector PIO transfers, chs addressing
>> wd3: 69632 KB, 1024 cyl, 8 head, 17 sec, 512 bytes/sect x 139264 sectors
>> wd3(ahcisata1:5:0): using PIO mode 0
>>
>
> Could you set atadebug_mask to 0x10, and send me the boot message ?
>
> You could also try setting ahcidebug_mask to 0x02, but this will probably
> be much more verbose, at it will print debug messages for all transfers ...
>
>
--------------090805020506090209040102
Content-Type: text/x-patch;
name="ata.c.workaround.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ata.c.workaround.patch"
Index: ata.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata.c,v
retrieving revision 1.90
diff -u -u -r1.90 ata.c
--- ata.c 9 Jul 2007 21:00:30 -0000 1.90
+++ ata.c 25 Aug 2007 19:45:08 -0000
@@ -69,7 +69,7 @@
#define DEBUG_DETACH 0x20
#define DEBUG_XFERS 0x40
#ifdef ATADEBUG
-int atadebug_mask = 0;
+int atadebug_mask = DEBUG_PROBE;
#define ATADEBUG_PRINT(args, level) \
if (atadebug_mask & (level)) \
printf args
@@ -569,6 +569,34 @@
memset(prms, 0, sizeof(struct ataparams));
memset(&ata_c, 0, sizeof(struct ata_command));
+#define SKD 1
+#ifdef SKD
+ if (drvp->drive_flags & DRIVE_ATA) {
+ ata_c.r_command = WDCC_IDENTIFY;
+ ata_c.r_st_bmask = WDCS_DRDY;
+ ata_c.r_st_pmask = WDCS_DRQ;
+ ata_c.timeout = 3000; /* 3s */
+ ata_c.flags = AT_READ | flags;
+ ata_c.data = tb;
+ ata_c.bcount = DEV_BSIZE;
+ ata_c.timeout = 10000; /* 10s */
+ if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
+ &ata_c) != ATACMD_COMPLETE) {
+ ATADEBUG_PRINT(("ata_get_parms (reset): wdc_exec_command failed\n"),
+ DEBUG_FUNCS|DEBUG_PROBE);
+ }
+ if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+ ATADEBUG_PRINT(("ata_get_parms (reset): ata_c.flags=0x%x\n",
+ ata_c.flags), DEBUG_FUNCS|DEBUG_PROBE);
+ }
+ }
+
+ memset(tb, 0, DEV_BSIZE);
+ memset(prms, 0, sizeof(struct ataparams));
+ memset(&ata_c, 0, sizeof(struct ata_command));
+
+#endif /* SKD */
+
if (drvp->drive_flags & DRIVE_ATA) {
ata_c.r_command = WDCC_IDENTIFY;
ata_c.r_st_bmask = WDCS_DRDY;
--------------090805020506090209040102--