tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: WD_QUIRK_FORCE_LBA48



On Sun, Dec 13, 2009 at 10:41:15PM +0000, Christoph Badura wrote:
> [...]
> On the other hand I find it obvious that we can't expect a LBA28 command to
> access the disk across the LBA48 boundary.  So we need to actaually check 
> whether the last block of requested transfer is beyond the LBA48 barrier,
> as David Laight suggested, and use an LBA48 transfer in that case.
> Incidentally, wddump() does this already.

Yes, we should probably do this

> 
> That makes the above disk work for me without throwing spurious errors.
> 
> I don't expect this to be a problem with controllers that do mishandle LBA48
> commands.  LBA48 commands will only be used when accessing sectors beyond the
> LBA48 border and those sectors are inaccessible by these controllers anyway.
> 
> The other option would be to split the transfer similar to the MOD15 case.
> But I see no need for that.
> 
> Index: wd.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/ata/wd.c,v
> retrieving revision 1.363.8.1
> diff -u -r1.363.8.1 wd.c
> --- wd.c        18 Feb 2009 00:23:09 -0000      1.363.8.1
> +++ wd.c        13 Dec 2009 22:06:33 -0000
> @@ -732,6 +732,7 @@
>         }
>  
>         wd->sc_wdc_bio.blkno = bp->b_rawblkno;
> +       wd->sc_wdc_bio.bcount = bp->b_bcount;
>         wd->sc_wdc_bio.blkdone =0;
>         wd->sc_bp = bp;
>         /*
> @@ -744,14 +745,15 @@
>         else
>                 wd->sc_wdc_bio.flags = 0;
>         if (wd->sc_flags & WDF_LBA48 &&
> -           (wd->sc_wdc_bio.blkno > LBA48_THRESHOLD ||
> +           (wd->sc_wdc_bio.blkno +
> +               wd->sc_wdc_bio.bcount / wd->sc_dk.dk_label->d_secsize >
> +               LBA48_THRESHOLD ||

but please make this (LBA48_THRESHOLD + 1). Otherwise the last
LBA24 sector will be inaccessible on non-LBA48 controllers.

>             (wd->sc_quirks & WD_QUIRK_FORCE_LBA48) != 0))
>                 wd->sc_wdc_bio.flags |= ATA_LBA48;
>         if (wd->sc_flags & WDF_LBA)
>                 wd->sc_wdc_bio.flags |= ATA_LBA;
>         if (bp->b_flags & B_READ)
>                 wd->sc_wdc_bio.flags |= ATA_READ;
> -       wd->sc_wdc_bio.bcount = bp->b_bcount;
>         wd->sc_wdc_bio.databuf = bp->b_data;
>         /* Instrumentation. */
>         disk_busy(&wd->sc_dk);
> @@ -1634,7 +1636,7 @@
>         wd->sc_wdc_bio.blkno = blkno;
>         wd->sc_wdc_bio.flags = ATA_POLL;
>         if (wd->sc_flags & WDF_LBA48 &&
> -           (blkno > LBA48_THRESHOLD ||
> +           (blkno + nblks > LBA48_THRESHOLD ||
>             (wd->sc_quirks & WD_QUIRK_FORCE_LBA48) != 0))
>                 wd->sc_wdc_bio.flags |= ATA_LBA48;

This one should be OK to detect LBA48 drives that have a problem
accessing the last LBA24 sector using LBA24 commands.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--


Home | Main Index | Thread Index | Old Index