[PATCH] 2.5.10 IDE 42

Martin Dalecki
2002-04-26T08:44:16Z

[-- Attachment #1: Type: text/plain, Size: 695 bytes --]

Thu Apr 25 21:54:03 CEST 2002 ide-clean-42

- Streamline the usage of sector_t over the strategy routines in question a
bit. Streamline the do_request code in ide-disk.c.

- Improve the readability of start_request in ide.c.

- Remove obsolete/nowhere used stuff from hdreg.h.

- Splitup special_t into classical flag field.

- Use only a single field to determine the capacity of a drive. Make this
field and the code paths it follows as far as possible use the sector_t
instead of a hard coded integer types. This increases the chances that at
some distant point in time we will indeed be able to use 64 bit wide sector_t
entities. (Disks are getting huge those times now...)

[-- Attachment #2: ide-clean-42.diff --]
[-- Type: text/plain, Size: 73640 bytes --]

diff -urN linux-2.5.10/arch/mips64/kernel/ioctl32.c linux/arch/mips64/kernel/ioctl32.c
--- linux-2.5.10/arch/mips64/kernel/ioctl32.c 2002-04-23 00:29:14.000000000 +0200
+++ linux/arch/mips64/kernel/ioctl32.c 2002-04-25 23:04:42.000000000 +0200
@@ -732,15 +732,12 @@
IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */
IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
- // HDIO_OBSOLETE_IDENTITY
IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans),
IOCTL32_DEFAULT(HDIO_GET_IDENTITY),
- // HDIO_TRISTATE_HWIF /* not implemented */
- // HDIO_DRIVE_TASK /* To do, need specs */
IOCTL32_DEFAULT(HDIO_DRIVE_CMD),
IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT),
IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR),
diff -urN linux-2.5.10/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.5.10/drivers/block/ll_rw_blk.c 2002-04-23 00:27:58.000000000 +0200
+++ linux/drivers/block/ll_rw_blk.c 2002-04-25 23:27:41.000000000 +0200
@@ -334,7 +334,7 @@

static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER",
"REQ_CMD", "REQ_NOMERGE", "REQ_STARTED",
- "REQ_DONTPREP", "REQ_DRIVE_CMD", "REQ_DRIVE_TASK",
+ "REQ_DONTPREP", "REQ_DRIVE_CMD",
"REQ_DRIVE_ACB", "REQ_PC", "REQ_BLOCK_PC",
"REQ_SENSE", "REQ_SPECIAL" };

diff -urN linux-2.5.10/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.10/drivers/ide/ide.c 2002-04-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide.c 2002-04-26 03:30:21.000000000 +0200
@@ -283,6 +283,7 @@
hwif->major = ide_major[index];
sprintf(hwif->name, "ide%d", index);
hwif->bus_state = BUSSTATE_ON;
+
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];

@@ -292,10 +293,10 @@
drive->ctl = 0x08;
drive->ready_stat = READY_STAT;
drive->bad_wstat = BAD_W_STAT;
- drive->special.b.recalibrate = 1;
- drive->special.b.set_geometry = 1;
+ drive->special_cmd = (ATA_SPECIAL_RECALIBRATE | ATA_SPECIAL_GEOMETRY);
sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit);
drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
+
init_waitqueue_head(&drive->wqueue);
}
}
@@ -455,7 +456,7 @@
* The capacity of a drive according to its current geometry/LBA settings in
* sectors.
*/
-unsigned long ata_capacity(ide_drive_t *drive)
+sector_t ata_capacity(struct ata_device *drive)
{
if (!drive->present || !drive->driver)
return 0;
@@ -472,31 +473,31 @@

/*
* This is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT commands to
- * a drive. It used to do much more, but has been scaled back.
+ * a drive.
*/
-static ide_startstop_t ata_special (ide_drive_t *drive)
+static ide_startstop_t ata_special(struct ata_device *drive)
{
- special_t *s = &drive->special;
+ unsigned char special_cmd = drive->special_cmd;

#ifdef DEBUG
- printk("%s: ata_special: 0x%02x\n", drive->name, s->all);
+ printk("%s: ata_special: 0x%02x\n", drive->name, special_cmd);
#endif
- if (s->b.set_tune) {
- s->b.set_tune = 0;
+ if (special_cmd & ATA_SPECIAL_TUNE) {
+ drive->special_cmd &= ~ATA_SPECIAL_TUNE;
if (drive->channel->tuneproc != NULL)
drive->channel->tuneproc(drive, drive->tune_req);
} else if (drive->driver != NULL) {
if (ata_ops(drive)->special)
return ata_ops(drive)->special(drive);
else {
- drive->special.all = 0;
+ drive->special_cmd = 0;
drive->mult_req = 0;

return ide_stopped;
}
- } else if (s->all) {
- printk("%s: bad special flag: 0x%02x\n", drive->name, s->all);
- s->all = 0;
+ } else if (special_cmd) {
+ printk("%s: bad special flag: 0x%02x\n", drive->name, special_cmd);
+ drive->special_cmd = 0;
}

return ide_stopped;
@@ -584,27 +585,25 @@
drive->failures = 0;
} else {
drive->failures++;
+ char *msg = "";
#if FANCY_STATUS_DUMPS
- printk("master: ");
+ printk("master:");
switch (tmp & 0x7f) {
- case 1: printk("passed");
+ case 1: msg = " passed";
break;
- case 2: printk("formatter device error");
+ case 2: msg = " formatter device";
break;
- case 3: printk("sector buffer error");
+ case 3: msg = " sector buffer";
break;
- case 4: printk("ECC circuitry error");
+ case 4: msg = " ECC circuitry";
break;
- case 5: printk("controlling MPU error");
+ case 5: msg = " controlling MPU error";
break;
- default:printk("error (0x%02x?)", tmp);
}
if (tmp & 0x80)
- printk("; slave: failed");
- printk("\n");
-#else
- printk("failed\n");
+ printk("; slave:");
#endif
+ printk("%s error [%02x]\n", msg, tmp);
}
}
hwgroup->poll_timeout = 0; /* done polling */
@@ -705,7 +704,7 @@
/*
* Clean up after success/failure of an explicit drive cmd
*/
-void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err)
+void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err)
{
unsigned long flags;
struct request *rq;
@@ -714,27 +713,16 @@
rq = HWGROUP(drive)->rq;

if (rq->flags & REQ_DRIVE_CMD) {
- byte *args = (byte *) rq->buffer;
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
- if (args) {
- args[0] = stat;
- args[1] = err;
- args[2] = IN_BYTE(IDE_NSECTOR_REG);
- }
- } else if (rq->flags & REQ_DRIVE_TASK) {
- byte *args = (byte *) rq->buffer;
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+ u8 *args = rq->buffer;
+ rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
if (args) {
args[0] = stat;
args[1] = err;
args[2] = IN_BYTE(IDE_NSECTOR_REG);
- args[3] = IN_BYTE(IDE_SECTOR_REG);
- args[4] = IN_BYTE(IDE_LCYL_REG);
- args[5] = IN_BYTE(IDE_HCYL_REG);
- args[6] = IN_BYTE(IDE_SELECT_REG);
}
- } else if (rq->flags & REQ_DRIVE_TASKFILE) {
+ } else if (rq->flags & REQ_DRIVE_ACB) {
struct ata_taskfile *args = rq->special;
+
rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
if (args) {
args->taskfile.feature = err;
@@ -783,16 +771,23 @@
if (stat & BUSY_STAT)
printk("Busy ");
else {
- if (stat & READY_STAT) printk("DriveReady ");
- if (stat & WRERR_STAT) printk("DeviceFault ");
- if (stat & SEEK_STAT) printk("SeekComplete ");
- if (stat & DRQ_STAT) printk("DataRequest ");
- if (stat & ECC_STAT) printk("CorrectedError ");
- if (stat & INDEX_STAT) printk("Index ");
- if (stat & ERR_STAT) printk("Error ");
+ if (stat & READY_STAT)
+ printk("DriveReady ");
+ if (stat & WRERR_STAT)
+ printk("DeviceFault ");
+ if (stat & SEEK_STAT)
+ printk("SeekComplete ");
+ if (stat & DRQ_STAT)
+ printk("DataRequest ");
+ if (stat & ECC_STAT)
+ printk("CorrectedError ");
+ if (stat & INDEX_STAT)
+ printk("Index ");
+ if (stat & ERR_STAT)
+ printk("Error ");
}
printk("}");
-#endif /* FANCY_STATUS_DUMPS */
+#endif
printk("\n");
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
err = GET_ERR();
@@ -839,7 +834,7 @@
printk(", sector=%ld", HWGROUP(drive)->rq->sector);
}
}
-#endif /* FANCY_STATUS_DUMPS */
+#endif
printk("\n");
}
__restore_flags (flags); /* local CPU only */
@@ -907,7 +902,6 @@
OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */

