Commit 0d9bef55 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/mingo/BK/linux-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 4c63ad73 1a495cba
This diff is collapsed.
...@@ -280,7 +280,7 @@ init_e100_ide (void) ...@@ -280,7 +280,7 @@ init_e100_ide (void)
hwif->tuneproc = &tune_e100_ide; hwif->tuneproc = &tune_e100_ide;
hwif->dmaproc = &e100_dmaproc; hwif->dmaproc = &e100_dmaproc;
hwif->ata_read = e100_ide_input_data; hwif->ata_read = e100_ide_input_data;
hwif->ata_write = e100_ide_input_data; hwif->ata_write = e100_ide_output_data;
hwif->atapi_read = e100_atapi_read; hwif->atapi_read = e100_atapi_read;
hwif->atapi_write = e100_atapi_write; hwif->atapi_write = e100_atapi_write;
} }
...@@ -560,32 +560,6 @@ e100_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -560,32 +560,6 @@ e100_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
e100_atapi_write(drive, buffer, wcount << 2); e100_atapi_write(drive, buffer, wcount << 2);
} }
/*
* The multiplexor for ide_xxxput_data and atapi calls
*/
static void
e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
void *buffer, unsigned int length)
{
switch (func) {
case ideproc_ide_input_data:
e100_ide_input_data(drive, buffer, length);
break;
case ideproc_ide_output_data:
e100_ide_input_data(drive, buffer, length);
break;
case ideproc_atapi_read:
e100_atapi_read(drive, buffer, length);
break;
case ideproc_atapi_write:
e100_atapi_write(drive, buffer, length);
break;
default:
printk("e100_ideproc: unsupported func %d!\n", func);
break;
}
}
/* we only have one DMA channel on the chip for ATA, so we can keep these statically */ /* we only have one DMA channel on the chip for ATA, so we can keep these statically */
static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS]; static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
static unsigned int ata_tot_size; static unsigned int ata_tot_size;
......
...@@ -422,9 +422,10 @@ void __init ide_init_amd74xx(struct ata_channel *hwif) ...@@ -422,9 +422,10 @@ void __init ide_init_amd74xx(struct ata_channel *hwif)
hwif->speedproc = &amd_set_drive; hwif->speedproc = &amd_set_drive;
hwif->autodma = 0; hwif->autodma = 0;
hwif->io_32bit = 1;
hwif->unmask = 1;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
hwif->drives[i].unmask = 1;
hwif->drives[i].autotune = 1; hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->unit * 2 + i; hwif->drives[i].dn = hwif->unit * 2 + i;
} }
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* *
* A.Hartgers@stud.tue.nl, JZDQC@CUNYVM.CUNY.edu, abramov@cecmow.enet.dec.com, * A.Hartgers@stud.tue.nl, JZDQC@CUNYVM.CUNY.edu, abramov@cecmow.enet.dec.com,
* bardj@utopia.ppp.sn.no, bart@gaga.tue.nl, bbol001@cs.auckland.ac.nz, * bardj@utopia.ppp.sn.no, bart@gaga.tue.nl, bbol001@cs.auckland.ac.nz,
* chrisc@dbass.demon.co.uk, dalecki@evision-ventures.com, * chrisc@dbass.demon.co.uk, martin@dalecki.de,
* derekn@vw.ece.cmu.edu, florian@btp2x3.phy.uni-bayreuth.de, * derekn@vw.ece.cmu.edu, florian@btp2x3.phy.uni-bayreuth.de,
* flynn@dei.unipd.it, gadio@netvision.net.il, godzilla@futuris.net, * flynn@dei.unipd.it, gadio@netvision.net.il, godzilla@futuris.net,
* j@pobox.com, jkemp1@mises.uni-paderborn.de, jtoppe@hiwaay.net, * j@pobox.com, jkemp1@mises.uni-paderborn.de, jtoppe@hiwaay.net,
...@@ -403,19 +403,19 @@ void cmd640_dump_regs (void) ...@@ -403,19 +403,19 @@ void cmd640_dump_regs (void)
*/ */
static void __init check_prefetch (unsigned int index) static void __init check_prefetch (unsigned int index)
{ {
ide_drive_t *drive = cmd_drives[index]; struct ata_device *drive = cmd_drives[index];
byte b = get_cmd640_reg(prefetch_regs[index]); byte b = get_cmd640_reg(prefetch_regs[index]);
if (b & prefetch_masks[index]) { /* is prefetch off? */ if (b & prefetch_masks[index]) { /* is prefetch off? */
drive->no_unmask = 0; drive->channel->no_unmask = 0;
drive->no_io_32bit = 1; drive->channel->no_io_32bit = 1;
drive->io_32bit = 0; drive->channel->io_32bit = 0;
} else { } else {
#if CMD640_PREFETCH_MASKS #if CMD640_PREFETCH_MASKS
drive->no_unmask = 1; drive->channel->no_unmask = 1;
drive->unmask = 0; drive->channel->unmask = 0;
#endif #endif
drive->no_io_32bit = 0; drive->channel->no_io_32bit = 0;
} }
} }
...@@ -460,15 +460,15 @@ static void set_prefetch_mode (unsigned int index, int mode) ...@@ -460,15 +460,15 @@ static void set_prefetch_mode (unsigned int index, int mode)
b = get_cmd640_reg(reg); b = get_cmd640_reg(reg);
if (mode) { /* want prefetch on? */ if (mode) { /* want prefetch on? */
#if CMD640_PREFETCH_MASKS #if CMD640_PREFETCH_MASKS
drive->no_unmask = 1; drive->channel->no_unmask = 1;
drive->unmask = 0; drive->channel->unmask = 0;
#endif #endif
drive->no_io_32bit = 0; drive->channel->no_io_32bit = 0;
b &= ~prefetch_masks[index]; /* enable prefetch */ b &= ~prefetch_masks[index]; /* enable prefetch */
} else { } else {
drive->no_unmask = 0; drive->channel->no_unmask = 0;
drive->no_io_32bit = 1; drive->channel->no_io_32bit = 1;
drive->io_32bit = 0; drive->channel->io_32bit = 0;
b |= prefetch_masks[index]; /* disable prefetch */ b |= prefetch_masks[index]; /* disable prefetch */
} }
put_cmd640_reg(reg, b); put_cmd640_reg(reg, b);
...@@ -827,7 +827,7 @@ int __init ide_probe_for_cmd640x(void) ...@@ -827,7 +827,7 @@ int __init ide_probe_for_cmd640x(void)
retrieve_drive_counts (index); retrieve_drive_counts (index);
check_prefetch (index); check_prefetch (index);
printk("cmd640: drive%d timings/prefetch(%s) preserved", printk("cmd640: drive%d timings/prefetch(%s) preserved",
index, drive->no_io_32bit ? "off" : "on"); index, drive->channel->no_io_32bit ? "off" : "on");
display_clocks(index); display_clocks(index);
} }
#else #else
...@@ -836,7 +836,7 @@ int __init ide_probe_for_cmd640x(void) ...@@ -836,7 +836,7 @@ int __init ide_probe_for_cmd640x(void)
*/ */
check_prefetch (index); check_prefetch (index);
printk("cmd640: drive%d timings/prefetch(%s) preserved\n", printk("cmd640: drive%d timings/prefetch(%s) preserved\n",
index, drive->no_io_32bit ? "off" : "on"); index, drive->channel->no_io_32bit ? "off" : "on");
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
} }
......
...@@ -88,8 +88,7 @@ static void tune_dtc2278 (ide_drive_t *drive, byte pio) ...@@ -88,8 +88,7 @@ static void tune_dtc2278 (ide_drive_t *drive, byte pio)
/* /*
* 32bit I/O has to be enabled for *both* drives at the same time. * 32bit I/O has to be enabled for *both* drives at the same time.
*/ */
drive->io_32bit = 1; drive->channel->io_32bit = 1;
drive->channel->drives[!drive->select.b.unit].io_32bit = 1;
} }
void __init init_dtc2278 (void) void __init init_dtc2278 (void)
...@@ -120,10 +119,11 @@ void __init init_dtc2278 (void) ...@@ -120,10 +119,11 @@ void __init init_dtc2278 (void)
ide_hwifs[0].chipset = ide_dtc2278; ide_hwifs[0].chipset = ide_dtc2278;
ide_hwifs[1].chipset = ide_dtc2278; ide_hwifs[1].chipset = ide_dtc2278;
ide_hwifs[0].tuneproc = &tune_dtc2278; ide_hwifs[0].tuneproc = &tune_dtc2278;
ide_hwifs[0].drives[0].no_unmask = 1; /* FIXME: What about the following?!
ide_hwifs[0].drives[1].no_unmask = 1; ide_hwifs[1].tuneproc = &tune_dtc2278;
ide_hwifs[1].drives[0].no_unmask = 1; */
ide_hwifs[1].drives[1].no_unmask = 1; ide_hwifs[0].no_unmask = 1;
ide_hwifs[1].no_unmask = 1;
ide_hwifs[0].unit = ATA_PRIMARY; ide_hwifs[0].unit = ATA_PRIMARY;
ide_hwifs[1].unit = ATA_SECONDARY; ide_hwifs[1].unit = ATA_SECONDARY;
} }
...@@ -261,11 +261,11 @@ static void ht_set_prefetch(ide_drive_t *drive, byte state) ...@@ -261,11 +261,11 @@ static void ht_set_prefetch(ide_drive_t *drive, byte state)
*/ */
if (state) { if (state) {
drive->drive_data |= t; /* enable prefetch mode */ drive->drive_data |= t; /* enable prefetch mode */
drive->no_unmask = 1; drive->channel->no_unmask = 1;
drive->unmask = 0; drive->channel->unmask = 0;
} else { } else {
drive->drive_data &= ~t; /* disable prefetch mode */ drive->drive_data &= ~t; /* disable prefetch mode */
drive->no_unmask = 0; drive->channel->no_unmask = 0;
} }
restore_flags (flags); /* all CPUs */ restore_flags (flags); /* all CPUs */
......
...@@ -669,6 +669,12 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, ...@@ -669,6 +669,12 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
request or data protect error.*/ request or data protect error.*/
ide_dump_status (drive, "command error", stat); ide_dump_status (drive, "command error", stat);
cdrom_end_request(drive, 0); cdrom_end_request(drive, 0);
} else if (sense_key == MEDIUM_ERROR) {
/* No point in re-trying a zillion times on a bad
* sector. The error is not correctable at all.
*/
ide_dump_status (drive, "media error (bad sector)", stat);
cdrom_end_request(drive, 0);
} else if ((err & ~ABRT_ERR) != 0) { } else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler /* Go to the default handler
for other errors. */ for other errors. */
......
...@@ -755,8 +755,6 @@ static void idedisk_pre_reset (ide_drive_t *drive) ...@@ -755,8 +755,6 @@ static void idedisk_pre_reset (ide_drive_t *drive)
drive->special.b.recalibrate = legacy; drive->special.b.recalibrate = legacy;
if (OK_TO_RESET_CONTROLLER) if (OK_TO_RESET_CONTROLLER)
drive->mult_count = 0; drive->mult_count = 0;
if (!drive->keep_settings && !drive->using_dma)
drive->mult_req = 0;
if (drive->mult_req != drive->mult_count) if (drive->mult_req != drive->mult_count)
drive->special.b.set_multmode = 1; drive->special.b.set_multmode = 1;
} }
...@@ -1231,7 +1229,14 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -1231,7 +1229,14 @@ static void idedisk_setup(ide_drive_t *drive)
drive->special.b.set_multmode = 1; drive->special.b.set_multmode = 1;
#endif #endif
} }
drive->no_io_32bit = id->dword_io ? 1 : 0;
/* FIXME: Nowadays there are many chipsets out there which *require* 32
* bit IO. Those will most propably not work properly with drives not
* supporting this. But right now we don't do anything about this. We
* dont' even *warn* the user!
*/
drive->channel->no_io_32bit = id->dword_io ? 1 : 0;
if (drive->id->cfs_enable_2 & 0x3000) if (drive->id->cfs_enable_2 & 0x3000)
write_cache(drive, (id->cfs_enable_2 & 0x3000)); write_cache(drive, (id->cfs_enable_2 & 0x3000));
......
...@@ -599,13 +599,19 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -599,13 +599,19 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
printk("%s: DMA disabled\n", drive->name); printk("%s: DMA disabled\n", drive->name);
case ide_dma_off_quietly: case ide_dma_off_quietly:
set_high = 0; set_high = 0;
drive->using_tcq = 0;
outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
hwif->dmaproc(ide_dma_queued_off, drive);
#endif
case ide_dma_on: case ide_dma_on:
ide_toggle_bounce(drive, set_high); ide_toggle_bounce(drive, set_high);
drive->using_dma = (func == ide_dma_on); drive->using_dma = (func == ide_dma_on);
if (drive->using_dma) if (drive->using_dma) {
outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
hwif->dmaproc(ide_dma_queued_on, drive);
#endif
}
return 0; return 0;
case ide_dma_check: case ide_dma_check:
return config_drive_for_dma (drive); return config_drive_for_dma (drive);
......
...@@ -156,7 +156,7 @@ void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -156,7 +156,7 @@ void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount)
return; return;
} }
io_32bit = drive->io_32bit; io_32bit = drive->channel->io_32bit;
if (io_32bit) { if (io_32bit) {
#if SUPPORT_VLB_SYNC #if SUPPORT_VLB_SYNC
...@@ -167,7 +167,7 @@ void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -167,7 +167,7 @@ void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount)
ata_read_32(drive, buffer, wcount); ata_read_32(drive, buffer, wcount);
} else { } else {
#if SUPPORT_SLOW_DATA_PORTS #if SUPPORT_SLOW_DATA_PORTS
if (drive->slow) if (drive->channel->slow)
ata_read_slow(drive, buffer, wcount); ata_read_slow(drive, buffer, wcount);
else else
#endif #endif
...@@ -187,7 +187,7 @@ void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -187,7 +187,7 @@ void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount)
return; return;
} }
io_32bit = drive->io_32bit; io_32bit = drive->channel->io_32bit;
if (io_32bit) { if (io_32bit) {
#if SUPPORT_VLB_SYNC #if SUPPORT_VLB_SYNC
...@@ -198,7 +198,7 @@ void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount) ...@@ -198,7 +198,7 @@ void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount)
ata_write_32(drive, buffer, wcount); ata_write_32(drive, buffer, wcount);
} else { } else {
#if SUPPORT_SLOW_DATA_PORTS #if SUPPORT_SLOW_DATA_PORTS
if (drive->slow) if (drive->channel->slow)
ata_write_slow(drive, buffer, wcount); ata_write_slow(drive, buffer, wcount);
else else
#endif #endif
...@@ -413,6 +413,20 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive, ...@@ -413,6 +413,20 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive,
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF; u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
#if 0
printk("ata_taskfile ... %p\n", args->handler);
printk(" sector feature %02x\n", args->taskfile.feature);
printk(" sector count %02x\n", args->taskfile.sector_count);
printk(" drive/head %02x\n", args->taskfile.device_head);
printk(" command %02x\n", args->taskfile.command);
if (rq)
printk(" rq->nr_sectors %2li\n", rq->nr_sectors);
else
printk(" rq-> = null\n");
#endif
/* (ks/hs): Moved to start, do not use for multiple out commands */ /* (ks/hs): Moved to start, do not use for multiple out commands */
if (args->handler != task_mulout_intr) { if (args->handler != task_mulout_intr) {
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
...@@ -577,18 +591,22 @@ static ide_startstop_t task_in_intr (ide_drive_t *drive) ...@@ -577,18 +591,22 @@ static ide_startstop_t task_in_intr (ide_drive_t *drive)
ata_read(drive, pBuf, SECTOR_WORDS); ata_read(drive, pBuf, SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags); ide_unmap_rq(rq, pBuf, &flags);
/*
* first segment of the request is complete. note that this does not
* necessarily mean that the entire request is done!! this is only
* true if ide_end_request() returns 0.
*/
if (--rq->current_nr_sectors <= 0) { if (--rq->current_nr_sectors <= 0) {
/* (hs): swapped next 2 lines */
DTF("Request Ended stat: %02x\n", GET_STAT()); DTF("Request Ended stat: %02x\n", GET_STAT());
if (ide_end_request(drive, 1)) { if (!ide_end_request(drive, 1))
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); return ide_stopped;
return ide_started;
}
} else {
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started;
} }
return ide_stopped;
/*
* still data left to transfer
*/
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started;
} }
static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
...@@ -874,7 +892,6 @@ void ide_cmd_type_parser(struct ata_taskfile *args) ...@@ -874,7 +892,6 @@ void ide_cmd_type_parser(struct ata_taskfile *args)
return; return;
case WIN_NOP: case WIN_NOP:
args->command_type = IDE_DRIVE_TASK_NO_DATA; args->command_type = IDE_DRIVE_TASK_NO_DATA;
return; return;
...@@ -904,11 +921,6 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf) ...@@ -904,11 +921,6 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
struct ata_request star; struct ata_request star;
ata_ar_init(drive, &star); ata_ar_init(drive, &star);
/* Don't put this request on free_req list after usage.
*/
star.ar_flags |= ATA_AR_STATIC;
init_taskfile_request(&rq); init_taskfile_request(&rq);
rq.buffer = buf; rq.buffer = buf;
...@@ -976,6 +988,7 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -976,6 +988,7 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
if (argbuf == NULL) if (argbuf == NULL)
return -ENOMEM; return -ENOMEM;
memcpy(argbuf, vals, 4); memcpy(argbuf, vals, 4);
memset(argbuf + 4, 0, argsize - 4);
} }
if (set_transfer(drive, &args)) { if (set_transfer(drive, &args)) {
...@@ -986,14 +999,8 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -986,14 +999,8 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
/* Issue ATA command and wait for completion. /* Issue ATA command and wait for completion.
*/ */
/* FIXME: Do we really have to zero out the buffer?
*/
memset(argbuf, 4, SECTOR_WORDS * 4 * vals[3]);
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
rq.buffer = argbuf; rq.buffer = argbuf;
memcpy(argbuf, vals, 4);
err = ide_do_drive_cmd(drive, &rq, ide_wait); err = ide_do_drive_cmd(drive, &rq, ide_wait);
if (!err && xfer_rate) { if (!err && xfer_rate) {
......
...@@ -51,21 +51,17 @@ ...@@ -51,21 +51,17 @@
*/ */
#undef IDE_TCQ_FIDDLE_SI #undef IDE_TCQ_FIDDLE_SI
/*
* wait for data phase before starting DMA or not
*/
#undef IDE_TCQ_WAIT_DATAPHASE
ide_startstop_t ide_dmaq_intr(ide_drive_t *drive); ide_startstop_t ide_dmaq_intr(ide_drive_t *drive);
ide_startstop_t ide_service(ide_drive_t *drive); ide_startstop_t ide_service(ide_drive_t *drive);
static inline void drive_ctl_nien(ide_drive_t *drive, int clear) static inline void drive_ctl_nien(ide_drive_t *drive, int clear)
{ {
#ifdef IDE_TCQ_NIEN #ifdef IDE_TCQ_NIEN
int mask = clear ? 0x00 : 0x02; if (IDE_CONTROL_REG) {
int mask = clear ? 0x00 : 0x02;
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl | mask, IDE_CONTROL_REG); OUT_BYTE(drive->ctl | mask, IDE_CONTROL_REG);
}
#endif #endif
} }
...@@ -123,7 +119,6 @@ static void ide_tcq_invalidate_queue(ide_drive_t *drive) ...@@ -123,7 +119,6 @@ static void ide_tcq_invalidate_queue(ide_drive_t *drive)
init_taskfile_request(ar->ar_rq); init_taskfile_request(ar->ar_rq);
ar->ar_rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS); ar->ar_rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
ar->ar_rq->special = ar; ar->ar_rq->special = ar;
ar->ar_flags |= ATA_AR_RETURN;
_elv_add_request(q, ar->ar_rq, 0, 0); _elv_add_request(q, ar->ar_rq, 0, 0);
/* /*
...@@ -222,7 +217,7 @@ ide_startstop_t ide_service(ide_drive_t *drive) ...@@ -222,7 +217,7 @@ ide_startstop_t ide_service(ide_drive_t *drive)
{ {
struct ata_request *ar; struct ata_request *ar;
byte feat, stat; byte feat, stat;
int tag; int tag, ret;
TCQ_PRINTK("%s: started service\n", drive->name); TCQ_PRINTK("%s: started service\n", drive->name);
...@@ -272,9 +267,6 @@ ide_startstop_t ide_service(ide_drive_t *drive) ...@@ -272,9 +267,6 @@ ide_startstop_t ide_service(ide_drive_t *drive)
return ide_stopped; return ide_stopped;
} }
/*
* start dma
*/
tag = feat >> 3; tag = feat >> 3;
IDE_SET_CUR_TAG(drive, tag); IDE_SET_CUR_TAG(drive, tag);
...@@ -293,16 +285,16 @@ ide_startstop_t ide_service(ide_drive_t *drive) ...@@ -293,16 +285,16 @@ ide_startstop_t ide_service(ide_drive_t *drive)
*/ */
if (rq_data_dir(ar->ar_rq) == READ) { if (rq_data_dir(ar->ar_rq) == READ) {
TCQ_PRINTK("ide_service: starting READ %x\n", stat); TCQ_PRINTK("ide_service: starting READ %x\n", stat);
drive->channel->dmaproc(ide_dma_read_queued, drive); ret = drive->channel->dmaproc(ide_dma_read_queued, drive);
} else { } else {
TCQ_PRINTK("ide_service: starting WRITE %x\n", stat); TCQ_PRINTK("ide_service: starting WRITE %x\n", stat);
drive->channel->dmaproc(ide_dma_write_queued, drive); ret = drive->channel->dmaproc(ide_dma_write_queued, drive);
} }
/* /*
* dmaproc set intr handler * dmaproc set intr handler
*/ */
return ide_started; return !ret ? ide_started : ide_stopped;
} }
ide_startstop_t ide_check_service(ide_drive_t *drive) ide_startstop_t ide_check_service(ide_drive_t *drive)
...@@ -410,14 +402,15 @@ ide_startstop_t ide_dmaq_intr(ide_drive_t *drive) ...@@ -410,14 +402,15 @@ ide_startstop_t ide_dmaq_intr(ide_drive_t *drive)
*/ */
static int ide_tcq_configure(ide_drive_t *drive) static int ide_tcq_configure(ide_drive_t *drive)
{ {
int tcq_mask = 1 << 1 | 1 << 14;
int tcq_bits = tcq_mask | 1 << 15;
struct ata_taskfile args; struct ata_taskfile args;
int tcq_supp = 1 << 1 | 1 << 14;
/* /*
* bit 14 and 1 must be set in word 83 of the device id to indicate * bit 14 and 1 must be set in word 83 of the device id to indicate
* support for dma queued protocol * support for dma queued protocol, and bit 15 must be cleared
*/ */
if ((drive->id->command_set_2 & tcq_supp) != tcq_supp) if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask)
return -EIO; return -EIO;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
...@@ -477,11 +470,14 @@ static int ide_tcq_configure(ide_drive_t *drive) ...@@ -477,11 +470,14 @@ static int ide_tcq_configure(ide_drive_t *drive)
*/ */
static int ide_enable_queued(ide_drive_t *drive, int on) static int ide_enable_queued(ide_drive_t *drive, int on)
{ {
int depth = drive->using_tcq ? drive->queue_depth : 0;
/* /*
* disable or adjust queue depth * disable or adjust queue depth
*/ */
if (!on) { if (!on) {
printk("%s: TCQ disabled\n", drive->name); if (drive->using_tcq)
printk("%s: TCQ disabled\n", drive->name);
drive->using_tcq = 0; drive->using_tcq = 0;
return 0; return 0;
} }
...@@ -491,25 +487,33 @@ static int ide_enable_queued(ide_drive_t *drive, int on) ...@@ -491,25 +487,33 @@ static int ide_enable_queued(ide_drive_t *drive, int on)
return 1; return 1;
} }
/*
* possibly expand command list
*/
if (ide_build_commandlist(drive)) if (ide_build_commandlist(drive))
return 1; return 1;
printk("%s: tagged command queueing enabled, command queue depth %d\n", drive->name, drive->queue_depth); if (depth != drive->queue_depth)
printk("%s: tagged command queueing enabled, command queue depth %d\n", drive->name, drive->queue_depth);
drive->using_tcq = 1; drive->using_tcq = 1;
/*
* clear stats
*/
drive->tcq->max_depth = 0; drive->tcq->max_depth = 0;
return 0; return 0;
} }
int ide_tcq_wait_dataphase(ide_drive_t *drive) int ide_tcq_wait_dataphase(ide_drive_t *drive)
{ {
#ifdef IDE_TCQ_WAIT_DATAPHASE
ide_startstop_t foo; ide_startstop_t foo;
if (ide_wait_stat(&startstop, drive, READY_STAT | DRQ_STAT, BUSY_STAT, WAIT_READY)) { if (ide_wait_stat(&foo, drive, READY_STAT | DRQ_STAT, BUSY_STAT, WAIT_READY)) {
printk("%s: timeout waiting for data phase\n", drive->name); printk("%s: timeout waiting for data phase\n", drive->name);
return 1; return 1;
} }
#endif
return 0; return 0;
} }
...@@ -595,6 +599,8 @@ int ide_tcq_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -595,6 +599,8 @@ int ide_tcq_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
if (ide_start_dma(hwif, drive, func)) if (ide_start_dma(hwif, drive, func))
return ide_stopped; return ide_stopped;
TCQ_PRINTK("IMMED in queued_start\n");
/* /*
* need to arm handler before starting dma engine, * need to arm handler before starting dma engine,
* transfer could complete right away * transfer could complete right away
...@@ -612,6 +618,8 @@ int ide_tcq_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -612,6 +618,8 @@ int ide_tcq_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_queued_off: case ide_dma_queued_off:
enable_tcq = 0; enable_tcq = 0;
case ide_dma_queued_on: case ide_dma_queued_on:
if (enable_tcq && !drive->using_dma)
return 1;
return ide_enable_queued(drive, enable_tcq); return ide_enable_queued(drive, enable_tcq);
default: default:
break; break;
......
...@@ -479,22 +479,18 @@ static void ata_pre_reset(ide_drive_t *drive) ...@@ -479,22 +479,18 @@ static void ata_pre_reset(ide_drive_t *drive)
if (ata_ops(drive) && ata_ops(drive)->pre_reset) if (ata_ops(drive) && ata_ops(drive)->pre_reset)
ata_ops(drive)->pre_reset(drive); ata_ops(drive)->pre_reset(drive);
if (!drive->keep_settings && !drive->using_dma) { if (!drive->using_dma)
drive->unmask = 0; return;
drive->io_32bit = 0;
}
if (drive->using_dma) { /* check the DMA crc count */
/* check the DMA crc count */ if (drive->crc_count) {
if (drive->crc_count) { drive->channel->dmaproc(ide_dma_off_quietly, drive);
drive->channel->dmaproc(ide_dma_off_quietly, drive); if ((drive->channel->speedproc) != NULL)
if ((drive->channel->speedproc) != NULL) drive->channel->speedproc(drive, ide_auto_reduce_xfer(drive));
drive->channel->speedproc(drive, ide_auto_reduce_xfer(drive)); if (drive->current_speed >= XFER_SW_DMA_0)
if (drive->current_speed >= XFER_SW_DMA_0) drive->channel->dmaproc(ide_dma_on, drive);
drive->channel->dmaproc(ide_dma_on, drive); } else
} else drive->channel->dmaproc(ide_dma_off, drive);
drive->channel->dmaproc(ide_dma_off, drive);
}
} }
/* /*
...@@ -807,8 +803,7 @@ void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err) ...@@ -807,8 +803,7 @@ void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err)
args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG); args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
} }
} }
if (ar->ar_flags & ATA_AR_RETURN) ata_ar_put(drive, ar);
ata_ar_put(drive, ar);
} }
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
...@@ -905,17 +900,15 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat) ...@@ -905,17 +900,15 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
*/ */
static void try_to_flush_leftover_data (ide_drive_t *drive) static void try_to_flush_leftover_data (ide_drive_t *drive)
{ {
int i = (drive->mult_count ? drive->mult_count : 1); int i;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return; return;
while (i > 0) { for (i = (drive->mult_count ? drive->mult_count : 1); i > 0; --i) {
u32 buffer[SECTOR_WORDS]; u32 buffer[SECTOR_WORDS];
unsigned int count = (i > 1) ? 1 : i;
ata_read(drive, buffer, count * SECTOR_WORDS); ata_read(drive, buffer, SECTOR_WORDS);
i -= count;
} }
} }
...@@ -999,7 +992,7 @@ void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) ...@@ -999,7 +992,7 @@ void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
/* /*
* Invoked on completion of a special DRIVE_CMD. * Invoked on completion of a special DRIVE_CMD.
*/ */
static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) static ide_startstop_t drive_cmd_intr(ide_drive_t *drive)
{ {
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
u8 *args = rq->buffer; u8 *args = rq->buffer;
...@@ -1008,11 +1001,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) ...@@ -1008,11 +1001,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
if ((stat & DRQ_STAT) && args && args[3]) { if ((stat & DRQ_STAT) && args && args[3]) {
int io_32bit = drive->io_32bit;
drive->io_32bit = 0;
ata_read(drive, &args[4], args[3] * SECTOR_WORDS); ata_read(drive, &args[4], args[3] * SECTOR_WORDS);
drive->io_32bit = io_32bit;
while (((stat = GET_STAT()) & BUSY_STAT) && retries--) while (((stat = GET_STAT()) & BUSY_STAT) && retries--)
udelay(100); udelay(100);
...@@ -1824,7 +1813,7 @@ void ide_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1824,7 +1813,7 @@ void ide_intr(int irq, void *dev_id, struct pt_regs *regs)
del_timer(&hwgroup->timer); del_timer(&hwgroup->timer);
spin_unlock(&ide_lock); spin_unlock(&ide_lock);
if (drive->unmask) if (hwif->unmask)
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
startstop = handler(drive); /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); /* service this interrupt, may set handler for next interrupt */
spin_lock_irq(&ide_lock); spin_lock_irq(&ide_lock);
...@@ -2572,14 +2561,10 @@ int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val) ...@@ -2572,14 +2561,10 @@ int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
static int set_io_32bit(struct ata_device *drive, int arg) static int set_io_32bit(struct ata_device *drive, int arg)
{ {
if (drive->no_io_32bit) if (drive->channel->no_io_32bit)
return -EIO; return -EIO;
drive->io_32bit = arg; drive->channel->io_32bit = arg;
#ifdef CONFIG_BLK_DEV_DTC2278
if (drive->channel->chipset == ide_dtc2278)
drive->channel->drives[!drive->select.b.unit].io_32bit = arg;
#endif
return 0; return 0;
} }
...@@ -2613,11 +2598,10 @@ static int set_pio_mode (ide_drive_t *drive, int arg) ...@@ -2613,11 +2598,10 @@ static int set_pio_mode (ide_drive_t *drive, int arg)
void ide_add_generic_settings (ide_drive_t *drive) void ide_add_generic_settings (ide_drive_t *drive)
{ {
/* drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function */ /* drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function */
ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit); ide_add_setting(drive, "io_32bit", drive->channel->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->channel->io_32bit, set_io_32bit);
ide_add_setting(drive, "keepsettings", SETTING_RW, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL);
ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode); ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode);
ide_add_setting(drive, "slow", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->slow, NULL); ide_add_setting(drive, "slow", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->channel->slow, NULL);
ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL); ide_add_setting(drive, "unmaskirq", drive->channel->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->channel->unmask, NULL);
ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma); ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma);
ide_add_setting(drive, "ide_scsi", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->scsi, NULL); ide_add_setting(drive, "ide_scsi", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->scsi, NULL);
ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->init_speed, NULL); ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->init_speed, NULL);
...@@ -3182,7 +3166,7 @@ int __init ide_setup (char *s) ...@@ -3182,7 +3166,7 @@ int __init ide_setup (char *s)
drive->autotune = 2; drive->autotune = 2;
goto done; goto done;
case -8: /* "slow" */ case -8: /* "slow" */
drive->slow = 1; hwif->slow = 1;
goto done; goto done;
case -9: /* "flash" */ case -9: /* "flash" */
drive->ata_flash = 1; drive->ata_flash = 1;
......
...@@ -1268,11 +1268,8 @@ void __init ide_init_pdc202xx(struct ata_channel *hwif) ...@@ -1268,11 +1268,8 @@ void __init ide_init_pdc202xx(struct ata_channel *hwif)
#undef CONFIG_PDC202XX_32_UNMASK #undef CONFIG_PDC202XX_32_UNMASK
#ifdef CONFIG_PDC202XX_32_UNMASK #ifdef CONFIG_PDC202XX_32_UNMASK
hwif->drives[0].io_32bit = 1; hwif->io_32bit = 1;
hwif->drives[1].io_32bit = 1; hwif->unmask = 1;
hwif->drives[0].unmask = 1;
hwif->drives[1].unmask = 1;
#endif #endif
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
......
...@@ -250,11 +250,9 @@ int __init setup_pdc4030(struct ata_channel *hwif) ...@@ -250,11 +250,9 @@ int __init setup_pdc4030(struct ata_channel *hwif)
memcpy(hwif2->io_ports, hwif->hw.io_ports, sizeof(hwif2->io_ports)); memcpy(hwif2->io_ports, hwif->hw.io_ports, sizeof(hwif2->io_ports));
hwif2->irq = hwif->irq; hwif2->irq = hwif->irq;
hwif2->hw.irq = hwif->hw.irq = hwif->irq; hwif2->hw.irq = hwif->hw.irq = hwif->irq;
hwif->io_32bit = 3;
hwif2->io_32bit = 3;
for (i=0; i<2 ; i++) { for (i=0; i<2 ; i++) {
hwif->drives[i].io_32bit = 3;
hwif2->drives[i].io_32bit = 3;
hwif->drives[i].keep_settings = 1;
hwif2->drives[i].keep_settings = 1;
if (!ident.current_tm[i].cyl) if (!ident.current_tm[i].cyl)
hwif->drives[i].noprobe = 1; hwif->drives[i].noprobe = 1;
if (!ident.current_tm[i+2].cyl) if (!ident.current_tm[i+2].cyl)
...@@ -634,7 +632,7 @@ ide_startstop_t do_pdc4030_io(ide_drive_t *drive, struct ata_taskfile *task) ...@@ -634,7 +632,7 @@ ide_startstop_t do_pdc4030_io(ide_drive_t *drive, struct ata_taskfile *task)
"PROMISE_WRITE\n", drive->name); "PROMISE_WRITE\n", drive->name);
return startstop; return startstop;
} }
if (!drive->unmask) if (!drive->channel->unmask)
__cli(); /* local CPU only */ __cli(); /* local CPU only */
HWGROUP(drive)->wrq = *rq; /* scratchpad */ HWGROUP(drive)->wrq = *rq; /* scratchpad */
return promise_write(drive); return promise_write(drive);
......
...@@ -545,10 +545,9 @@ void __init ide_init_piix(struct ata_channel *hwif) ...@@ -545,10 +545,9 @@ void __init ide_init_piix(struct ata_channel *hwif)
hwif->tuneproc = &piix_tune_drive; hwif->tuneproc = &piix_tune_drive;
hwif->speedproc = &piix_set_drive; hwif->speedproc = &piix_set_drive;
hwif->autodma = 0; hwif->autodma = 0;
hwif->io_32bit = 1;
hwif->unmask = 1;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
hwif->drives[i].unmask = 1;
hwif->drives[i].autotune = 1; hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->unit * 2 + i; hwif->drives[i].dn = hwif->unit * 2 + i;
} }
......
...@@ -370,8 +370,7 @@ int __init probe (int base) ...@@ -370,8 +370,7 @@ int __init probe (int base)
hwif->config_data = config; hwif->config_data = config;
hwif->drives[0].drive_data = hwif->drives[0].drive_data =
hwif->drives[1].drive_data = QD6500_DEF_DATA; hwif->drives[1].drive_data = QD6500_DEF_DATA;
hwif->drives[0].io_32bit = hwif->io_32bit = 1;
hwif->drives[1].io_32bit = 1;
hwif->tuneproc = &qd6500_tune_drive; hwif->tuneproc = &qd6500_tune_drive;
return 1; return 1;
} }
...@@ -403,8 +402,7 @@ int __init probe (int base) ...@@ -403,8 +402,7 @@ int __init probe (int base)
hwif->config_data = config | (control <<8); hwif->config_data = config | (control <<8);
hwif->drives[0].drive_data = hwif->drives[0].drive_data =
hwif->drives[1].drive_data = QD6580_DEF_DATA; hwif->drives[1].drive_data = QD6580_DEF_DATA;
hwif->drives[0].io_32bit = hwif->io_32bit = 1;
hwif->drives[1].io_32bit = 1;
hwif->tuneproc = &qd6580_tune_drive; hwif->tuneproc = &qd6580_tune_drive;
qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT); qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
...@@ -426,11 +424,11 @@ int __init probe (int base) ...@@ -426,11 +424,11 @@ int __init probe (int base)
ide_hwifs[i].select_data = base; ide_hwifs[i].select_data = base;
ide_hwifs[i].config_data = config | (control <<8); ide_hwifs[i].config_data = config | (control <<8);
ide_hwifs[i].tuneproc = &qd6580_tune_drive; ide_hwifs[i].tuneproc = &qd6580_tune_drive;
ide_hwifs[i].io_32bit = 1;
for (j = 0; j < 2; j++) { for (j = 0; j < 2; j++) {
ide_hwifs[i].drives[j].drive_data = ide_hwifs[i].drives[j].drive_data =
i?QD6580_DEF_DATA2:QD6580_DEF_DATA; i?QD6580_DEF_DATA2:QD6580_DEF_DATA;
ide_hwifs[i].drives[j].io_32bit = 1;
} }
} }
......
...@@ -40,8 +40,7 @@ void __init ide_init_rz1000(struct ata_channel *hwif) /* called from ide-pci.c * ...@@ -40,8 +40,7 @@ void __init ide_init_rz1000(struct ata_channel *hwif) /* called from ide-pci.c *
printk("%s: disabled chipset read-ahead (buggy RZ1000/RZ1001)\n", hwif->name); printk("%s: disabled chipset read-ahead (buggy RZ1000/RZ1001)\n", hwif->name);
} else { } else {
hwif->serialized = 1; hwif->serialized = 1;
hwif->drives[0].no_unmask = 1; hwif->no_unmask = 1;
hwif->drives[1].no_unmask = 1;
printk("%s: serialized, disabled unmasking (buggy RZ1000/RZ1001)\n", hwif->name); printk("%s: serialized, disabled unmasking (buggy RZ1000/RZ1001)\n", hwif->name);
} }
} }
......
...@@ -535,10 +535,10 @@ void __init ide_init_via82cxxx(struct ata_channel *hwif) ...@@ -535,10 +535,10 @@ void __init ide_init_via82cxxx(struct ata_channel *hwif)
hwif->tuneproc = &via82cxxx_tune_drive; hwif->tuneproc = &via82cxxx_tune_drive;
hwif->speedproc = &via_set_drive; hwif->speedproc = &via_set_drive;
hwif->autodma = 0; hwif->autodma = 0;
hwif->io_32bit = 1;
hwif->unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
hwif->drives[i].autotune = 1; hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->unit * 2 + i; hwif->drives[i].dn = hwif->unit * 2 + i;
} }
......
...@@ -91,32 +91,6 @@ static inline void lock_metapage(struct metapage *mp) ...@@ -91,32 +91,6 @@ static inline void lock_metapage(struct metapage *mp)
__lock_metapage(mp); __lock_metapage(mp);
} }
/* We're currently re-evaluating the method we use to write metadata
* pages. Currently, we have to make sure there no dirty buffer_heads
* hanging around after we free the metadata page, since the same
* physical disk blocks may be used in a different address space and we
* can't write old data over the good data.
*
* The best way to do this now is with block_invalidate_page. However,
* this is only available in the newer kernels and is not exported
* to modules. block_flushpage is the next best, but it too is not exported
* to modules.
*
* In a module, about the best we have is generic_buffer_fdatasync. This
* synchronously writes any dirty buffers. This is not optimal, but it will
* keep old dirty buffers from overwriting newer data.
*/
static inline void invalidate_page(metapage_t *mp)
{
#ifdef MODULE
generic_buffer_fdatasync(mp->mapping->host, mp->index, mp->index + 1);
#else
lock_page(mp->page);
block_flushpage(mp->page, 0);
UnlockPage(mp->page);
#endif
}
int __init metapage_init(void) int __init metapage_init(void)
{ {
int i; int i;
...@@ -559,8 +533,11 @@ void release_metapage(metapage_t * mp) ...@@ -559,8 +533,11 @@ void release_metapage(metapage_t * mp)
clear_bit(META_sync, &mp->flag); clear_bit(META_sync, &mp->flag);
} }
if (test_bit(META_discard, &mp->flag)) if (test_bit(META_discard, &mp->flag)) {
invalidate_page(mp); lock_page(mp->page);
block_flushpage(mp->page, 0);
UnlockPage(mp->page);
}
page_cache_release(mp->page); page_cache_release(mp->page);
INCREMENT(mpStat.pagefree); INCREMENT(mpStat.pagefree);
...@@ -593,9 +570,7 @@ void invalidate_metapages(struct inode *ip, unsigned long addr, ...@@ -593,9 +570,7 @@ void invalidate_metapages(struct inode *ip, unsigned long addr,
int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_sb->s_blocksize_bits; int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_sb->s_blocksize_bits;
struct address_space *mapping = ip->i_mapping; struct address_space *mapping = ip->i_mapping;
metapage_t *mp; metapage_t *mp;
#ifndef MODULE
struct page *page; struct page *page;
#endif
/* /*
* First, mark metapages to discard. They will eventually be * First, mark metapages to discard. They will eventually be
...@@ -612,27 +587,14 @@ void invalidate_metapages(struct inode *ip, unsigned long addr, ...@@ -612,27 +587,14 @@ void invalidate_metapages(struct inode *ip, unsigned long addr,
/* /*
* If in the metapage cache, we've got the page locked * If in the metapage cache, we've got the page locked
*/ */
#ifdef MODULE
UnlockPage(mp->page);
generic_buffer_fdatasync(mp->mapping->host, mp->index,
mp->index+1);
lock_page(mp->page);
#else
block_flushpage(mp->page, 0); block_flushpage(mp->page, 0);
#endif
} else { } else {
spin_unlock(&meta_lock); spin_unlock(&meta_lock);
#ifdef MODULE page = find_lock_page(mapping, lblock>>l2BlocksPerPage);
generic_buffer_fdatasync(ip, lblock << l2BlocksPerPage,
(lblock + 1) << l2BlocksPerPage);
#else
page = find_lock_page(mapping,
lblock >> l2BlocksPerPage);
if (page) { if (page) {
block_flushpage(page, 0); block_flushpage(page, 0);
UnlockPage(page); UnlockPage(page);
} }
#endif
} }
} }
} }
......
...@@ -296,7 +296,6 @@ struct hd_big_geometry { ...@@ -296,7 +296,6 @@ struct hd_big_geometry {
#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */ #define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
#define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */ #define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */
#define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */ #define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */
#define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */
#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */ #define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */ #define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
#define HDIO_GET_DMA 0x030b /* get use-dma flag */ #define HDIO_GET_DMA 0x030b /* get use-dma flag */
...@@ -316,7 +315,6 @@ struct hd_big_geometry { ...@@ -316,7 +315,6 @@ struct hd_big_geometry {
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */ /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */ #define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */ #define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
#define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */
#define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */ #define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */
#define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */ #define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
#define HDIO_SET_DMA 0x0326 /* change use-dma flag */ #define HDIO_SET_DMA 0x0326 /* change use-dma flag */
......
...@@ -342,12 +342,10 @@ struct ata_device { ...@@ -342,12 +342,10 @@ struct ata_device {
unsigned long PADAM_timeout; /* max time to wait for irq */ unsigned long PADAM_timeout; /* max time to wait for irq */
special_t special; /* special action flags */ special_t special; /* special action flags */
byte keep_settings; /* restore settings after drive reset */
byte using_dma; /* disk is using dma for read/write */ byte using_dma; /* disk is using dma for read/write */
byte using_tcq; /* disk is using queued dma operations*/ byte using_tcq; /* disk is using queued dma operations*/
byte retry_pio; /* retrying dma capable host in pio */ byte retry_pio; /* retrying dma capable host in pio */
byte state; /* retry state */ byte state; /* retry state */
byte unmask; /* flag: okay to unmask other irqs */
byte dsc_overlap; /* flag: DSC overlap */ byte dsc_overlap; /* flag: DSC overlap */
unsigned waiting_for_dma: 1; /* dma currently in progress */ unsigned waiting_for_dma: 1; /* dma currently in progress */
...@@ -358,7 +356,6 @@ struct ata_device { ...@@ -358,7 +356,6 @@ struct ata_device {
unsigned noprobe : 1; /* from: hdx=noprobe */ unsigned noprobe : 1; /* from: hdx=noprobe */
unsigned removable : 1; /* 1 if need to do check_media_change */ unsigned removable : 1; /* 1 if need to do check_media_change */
unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
unsigned no_unmask : 1; /* disallow setting unmask bit */
unsigned nobios : 1; /* flag: do not probe bios for drive */ unsigned nobios : 1; /* flag: do not probe bios for drive */
unsigned revalidate : 1; /* request revalidation */ unsigned revalidate : 1; /* request revalidation */
unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */ unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */
...@@ -388,13 +385,6 @@ struct ata_device { ...@@ -388,13 +385,6 @@ struct ata_device {
unsigned long long capacity48; /* total number of sectors */ unsigned long long capacity48; /* total number of sectors */
unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ unsigned int drive_data; /* for use by tuneproc/selectproc as needed */
/* FIXME: Those are properties of a channel and not a drive! Move them
* later there.
*/
byte slow; /* flag: slow data port */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
wait_queue_head_t wqueue; /* used to wait for drive in open() */ wait_queue_head_t wqueue; /* used to wait for drive in open() */
struct hd_driveid *id; /* drive model identification info */ struct hd_driveid *id; /* drive model identification info */
...@@ -523,6 +513,12 @@ struct ata_channel { ...@@ -523,6 +513,12 @@ struct ata_channel {
unsigned autodma : 1; /* automatically try to enable DMA at boot */ unsigned autodma : 1; /* automatically try to enable DMA at boot */
unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
unsigned highmem : 1; /* can do full 32-bit dma */ unsigned highmem : 1; /* can do full 32-bit dma */
byte slow; /* flag: slow data port */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
unsigned no_unmask : 1; /* disallow setting unmask bit */
byte unmask; /* flag: okay to unmask other irqs */
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */ unsigned long last_time; /* time when previous rq was done */
#endif #endif
...@@ -972,10 +968,9 @@ extern void revalidate_drives(void); ...@@ -972,10 +968,9 @@ extern void revalidate_drives(void);
/* /*
* ata_request flag bits * ata_request flag bits
*/ */
#define ATA_AR_QUEUED 1 #define ATA_AR_QUEUED 1 /* was queued */
#define ATA_AR_SETUP 2 #define ATA_AR_SETUP 2 /* dma table mapped */
#define ATA_AR_RETURN 4 #define ATA_AR_POOL 4 /* originated from drive pool */
#define ATA_AR_STATIC 8
/* /*
* if turn-around time is longer than this, halve queue depth * if turn-around time is longer than this, halve queue depth
...@@ -1007,8 +1002,10 @@ static inline struct ata_request *ata_ar_get(ide_drive_t *drive) ...@@ -1007,8 +1002,10 @@ static inline struct ata_request *ata_ar_get(ide_drive_t *drive)
if (!list_empty(&drive->free_req)) { if (!list_empty(&drive->free_req)) {
ar = list_ata_entry(drive->free_req.next); ar = list_ata_entry(drive->free_req.next);
list_del(&ar->ar_queue); list_del(&ar->ar_queue);
ata_ar_init(drive, ar); ata_ar_init(drive, ar);
ar->ar_flags |= ATA_AR_POOL;
} }
return ar; return ar;
...@@ -1016,8 +1013,8 @@ static inline struct ata_request *ata_ar_get(ide_drive_t *drive) ...@@ -1016,8 +1013,8 @@ static inline struct ata_request *ata_ar_get(ide_drive_t *drive)
static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar) static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar)
{ {
if (!(ar->ar_flags & ATA_AR_STATIC)) if (ar->ar_flags & ATA_AR_POOL)
list_add(&ar->ar_queue, &drive->free_req); list_add(&ar->ar_queue, &drive->free_req);
if (ar->ar_flags & ATA_AR_QUEUED) { if (ar->ar_flags & ATA_AR_QUEUED) {
/* clear the tag */ /* clear the tag */
......
...@@ -211,6 +211,7 @@ EXPORT_SYMBOL(unlock_buffer); ...@@ -211,6 +211,7 @@ EXPORT_SYMBOL(unlock_buffer);
EXPORT_SYMBOL(__wait_on_buffer); EXPORT_SYMBOL(__wait_on_buffer);
EXPORT_SYMBOL(___wait_on_page); EXPORT_SYMBOL(___wait_on_page);
EXPORT_SYMBOL(generic_direct_IO); EXPORT_SYMBOL(generic_direct_IO);
EXPORT_SYMBOL(discard_bh_page);
EXPORT_SYMBOL(block_write_full_page); EXPORT_SYMBOL(block_write_full_page);
EXPORT_SYMBOL(block_read_full_page); EXPORT_SYMBOL(block_read_full_page);
EXPORT_SYMBOL(block_prepare_write); EXPORT_SYMBOL(block_prepare_write);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/radix-tree.h> #include <linux/radix-tree.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h>
/* /*
* Radix tree node definition. * Radix tree node definition.
......
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