Commit e9b2bbae authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz Committed by Linus Torvalds

[PATCH] add hwif->rw_disk callout

Add hwif->rw_disk callout (forward port of 2.4 Alan's work).

"This allows us to remove the PDC4030 special case
 and also allows for the 372N clock switch stuff."
parent 17e71a0b
...@@ -247,7 +247,7 @@ static ide_startstop_t write_intr (ide_drive_t *drive) ...@@ -247,7 +247,7 @@ static ide_startstop_t write_intr (ide_drive_t *drive)
* *
* Returns 0 on success. * Returns 0 on success.
* *
* Note that we may be called from two contexts - the do_rw_disk context * Note that we may be called from two contexts - __ide_do_rw_disk() context
* and IRQ context. The IRQ can happen any time after we've output the * and IRQ context. The IRQ can happen any time after we've output the
* full "mcount" number of sectors, so we must make sure we update the * full "mcount" number of sectors, so we must make sure we update the
* state _before_ we output the final part of the data! * state _before_ we output the final part of the data!
...@@ -351,11 +351,11 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive) ...@@ -351,11 +351,11 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive)
} }
/* /*
* do_rw_disk() issues READ and WRITE commands to a disk, * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
* using LBA if supported, or CHS otherwise, to address sectors. * using LBA if supported, or CHS otherwise, to address sectors.
* It also takes care of issuing special DRIVE_CMDs. * It also takes care of issuing special DRIVE_CMDs.
*/ */
static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) ide_startstop_t __ide_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 = (drive->addressing == 1) ? 1 : 0;
...@@ -367,11 +367,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -367,11 +367,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
if (driver_blocked) if (driver_blocked)
panic("Request while ide driver is blocked?"); panic("Request while ide driver is blocked?");
#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE)
if (IS_PDC4030_DRIVE)
return promise_rw_disk(drive, rq, block);
#endif /* CONFIG_BLK_DEV_PDC4030 */
if (drive->using_tcq && idedisk_start_tag(drive, rq)) { if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
if (!ata_pending_commands(drive)) if (!ata_pending_commands(drive))
BUG(); BUG();
...@@ -550,10 +545,11 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -550,10 +545,11 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
} }
return ide_started; return ide_started;
} }
blk_dump_rq_flags(rq, "do_rw_disk - bad command"); blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command");
ide_end_request(drive, 0, 0); ide_end_request(drive, 0, 0);
return ide_stopped; return ide_stopped;
} }
EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
#else /* CONFIG_IDE_TASKFILE_IO */ #else /* CONFIG_IDE_TASKFILE_IO */
...@@ -562,15 +558,15 @@ static ide_startstop_t lba_28_rw_disk(ide_drive_t *, struct request *, unsigned ...@@ -562,15 +558,15 @@ static ide_startstop_t lba_28_rw_disk(ide_drive_t *, struct request *, unsigned
static ide_startstop_t lba_48_rw_disk(ide_drive_t *, struct request *, unsigned long long); static ide_startstop_t lba_48_rw_disk(ide_drive_t *, struct request *, unsigned long long);
/* /*
* do_rw_disk() issues READ and WRITE commands to a disk, * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
* using LBA if supported, or CHS otherwise, to address sectors. * using LBA if supported, or CHS otherwise, to address sectors.
* It also takes care of issuing special DRIVE_CMDs. * It also takes care of issuing special DRIVE_CMDs.
*/ */
static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
{ {
BUG_ON(drive->blocked); BUG_ON(drive->blocked);
if (!blk_fs_request(rq)) { if (!blk_fs_request(rq)) {
blk_dump_rq_flags(rq, "do_rw_disk - bad command"); blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command");
ide_end_request(drive, 0, 0); ide_end_request(drive, 0, 0);
return ide_stopped; return ide_stopped;
} }
...@@ -581,11 +577,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -581,11 +577,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
* need to add split taskfile operations based on 28bit threshold. * need to add split taskfile operations based on 28bit threshold.
*/ */
#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE)
if (IS_PDC4030_DRIVE)
return promise_rw_disk(drive, rq, block);
#endif /* CONFIG_BLK_DEV_PDC4030 */
if (drive->using_tcq && idedisk_start_tag(drive, rq)) { if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
if (!ata_pending_commands(drive)) if (!ata_pending_commands(drive))
BUG(); BUG();
...@@ -601,6 +592,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto ...@@ -601,6 +592,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto
/* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */ /* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */
return chs_rw_disk(drive, rq, (unsigned long) block); return chs_rw_disk(drive, rq, (unsigned long) block);
} }
EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
static task_ioreg_t get_command (ide_drive_t *drive, int cmd) static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
{ {
...@@ -760,6 +752,16 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u ...@@ -760,6 +752,16 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u
#endif /* CONFIG_IDE_TASKFILE_IO */ #endif /* CONFIG_IDE_TASKFILE_IO */
static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
{
ide_hwif_t *hwif = HWIF(drive);
if (hwif->rw_disk)
return hwif->rw_disk(drive, rq, block);
else
return __ide_do_rw_disk(drive, rq, block);
}
static int do_idedisk_flushcache(ide_drive_t *drive); static int do_idedisk_flushcache(ide_drive_t *drive);
static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat) static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
...@@ -1541,11 +1543,6 @@ static void idedisk_setup (ide_drive_t *drive) ...@@ -1541,11 +1543,6 @@ static void idedisk_setup (ide_drive_t *drive)
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
unsigned long capacity; unsigned long capacity;
#if 0
if (IS_PDC4030_DRIVE)
DRIVER(drive)->do_request = promise_rw_disk;
#endif
idedisk_add_settings(drive); idedisk_add_settings(drive);
if (drive->id_read == 0) if (drive->id_read == 0)
...@@ -1674,7 +1671,7 @@ static ide_driver_t idedisk_driver = { ...@@ -1674,7 +1671,7 @@ static ide_driver_t idedisk_driver = {
.supports_dsc_overlap = 0, .supports_dsc_overlap = 0,
.cleanup = idedisk_cleanup, .cleanup = idedisk_cleanup,
.flushcache = do_idedisk_flushcache, .flushcache = do_idedisk_flushcache,
.do_request = do_rw_disk, .do_request = ide_do_rw_disk,
.sense = idedisk_dump_status, .sense = idedisk_dump_status,
.error = idedisk_error, .error = idedisk_error,
.abort = idedisk_abort, .abort = idedisk_abort,
......
...@@ -94,6 +94,8 @@ ...@@ -94,6 +94,8 @@
#include "pdc4030.h" #include "pdc4030.h"
static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
/* /*
* promise_selectproc() is invoked by ide.c * promise_selectproc() is invoked by ide.c
* in preparation for access to the specified drive. * in preparation for access to the specified drive.
...@@ -231,6 +233,10 @@ int __init setup_pdc4030(ide_hwif_t *hwif) ...@@ -231,6 +233,10 @@ int __init setup_pdc4030(ide_hwif_t *hwif)
/* DC4030 hosted drives need their own identify... */ /* DC4030 hosted drives need their own identify... */
hwif->identify = hwif2->identify = &pdc4030_identify; hwif->identify = hwif2->identify = &pdc4030_identify;
/* Override the normal ide disk read/write. */
hwif->rw_disk = promise_rw_disk;
hwif2->rw_disk = promise_rw_disk;
/* Shift the remaining interfaces up by one */ /* Shift the remaining interfaces up by one */
for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) { for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
ide_hwif_t *h = &ide_hwifs[i]; ide_hwif_t *h = &ide_hwifs[i];
...@@ -803,7 +809,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) ...@@ -803,7 +809,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
} }
} }
ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
{ {
/* The four drives on the two logical (one physical) interfaces /* The four drives on the two logical (one physical) interfaces
are distinguished by writing the drive number (0-3) to the are distinguished by writing the drive number (0-3) to the
......
...@@ -886,6 +886,8 @@ typedef struct hwif_s { ...@@ -886,6 +886,8 @@ typedef struct hwif_s {
struct pnp_dev *pnp_dev; /* for PnP devices */ struct pnp_dev *pnp_dev; /* for PnP devices */
ide_startstop_t (*rw_disk)(ide_drive_t *, struct request *, sector_t);
#if 0 #if 0
ide_hwif_ops_t *hwifops; ide_hwif_ops_t *hwifops;
#else #else
...@@ -1535,6 +1537,8 @@ extern u8 eighty_ninty_three (ide_drive_t *); ...@@ -1535,6 +1537,8 @@ extern u8 eighty_ninty_three (ide_drive_t *);
extern int set_transfer(ide_drive_t *, ide_task_t *); extern int set_transfer(ide_drive_t *, ide_task_t *);
extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *); extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block);
/* /*
* ide_system_bus_speed() returns what we think is the system VESA/PCI * ide_system_bus_speed() returns what we think is the system VESA/PCI
* bus speed (in MHz). This is used for calculating interface PIO timings. * bus speed (in MHz). This is used for calculating interface PIO timings.
......
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