From: Martin Dalecki <dalecki@evision-ventures.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] 2.5.10 IDE 42
Date: Fri, 26 Apr 2002 09:41:30 +0200 [thread overview]
Message-ID: <3CC904AA.7020706@evision-ventures.com> (raw)
In-Reply-To: <1019549894.1450.41.camel@turbulence.megapathdsl.net> <3CC7E358.8050905@evision-ventures.com> <20020425172508.GK3542@suse.de> <20020425173439.GM3542@suse.de> <aa9qtb$d8a$1@penguin.transmeta.com>
[-- 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
next prev parent reply other threads:[~2002-04-26 8:44 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-04-23 8:18 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Miles Lane
2002-04-23 8:00 ` Martin Dalecki
2002-04-23 9:18 ` Jens Axboe
2002-04-23 8:43 ` Martin Dalecki
2002-04-23 9:54 ` Jens Axboe
2002-04-23 17:39 ` Miles Lane
2002-04-23 17:54 ` Miles Lane
2002-04-24 8:06 ` Martin Dalecki
2002-04-24 9:11 ` Jens Axboe
2002-04-24 8:20 ` Martin Dalecki
2002-04-25 11:07 ` Martin Dalecki
2002-04-25 17:25 ` Jens Axboe
2002-04-25 17:34 ` Jens Axboe
2002-04-25 21:02 ` Linus Torvalds
2002-04-26 7:33 ` [PATCH] 2.5.10 UTS_VERSION Martin Dalecki
2002-04-26 9:52 ` Keith Owens
2002-04-26 8:58 ` Martin Dalecki
2002-04-26 7:41 ` Martin Dalecki [this message]
2002-04-26 16:09 ` [PATCH] 2.5.10 IDE 42 Pavel Machek
2002-04-26 17:31 ` Dave Jones
2002-04-26 17:37 ` Linus Torvalds
2002-04-26 20:05 ` Oliver Xymoron
2002-04-26 21:34 ` Martin Dalecki
2002-04-26 22:25 ` Martin Dalecki
2002-04-26 21:32 ` Martin Dalecki
2002-04-26 23:21 ` Rene Rebe
2002-04-26 21:42 ` Martin Dalecki
2002-04-26 16:10 ` Sebastian Droege
2002-04-26 21:28 ` Martin Dalecki
2002-04-26 22:44 ` Padraig Brady
2002-04-28 9:18 ` Kai Henningsen
2002-05-05 15:54 ` [PATCH] 2.5.13 IDE 52 Martin Dalecki
2002-05-05 17:09 ` Jens Axboe
2002-05-05 16:16 ` Martin Dalecki
2002-05-05 15:55 ` [PATCH] 2.5.13 IDE 53 Martin Dalecki
2002-05-06 9:53 ` Russell King
2002-05-06 8:55 ` Martin Dalecki
2002-05-06 23:48 ` jw schultz
2002-05-05 15:56 ` [PATCH 2.5.13 IDE 54 Martin Dalecki
2002-05-07 12:52 ` Paul Mackerras
2002-05-07 12:06 ` Martin Dalecki
2002-05-07 14:40 ` benh
2002-05-07 13:40 ` Martin Dalecki
2002-05-07 15:18 ` benh
2002-05-07 14:07 ` Alan Cox
2002-05-07 13:24 ` Martin Dalecki
2002-04-24 9:29 ` 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Luigi Genoni
2002-04-23 18:23 ` Melchior FRANZ
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3CC904AA.7020706@evision-ventures.com \
--to=dalecki@evision-ventures.com \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.