Commit ff8fef566601ba27767e885386cb2074c4f09886

Authored by Sascha Silbe
Committed by Tom Rini
1 parent eeaef5e430

Fix block device accesses beyond 2TiB

With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
which is required to represent block numbers for storage devices that
exceed 2TiB (the block size usually is 512B), e.g. recent hard drives.

For some obscure reason, the current U-Boot code uses lbaint_t for the
number of blocks to read (a rather optimistic estimation of how RAM
sizes will evolve), but not for the starting address. Trying to access
blocks beyond the 2TiB boundary will simply wrap around and read a
block within the 0..2TiB range.

We now use lbaint_t for block start addresses, too. This required
changes to all block drivers as the signature of block_read(),
block_write() and block_erase() in block_dev_desc_t changed.

Signed-off-by: Sascha Silbe <t-uboot@infra-silbe.de>

Showing 5 changed files with 26 additions and 24 deletions Side-by-side Diff

... ... @@ -830,7 +830,7 @@
830 830  
831 831 /* ------------------------------------------------------------------------- */
832 832  
833   -ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
  833 +ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
834 834 {
835 835 ulong n = 0;
836 836 unsigned char c;
... ... @@ -844,7 +844,7 @@
844 844 lba48 = 1;
845 845 }
846 846 #endif
847   - debug("ide_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
  847 + debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
848 848 device, blknr, blkcnt, (ulong) buffer);
849 849  
850 850 ide_led(DEVICE_LED(device), 1); /* LED on */
... ... @@ -934,8 +934,8 @@
934 934  
935 935 if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
936 936 ATA_STAT_DRQ) {
937   - printf("Error (no IRQ) dev %d blk %ld: status %#02x\n",
938   - device, blknr, c);
  937 + printf("Error (no IRQ) dev %d blk " LBAF ": status "
  938 + "%#02x\n", device, blknr, c);
939 939 break;
940 940 }
941 941  
... ... @@ -954,7 +954,7 @@
954 954 /* ------------------------------------------------------------------------- */
955 955  
956 956  
957   -ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
  957 +ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer)
958 958 {
959 959 ulong n = 0;
960 960 unsigned char c;
... ... @@ -1022,8 +1022,8 @@
1022 1022  
1023 1023 if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
1024 1024 ATA_STAT_DRQ) {
1025   - printf("Error (no IRQ) dev %d blk %ld: status %#02x\n",
1026   - device, blknr, c);
  1025 + printf("Error (no IRQ) dev %d blk " LBAF ": status "
  1026 + "%#02x\n", device, blknr, c);
1027 1027 goto WR_OUT;
1028 1028 }
1029 1029  
common/usb_storage.c
... ... @@ -170,9 +170,9 @@
170 170 block_dev_desc_t *dev_desc);
171 171 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
172 172 struct us_data *ss);
173   -unsigned long usb_stor_read(int device, unsigned long blknr,
  173 +unsigned long usb_stor_read(int device, lbaint_t blknr,
174 174 lbaint_t blkcnt, void *buffer);
175   -unsigned long usb_stor_write(int device, unsigned long blknr,
  175 +unsigned long usb_stor_write(int device, lbaint_t blknr,
176 176 lbaint_t blkcnt, const void *buffer);
177 177 struct usb_device * usb_get_dev_index(int index);
178 178 void uhci_show_temp_int_td(void);
... ... @@ -1054,7 +1054,7 @@
1054 1054 }
1055 1055 #endif /* CONFIG_USB_BIN_FIXUP */
1056 1056  
1057   -unsigned long usb_stor_read(int device, unsigned long blknr,
  1057 +unsigned long usb_stor_read(int device, lbaint_t blknr,
1058 1058 lbaint_t blkcnt, void *buffer)
1059 1059 {
1060 1060 lbaint_t start, blks;
... ... @@ -1127,7 +1127,7 @@
1127 1127 return blkcnt;
1128 1128 }
1129 1129  
1130   -unsigned long usb_stor_write(int device, unsigned long blknr,
  1130 +unsigned long usb_stor_write(int device, lbaint_t blknr,
1131 1131 lbaint_t blkcnt, const void *buffer)
1132 1132 {
1133 1133 lbaint_t start, blks;
... ... @@ -254,7 +254,7 @@
254 254 }
255 255  
256 256 static unsigned long
257   -mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
  257 +mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
258 258 {
259 259 int err = 0;
260 260 struct mmc *mmc = find_mmc_device(dev_num);
... ... @@ -266,7 +266,8 @@
266 266  
267 267 if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
268 268 printf("\n\nCaution! Your devices Erase group is 0x%x\n"
269   - "The erase range would be change to 0x%lx~0x%lx\n\n",
  269 + "The erase range would be change to "
  270 + "0x" LBAF "~0x" LBAF "\n\n",
270 271 mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
271 272 ((start + blkcnt + mmc->erase_grp_size)
272 273 & ~(mmc->erase_grp_size - 1)) - 1);
273 274  
... ... @@ -289,14 +290,14 @@
289 290 }
290 291  
291 292 static ulong
292   -mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
  293 +mmc_write_blocks(struct mmc *mmc, lbaint_t start, lbaint_t blkcnt, const void*src)
293 294 {
294 295 struct mmc_cmd cmd;
295 296 struct mmc_data data;
296 297 int timeout = 1000;
297 298  
298 299 if ((start + blkcnt) > mmc->block_dev.lba) {
299   - printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
  300 + printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
300 301 start + blkcnt, mmc->block_dev.lba);
301 302 return 0;
302 303 }
... ... @@ -346,7 +347,7 @@
346 347 }
347 348  
348 349 static ulong
349   -mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
  350 +mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void*src)
350 351 {
351 352 lbaint_t cur, blocks_todo = blkcnt;
352 353  
... ... @@ -369,7 +370,7 @@
369 370 return blkcnt;
370 371 }
371 372  
372   -static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
  373 +static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
373 374 lbaint_t blkcnt)
374 375 {
375 376 struct mmc_cmd cmd;
... ... @@ -408,7 +409,7 @@
408 409 return blkcnt;
409 410 }
410 411  
411   -static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
  412 +static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
412 413 {
413 414 lbaint_t cur, blocks_todo = blkcnt;
414 415  
... ... @@ -420,7 +421,7 @@
420 421 return 0;
421 422  
422 423 if ((start + blkcnt) > mmc->block_dev.lba) {
423   - printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
  424 + printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
424 425 start + blkcnt, mmc->block_dev.lba);
425 426 return 0;
426 427 }
... ... @@ -54,8 +54,9 @@
54 54 */
55 55  
56 56 void ide_init(void);
57   -ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer);
58   -ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer);
  57 +ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer);
  58 +ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt,
  59 + const void *buffer);
59 60  
60 61 #ifdef CONFIG_IDE_PREINIT
61 62 int ide_preinit(void);
... ... @@ -43,15 +43,15 @@
43 43 char product[20+1]; /* IDE Serial no, SCSI product */
44 44 char revision[8+1]; /* firmware revision */
45 45 unsigned long (*block_read)(int dev,
46   - unsigned long start,
  46 + lbaint_t start,
47 47 lbaint_t blkcnt,
48 48 void *buffer);
49 49 unsigned long (*block_write)(int dev,
50   - unsigned long start,
  50 + lbaint_t start,
51 51 lbaint_t blkcnt,
52 52 const void *buffer);
53 53 unsigned long (*block_erase)(int dev,
54   - unsigned long start,
  54 + lbaint_t start,
55 55 lbaint_t blkcnt);
56 56 void *priv; /* driver private struct pointer */
57 57 }block_dev_desc_t;