> > read: i/o error
> 
> i think i see the problem.  we're off by one bit.
> 
[...]
> /n/sources/plan9//sys/src/9/pc/sdata.c:1344,1350 - sdata.c:1344,1350
>   };
>   
>   static int
> - atageniostart(Drive* drive, vlong lba)
> + atageniostart(Drive* drive, uvlong lba)
>   {
>       Ctlr *ctlr;
>       uchar cmd;
> /n/sources/plan9//sys/src/9/pc/sdata.c:1351,1357 - sdata.c:1351,1357
>       int as, c, cmdport, ctlport, h, len, s, use48;
>   
>       use48 = 0;
> -     if((drive->flags&Lba48always) || (lba>>28) || drive->count > 256){
> +     if((drive->flags&Lba48always) || (lba>>27) || drive->count > 256){
>               if(!(drive->flags & Lba48))
>                       return -1;
>               use48 = 1;

while this does fix the problem, it's sloppy.  the problem is actually
that ata reports device sizes as number of sectors+1.  it also does not follow
the tradition used for sector counts, where 0 sector count = all-ones+1 = 256.
this is because removable media drives with no media (eg cdroms) give size = 0.
therefore if under any ata addressing scheme, the all-ones sector is not 
accessable.
credit to sam hopkins for pointing this out.

/n/sources/plan9//sys/src/9/pc/sdata.c:1344,1350 - sdata.c:1344,1350
  };
  
+ enum{
+       Last28  = (1<<28) - 1 - 1,
+ };
+ 
  static int
- atageniostart(Drive* drive, vlong lba)
+ atageniostart(Drive* drive, uvlong lba)
  {
        Ctlr *ctlr;
        uchar cmd;
/n/sources/plan9//sys/src/9/pc/sdata.c:1351,1357 - sdata.c:1355,1361
        int as, c, cmdport, ctlport, h, len, s, use48;
  
        use48 = 0;
-       if((drive->flags&Lba48always) || (lba>>28) || drive->count > 256){
+       if((drive->flags&Lba48always) || lba > Last28 || drive->count > 256){
                if(!(drive->flags & Lba48))
                        return -1;
                use48 = 1;


- erik

Reply via email to