if (rq->errors >= ERROR_MAX) {
- /* ATA-PATTERN */
if (ata_ops(drive) && ata_ops(drive)->end_request)
ata_ops(drive)->end_request(drive, 0);
else
@@ -918,7 +912,7 @@
return do_reset1(drive, 0);
}
if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
+ drive->special_cmd |= ATA_SPECIAL_RECALIBRATE;
++rq->errors;
}
return ide_stopped;
@@ -1020,47 +1014,55 @@
*/
static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
{
- ide_startstop_t startstop;
- unsigned long block;
- unsigned int minor = minor(rq->rq_dev), unit = minor >> PARTN_BITS;
- struct ata_channel *hwif = drive->channel;
+ sector_t block;
+ unsigned int minor = minor(rq->rq_dev);
+ unsigned int unit = minor >> PARTN_BITS;
+ struct ata_channel *ch = drive->channel;

BUG_ON(!(rq->flags & REQ_STARTED));

#ifdef DEBUG
- printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
+ printk("%s: start_request: current=0x%08lx\n", ch->name, (unsigned long) rq);
#endif

/* bail early if we've exceeded max_failures */
- if (drive->max_failures && (drive->failures > drive->max_failures)) {
+ if (drive->max_failures && (drive->failures > drive->max_failures))
goto kill_rq;
- }

if (unit >= MAX_DRIVES) {
- printk("%s: bad device number: %s\n", hwif->name, kdevname(rq->rq_dev));
+ printk(KERN_ERR "%s: bad device number: %s\n", ch->name, kdevname(rq->rq_dev));
goto kill_rq;
}
+
block = rq->sector;

- /* Strange disk manager remap */
+ /* Strange disk manager remap.
+ */
if ((rq->flags & REQ_CMD) &&
(drive->type == ATA_DISK || drive->type == ATA_FLOPPY)) {
block += drive->sect0;
}
- /* Yecch - this will shift the entire interval,
- possibly killing some innocent following sector */
+
+ /* Yecch - this will shift the entire interval, possibly killing some
+ * innocent following sector.
+ */
if (block == 0 && drive->remap_0_to_1 == 1)
block = 1; /* redirect MBR access to EZ-Drive partn table */

#if (DISK_RECOVERY_TIME > 0)
- while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
+ while ((read_timer() - ch->last_time) < DISK_RECOVERY_TIME);
#endif

- SELECT_DRIVE(hwif, drive);
- if (ide_wait_stat(&startstop, drive, drive->ready_stat,
- BUSY_STAT|DRQ_STAT, WAIT_READY)) {
- printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
- return startstop;
+ {
+ ide_startstop_t res;
+
+ SELECT_DRIVE(ch, drive);
+ if (ide_wait_stat(&res, drive, drive->ready_stat,
+ BUSY_STAT|DRQ_STAT, WAIT_READY)) {
+ printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
+
+ return res;
+ }
}

/* FIXME: We can see nicely here that all commands should be submitted
@@ -1068,110 +1070,93 @@
* go as soon as possible!
*/

- if (!drive->special.all) {
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
- /* This issues a special drive command, usually
- * initiated by ioctl() from the external hdparm
- * program.
- */
+ if (drive->special_cmd)
+ return ata_special(drive);

- if (rq->flags & REQ_DRIVE_TASKFILE) {
- struct ata_taskfile *args = rq->special;
+ /* This issues a special drive command, usually initiated by ioctl()
+ * from the external hdparm program.
+ */
+ if (rq->flags & REQ_DRIVE_ACB) {
+ struct ata_taskfile *args = rq->special;

- if (!(args))
- goto args_error;
+ if (!(args))
+ goto args_error;

- ata_taskfile(drive, args, NULL);
+ ata_taskfile(drive, args, NULL);

- if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
+ if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
(args->command_type == IDE_DRIVE_TASK_OUT)) &&
- args->prehandler && args->handler)
- return args->prehandler(drive, rq);
- return ide_started;
-
- } else if (rq->flags & REQ_DRIVE_TASK) {
- byte *args = rq->buffer;
- byte sel;
+ args->prehandler && args->handler)
+ return args->prehandler(drive, rq);

- if (!(args)) goto args_error;
-#ifdef DEBUG
- printk("%s: DRIVE_TASK_CMD ", drive->name);
- printk("cmd=0x%02x ", args[0]);
- printk("fr=0x%02x ", args[1]);
- printk("ns=0x%02x ", args[2]);
- printk("sc=0x%02x ", args[3]);
- printk("lcyl=0x%02x ", args[4]);
- printk("hcyl=0x%02x ", args[5]);
- printk("sel=0x%02x\n", args[6]);
-#endif
- OUT_BYTE(args[1], IDE_FEATURE_REG);
- OUT_BYTE(args[3], IDE_SECTOR_REG);
- OUT_BYTE(args[4], IDE_LCYL_REG);
- OUT_BYTE(args[5], IDE_HCYL_REG);
- sel = (args[6] & ~0x10);
- if (drive->select.b.unit)
- sel |= 0x10;
- OUT_BYTE(sel, IDE_SELECT_REG);
- ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
- return ide_started;
- } else if (rq->flags & REQ_DRIVE_CMD) {
- byte *args = rq->buffer;
- if (!(args)) goto args_error;
-#ifdef DEBUG
- printk("%s: DRIVE_CMD ", drive->name);
- printk("cmd=0x%02x ", args[0]);
- printk("sc=0x%02x ", args[1]);
- printk("fr=0x%02x ", args[2]);
- printk("xx=0x%02x\n", args[3]);
-#endif
- if (args[0] == WIN_SMART) {
- OUT_BYTE(0x4f, IDE_LCYL_REG);
- OUT_BYTE(0xc2, IDE_HCYL_REG);
- OUT_BYTE(args[2],IDE_FEATURE_REG);
- OUT_BYTE(args[1],IDE_SECTOR_REG);
- ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+ return ide_started;
+ }

- return ide_started;
- }
- OUT_BYTE(args[2],IDE_FEATURE_REG);
- ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
- return ide_started;
- }
+ if (rq->flags & REQ_DRIVE_CMD) {
+ u8 *args = rq->buffer;

-args_error:
- /*
- * NULL is actually a valid way of waiting for all
- * current requests to be flushed from the queue.
- */
+ if (!(args))
+ goto args_error;
#ifdef DEBUG
- printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
- ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
- return ide_stopped;
+ printk("%s: DRIVE_CMD ", drive->name);
+ printk("cmd=0x%02x ", args[0]);
+ printk("sc=0x%02x ", args[1]);
+ printk("fr=0x%02x ", args[2]);
+ printk("xx=0x%02x\n", args[3]);
+#endif
+ if (args[0] == WIN_SMART) {
+ OUT_BYTE(0x4f, IDE_LCYL_REG);
+ OUT_BYTE(0xc2, IDE_HCYL_REG);
+ OUT_BYTE(args[2],IDE_FEATURE_REG);
+ OUT_BYTE(args[1],IDE_SECTOR_REG);
+ ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+
+ return ide_started;
}
+ OUT_BYTE(args[2],IDE_FEATURE_REG);
+ ide_cmd(drive, args[0], args[1], &drive_cmd_intr);

- /* The normal way of execution is to pass execute the request
- * handler.
- */
+ return ide_started;
+ }

- if (ata_ops(drive)) {
- if (ata_ops(drive)->do_request)
- return ata_ops(drive)->do_request(drive, rq, block);
- else {
- ide_end_request(drive, 0);
- return ide_stopped;
- }
+ /* The normal way of execution is to pass and execute the request
+ * handler down to the device type driver.
+ */
+ if (ata_ops(drive)) {
+ if (ata_ops(drive)->do_request)
+ return ata_ops(drive)->do_request(drive, rq, block);
+ else {
+ ide_end_request(drive, 0);
+ return ide_stopped;
}
- printk(KERN_WARNING "%s: device type %d not supported\n",
- drive->name, drive->type);
- goto kill_rq;
}
- return ata_special(drive);
+
+ /*
+ * Error handling:
+ */
+
+ printk(KERN_WARNING "%s: device type %d not supported\n",
+ drive->name, drive->type);
+
kill_rq:
if (ata_ops(drive) && ata_ops(drive)->end_request)
ata_ops(drive)->end_request(drive, 0);
else
ide_end_request(drive, 0);
+
+ return ide_stopped;
+
+args_error:
+
+ /* NULL as arguemnt is used by ioctls as a way of waiting for all
+ * current requests to be flushed from the queue.
+ */
+
+#ifdef DEBUG
+ printk("%s: DRIVE_CMD (null)\n", drive->name);
+#endif
+ ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
+
return ide_stopped;
}

@@ -1678,7 +1663,7 @@
/*
* This function is intended to be used prior to invoking ide_do_drive_cmd().
*/
-void ide_init_drive_cmd (struct request *rq)
+void ide_init_drive_cmd(struct request *rq)
{
memset(rq, 0, sizeof(*rq));
rq->flags = REQ_DRIVE_CMD;
@@ -1742,6 +1727,7 @@
wait_for_completion(&wait); /* wait for it to be serviced */
return rq->errors ? -EIO : 0; /* return -EIO if errors */
}
+
return 0;

}
@@ -2386,18 +2372,21 @@
return 0;
}

-static int set_pio_mode (ide_drive_t *drive, int arg)
+static int set_pio_mode(ide_drive_t *drive, int arg)
{
struct request rq;

if (!drive->channel->tuneproc)
return -ENOSYS;
- if (drive->special.b.set_tune)
+
+ if (drive->special_cmd & ATA_SPECIAL_TUNE)
return -EBUSY;
+
ide_init_drive_cmd(&rq);
- drive->tune_req = (byte) arg;
- drive->special.b.set_tune = 1;
+ drive->tune_req = (u8) arg;
+ drive->special_cmd |= ATA_SPECIAL_TUNE;
ide_do_drive_cmd(drive, &rq, ide_wait);
+
return 0;
}

@@ -2433,8 +2422,7 @@
#endif /* CONFIG_BLK_DEV_IDECS */
}

-static int ide_ioctl (struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int err = 0, major, minor;
ide_drive_t *drive;
@@ -2468,7 +2456,7 @@
}
}

- ide_init_drive_cmd (&rq);
+ ide_init_drive_cmd(&rq);
switch (cmd) {
case HDIO_GETGEO:
{
@@ -2518,13 +2506,12 @@
return -EACCES;
return ide_revalidate_disk(inode->i_rdev);

- case HDIO_OBSOLETE_IDENTITY:
case HDIO_GET_IDENTITY:
if (minor(inode->i_rdev) & PARTN_MASK)
return -EINVAL;
if (drive->id == NULL)
return -ENOMSG;
- if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
+ if (copy_to_user((char *)arg, (char *)drive->id, sizeof(*drive->id)))
return -EFAULT;
return 0;

@@ -2538,11 +2525,6 @@
return -EACCES;
return ide_cmd_ioctl(drive, arg);

- case HDIO_DRIVE_TASK:
- if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
- return -EACCES;
- return ide_task_ioctl(drive, arg);
-
case HDIO_SET_NICE:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP))))
diff -urN linux-2.5.10/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.10/drivers/ide/ide-cd.c 2002-04-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-cd.c 2002-04-26 03:07:04.000000000 +0200
@@ -1162,11 +1162,12 @@
return ide_stopped;
}

-static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
+static ide_startstop_t cdrom_start_seek_continuation(struct ata_device *drive)
{
unsigned char cmd[CDROM_PACKET_SIZE];
struct request *rq = HWGROUP(drive)->rq;
- int sector, frame, nskip;
+ sector_t sector;
+ int frame, nskip;

sector = rq->sector;
nskip = (sector % SECTORS_PER_FRAME);
@@ -1181,14 +1182,14 @@
return cdrom_transfer_packet_command(drive, cmd, WAIT_CMD, &cdrom_seek_intr);
}

-static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
+static ide_startstop_t cdrom_start_seek(struct ata_device *drive, sector_t block)
{
struct cdrom_info *info = drive->driver_data;

info->dma = 0;
info->cmd = 0;
info->start_seek = jiffies;
- return cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation);
+ return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
}

/*
@@ -1199,7 +1200,7 @@
static void restore_request (struct request *rq)
{
if (rq->buffer != bio_data(rq->bio)) {
- int n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
+ sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
rq->buffer = bio_data(rq->bio);
rq->nr_sectors += n;
rq->sector -= n;
@@ -1213,7 +1214,7 @@
/*
* Start a read request from the CD-ROM.
*/
-static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
+static ide_startstop_t cdrom_start_read(struct ata_device *drive, sector_t block)
{
struct cdrom_info *info = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq;
@@ -1634,8 +1635,6 @@
struct cdrom_info *info = drive->driver_data;

if (rq->flags & REQ_CMD) {
-
-
if (CDROM_CONFIG_FLAGS(drive)->seeking) {
unsigned long elpased = jiffies - info->start_seek;
int stat = GET_STAT();
@@ -1650,7 +1649,7 @@
CDROM_CONFIG_FLAGS(drive)->seeking = 0;
}
if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
- action = cdrom_start_seek (drive, block);
+ action = cdrom_start_seek(drive, block);
else {
if (rq_data_dir(rq) == READ)
action = cdrom_start_read(drive, block);
@@ -1837,7 +1836,7 @@
return cdrom_queue_packet_command(drive, cmd, sense, &pc);
}

-static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
+static int cdrom_read_capacity(ide_drive_t *drive, u32 *capacity,
struct request_sense *sense)
{
struct {
@@ -2027,7 +2026,8 @@
/* Now try to get the total cdrom capacity. */
minor = (drive->select.b.unit) << PARTN_BITS;
dev = mk_kdev(drive->channel->major, minor);
- stat = cdrom_get_last_written(dev, &toc->capacity);
+ /* FIXME: This is making worng assumptions about register layout. */
+ stat = cdrom_get_last_written(dev, (unsigned long *) &toc->capacity);
if (stat)
stat = cdrom_read_capacity(drive, &toc->capacity, sense);
if (stat)
@@ -2686,7 +2686,7 @@
}

static
-int ide_cdrom_setup (ide_drive_t *drive)
+int ide_cdrom_setup(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo;
@@ -2702,7 +2702,6 @@

blk_queue_prep_rq(&drive->queue, ll_10byte_cmd_build);

- drive->special.all = 0;
drive->ready_stat = 0;

CDROM_STATE_FLAGS (drive)->media_changed = 1;
@@ -2891,10 +2890,9 @@
set_blocksize(mk_kdev(drive->channel->major, minor), CD_FRAMESIZE);
}

-static
-unsigned long ide_cdrom_capacity (ide_drive_t *drive)
+static sector_t ide_cdrom_capacity(struct ata_device *drive)
{
- unsigned long capacity;
+ u32 capacity;

if (cdrom_read_capacity(drive, &capacity, NULL))
return 0;
@@ -2934,9 +2932,7 @@
release: ide_cdrom_release,
check_media_change: ide_cdrom_check_media_change,
revalidate: ide_cdrom_revalidate,
- pre_reset: NULL,
capacity: ide_cdrom_capacity,
- special: NULL,
proc: NULL
};

diff -urN linux-2.5.10/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h
--- linux-2.5.10/drivers/ide/ide-cd.h 2002-04-23 00:29:47.000000000 +0200
+++ linux/drivers/ide/ide-cd.h 2002-04-26 03:04:52.000000000 +0200
@@ -151,12 +151,11 @@
};

struct atapi_toc {
- int last_session_lba;
- int xa_flag;
- unsigned long capacity;
+ int last_session_lba;
+ int xa_flag;
+ u32 capacity;
struct atapi_toc_header hdr;
- struct atapi_toc_entry ent[MAX_TRACKS+1];
- /* One extra for the leadout. */
+ struct atapi_toc_entry ent[MAX_TRACKS+1]; /* one extra for the leadout. */
};

diff -urN linux-2.5.10/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.10/drivers/ide/ide-disk.c 2002-04-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-disk.c 2002-04-26 03:20:07.000000000 +0200
@@ -132,34 +132,31 @@
return WIN_NOP;
}

-static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t chs_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct hd_drive_task_hdr taskfile;
- struct hd_drive_hob_hdr hobfile;
- struct ata_taskfile args;
- int sectors;
+ struct ata_taskfile args;
+ int sectors;

unsigned int track = (block / drive->sect);
unsigned int sect = (block % drive->sect) + 1;
unsigned int head = (track % drive->head);
unsigned int cyl = (track / drive->head);

- memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
- memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
-
sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;

- taskfile.sector_count = sectors;
+ memset(&args, 0, sizeof(args));
+
+ args.taskfile.sector_count = sectors;

- taskfile.sector_number = sect;
- taskfile.low_cylinder = cyl;
- taskfile.high_cylinder = (cyl>>8);
-
- taskfile.device_head = head;
- taskfile.device_head |= drive->select.all;
- taskfile.command = get_command(drive, rq_data_dir(rq));
+ args.taskfile.sector_number = sect;
+ args.taskfile.low_cylinder = cyl;
+ args.taskfile.high_cylinder = (cyl>>8);
+
+ args.taskfile.device_head = head;
+ args.taskfile.device_head |= drive->select.all;
+ args.taskfile.command = get_command(drive, rq_data_dir(rq));

#ifdef DEBUG
printk("%s: %sing: ", drive->name,
@@ -167,40 +164,35 @@
if (lba) printk("LBAsect=%lld, ", block);
else printk("CHS=%d/%d/%d, ", cyl, head, sect);
printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
+ printk("buffer=%p\n", rq->buffer);
#endif

- args.taskfile = taskfile;
- args.hobfile = hobfile;
ide_cmd_type_parser(&args);
rq->special = &args;

return ata_taskfile(drive, &args, rq);
}

-static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t lba28_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct hd_drive_task_hdr taskfile;
- struct hd_drive_hob_hdr hobfile;
- struct ata_taskfile args;
- int sectors;
+ struct ata_taskfile args;
+ int sectors;

sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;

- memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
- memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+ memset(&args, 0, sizeof(args));

- taskfile.sector_count = sectors;
- taskfile.sector_number = block;
- taskfile.low_cylinder = (block >>= 8);
-
- taskfile.high_cylinder = (block >>= 8);
-
- taskfile.device_head = ((block >> 8) & 0x0f);
- taskfile.device_head |= drive->select.all;
- taskfile.command = get_command(drive, rq_data_dir(rq));
+ args.taskfile.sector_count = sectors;
+ args.taskfile.sector_number = block;
+ args.taskfile.low_cylinder = (block >>= 8);
+
+ args.taskfile.high_cylinder = (block >>= 8);
+
+ args.taskfile.device_head = ((block >> 8) & 0x0f);
+ args.taskfile.device_head |= drive->select.all;
+ args.taskfile.command = get_command(drive, rq_data_dir(rq));

#ifdef DEBUG
printk("%s: %sing: ", drive->name,
@@ -208,11 +200,9 @@
if (lba) printk("LBAsect=%lld, ", block);
else printk("CHS=%d/%d/%d, ", cyl, head, sect);
printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
+ printk("buffer=%p\n", rq->buffer);
#endif

- args.taskfile = taskfile;
- args.hobfile = hobfile;
ide_cmd_type_parser(&args);
rq->special = &args;

@@ -225,40 +215,32 @@
* 1073741822 == 549756 MB or 48bit addressing fake drive
*/

-static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block)
+static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct hd_drive_task_hdr taskfile;
- struct hd_drive_hob_hdr hobfile;
- struct ata_taskfile args;
- int sectors;
-
- memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
- memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+ struct ata_taskfile args;
+ int sectors;

sectors = rq->nr_sectors;
if (sectors == 65536)
sectors = 0;

- taskfile.sector_count = sectors;
- hobfile.sector_count = sectors >> 8;
+ memset(&args, 0, sizeof(args));
+
+ args.taskfile.sector_count = sectors;
+ args.hobfile.sector_count = sectors >> 8;

- if (rq->nr_sectors == 65536) {
- taskfile.sector_count = 0x00;
- hobfile.sector_count = 0x00;
- }
-
- taskfile.sector_number = block; /* low lba */
- taskfile.low_cylinder = (block >>= 8); /* mid lba */
- taskfile.high_cylinder = (block >>= 8); /* hi lba */
-
- hobfile.sector_number = (block >>= 8); /* low lba */
- hobfile.low_cylinder = (block >>= 8); /* mid lba */
- hobfile.high_cylinder = (block >>= 8); /* hi lba */
-
- taskfile.device_head = drive->select.all;
- hobfile.device_head = taskfile.device_head;
- hobfile.control = (drive->ctl|0x80);
- taskfile.command = get_command(drive, rq_data_dir(rq));
+ args.taskfile.sector_number = block; /* low lba */
+ args.taskfile.low_cylinder = (block >>= 8); /* mid lba */
+ args.taskfile.high_cylinder = (block >>= 8); /* hi lba */
+
+ args.hobfile.sector_number = (block >>= 8); /* low lba */
+ args.hobfile.low_cylinder = (block >>= 8); /* mid lba */
+ args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
+
+ args.taskfile.device_head = drive->select.all;
+ args.hobfile.device_head = args.taskfile.device_head;
+ args.hobfile.control = (drive->ctl|0x80);
+ args.taskfile.command = get_command(drive, rq_data_dir(rq));

#ifdef DEBUG
printk("%s: %sing: ", drive->name,
@@ -266,11 +248,9 @@
if (lba) printk("LBAsect=%lld, ", block);
else printk("CHS=%d/%d/%d, ", cyl, head, sect);
printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
+ printk("buffer=%p\n",rq->buffer);
#endif

- args.taskfile = taskfile;
- args.hobfile = hobfile;
ide_cmd_type_parser(&args);
rq->special = &args;

@@ -282,7 +262,7 @@
* otherwise, to address sectors. It also takes care of issuing special
* DRIVE_CMDs.
*/
-static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
/*
* Wait until all request have bin finished.
@@ -290,7 +270,7 @@

while (drive->blocked) {
yield();
- printk("ide: Request while drive blocked?");
+ printk(KERN_ERR "ide: Request while drive blocked?");
}

if (!(rq->flags & REQ_CMD)) {
@@ -300,7 +280,7 @@
}

if (IS_PDC4030_DRIVE) {
- extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
+ extern ide_startstop_t promise_rw_disk(struct ata_device *, struct request *, unsigned long);

return promise_rw_disk(drive, rq, block);
}
@@ -386,256 +366,19 @@
return drive->removable;
}

-/*
- * Queries for true maximum capacity of the drive.
- * Returns maximum LBA address (> 0) of the drive, 0 if failed.
- */
-static unsigned long idedisk_read_native_max_address(ide_drive_t *drive)
+static sector_t idedisk_capacity(struct ata_device *drive)
{
- struct ata_taskfile args;
- unsigned long addr = 0;
-
- if (!(drive->id->command_set_1 & 0x0400) &&
- !(drive->id->cfs_enable_2 & 0x0100))
- return addr;
-
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(args));
- args.taskfile.device_head = 0x40;
- args.taskfile.command = WIN_READ_NATIVE_MAX;
- args.handler = task_no_data_intr;
-
- /* submit command request */
- ide_raw_taskfile(drive, &args, NULL);
-
- /* if OK, compute maximum address value */
- if ((args.taskfile.command & 0x01) == 0) {
- addr = ((args.taskfile.device_head & 0x0f) << 24)
- | (args.taskfile.high_cylinder << 16)
- | (args.taskfile.low_cylinder << 8)
- | args.taskfile.sector_number;
- }
-
- addr++; /* since the return value is (maxlba - 1), we add 1 */
-
- return addr;
-}
-
-static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive)
-{
- struct ata_taskfile args;
- unsigned long long addr = 0;
-
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(args));
-
- args.taskfile.device_head = 0x40;
- args.taskfile.command = WIN_READ_NATIVE_MAX_EXT;
- args.handler = task_no_data_intr;
-
- /* submit command request */
- ide_raw_taskfile(drive, &args, NULL);
-
- /* if OK, compute maximum address value */
- if ((args.taskfile.command & 0x01) == 0) {
- u32 high = (args.hobfile.high_cylinder << 16) |
- (args.hobfile.low_cylinder << 8) |
- args.hobfile.sector_number;
- u32 low = (args.taskfile.high_cylinder << 16) |
- (args.taskfile.low_cylinder << 8) |
- args.taskfile.sector_number;
- addr = ((__u64)high << 24) | low;
- }
-
- addr++; /* since the return value is (maxlba - 1), we add 1 */
-
- return addr;
+ return drive->capacity - drive->sect0;
}

-#ifdef CONFIG_IDEDISK_STROKE
-/*
- * Sets maximum virtual LBA address of the drive.
- * Returns new maximum virtual LBA address (> 0) or 0 on failure.
- */
-static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req)
+static ide_startstop_t idedisk_special(struct ata_device *drive)
{
- struct ata_taskfile args;
- unsigned long addr_set = 0;
-
- addr_req--;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(args));
-
- args.taskfile.sector_number = (addr_req >> 0);
- args.taskfile.low_cylinder = (addr_req >> 8);
- args.taskfile.high_cylinder = (addr_req >> 16);
+ unsigned char special_cmd = drive->special_cmd;

- args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
- args.taskfile.command = WIN_SET_MAX;
- args.handler = task_no_data_intr;
- /* submit command request */
- ide_raw_taskfile(drive, &args, NULL);
- /* if OK, read new maximum address value */
- if ((args.taskfile.command & 0x01) == 0) {
- addr_set = ((args.taskfile.device_head & 0x0f) << 24)
- | (args.taskfile.high_cylinder << 16)
- | (args.taskfile.low_cylinder << 8)
- | args.taskfile.sector_number;
- }
- addr_set++;
- return addr_set;
-}
-
-static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req)
-{
- struct ata_taskfile args;
- unsigned long long addr_set = 0;
-
- addr_req--;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(args));
-
- args.taskfile.sector_number = (addr_req >> 0);
- args.taskfile.low_cylinder = (addr_req >>= 8);
- args.taskfile.high_cylinder = (addr_req >>= 8);
- args.taskfile.device_head = 0x40;
- args.taskfile.command = WIN_SET_MAX_EXT;
-
- args.hobfile.sector_number = (addr_req >>= 8);
- args.hobfile.low_cylinder = (addr_req >>= 8);
- args.hobfile.high_cylinder = (addr_req >>= 8);
-
- args.hobfile.device_head = 0x40;
- args.hobfile.control = (drive->ctl | 0x80);
-
- args.handler = task_no_data_intr;
- /* submit command request */
- ide_raw_taskfile(drive, &args, NULL);
- /* if OK, compute maximum address value */
- if ((args.taskfile.command & 0x01) == 0) {
- u32 high = (args.hobfile.high_cylinder << 16) |
- (args.hobfile.low_cylinder << 8) |
- args.hobfile.sector_number;
- u32 low = (args.taskfile.high_cylinder << 16) |
- (args.taskfile.low_cylinder << 8) |
- args.taskfile.sector_number;
- addr_set = ((__u64)high << 24) | low;
- }
- return addr_set;
-}
-
-/*
- * Tests if the drive supports Host Protected Area feature.
- * Returns true if supported, false otherwise.
- */
-static inline int idedisk_supports_host_protected_area(ide_drive_t *drive)
-{
- int flag = (drive->id->cfs_enable_1 & 0x0400) ? 1 : 0;
- printk("%s: host protected area => %d\n", drive->name, flag);
- return flag;
-}
-
-#endif
-
-/*
- * Compute drive->capacity, the full capacity of the drive
- * Called with drive->id != NULL.
- *
- * To compute capacity, this uses either of
- *
- * 1. CHS value set by user (whatever user sets will be trusted)
- * 2. LBA value from target drive (require new ATA feature)
- * 3. LBA value from system BIOS (new one is OK, old one may break)
- * 4. CHS value from system BIOS (traditional style)
- *
- * in above order (i.e., if value of higher priority is available,
- * reset will be ignored).
- */
-static void init_idedisk_capacity (ide_drive_t *drive)
-{
- struct hd_driveid *id = drive->id;
- unsigned long capacity = drive->cyl * drive->head * drive->sect;
- unsigned long set_max = idedisk_read_native_max_address(drive);
- unsigned long long capacity_2 = capacity;
- unsigned long long set_max_ext;
-
- drive->capacity48 = 0;
- drive->select.b.lba = 0;
-
- if (id->cfs_enable_2 & 0x0400) {
- capacity_2 = id->lba_capacity_2;
- drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
- drive->head = drive->bios_head = 255;
- drive->sect = drive->bios_sect = 63;
- drive->select.b.lba = 1;
- set_max_ext = idedisk_read_native_max_address_ext(drive);
- if (set_max_ext > capacity_2) {
-#ifdef CONFIG_IDEDISK_STROKE
- set_max_ext = idedisk_read_native_max_address_ext(drive);
- set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext);
- if (set_max_ext) {
- drive->capacity48 = capacity_2 = set_max_ext;
- drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
- drive->select.b.lba = 1;
- drive->id->lba_capacity_2 = capacity_2;
- }
-#else
- printk("%s: setmax_ext LBA %llu, native %llu\n",
- drive->name, set_max_ext, capacity_2);
-#endif
- }
- drive->bios_cyl = drive->cyl;
- drive->capacity48 = capacity_2;
- drive->capacity = (unsigned long) capacity_2;
- return;
- /* Determine capacity, and use LBA if the drive properly supports it */
- } else if ((id->capability & 2) && lba_capacity_is_ok(id)) {
- capacity = id->lba_capacity;
- drive->cyl = capacity / (drive->head * drive->sect);
- drive->select.b.lba = 1;
- }
-
- if (set_max > capacity) {
-#ifdef CONFIG_IDEDISK_STROKE
- set_max = idedisk_read_native_max_address(drive);
- set_max = idedisk_set_max_address(drive, set_max);
- if (set_max) {
- drive->capacity = capacity = set_max;
- drive->cyl = set_max / (drive->head * drive->sect);
- drive->select.b.lba = 1;
- drive->id->lba_capacity = capacity;
- }
-#else
- printk("%s: setmax LBA %lu, native %lu\n",
- drive->name, set_max, capacity);
-#endif
- }
-
- drive->capacity = capacity;
-
- if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
- drive->capacity48 = id->lba_capacity_2;
- drive->head = 255;
- drive->sect = 63;
- drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect);
- }
-}
-
-static unsigned long idedisk_capacity (ide_drive_t *drive)
-{
- if (drive->id->cfs_enable_2 & 0x0400)
- return (drive->capacity48 - drive->sect0);
- return (drive->capacity - drive->sect0);
-}
-
-static ide_startstop_t idedisk_special (ide_drive_t *drive)
-{
- special_t *s = &drive->special;
-
- if (s->b.set_geometry) {
+ if (special_cmd & ATA_SPECIAL_GEOMETRY) {
struct ata_taskfile args;

- s->b.set_geometry = 0;
+ drive->special_cmd &= ~ATA_SPECIAL_GEOMETRY;

memset(&args, 0, sizeof(args));
args.taskfile.sector_number = drive->sect;
@@ -648,8 +391,9 @@
args.handler = set_geometry_intr;;
}
ata_taskfile(drive, &args, NULL);
- } else if (s->b.recalibrate) {
- s->b.recalibrate = 0;
+ } else if (special_cmd & ATA_SPECIAL_RECALIBRATE) {
+ drive->special_cmd &= ~ATA_SPECIAL_RECALIBRATE;
+
if (!IS_PDC4030_DRIVE) {
struct ata_taskfile args;

@@ -659,8 +403,8 @@
args.handler = recal_intr;
ata_taskfile(drive, &args, NULL);
}
- } else if (s->b.set_multmode) {
- s->b.set_multmode = 0;
+ } else if (special_cmd & ATA_SPECIAL_MMODE) {
+ drive->special_cmd &= ~ATA_SPECIAL_MMODE;
if (drive->id && drive->mult_req > drive->id->max_multsect)
drive->mult_req = drive->id->max_multsect;
if (!IS_PDC4030_DRIVE) {
@@ -673,10 +417,10 @@

ata_taskfile(drive, &args, NULL);
}
- } else if (s->all) {
- int special = s->all;
- s->all = 0;
- printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special);
+ } else if (special_cmd) {
+ drive->special_cmd = 0;
+
+ printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special_cmd);
return ide_stopped;
}
return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
@@ -686,13 +430,14 @@
{
int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;

- drive->special.all = 0;
- drive->special.b.set_geometry = legacy;
- drive->special.b.recalibrate = legacy;
+ if (legacy)
+ drive->special_cmd = (ATA_SPECIAL_GEOMETRY | ATA_SPECIAL_RECALIBRATE);
+ else
+ drive->special_cmd = 0;
if (OK_TO_RESET_CONTROLLER)
drive->mult_count = 0;
if (drive->mult_req != drive->mult_count)
- drive->special.b.set_multmode = 1;
+ drive->special_cmd |= ATA_SPECIAL_MMODE;
}

#ifdef CONFIG_PROC_FS
@@ -812,19 +557,23 @@
#endif /* CONFIG_PROC_FS */

/*
- * This is tightly woven into the driver->do_special can not touch.
+ * This is tightly woven into the driver->special can not touch.
* DON'T do it again until a total personality rewrite is committed.
*/
static int set_multcount(ide_drive_t *drive, int arg)
{
- struct request rq;
+ struct ata_taskfile args;

- if (drive->special.b.set_multmode)
+ if (drive->special_cmd & ATA_SPECIAL_MMODE)
return -EBUSY;
- ide_init_drive_cmd (&rq);
+
+ memset(&args, 0, sizeof(args));
+
drive->mult_req = arg;
- drive->special.b.set_multmode = 1;
- ide_do_drive_cmd (drive, &rq, ide_wait);
+ drive->special_cmd |= ATA_SPECIAL_MMODE;
+
+ ide_raw_taskfile(drive, &args, NULL);
+
return (drive->mult_count == arg) ? 0 : -EIO;
}

@@ -835,6 +584,7 @@
drive->nowerr = arg;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
spin_unlock_irq(&ide_lock);
+
return 0;
}

@@ -968,12 +718,153 @@
resume: idedisk_resume,
};

-static void idedisk_setup(ide_drive_t *drive)
+/*
+ * Queries for true maximum capacity of the drive.
+ * Returns maximum LBA address (> 0) of the drive, 0 if failed.
+ */
+static unsigned long native_max_address(struct ata_device *drive)
+{
+ struct ata_taskfile args;
+ unsigned long addr = 0;
+
+ if (!(drive->id->command_set_1 & 0x0400) &&
+ !(drive->id->cfs_enable_2 & 0x0100))
+ return addr;
+
+ /* Create IDE/ATA command request structure */
+ memset(&args, 0, sizeof(args));
+ args.taskfile.device_head = 0x40;
+ args.taskfile.command = WIN_READ_NATIVE_MAX;
+ args.handler = task_no_data_intr;
+
+ /* submit command request */
+ ide_raw_taskfile(drive, &args, NULL);
+
+ /* if OK, compute maximum address value */
+ if ((args.taskfile.command & 0x01) == 0) {
+ addr = ((args.taskfile.device_head & 0x0f) << 24)
+ | (args.taskfile.high_cylinder << 16)
+ | (args.taskfile.low_cylinder << 8)
+ | args.taskfile.sector_number;
+ }
+
+ addr++; /* since the return value is (maxlba - 1), we add 1 */
+
+ return addr;
+}
+
+static u64 native_max_address_ext(struct ata_device *drive)
+{
+ struct ata_taskfile args;
+ u64 addr = 0;
+
+ /* Create IDE/ATA command request structure */
+ memset(&args, 0, sizeof(args));
+
+ args.taskfile.device_head = 0x40;
+ args.taskfile.command = WIN_READ_NATIVE_MAX_EXT;
+ args.handler = task_no_data_intr;
+
+ /* submit command request */
+ ide_raw_taskfile(drive, &args, NULL);
+
+ /* if OK, compute maximum address value */
+ if ((args.taskfile.command & 0x01) == 0) {
+ u32 high = (args.hobfile.high_cylinder << 16) |
+ (args.hobfile.low_cylinder << 8) |
+ args.hobfile.sector_number;
+ u32 low = (args.taskfile.high_cylinder << 16) |
+ (args.taskfile.low_cylinder << 8) |
+ args.taskfile.sector_number;
+ addr = ((u64)high << 24) | low;
+ }
+
+ addr++; /* since the return value is (maxlba - 1), we add 1 */
+
+ return addr;
+}
+
+#ifdef CONFIG_IDEDISK_STROKE
+/*
+ * Sets maximum virtual LBA address of the drive.
+ * Returns new maximum virtual LBA address (> 0) or 0 on failure.
+ */
+static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
+{
+ struct ata_taskfile args;
+ sector_t addr_set = 0;
+
+ addr_req--;
+ /* Create IDE/ATA command request structure */
+ memset(&args, 0, sizeof(args));
+
+ args.taskfile.sector_number = (addr_req >> 0);
+ args.taskfile.low_cylinder = (addr_req >> 8);
+ args.taskfile.high_cylinder = (addr_req >> 16);
+
+ args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
+ args.taskfile.command = WIN_SET_MAX;
+ args.handler = task_no_data_intr;
+ /* submit command request */
+ ide_raw_taskfile(drive, &args, NULL);
+ /* if OK, read new maximum address value */
+ if ((args.taskfile.command & 0x01) == 0) {
+ addr_set = ((args.taskfile.device_head & 0x0f) << 24)
+ | (args.taskfile.high_cylinder << 16)
+ | (args.taskfile.low_cylinder << 8)
+ | args.taskfile.sector_number;
+ }
+ addr_set++;
+ return addr_set;
+}
+
+static u64 set_max_address_ext(ide_drive_t *drive, u64 addr_req)
+{
+ struct ata_taskfile args;
+ u64 addr_set = 0;
+
+ addr_req--;
+ /* Create IDE/ATA command request structure */
+ memset(&args, 0, sizeof(args));
+
+ args.taskfile.sector_number = (addr_req >> 0);
+ args.taskfile.low_cylinder = (addr_req >>= 8);
+ args.taskfile.high_cylinder = (addr_req >>= 8);
+ args.taskfile.device_head = 0x40;
+ args.taskfile.command = WIN_SET_MAX_EXT;
+
+ args.hobfile.sector_number = (addr_req >>= 8);
+ args.hobfile.low_cylinder = (addr_req >>= 8);
+ args.hobfile.high_cylinder = (addr_req >>= 8);
+
+ args.hobfile.device_head = 0x40;
+ args.hobfile.control = (drive->ctl | 0x80);
+
+ args.handler = task_no_data_intr;
+ /* submit command request */
+ ide_raw_taskfile(drive, &args, NULL);
+ /* if OK, compute maximum address value */
+ if ((args.taskfile.command & 0x01) == 0) {
+ u32 high = (args.hobfile.high_cylinder << 16) |
+ (args.hobfile.low_cylinder << 8) |
+ args.hobfile.sector_number;
+ u32 low = (args.taskfile.high_cylinder << 16) |
+ (args.taskfile.low_cylinder << 8) |
+ args.taskfile.sector_number;
+ addr_set = ((u64)high << 24) | low;
+ }
+ return addr_set;
+}
+
+#endif
+
+static void idedisk_setup(struct ata_device *drive)
{
int i;

struct hd_driveid *id = drive->id;
- unsigned long capacity;
+ sector_t capacity;
+ sector_t set_max;
int drvid = -1;

idedisk_add_settings(drive);
@@ -1024,7 +915,7 @@
drive->sect = drive->bios_sect = id->sectors;
}

