Commit 1e6c5dfd authored by Jens Axboe's avatar Jens Axboe

[PATCH] Proper 48-bit lba support

parent a04563a1
...@@ -657,7 +657,7 @@ static int icside_dma_read(ide_drive_t *drive) ...@@ -657,7 +657,7 @@ static int icside_dma_read(ide_drive_t *drive)
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
cmd = args->tfRegister[IDE_COMMAND_OFFSET]; cmd = args->tfRegister[IDE_COMMAND_OFFSET];
} else if (drive->addressing == 1) { } else if (rq_lba48(rq)) {
cmd = WIN_READDMA_EXT; cmd = WIN_READDMA_EXT;
} else { } else {
cmd = WIN_READDMA; cmd = WIN_READDMA;
...@@ -698,7 +698,7 @@ int icside_dma_write(ide_drive_t *drive) ...@@ -698,7 +698,7 @@ int icside_dma_write(ide_drive_t *drive)
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
cmd = args->tfRegister[IDE_COMMAND_OFFSET]; cmd = args->tfRegister[IDE_COMMAND_OFFSET];
} else if (drive->addressing == 1) { } else if (rq_lba48(rq)) {
cmd = WIN_WRITEDMA_EXT; cmd = WIN_WRITEDMA_EXT;
} else { } else {
cmd = WIN_WRITEDMA; cmd = WIN_WRITEDMA;
......
...@@ -358,7 +358,7 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive) ...@@ -358,7 +358,7 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
u8 lba48 = (drive->addressing == 1) ? 1 : 0; u8 lba48 = rq_lba48(rq);
task_ioreg_t command = WIN_NOP; task_ioreg_t command = WIN_NOP;
ata_nsector_t nsectors; ata_nsector_t nsectors;
...@@ -383,7 +383,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -383,7 +383,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
hwif->OUTB(drive->ctl, IDE_CONTROL_REG); hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
if (drive->select.b.lba) { if (drive->select.b.lba) {
if (drive->addressing == 1) { if (lba48) {
task_ioreg_t tasklets[10]; task_ioreg_t tasklets[10];
if (blk_rq_tagged(rq)) { if (blk_rq_tagged(rq)) {
...@@ -593,7 +593,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -593,7 +593,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
return ide_started; return ide_started;
} }
if (drive->addressing == 1) /* 48-bit LBA */ if (rq_lba48(rq)) /* 48-bit LBA */
return lba_48_rw_disk(drive, rq, (unsigned long long) block); return lba_48_rw_disk(drive, rq, (unsigned long long) block);
if (drive->select.b.lba) /* 28-bit LBA */ if (drive->select.b.lba) /* 28-bit LBA */
return lba_28_rw_disk(drive, rq, (unsigned long) block); return lba_28_rw_disk(drive, rq, (unsigned long) block);
...@@ -602,9 +602,10 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -602,9 +602,10 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
return chs_rw_disk(drive, rq, (unsigned long) block); 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 lba48bit = rq_lba48(rq);
int cmd = rq_data_dir(rq);
if ((cmd == READ) && drive->using_tcq) if ((cmd == READ) && drive->using_tcq)
return lba48bit ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED; return lba48bit ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED;
...@@ -631,7 +632,7 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi ...@@ -631,7 +632,7 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi
ide_task_t args; ide_task_t args;
int sectors; int sectors;
ata_nsector_t nsectors; 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 track = (block / drive->sect);
unsigned int sect = (block % drive->sect) + 1; unsigned int sect = (block % drive->sect) + 1;
unsigned int head = (track % drive->head); unsigned int head = (track % drive->head);
...@@ -663,6 +664,7 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi ...@@ -663,6 +664,7 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi
args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all; args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all;
args.tfRegister[IDE_COMMAND_OFFSET] = command; args.tfRegister[IDE_COMMAND_OFFSET] = command;
args.command_type = ide_cmd_type_parser(&args); args.command_type = ide_cmd_type_parser(&args);
args.addressing = 0;
args.rq = (struct request *) rq; args.rq = (struct request *) rq;
rq->special = (ide_task_t *)&args; rq->special = (ide_task_t *)&args;
return do_rw_taskfile(drive, &args); return do_rw_taskfile(drive, &args);
...@@ -673,7 +675,7 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u ...@@ -673,7 +675,7 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u
ide_task_t args; ide_task_t args;
int sectors; int sectors;
ata_nsector_t nsectors; 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; nsectors.all = (u16) rq->nr_sectors;
...@@ -701,6 +703,7 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u ...@@ -701,6 +703,7 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u
args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all; args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all;
args.tfRegister[IDE_COMMAND_OFFSET] = command; args.tfRegister[IDE_COMMAND_OFFSET] = command;
args.command_type = ide_cmd_type_parser(&args); args.command_type = ide_cmd_type_parser(&args);
args.addressing = 0;
args.rq = (struct request *) rq; args.rq = (struct request *) rq;
rq->special = (ide_task_t *)&args; rq->special = (ide_task_t *)&args;
return do_rw_taskfile(drive, &args); return do_rw_taskfile(drive, &args);
...@@ -717,7 +720,7 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u ...@@ -717,7 +720,7 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u
ide_task_t args; ide_task_t args;
int sectors; int sectors;
ata_nsector_t nsectors; 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; nsectors.all = (u16) rq->nr_sectors;
...@@ -753,6 +756,7 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u ...@@ -753,6 +756,7 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u
args.hobRegister[IDE_SELECT_OFFSET_HOB] = drive->select.all; args.hobRegister[IDE_SELECT_OFFSET_HOB] = drive->select.all;
args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80); args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80);
args.command_type = ide_cmd_type_parser(&args); args.command_type = ide_cmd_type_parser(&args);
args.addressing = 1;
args.rq = (struct request *) rq; args.rq = (struct request *) rq;
rq->special = (ide_task_t *)&args; rq->special = (ide_task_t *)&args;
return do_rw_taskfile(drive, &args); return do_rw_taskfile(drive, &args);
...@@ -1479,7 +1483,7 @@ static int probe_lba_addressing (ide_drive_t *drive, int arg) ...@@ -1479,7 +1483,7 @@ static int probe_lba_addressing (ide_drive_t *drive, int arg)
static int set_lba_addressing (ide_drive_t *drive, int arg) 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) static void idedisk_add_settings(ide_drive_t *drive)
...@@ -1566,6 +1570,18 @@ static void idedisk_setup (ide_drive_t *drive) ...@@ -1566,6 +1570,18 @@ static void idedisk_setup (ide_drive_t *drive)
(void) probe_lba_addressing(drive, 1); (void) probe_lba_addressing(drive, 1);
if (drive->addressing == 1) {
ide_hwif_t *hwif = HWIF(drive);
int max_s = 2048;
if (max_s > hwif->rqsize)
max_s = hwif->rqsize;
blk_queue_max_sectors(&drive->queue, max_s);
}
printk("%s: max request size: %dKiB\n", drive->name, drive->queue.max_sectors / 2);
/* Extract geometry if we did not already have one for the drive */ /* Extract geometry if we did not already have one for the drive */
if (!drive->cyl || !drive->head || !drive->sect) { if (!drive->cyl || !drive->head || !drive->sect) {
drive->cyl = drive->bios_cyl = id->cyls; drive->cyl = drive->bios_cyl = id->cyls;
......
...@@ -653,7 +653,7 @@ int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */) ...@@ -653,7 +653,7 @@ int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
unsigned int reading = 1 << 3; unsigned int reading = 1 << 3;
u8 lba48 = (drive->addressing == 1) ? 1 : 0; u8 lba48 = rq_lba48(rq);
task_ioreg_t command = WIN_NOP; task_ioreg_t command = WIN_NOP;
/* try pio */ /* try pio */
...@@ -685,7 +685,7 @@ int __ide_dma_write (ide_drive_t *drive /*, struct request *rq */) ...@@ -685,7 +685,7 @@ int __ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
unsigned int reading = 0; unsigned int reading = 0;
u8 lba48 = (drive->addressing == 1) ? 1 : 0; u8 lba48 = rq_lba48(rq);
task_ioreg_t command = WIN_NOP; task_ioreg_t command = WIN_NOP;
/* try PIO instead of DMA */ /* try PIO instead of DMA */
......
...@@ -205,7 +205,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) ...@@ -205,7 +205,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG); args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG);
args->tfRegister[IDE_STATUS_OFFSET] = stat; args->tfRegister[IDE_STATUS_OFFSET] = stat;
if (drive->addressing == 1) { if (args->addressing == 1) {
hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB); hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG); args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG);
args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG); args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG);
......
...@@ -998,6 +998,7 @@ EXPORT_SYMBOL(save_match); ...@@ -998,6 +998,7 @@ EXPORT_SYMBOL(save_match);
static void ide_init_queue(ide_drive_t *drive) static void ide_init_queue(ide_drive_t *drive)
{ {
request_queue_t *q = &drive->queue; request_queue_t *q = &drive->queue;
ide_hwif_t *hwif = HWIF(drive);
int max_sectors = 256; int max_sectors = 256;
/* /*
...@@ -1013,8 +1014,15 @@ static void ide_init_queue(ide_drive_t *drive) ...@@ -1013,8 +1014,15 @@ static void ide_init_queue(ide_drive_t *drive)
drive->queue_setup = 1; drive->queue_setup = 1;
blk_queue_segment_boundary(q, 0xffff); blk_queue_segment_boundary(q, 0xffff);
if (HWIF(drive)->rqsize) /*
max_sectors = HWIF(drive)->rqsize; * use rqsize if specified, else set it to defaults for 28-bit or
* 48-bit lba commands
*/
if (hwif->rqsize)
max_sectors = hwif->rqsize;
else
hwif->rqsize = hwif->addressing ? 256 : 65536;
blk_queue_max_sectors(q, max_sectors); blk_queue_max_sectors(q, max_sectors);
/* IDE DMA can do PRD_ENTRIES number of segments. */ /* IDE DMA can do PRD_ENTRIES number of segments. */
......
...@@ -138,7 +138,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -138,7 +138,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister; task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; 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 #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
void debug_taskfile(drive, task); void debug_taskfile(drive, task);
...@@ -151,7 +151,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -151,7 +151,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
} }
SELECT_MASK(drive, 0); SELECT_MASK(drive, 0);
if (drive->addressing == 1) { if (task->addressing == 1) {
hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
...@@ -241,7 +241,7 @@ void ide_end_taskfile (ide_drive_t *drive, u8 stat, u8 err) ...@@ -241,7 +241,7 @@ void ide_end_taskfile (ide_drive_t *drive, u8 stat, u8 err)
args->tfRegister[IDE_STATUS_OFFSET] = stat; args->tfRegister[IDE_STATUS_OFFSET] = stat;
if ((drive->id->command_set_2 & 0x0400) && if ((drive->id->command_set_2 & 0x0400) &&
(drive->id->cfs_enable_2 & 0x0400) && (drive->id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) { (args->addressing == 1)) {
hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB); hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG); args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG);
args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG); args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG);
...@@ -1272,6 +1272,13 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -1272,6 +1272,13 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
args.data_phase = req_task->data_phase; args.data_phase = req_task->data_phase;
args.command_type = req_task->req_cmd; args.command_type = req_task->req_cmd;
/*
* this forces 48-bit commands if the drive is configured to do so.
* it would also be possible to lookup the command type based on the
* opcode, but this is way simpler.
*/
args.addressing = drive->addressing;
#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
DTF("%s: ide_ioctl_cmd %s: ide_task_cmd %s\n", DTF("%s: ide_ioctl_cmd %s: ide_task_cmd %s\n",
drive->name, drive->name,
...@@ -1611,13 +1618,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) ...@@ -1611,13 +1618,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
*/ */
if (task->tf_out_flags.all == 0) { if (task->tf_out_flags.all == 0) {
task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS; 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); task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
} }
if (task->tf_in_flags.all == 0) { if (task->tf_in_flags.all == 0) {
task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; 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); task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
} }
......
...@@ -664,20 +664,20 @@ static ide_startstop_t ide_dma_queued_rw(ide_drive_t *drive, u8 command) ...@@ -664,20 +664,20 @@ static ide_startstop_t ide_dma_queued_rw(ide_drive_t *drive, u8 command)
ide_startstop_t __ide_dma_queued_read(ide_drive_t *drive) ide_startstop_t __ide_dma_queued_read(ide_drive_t *drive)
{ {
u8 command = WIN_READDMA_QUEUED; struct request *rq = hwgroup->rq;
u8 command;
if (drive->addressing == 1) command = rq_lba48(rq) ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED;
command = WIN_READDMA_QUEUED_EXT;
return ide_dma_queued_rw(drive, command); return ide_dma_queued_rw(drive, command);
} }
ide_startstop_t __ide_dma_queued_write(ide_drive_t *drive) ide_startstop_t __ide_dma_queued_write(ide_drive_t *drive)
{ {
u8 command = WIN_WRITEDMA_QUEUED; struct request *rq = hwgroup->rq;
u8 command;
if (drive->addressing == 1) command = rq_lba48(rq) ? WIN_WRITEDMA_QUEUED_EXT : WIN_WRITEDMA_QUEUED;
command = WIN_WRITEDMA_QUEUED_EXT;
return ide_dma_queued_rw(drive, command); return ide_dma_queued_rw(drive, command);
} }
......
...@@ -400,9 +400,20 @@ u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat) ...@@ -400,9 +400,20 @@ u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
if (err & MARK_ERR) printk("AddrMarkNotFound "); if (err & MARK_ERR) printk("AddrMarkNotFound ");
printk("}"); printk("}");
if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) { if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
struct request *rq = HWGROUP(drive)->rq;
int lba48 = drive->addressing;
if (rq) {
if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *t = rq->special;
lba48 = t->addressing;
} else
lba48 = rq_lba48(rq);
}
if ((drive->id->command_set_2 & 0x0400) && if ((drive->id->command_set_2 & 0x0400) &&
(drive->id->cfs_enable_2 & 0x0400) && (drive->id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) { lba48) {
u64 sectors = 0; u64 sectors = 0;
u32 high = 0; u32 high = 0;
u32 low = ide_read_24(drive); u32 low = ide_read_24(drive);
......
...@@ -535,8 +535,9 @@ static int pdc202xx_quirkproc (ide_drive_t *drive) ...@@ -535,8 +535,9 @@ static int pdc202xx_quirkproc (ide_drive_t *drive)
static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive) static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive)
{ {
if (drive->addressing == 1) {
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
if (rq_lba48(rq)) {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
// struct pci_dev *dev = hwif->pci_dev; // struct pci_dev *dev = hwif->pci_dev;
// unsgned long high_16 = pci_resource_start(dev, 4); // unsgned long high_16 = pci_resource_start(dev, 4);
...@@ -557,7 +558,9 @@ static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive) ...@@ -557,7 +558,9 @@ static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive)
static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
{ {
if (drive->addressing == 1) { struct request *rq = HWGROUP(drive)->rq;
if (rq_lba48(rq)) {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
// unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); // unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4);
unsigned long high_16 = hwif->dma_master; unsigned long high_16 = hwif->dma_master;
......
...@@ -1240,7 +1240,6 @@ pmac_ide_dma_read (ide_drive_t *drive) ...@@ -1240,7 +1240,6 @@ pmac_ide_dma_read (ide_drive_t *drive)
// ide_task_t *args = rq->special; // ide_task_t *args = rq->special;
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
u8 ata4; u8 ata4;
u8 lba48 = (drive->addressing == 1) ? 1 : 0;
task_ioreg_t command = WIN_NOP; task_ioreg_t command = WIN_NOP;
if (pmif == NULL) if (pmif == NULL)
...@@ -1272,7 +1271,7 @@ pmac_ide_dma_read (ide_drive_t *drive) ...@@ -1272,7 +1271,7 @@ pmac_ide_dma_read (ide_drive_t *drive)
command = args->tfRegister[IDE_COMMAND_OFFSET]; command = args->tfRegister[IDE_COMMAND_OFFSET];
} }
#else #else
command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA; command = rq_lba48(rq) ? WIN_READDMA_EXT : WIN_READDMA;
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
command = args->tfRegister[IDE_COMMAND_OFFSET]; command = args->tfRegister[IDE_COMMAND_OFFSET];
...@@ -1293,7 +1292,6 @@ pmac_ide_dma_write (ide_drive_t *drive) ...@@ -1293,7 +1292,6 @@ pmac_ide_dma_write (ide_drive_t *drive)
// ide_task_t *args = rq->special; // ide_task_t *args = rq->special;
u8 unit = (drive->select.b.unit & 0x01); u8 unit = (drive->select.b.unit & 0x01);
u8 ata4; u8 ata4;
u8 lba48 = (drive->addressing == 1) ? 1 : 0;
task_ioreg_t command = WIN_NOP; task_ioreg_t command = WIN_NOP;
if (pmif == NULL) if (pmif == NULL)
...@@ -1325,7 +1323,7 @@ pmac_ide_dma_write (ide_drive_t *drive) ...@@ -1325,7 +1323,7 @@ pmac_ide_dma_write (ide_drive_t *drive)
command = args->tfRegister[IDE_COMMAND_OFFSET]; command = args->tfRegister[IDE_COMMAND_OFFSET];
} }
#else #else
command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; command = rq_lba48(rq) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special; ide_task_t *args = rq->special;
command = args->tfRegister[IDE_COMMAND_OFFSET]; command = args->tfRegister[IDE_COMMAND_OFFSET];
......
...@@ -846,6 +846,12 @@ static inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned l ...@@ -846,6 +846,12 @@ static inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned l
bio_kunmap_irq(buffer, flags); 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 \ #define IDE_CHIPSET_PCI_MASK \
((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx)) ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1) #define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
...@@ -1387,6 +1393,7 @@ typedef struct ide_task_s { ...@@ -1387,6 +1393,7 @@ typedef struct ide_task_s {
ide_reg_valid_t tf_in_flags; ide_reg_valid_t tf_in_flags;
int data_phase; int data_phase;
int command_type; int command_type;
int addressing; /* 1 for 48-bit */
ide_pre_handler_t *prehandler; ide_pre_handler_t *prehandler;
ide_handler_t *handler; ide_handler_t *handler;
ide_post_handler_t *posthandler; ide_post_handler_t *posthandler;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment