9fans archive / 2008 / 04 / 277 /    prev next

From: erik quanstrom <quanstro@qua...>
Subject: Re: [9fans] i/o error reading large sata disk
Date: Tue, 22 Apr 2008 09:56:18 -0400

> > 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