- /* Handle logical geometry translation by the drive */
+ /* Handle logical geometry translation by the drive. */
if ((id->field_valid & 1) && id->cur_cyls &&
id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) {
drive->cyl = id->cur_cyls;
@@ -1032,31 +923,126 @@
drive->sect = id->cur_sectors;
}

- /* Use physical geometry if what we have still makes no sense */
+ /* Use physical geometry if what we have still makes no sense. */
if (drive->head > 16 && id->heads && id->heads <= 16) {
drive->cyl = id->cyls;
drive->head = id->heads;
drive->sect = id->sectors;
}

- /* calculate drive capacity, and select LBA if possible */
- init_idedisk_capacity (drive);
+ /* Calculate drive capacity, and select LBA if possible.
+ * drive->id != NULL is spected
+ *
+ * To compute capacity, this uses either of
+ *
+ * 1. CHS value set by user (whatever user sets will be trusted)
+ * 2. LBA value from target drive (require new ATA feature)
+ * 3. LBA value from system BIOS (new one is OK, old one may break)
+ * 4. CHS value from system BIOS (traditional style)
+ *
+ * in above order (i.e., if value of higher priority is available,
+ * reset will be ignored).
+ */
+ capacity = drive->cyl * drive->head * drive->sect;
+ set_max = native_max_address(drive);
+
+ drive->capacity = 0;
+ drive->select.b.lba = 0;
+
+ if (id->cfs_enable_2 & 0x0400) {
+ u64 set_max_ext;
+ u64 capacity_2;
+ capacity_2 = capacity;
+ capacity_2 = id->lba_capacity_2;
+
+ drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
+ drive->head = drive->bios_head = 255;
+ drive->sect = drive->bios_sect = 63;
+
+ drive->select.b.lba = 1;
+ set_max_ext = native_max_address_ext(drive);
+ if (set_max_ext > capacity_2) {
+#ifdef CONFIG_IDEDISK_STROKE
+ set_max_ext = native_max_address_ext(drive);
+ set_max_ext = set_max_address_ext(drive, set_max_ext);
+ if (set_max_ext) {
+ drive->capacity = capacity_2 = set_max_ext;
+ drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
+ drive->select.b.lba = 1;
+ drive->id->lba_capacity_2 = capacity_2;
+ }
+#else
+ printk("%s: setmax_ext LBA %llu, native %llu\n",
+ drive->name, set_max_ext, capacity_2);
+#endif
+ }
+ drive->bios_cyl = drive->cyl;
+ drive->capacity = capacity_2;
+ } else {
+
+ /*
+ * Determine capacity, and use LBA if the drive properly
+ * supports it.
+ */
+
+ if ((id->capability & 2) && lba_capacity_is_ok(id)) {
+ capacity = id->lba_capacity;
+ drive->cyl = capacity / (drive->head * drive->sect);
+ drive->select.b.lba = 1;
+ }
+
+ if (set_max > capacity) {
+#ifdef CONFIG_IDEDISK_STROKE
+ set_max = native_max_address(drive);
+ set_max = set_max_address(drive, set_max);
+ if (set_max) {
+ drive->capacity = capacity = set_max;
+ drive->cyl = set_max / (drive->head * drive->sect);
+ drive->select.b.lba = 1;
+ drive->id->lba_capacity = capacity;
+ }
+#else
+ printk("%s: setmax LBA %lu, native %lu\n",
+ drive->name, set_max, capacity);
+#endif
+ }
+
+ drive->capacity = capacity;
+
+ if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
+ drive->capacity = id->lba_capacity_2;
+ drive->head = 255;
+ drive->sect = 63;
+ drive->cyl = (unsigned long)(drive->capacity) / (drive->head * drive->sect);
+ }
+ }

/*
- * if possible, give fdisk access to more of the drive,
+ * If possible, give fdisk access to more of the drive,
* by correcting bios_cyls:
*/
- capacity = idedisk_capacity (drive);
+ capacity = idedisk_capacity(drive);
if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) &&
(!drive->forced_geom) && drive->bios_sect && drive->bios_head)
drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
printk(KERN_INFO "%s: %ld sectors", drive->name, capacity);

- /* Give size in megabytes (MB), not mebibytes (MiB). */
- /* We compute the exact rounded value, avoiding overflow. */
+#if 0
+
+ /* Right now we avoid this calculation, since it can result in the
+ * usage of not supported compiler internal functions on 32 bit hosts.
+ * However since the calculation appears to be an interesting piece of
+ * number theory let's preserve the formula here.
+ */
+
+ /* Give size in megabytes (MB), not mebibytes (MiB).
+ * We compute the exact rounded value, avoiding overflow.
+ */
printk(" (%ld MB)", (capacity - capacity/625 + 974)/1950);
+#endif

- /* Only print cache size when it was specified */
+ /* Only print cache size when it was specified.
+ */
if (id->buf_size)
printk (" w/%dKiB Cache", id->buf_size/2);

@@ -1074,14 +1060,15 @@
id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0;
id->multsect_valid = id->multsect ? 1 : 0;
drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT;
- drive->special.b.set_multmode = drive->mult_req ? 1 : 0;
+ if (drive->mult_req)
+ drive->special_cmd |= ATA_SPECIAL_MMODE;
#else
/* original, pre IDE-NFG, per request of AC */
drive->mult_req = INITIAL_MULT_COUNT;
if (drive->mult_req > id->max_multsect)
drive->mult_req = id->max_multsect;
if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
- drive->special.b.set_multmode = 1;
+ drive->special_cmd |= ATA_SPECIAL_MMODE;
#endif
}

@@ -1095,6 +1082,7 @@

if (drive->id->cfs_enable_2 & 0x3000)
write_cache(drive, (id->cfs_enable_2 & 0x3000));
+
probe_lba_addressing(drive, 1);
}

diff -urN linux-2.5.10/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.10/drivers/ide/ide-dma.c 2002-04-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-dma.c 2002-04-25 23:20:20.000000000 +0200
@@ -295,7 +295,7 @@
int i;
struct scatterlist *sg;

- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
+ if (HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) {
hwif->sg_nents = i = raw_build_sglist(hwif, HWGROUP(drive)->rq);
} else {
hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq);
@@ -590,9 +590,10 @@

BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
- if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
(drive->addressing == 1)) {
struct ata_taskfile *args = HWGROUP(drive)->rq->special;
+
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
} else if (drive->addressing) {
OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
diff -urN linux-2.5.10/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.10/drivers/ide/ide-floppy.c 2002-04-23 00:28:19.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c 2002-04-26 00:32:21.000000000 +0200
@@ -1255,12 +1255,12 @@
pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
}

-static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
+static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, sector_t sector)
{
int block = sector / floppy->bs_factor;
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
-
+
#if IDEFLOPPY_DEBUG_LOG
printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), block, blocks);
@@ -1287,9 +1287,9 @@
}

/*
- * idefloppy_do_request is our request handling function.
+ * This is our request handling function.
*/
-static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t *pc;
@@ -1297,7 +1297,7 @@
#if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors);
printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+#endif

