Support ATA disks with 4K sectors.
* include/grub/ata.h (grub_ata): New member log_sector_size. * grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. (grub_ata_identify): Read sector size. (grub_ata_readwrite): Use log_sector_size rather than hardcoded value.
This commit is contained in:
		
							parent
							
								
									9222759765
								
							
						
					
					
						commit
						6795300e7f
					
				
					 3 changed files with 30 additions and 3 deletions
				
			
		|  | @ -1,3 +1,12 @@ | ||||||
|  | 2011-07-25  Vladimir Serbinenko  <phcoder@gmail.com> | ||||||
|  | 
 | ||||||
|  | 	Support ATA disks with non-4K sectors. | ||||||
|  | 
 | ||||||
|  | 	* include/grub/ata.h (grub_ata): New member log_sector_size. | ||||||
|  | 	* grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. | ||||||
|  | 	(grub_ata_identify): Read sector size. | ||||||
|  | 	(grub_ata_readwrite): Use log_sector_size rather than hardcoded value. | ||||||
|  | 
 | ||||||
| 2011-07-25  Vladimir Serbinenko  <phcoder@gmail.com> | 2011-07-25  Vladimir Serbinenko  <phcoder@gmail.com> | ||||||
| 
 | 
 | ||||||
| 	* util/grub-install.in: Don't use uhci outside of x86. | 	* util/grub-install.in: Don't use uhci outside of x86. | ||||||
|  |  | ||||||
|  | @ -57,6 +57,7 @@ grub_ata_dumpinfo (struct grub_ata *dev, char *info) | ||||||
|     { |     { | ||||||
|       grub_dprintf ("ata", "Addressing: %d\n", dev->addr); |       grub_dprintf ("ata", "Addressing: %d\n", dev->addr); | ||||||
|       grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size); |       grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size); | ||||||
|  |       grub_dprintf ("ata", "Sector size: %u\n", 1U << dev->log_sector_size); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -170,6 +171,21 @@ grub_ata_identify (struct grub_ata *dev) | ||||||
|   else |   else | ||||||
|     dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100])); |     dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100])); | ||||||
| 
 | 
 | ||||||
|  |   if (info16[106] & (1 << 12)) | ||||||
|  |     { | ||||||
|  |       grub_uint32_t secsize; | ||||||
|  |       secsize = grub_le_to_cpu32 (*((grub_uint32_t *) &info16[117])); | ||||||
|  |       if (secsize & (secsize - 1) || !secsize | ||||||
|  | 	  || secsize > 1048576) | ||||||
|  | 	secsize = 256; | ||||||
|  |       for (dev->log_sector_size = 0; | ||||||
|  | 	   (1U << dev->log_sector_size) < secsize; | ||||||
|  | 	   dev->log_sector_size++); | ||||||
|  |       dev->log_sector_size++; | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     dev->log_sector_size = 9; | ||||||
|  | 
 | ||||||
|   /* Read CHS information.  */ |   /* Read CHS information.  */ | ||||||
|   dev->cylinders = info16[1]; |   dev->cylinders = info16[1]; | ||||||
|   dev->heads = info16[3]; |   dev->heads = info16[3]; | ||||||
|  | @ -314,7 +330,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, | ||||||
|       grub_ata_setaddress (ata, &parms, sector, batch, addressing); |       grub_ata_setaddress (ata, &parms, sector, batch, addressing); | ||||||
|       parms.taskfile.cmd = (! rw ? cmd : cmd_write); |       parms.taskfile.cmd = (! rw ? cmd : cmd_write); | ||||||
|       parms.buffer = buf; |       parms.buffer = buf; | ||||||
|       parms.size = batch * GRUB_DISK_SECTOR_SIZE; |       parms.size = batch << ata->log_sector_size; | ||||||
|       parms.write = rw; |       parms.write = rw; | ||||||
|       if (ata->dma) |       if (ata->dma) | ||||||
| 	parms.dma = 1; | 	parms.dma = 1; | ||||||
|  | @ -322,9 +338,9 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, | ||||||
|       err = ata->dev->readwrite (ata, &parms, 0); |       err = ata->dev->readwrite (ata, &parms, 0); | ||||||
|       if (err) |       if (err) | ||||||
| 	return err; | 	return err; | ||||||
|       if (parms.size != batch * GRUB_DISK_SECTOR_SIZE) |       if (parms.size != batch << ata->log_sector_size) | ||||||
| 	return grub_error (GRUB_ERR_READ_ERROR, "incomplete read"); | 	return grub_error (GRUB_ERR_READ_ERROR, "incomplete read"); | ||||||
|       buf += GRUB_DISK_SECTOR_SIZE * batch; |       buf += batch << ata->log_sector_size; | ||||||
|       sector += batch; |       sector += batch; | ||||||
|       nsectors += batch; |       nsectors += batch; | ||||||
|     } |     } | ||||||
|  | @ -433,6 +449,7 @@ grub_ata_open (const char *name, grub_disk_t disk) | ||||||
|     return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); |     return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); | ||||||
| 
 | 
 | ||||||
|   disk->total_sectors = ata->size; |   disk->total_sectors = ata->size; | ||||||
|  |   disk->log_sector_size = ata->log_sector_size; | ||||||
| 
 | 
 | ||||||
|   disk->id = grub_make_scsi_id (id, bus, 0); |   disk->id = grub_make_scsi_id (id, bus, 0); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -170,6 +170,7 @@ struct grub_ata | ||||||
| 
 | 
 | ||||||
|   /* Sector count.  */ |   /* Sector count.  */ | ||||||
|   grub_uint64_t size; |   grub_uint64_t size; | ||||||
|  |   grub_uint32_t log_sector_size; | ||||||
| 
 | 
 | ||||||
|   /* CHS maximums.  */ |   /* CHS maximums.  */ | ||||||
|   grub_uint16_t cylinders; |   grub_uint16_t cylinders; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue