| QUOTE (ZWinFlame @ Sep 24 2003, 11:00 PM) |
| What is this warning below on Xbins. How do I format my partition 6. I just got another 200 gig hard drive?. Sorry for such a question all. ***** LBA48 Warning ***** If you choose the partitioning option "Partition 6 Takes Rest of the Drive", and if your drive is greater than 137GB and has a partition 6, data corruption will result. Only use this option if you plan on reformatting partition 6. ********** |
| QUOTE |
Thanks for taking the previous bit Alan, here's an incremental update to 2.5.66-ac2. Just cleans up the 'when to use 48-bit lba' logic a bit per Andries suggestion, and also expands the request size for 48-bit lba capable drives to 512KiB. Works perfectly in testing here, ext2/3 generates nice big 512KiB requests and the drive flies. diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.66-ac2/drivers/ide/ide-disk.c linux-2.5.66-ac2/drivers/ide/ide-disk.c --- /opt/kernel/linux-2.5.66-ac2/drivers/ide/ide-disk.c 2003-04-06 13:15:19.000000000 +0200 +++ linux-2.5.66-ac2/drivers/ide/ide-disk.c 2003-04-06 15:05:07.000000000 +0200 @@ -373,7 +373,7 @@ nsectors.all = (u16) rq->nr_sectors; - if (drive->addressing == 1 && block + rq->nr_sectors > 0xfffffff) + if (drive->addressing == 1 && rq_lba48(rq)) lba48 = 1; if (driver_blocked) @@ -583,7 +583,7 @@ { int lba48bit = 0; - if (drive->addressing == 1 && block > 0xfffffff) + if (drive->addressing == 1 && rq_lba48(rq)) lba48bit = 1; BUG_ON(drive->blocked); @@ -611,7 +611,7 @@ return ide_started; } - if (lba48bit && block > 0xfffffff) + if (lba48bit) return lba_48_rw_disk(drive, rq, (unsigned long long) block); if (drive->select.b.lba) /* 28-bit LBA */ return lba_28_rw_disk(drive, rq, (unsigned long) block); @@ -625,7 +625,7 @@ int cmd = rq_data_dir(rq); int lba48bit = 0; - if (drive->addressing == 1 && rq->sector > 0xfffffff) + if (drive->addressing == 1 && rq_lba48(rq)) lba48bit = 1; if ((cmd == READ) && drive->using_tcq) @@ -1504,7 +1504,7 @@ static int set_lba_addressing (ide_drive_t *drive, int arg) { - return (probe_lba_addressing(drive, arg)); + return probe_lba_addressing(drive, arg); } static void idedisk_add_settings(ide_drive_t *drive) @@ -1591,6 +1591,9 @@ (void) probe_lba_addressing(drive, 1); + if (drive->addressing) + blk_queue_max_sectors(&drive->queue, 1024); + /* Extract geometry if we did not already have one for the drive */ if (!drive->cyl || !drive->head || !drive->sect) { drive->cyl = drive->bios_cyl = id->cyls; diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.66-ac2/drivers/ide/ide-dma.c linux-2.5.66-ac2/drivers/ide/ide-dma.c --- /opt/kernel/linux-2.5.66-ac2/drivers/ide/ide-dma.c 2003-04-06 13:15:19.000000000 +0200 +++ linux-2.5.66-ac2/drivers/ide/ide-dma.c 2003-04-06 13:19:34.000000000 +0200 @@ -663,7 +663,7 @@ if (drive->media != ide_disk) return 0; - if (drive->addressing == 1 && rq->sector > 0xfffffff) + if (drive->addressing == 1 && rq_lba48(rq)) lba48 = 1; command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA; @@ -698,7 +698,7 @@ if (drive->media != ide_disk) return 0; - if (drive->addressing == 1 && rq->sector > 0xfffffff) + if (drive->addressing == 1 && rq_lba48(rq)) lba48 = 1; command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.5.66-ac2/include/linux/ide.h linux-2.5.66-ac2/include/linux/ide.h --- /opt/kernel/linux-2.5.66-ac2/include/linux/ide.h 2003-04-06 13:15:20.000000000 +0200 +++ linux-2.5.66-ac2/include/linux/ide.h 2003-04-06 13:20:25.000000000 +0200 @@ -866,6 +866,12 @@ bio_kunmap_irq(buffer, flags); } +/* + * must be addressed with 48-bit lba + */ +#define rq_lba48(rq) + (((rq)->sector + (rq)->nr_sectors) > 0xfffffff || rq->nr_sectors > 256) + #define IDE_CHIPSET_PCI_MASK ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx)) #define IDE_CHIPSET_IS_PCI© ((IDE_CHIPSET_PCI_MASK >> ©) & 1) -- Jens Axboe ----------------------------------------------------------------------------------------------------------------- Hi, 48-bit lba has a non-significant overhead (twice the outb's, 12 instead of 6 per command), so it makes sense to use 28-bit lba commands whenever we can. Patch is against 2.5.66-BK. ===== drivers/ide/ide-disk.c 1.36 vs edited ===== --- 1.36/drivers/ide/ide-disk.c Wed Mar 26 21:23:01 2003 +++ edited/drivers/ide/ide-disk.c Fri Apr 4 14:18:41 2003 @@ -367,12 +367,15 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) { ide_hwif_t *hwif = HWIF(drive); - u8 lba48 = (drive->addressing == 1) ? 1 : 0; + u8 lba48 = 0; task_ioreg_t command = WIN_NOP; ata_nsector_t nsectors; nsectors.all = (u16) rq->nr_sectors; + if (drive->addressing == 1 && block > 0xfffffff) + lba48 = 1; + if (driver_blocked) panic("Request while ide driver is blocked?"); @@ -392,7 +395,7 @@ hwif->OUTB(drive->ctl, IDE_CONTROL_REG); if (drive->select.b.lba) { - if (drive->addressing == 1) { + if (lba48) { task_ioreg_t tasklets[10]; if (blk_rq_tagged(rq)) { @@ -502,6 +505,7 @@ command = ((drive->mult_count) ? ((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) : ((lba48) ? WIN_READ_EXT : WIN_READ)); + ide_execute_command(drive, command, &read_intr, WAIT_CMD, NULL); return ide_started; } else if (rq_data_dir(rq) == WRITE) { @@ -577,6 +581,11 @@ */ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) { + int lba48bit = 0; + + if (drive->addressing == 1 && block > 0xfffffff) + lba48bit = 1; + BUG_ON(drive->blocked); if (!blk_fs_request(rq)) { blk_dump_rq_flags(rq, "do_rw_disk - bad command"); @@ -602,7 +611,7 @@ return ide_started; } - if (drive->addressing == 1) /* 48-bit LBA */ + if (lba48bit && block > 0xfffffff) return lba_48_rw_disk(drive, rq, (unsigned long long) block); if (drive->select.b.lba) /* 28-bit LBA */ return lba_28_rw_disk(drive, rq, (unsigned long) block); @@ -611,9 +620,13 @@ return chs_rw_disk(drive, rq, (unsigned long) block); } -static task_ioreg_t get_command (ide_drive_t *drive, int cmd) +static task_ioreg_t get_command (ide_drive_t *drive, struct request *rq) { - int lba48bit = (drive->addressing == 1) ? 1 : 0; + int cmd = rq_data_dir(rq); + int lba48bit = 0; + + if (drive->addressing == 1 && rq->sector > 0xfffffff) + lba48bit = 1; if ((cmd == READ) && drive->using_tcq) return lba48bit ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED; @@ -640,7 +653,7 @@ ide_task_t args; int sectors; ata_nsector_t nsectors; - task_ioreg_t command = get_command(drive, rq_data_dir(rq)); + task_ioreg_t command = get_command(drive, rq); unsigned int track = (block / drive->sect); unsigned int sect = (block % drive->sect) + 1; unsigned int head = (track % drive->head); @@ -672,6 +685,7 @@ args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all; args.tfRegister[IDE_COMMAND_OFFSET] = command; args.command_type = ide_cmd_type_parser(&args); + args.addressing = 0; args.rq = (struct request *) rq; rq->special = (ide_task_t *)&args; return do_rw_taskfile(drive, &args); @@ -682,7 +696,7 @@ ide_task_t args; int sectors; ata_nsector_t nsectors; - task_ioreg_t command = get_command(drive, rq_data_dir(rq)); + task_ioreg_t command = get_command(drive, rq); nsectors.all = (u16) rq->nr_sectors; @@ -710,6 +724,7 @@ args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all; args.tfRegister[IDE_COMMAND_OFFSET] = command; args.command_type = ide_cmd_type_parser(&args); + args.addressing = 0; args.rq = (struct request *) rq; rq->special = (ide_task_t *)&args; return do_rw_taskfile(drive, &args); @@ -726,7 +741,7 @@ ide_task_t args; int sectors; ata_nsector_t nsectors; - task_ioreg_t command = get_command(drive, rq_data_dir(rq)); + task_ioreg_t command = get_command(drive, rq); nsectors.all = (u16) rq->nr_sectors; @@ -762,6 +777,7 @@ args.hobRegister[IDE_SELECT_OFFSET_HOB] = drive->select.all; args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80); args.command_type = ide_cmd_type_parser(&args); + args.addressing = 1; args.rq = (struct request *) rq; rq->special = (ide_task_t *)&args; return do_rw_taskfile(drive, &args); ===== drivers/ide/ide-dma.c 1.13 vs edited ===== --- 1.13/drivers/ide/ide-dma.c Fri Mar 7 18:14:31 2003 +++ edited/drivers/ide/ide-dma.c Fri Apr 4 14:15:37 2003 @@ -653,7 +653,7 @@ ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; unsigned int reading = 1 << 3; - u8 lba48 = (drive->addressing == 1) ? 1 : 0; + u8 lba48 = 0; task_ioreg_t command = WIN_NOP; /* try pio */ @@ -663,11 +663,14 @@ if (drive->media != ide_disk) return 0; + if (drive->addressing == 1 && rq->sector > 0xfffffff) + lba48 = 1; + command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA; - + if (drive->vdma) command = (lba48) ? WIN_READ_EXT: WIN_READ; - + if (rq->flags & REQ_DRIVE_TASKFILE) { ide_task_t *args = rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; @@ -685,7 +688,7 @@ ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; unsigned int reading = 0; - u8 lba48 = (drive->addressing == 1) ? 1 : 0; + u8 lba48 = 0; task_ioreg_t command = WIN_NOP; /* try PIO instead of DMA */ @@ -695,10 +698,13 @@ if (drive->media != ide_disk) return 0; + if (drive->addressing == 1 && rq->sector > 0xfffffff) + lba48 = 1; + command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; if (drive->vdma) command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE; - + if (rq->flags & REQ_DRIVE_TASKFILE) { ide_task_t *args = rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; ===== drivers/ide/ide-taskfile.c 1.14 vs edited ===== --- 1.14/drivers/ide/ide-taskfile.c Wed Mar 26 21:22:22 2003 +++ edited/drivers/ide/ide-taskfile.c Fri Apr 4 14:20:26 2003 @@ -147,7 +147,7 @@ ide_hwif_t *hwif = HWIF(drive); task_struct_t *taskfile = (task_struct_t *) task->tfRegister; hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; - u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; + u8 HIHI = task->addressing == 1 ? 0xE0 : 0xEF; #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG void debug_taskfile(drive, task); @@ -160,7 +160,7 @@ } SELECT_MASK(drive, 0); - if (drive->addressing == 1) { + if (task->addressing == 1) { hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); @@ -332,7 +332,7 @@ args->tfRegister[IDE_STATUS_OFFSET] = stat; if ((drive->id->command_set_2 & 0x0400) && (drive->id->cfs_enable_2 & 0x0400) && - (drive->addressing == 1)) { + (args->addressing == 1)) { hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB); args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG); args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG); @@ -1795,13 +1795,13 @@ */ if (task->tf_out_flags.all == 0) { task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS; - if (drive->addressing == 1) + if (task->addressing == 1) task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8); } if (task->tf_in_flags.all == 0) { task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; - if (drive->addressing == 1) + if (task->addressing == 1) task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); } ===== include/linux/ide.h 1.42 vs edited ===== --- 1.42/include/linux/ide.h Thu Mar 20 19:23:19 2003 +++ edited/include/linux/ide.h Fri Apr 4 14:07:50 2003 @@ -1408,6 +1408,7 @@ ide_reg_valid_t tf_in_flags; int data_phase; int command_type; + int addressing; /* 1 for 48-bit */ ide_pre_handler_t *prehandler; ide_handler_t *handler; ide_post_handler_t *posthandler; -- Jens Axboe |