if (rq->errors >= ERROR_MAX) {
if (floppy->failed_pc != NULL)
@@ -1314,7 +1314,7 @@
idefloppy_end_request(drive, 0);
return ide_stopped;
}
- pc = idefloppy_next_pc_storage (drive);
+ pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd (floppy, pc, rq, block);
} else if (rq->flags & IDEFLOPPY_RQ) {
pc = (idefloppy_pc_t *) rq->buffer;
@@ -2063,9 +2063,7 @@
release: idefloppy_release,
check_media_change: idefloppy_check_media_change,
revalidate: NULL, /* use default method */
- pre_reset: NULL,
capacity: idefloppy_capacity,
- special: NULL,
proc: idefloppy_proc
};

diff -urN linux-2.5.10/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.10/drivers/ide/ide-pmac.c 2002-04-23 00:29:34.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c 2002-04-25 23:27:08.000000000 +0200
@@ -1109,7 +1109,7 @@
udelay(1);

/* Build sglist */
- if (rq->flags & REQ_DRIVE_TASKFILE) {
+ if (rq->flags & REQ_DRIVE_ACB) {
pmac_ide[ix].sg_nents = i = pmac_raw_build_sglist(ix, rq);
} else {
pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq);
@@ -1386,7 +1386,7 @@
return 0;
BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
- if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
(drive->addressing == 1)) {
struct ata_taskfile *args = HWGROUP(drive)->rq->special;
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
diff -urN linux-2.5.10/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
--- linux-2.5.10/drivers/ide/ide-proc.c 2002-04-23 00:27:49.000000000 +0200
+++ linux/drivers/ide/ide-proc.c 2002-04-26 00:09:09.000000000 +0200
@@ -160,8 +160,8 @@
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}

-static int proc_ide_read_channel
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_ide_read_channel(char *page, char **start,
+ off_t off, int count, int *eof, void *data)
{
struct ata_channel *hwif = data;
int len;
diff -urN linux-2.5.10/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.10/drivers/ide/ide-tape.c 2002-04-23 00:28:08.000000000 +0200
+++ linux/drivers/ide/ide-tape.c 2002-04-25 21:57:49.000000000 +0200
@@ -2614,9 +2614,9 @@
}

/*
- * idetape_do_request is our request handling function.
+ * This is our request handling function.
*/
-static ide_startstop_t idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc;
diff -urN linux-2.5.10/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.10/drivers/ide/ide-taskfile.c 2002-04-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c 2002-04-26 01:44:57.000000000 +0200
@@ -476,15 +476,15 @@
/*
* This is invoked on completion of a WIN_SETMULT cmd.
*/
-ide_startstop_t set_multmode_intr (ide_drive_t *drive)
+ide_startstop_t set_multmode_intr(struct ata_device *drive)
{
- byte stat;
+ u8 stat;

if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) {
drive->mult_count = drive->mult_req;
} else {
drive->mult_req = drive->mult_count = 0;
- drive->special.b.recalibrate = 1;
+ drive->special_cmd |= ATA_SPECIAL_RECALIBRATE;
ide_dump_status(drive, "set_multmode", stat);
}
return ide_stopped;
@@ -879,20 +879,12 @@
}
}

-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
-static void init_taskfile_request(struct request *rq)
-{
- memset(rq, 0, sizeof(*rq));
- rq->flags = REQ_DRIVE_TASKFILE;
-}
-
int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
{
struct request rq;
- init_taskfile_request(&rq);

+ memset(&rq, 0, sizeof(rq));
+ rq.flags = REQ_DRIVE_ACB;
rq.buffer = buf;

if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
@@ -909,13 +901,8 @@
* Implement generic ioctls invoked from userspace to imlpement specific
* functionality.
*
- * FIXME:
- *
- * 1. Rewrite hdparm to use the ide_task_ioctl function.
- *
- * 2. Publish it.
- *
- * 3. Kill this and HDIO_DRIVE_CMD alltogether.
+ * Unfortunately every single low level programm out there is using this
+ * interface.
*/

int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
@@ -923,22 +910,19 @@
int err = 0;
u8 vals[4];
u8 *argbuf = vals;
- byte xfer_rate = 0;
+ u8 xfer_rate = 0;
int argsize = 4;
struct ata_taskfile args;
struct request rq;

- /*
- * First phase.
+ ide_init_drive_cmd(&rq);
+
+ /* Wait for drive ready.
*/
- if (NULL == (void *) arg) {
- struct request rq;
- ide_init_drive_cmd(&rq);
+ if (!arg)
return ide_do_drive_cmd(drive, &rq, ide_wait);
- }

- /*
- * Second phase.
+ /* Second phase.
*/
if (copy_from_user(vals, (void *)arg, 4))
return -EFAULT;
@@ -960,6 +944,8 @@
memset(argbuf + 4, 0, argsize - 4);
}

+ /* Always make sure the transfer reate has been setup.
+ */
if (set_transfer(drive, &args)) {
xfer_rate = vals[1];
if (ide_ata66_check(drive, &args))
@@ -968,7 +954,6 @@

/* Issue ATA command and wait for completion.
*/
- ide_init_drive_cmd(&rq);
rq.buffer = argbuf;
err = ide_do_drive_cmd(drive, &rq, ide_wait);

@@ -978,44 +963,22 @@
drive->channel->speedproc(drive, xfer_rate);
ide_driveid_update(drive);
}
+
abort:
if (copy_to_user((void *)arg, argbuf, argsize))
err = -EFAULT;
+
if (argsize > 4)
kfree(argbuf);

return err;
}

-int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
-{
- int err = 0;
- u8 args[7];
- u8 *argbuf;
- int argsize = 7;
- struct request rq;
-
- argbuf = args;
-
- if (copy_from_user(args, (void *)arg, 7))
- return -EFAULT;
-
- ide_init_drive_cmd(&rq);
- rq.flags = REQ_DRIVE_TASK;
- rq.buffer = argbuf;
- err = ide_do_drive_cmd(drive, &rq, ide_wait);
- if (copy_to_user((void *)arg, argbuf, argsize))
- err = -EFAULT;
- return err;
-}
-
EXPORT_SYMBOL(drive_is_ready);
-
EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(atapi_read);
EXPORT_SYMBOL(atapi_write);
-
EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(set_geometry_intr);
@@ -1023,6 +986,4 @@
EXPORT_SYMBOL(task_no_data_intr);
EXPORT_SYMBOL(ide_raw_taskfile);
EXPORT_SYMBOL(ide_cmd_type_parser);
-
EXPORT_SYMBOL(ide_cmd_ioctl);
-EXPORT_SYMBOL(ide_task_ioctl);
diff -urN linux-2.5.10/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.10/drivers/scsi/ide-scsi.c 2002-04-23 00:27:48.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c 2002-04-26 00:32:14.000000000 +0200
@@ -458,9 +458,9 @@
}

/*
- * idescsi_do_request is our request handling function.
+ * This is our request handling function.
*/
-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
#if IDESCSI_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
@@ -468,20 +468,20 @@
#endif /* IDESCSI_DEBUG_LOG */

if (rq->flags & REQ_SPECIAL) {
- return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special);
+ return idescsi_issue_pc(drive, (idescsi_pc_t *) rq->special);
}
blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request(drive, 0);
return ide_stopped;
}

-static int idescsi_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static int idescsi_open(struct inode *inode, struct file *filp, struct ata_device *drive)
{
MOD_INC_USE_COUNT;
return 0;
}

-static void idescsi_ide_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static void idescsi_ide_release(struct inode *inode, struct file *filp, struct ata_device *drive)
{
MOD_DEC_USE_COUNT;
}
@@ -556,9 +556,7 @@
release: idescsi_ide_release,
check_media_change: NULL,
revalidate: idescsi_revalidate,
- pre_reset: NULL,
capacity: NULL,
- special: NULL,
proc: NULL
};

diff -urN linux-2.5.10/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.5.10/include/linux/blkdev.h 2002-04-23 00:28:15.000000000 +0200
+++ linux/include/linux/blkdev.h 2002-04-25 23:28:54.000000000 +0200
@@ -76,17 +76,16 @@
__REQ_STARTED, /* drive already may have started this one */
__REQ_DONTPREP, /* don't call prep for this one */
/*
- * for IDE
- */
+ * for ATA/ATAPI devices
+ */
__REQ_DRIVE_CMD,
- __REQ_DRIVE_TASK,
__REQ_DRIVE_ACB,

__REQ_PC, /* packet command (special) */
__REQ_BLOCK_PC, /* queued down pc from block layer */
__REQ_SENSE, /* sense retrival */

- __REQ_SPECIAL, /* driver special command */
+ __REQ_SPECIAL, /* driver special command (currently reset) */

__REQ_NR_BITS, /* stops here */
};
@@ -99,15 +98,12 @@
#define REQ_STARTED (1 << __REQ_STARTED)
#define REQ_DONTPREP (1 << __REQ_DONTPREP)
#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD)
-#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)
#define REQ_DRIVE_ACB (1 << __REQ_DRIVE_ACB)
#define REQ_PC (1 << __REQ_PC)
-#define REQ_SENSE (1 << __REQ_SENSE)
#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
+#define REQ_SENSE (1 << __REQ_SENSE)
#define REQ_SPECIAL (1 << __REQ_SPECIAL)

-#define REQ_DRIVE_TASKFILE REQ_DRIVE_ACB
-
#include <linux/elevator.h>

typedef int (merge_request_fn) (request_queue_t *, struct request *,
diff -urN linux-2.5.10/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.5.10/include/linux/hdreg.h 2002-04-26 03:38:13.000000000 +0200
+++ linux/include/linux/hdreg.h 2002-04-25 23:05:19.000000000 +0200
@@ -3,7 +3,7 @@

/*
* This file contains some defines for the AT-hd-controller.
- * Various sources.
+ * Various sources.
*/

#define HD_IRQ 14 /* the standard disk interrupt */
@@ -51,11 +51,9 @@

/*
* Command Header sizes for IOCTL commands
- * HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
*/

#define HDIO_DRIVE_CMD_HDR_SIZE (4 * sizeof(u8))
-#define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(u8))
#define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(u8))

#define IDE_DRIVE_TASK_INVALID -1
@@ -287,7 +285,6 @@
#define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
#define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */
-#define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */
#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
#define HDIO_GET_DMA 0x030b /* get use-dma flag */
@@ -298,12 +295,8 @@
#define HDIO_GET_ADDRESS 0x0310 /* */

#define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */
-#define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */
-#define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */
#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */

-#define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK
-
/* 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_UNMASKINTR 0x0322 /* permit other irqs during I/O */
@@ -521,11 +514,7 @@
* 7:0 current value
*/
unsigned short words95_99[5]; /* reserved words 95-99 */
-#if 0
- unsigned short words100_103[4] ;/* reserved words 100-103 */
-#else
unsigned long long lba_capacity_2;/* 48-bit total number of sectors */
-#endif
unsigned short words104_125[22];/* reserved words 104-125 */
unsigned short last_lun; /* (word 126) */
unsigned short word127; /* (word 127) Feature Set
@@ -573,7 +562,7 @@
* 15:8 Checksum
* 7:0 Signature
*/
-};
+} __attribute__((packed));

/*
* IDE "nice" flags. These are used on a per drive basis to determine
diff -urN linux-2.5.10/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.10/include/linux/ide.h 2002-04-26 03:38:13.000000000 +0200
+++ linux/include/linux/ide.h 2002-04-26 03:30:50.000000000 +0200
@@ -33,23 +33,26 @@
*/
#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */

-#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */
-#define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */
+#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */
+# define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */
#endif
+
+/* Right now this is only needed by a promise controlled.
+ */
#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */
-#define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */
+# define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */
#endif
#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */
-#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */
+# define DISK_RECOVERY_TIME 0 /* for hardware that needs it */
#endif
#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
-#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */
+# define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */
#endif
#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
-#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
+# define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#endif
#ifndef DISABLE_IRQ_NOSYNC
-#define DISABLE_IRQ_NOSYNC 0
+# define DISABLE_IRQ_NOSYNC 0
#endif

/*
@@ -262,17 +265,6 @@
#define ATA_SCSI 0x21
#define ATA_NO_LUN 0x7f

-typedef union {
- unsigned all : 8; /* all of the bits together */
- struct {
- unsigned set_geometry : 1; /* respecify drive geometry */
- unsigned recalibrate : 1; /* seek to cyl 0 */
- unsigned set_multmode : 1; /* set multmode count */
- unsigned set_tune : 1; /* tune interface for drive */
- unsigned reserved : 4; /* unused */
- } b;
-} special_t;
-
struct ide_settings_s;
/* structure describing an ATA/ATAPI device */
typedef
@@ -300,7 +292,17 @@
unsigned long PADAM_service_time; /* service time of last request */
unsigned long PADAM_timeout; /* max time to wait for irq */

- special_t special; /* special action flags */
+ /* Flags requesting/indicating one of the following special commands
+ * executed on the request queue.
+ */
+#define ATA_SPECIAL_GEOMETRY 0x01
+#define ATA_SPECIAL_RECALIBRATE 0x02
+#define ATA_SPECIAL_MMODE 0x04
+#define ATA_SPECIAL_TUNE 0x08
+ unsigned char special_cmd;
+ u8 mult_req; /* requested multiple sector setting */
+ u8 tune_req; /* requested drive tuning setting */
+
byte using_dma; /* disk is using dma for read/write */
byte retry_pio; /* retrying dma capable host in pio */
byte state; /* retry state */
@@ -327,8 +329,6 @@
byte ctl; /* "normal" value for IDE_CONTROL_REG */
byte ready_stat; /* min status value for drive ready */
byte mult_count; /* current multiple sector setting */
- byte mult_req; /* requested multiple sector setting */
- byte tune_req; /* requested drive tuning setting */
byte bad_wstat; /* used for ignoring WRERR_STAT */
byte nowerr; /* used for ignoring WRERR_STAT */
byte sect0; /* offset of first sector for DM6:DDO */
@@ -338,8 +338,7 @@
byte bios_sect; /* BIOS/fdisk/LILO sectors per track */
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
- unsigned long capacity; /* total number of sectors */
- unsigned long long capacity48; /* total number of sectors */
+ u64 capacity; /* total number of sectors */
unsigned int drive_data; /* for use by tuneproc/selectproc as needed */

wait_queue_head_t wqueue; /* used to wait for drive in open() */
@@ -462,19 +461,19 @@
char name[8]; /* name of interface */
int index; /* 0 for ide0; 1 for ide1; ... */
hwif_chipset_t chipset; /* sub-module for tuning.. */
- unsigned noprobe : 1; /* don't probe for this interface */
- unsigned present : 1; /* there is a device on this interface */
- unsigned serialized : 1; /* serialized operation between channels */
- unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
- unsigned reset : 1; /* reset after probe */
- unsigned autodma : 1; /* automatically try to enable DMA at boot */
- unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
- 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 */
+ unsigned noprobe : 1; /* don't probe for this interface */
+ unsigned present : 1; /* there is a device on this interface */
+ unsigned serialized : 1; /* serialized operation between channels */
+ unsigned sharing_irq : 1; /* 1 = sharing irq with another hwif */
+ unsigned reset : 1; /* reset after probe */
+ unsigned autodma : 1; /* automatically try to enable DMA at boot */
+ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
+ unsigned highmem : 1; /* can do full 32-bit dma */
+ unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
+ unsigned no_unmask : 1; /* disallow setting unmask bit */
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 */
+ byte slow; /* flag: slow data port */

#if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */
@@ -616,20 +615,20 @@

struct ata_operations {
struct module *owner;
- int (*cleanup)(ide_drive_t *);
- int (*standby)(ide_drive_t *);
- ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long);
- int (*end_request)(ide_drive_t *drive, int uptodate);
-
- int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
- int (*open)(struct inode *, struct file *, ide_drive_t *);
- void (*release)(struct inode *, struct file *, ide_drive_t *);
- int (*check_media_change)(ide_drive_t *);
- void (*revalidate)(ide_drive_t *);
-
- void (*pre_reset)(ide_drive_t *);
- unsigned long (*capacity)(ide_drive_t *);
- ide_startstop_t (*special)(ide_drive_t *);
+ int (*cleanup)(struct ata_device *);
+ int (*standby)(struct ata_device *);
+ ide_startstop_t (*do_request)(struct ata_device *, struct request *, sector_t);
+ int (*end_request)(struct ata_device *, int);
+
+ int (*ioctl)(struct ata_device *, struct inode *, struct file *, unsigned int, unsigned long);
+ int (*open)(struct inode *, struct file *, struct ata_device *);
+ void (*release)(struct inode *, struct file *, struct ata_device *);
+ int (*check_media_change)(struct ata_device *);
+ void (*revalidate)(struct ata_device *);
+
+ void (*pre_reset)(struct ata_device *);
+ sector_t (*capacity)(struct ata_device *);
+ ide_startstop_t (*special)(struct ata_device *);

ide_proc_entry_t *proc;
};
@@ -646,7 +645,7 @@
__MOD_DEC_USE_COUNT((ata)->owner); \
} while(0)

-extern unsigned long ata_capacity(ide_drive_t *drive);
+extern sector_t ata_capacity(struct ata_device *drive);

/* FIXME: Actually implement and use them as soon as possible! to make the
* ide_scan_devices() go away! */
@@ -733,7 +732,6 @@
* This function is intended to be used prior to invoking ide_do_drive_cmd().
*/
extern void ide_init_drive_cmd(struct request *rq);
-extern void init_taskfile_request(struct request *rq);

/*
* "action" parameter type for ide_do_drive_cmd() below.
@@ -787,10 +785,8 @@
/* This is setting up all fields in args, which depend upon the command type.
*/
extern void ide_cmd_type_parser(struct ata_taskfile *args);
-extern int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *cmd, byte *buf);
-
-extern int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg);
-extern int ide_task_ioctl(ide_drive_t *drive, unsigned long arg);
+extern int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *cmd, byte *buf);
+extern int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg);

void ide_delay_50ms(void);

@@ -864,13 +860,13 @@
extern int ide_unregister_subdriver(ide_drive_t *drive);

#ifdef CONFIG_BLK_DEV_IDEPCI
-#define ON_BOARD 1
-#define NEVER_BOARD 0
-#ifdef CONFIG_BLK_DEV_OFFBOARD
-# define OFF_BOARD ON_BOARD
-#else
-# define OFF_BOARD NEVER_BOARD
-#endif
+# define ON_BOARD 1
+# define NEVER_BOARD 0
+# ifdef CONFIG_BLK_DEV_OFFBOARD
+# define OFF_BOARD ON_BOARD
+# else
+# define OFF_BOARD NEVER_BOARD
+# endif

void __init ide_scan_pcibus(int scan_direction);
#endif
@@ -892,4 +888,4 @@
extern int drive_is_ready(ide_drive_t *drive);
extern void revalidate_drives(void);

-#endif /* _IDE_H */
+#endif