All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Dalecki <dalecki@evision-ventures.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH] 2.5.19 IDE 80
Date: Sun, 02 Jun 2002 08:07:08 +0200	[thread overview]
Message-ID: <3CF9B60C.3080506@evision-ventures.com> (raw)
In-Reply-To: <Pine.LNX.4.33.0205291146510.1344-100000@penguin.transmeta.com>

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

Sun Jun  2 03:31:56 CEST 2002 ide-clean-80

- Sanitize the handling of the ioctl's and fix a bug on the way in dealing with
   the WIN_SMART command where arguments where exchanged.

- Finally sanitize ioctl further until it turned out that we could get rid of
   the special request type REQ_DRIVE_CMD entierly. We are now using
   consistently REQ_DRIVE_ACB.

   One hidden code path less again!

- Realize the ide_end_drive_cmd can be on the REQ_DRIVE_ACB only for ioctl() to
   a disk. Eliminate it's usage from device type driver modules.

- Remove command member from struct  hd_drive_task_hdr and place it in strcut
   ata_taskfile. It is not common between the normal register file and HOB.

   We will have to introduce some helper functions for particular command types.


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

diff -urN linux-2.5.19/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.5.19/drivers/block/ll_rw_blk.c	2002-05-29 20:42:46.000000000 +0200
+++ linux/drivers/block/ll_rw_blk.c	2002-06-02 06:33:53.000000000 +0200
@@ -490,11 +490,21 @@
 	}
 }
 
-static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER",
-			   "REQ_CMD", "REQ_NOMERGE", "REQ_STARTED",
-			   "REQ_DONTPREP", "REQ_QUEUED", "REQ_DRIVE_CMD",
-			   "REQ_DRIVE_ACB", "REQ_PC", "REQ_BLOCK_PC",
-			   "REQ_SENSE", "REQ_SPECIAL" };
+static char *rq_flags[] = {
+	"REQ_RW",
+	"REQ_RW_AHEAD",
+	"REQ_BARRIER",
+	"REQ_CMD",
+	"REQ_NOMERGE",
+	"REQ_STARTED",
+	"REQ_DONTPREP",
+	"REQ_QUEUED",
+	"REQ_DRIVE_ACB",
+	"REQ_PC",
+	"REQ_BLOCK_PC",
+	"REQ_SENSE",
+	"REQ_SPECIAL"
+};
 
 void blk_dump_rq_flags(struct request *rq, char *msg)
 {
diff -urN linux-2.5.19/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.19/drivers/ide/ide.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-06-02 07:09:29.000000000 +0200
@@ -395,38 +395,30 @@
  *
  * Should be called under lock held.
  */
-void ide_end_drive_cmd(struct ata_device *drive, struct request *rq, u8 err)
+void ide_end_drive_cmd(struct ata_device *drive, struct request *rq)
 {
-	if (rq->flags & REQ_DRIVE_CMD) {
-		u8 *args = rq->buffer;
-		rq->errors = !ata_status(drive, READY_STAT, BAD_STAT);
-		if (args) {
-			args[0] = drive->status;
-			args[1] = err;
-			args[2] = IN_BYTE(IDE_NSECTOR_REG);
-		}
-	} else if (rq->flags & REQ_DRIVE_ACB) {
-		struct ata_taskfile *args = rq->special;
+	if (rq->flags & REQ_DRIVE_ACB) {
+		struct ata_taskfile *ar = rq->special;
 
 		rq->errors = !ata_status(drive, READY_STAT, BAD_STAT);
-		if (args) {
-			args->taskfile.feature = err;
-			args->taskfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
-			args->taskfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
-			args->taskfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
-			args->taskfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
-			args->taskfile.device_head = IN_BYTE(IDE_SELECT_REG);
-			args->taskfile.command = drive->status;
+		if (ar) {
+			ar->taskfile.feature = IN_BYTE(IDE_ERROR_REG);
+			ar->taskfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
+			ar->taskfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
+			ar->taskfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
+			ar->taskfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
+			ar->taskfile.device_head = IN_BYTE(IDE_SELECT_REG);
+			ar->cmd = drive->status;
 			if ((drive->id->command_set_2 & 0x0400) &&
 			    (drive->id->cfs_enable_2 & 0x0400) &&
 			    (drive->addressing == 1)) {
 				/* The following command goes to the hob file! */
 				OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
-				args->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
-				args->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
-				args->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
-				args->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
-				args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
+				ar->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
+				ar->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
+				ar->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
+				ar->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
+				ar->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
 			}
 		}
 	}
@@ -583,7 +575,7 @@
 
 		memset(&args, 0, sizeof(args));
 		args.taskfile.sector_count = drive->sect;
-		args.taskfile.command = WIN_RESTORE;
+		args.cmd = WIN_RESTORE;
 		args.handler = recal_intr;
 		ata_taskfile(drive, &args, NULL);
 	}
@@ -602,10 +594,12 @@
 	err = ide_dump_status(drive, rq, msg, stat);
 	if (!drive || !rq)
 		return ide_stopped;
+
 	/* retry only "normal" I/O: */
 	if (!(rq->flags & REQ_CMD)) {
 		rq->errors = 1;
-		ide_end_drive_cmd(drive, rq, err);
+		ide_end_drive_cmd(drive, rq);
+
 		return ide_stopped;
 	}
 	/* other bits are useless when BUSY */
@@ -649,30 +643,6 @@
 }
 
 /*
- * Invoked on completion of a special DRIVE_CMD.
- */
-static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *rq)
-{
-	u8 *args = rq->buffer;
-
-	ide__sti();	/* local CPU only */
-	if (!ata_status(drive, 0, DRQ_STAT) && args && args[3]) {
-		int retries = 10;
-
-		ata_read(drive, &args[4], args[3] * SECTOR_WORDS);
-
-		while (!ata_status(drive, 0, BUSY_STAT) && retries--)
-			udelay(100);
-	}
-
-	if (!ata_status(drive, READY_STAT, BAD_STAT))
-		return ata_error(drive, rq, __FUNCTION__); /* already calls ide_end_drive_cmd */
-	ide_end_drive_cmd(drive, rq, GET_ERR());
-
-	return ide_stopped;
-}
-
-/*
  * Busy-wait for the drive status to be not "busy".  Check then the status for
  * all of the "good" bits and none of the "bad" bits, and if all is okay it
  * returns 0.  All other cases return 1 after invoking error handler -- caller
@@ -775,53 +745,20 @@
 		}
 	}
 
-	/* This issues a special drive command, usually initiated by ioctl()
-	 * from the external hdparm program.
+	/* This issues a special drive command.
 	 */
 	if (rq->flags & REQ_DRIVE_ACB) {
-		struct ata_taskfile *args = rq->special;
+		struct ata_taskfile *ar = rq->special;
 
-		if (!(args))
+		if (!(ar))
 			goto args_error;
 
-		ata_taskfile(drive, args, NULL);
-
-		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;
-	}
+		ata_taskfile(drive, ar, NULL);
 
-	if (rq->flags & REQ_DRIVE_CMD) {
-		u8 *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
-		ide_set_handler(drive, drive_cmd_intr, WAIT_CMD, NULL);
-		ata_irq_enable(drive, 1);
-		ata_mask(drive);
-		if (args[0] == WIN_SMART) {
-			struct hd_drive_task_hdr regfile;
-			regfile.feature = args[2];
-			regfile.sector_count = args[3];
-			regfile.sector_number = args[1];
-			regfile.low_cylinder = 0x4f;
-			regfile.high_cylinder = 0xc2;
-			ata_out_regfile(drive, &regfile);
-		} else {
-			OUT_BYTE(args[2], IDE_FEATURE_REG);
-			OUT_BYTE(args[1], IDE_NSECTOR_REG);
-		}
-		OUT_BYTE(args[0], IDE_COMMAND_REG);
+		if (((ar->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
+		     (ar->command_type == IDE_DRIVE_TASK_OUT)) &&
+				ar->prehandler && ar->handler)
+			return ar->prehandler(drive, rq);
 
 		return ide_started;
 	}
@@ -863,7 +800,7 @@
 #ifdef DEBUG
 	printk("%s: DRIVE_CMD (null)\n", drive->name);
 #endif
-	ide_end_drive_cmd(drive, rq, GET_ERR());
+	ide_end_drive_cmd(drive, rq);
 
 	return ide_stopped;
 }
diff -urN linux-2.5.19/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.19/drivers/ide/ide-disk.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-06-02 07:18:26.000000000 +0200
@@ -170,7 +170,7 @@
 
 	args.taskfile.device_head = head;
 	args.taskfile.device_head |= drive->select.all;
-	args.taskfile.command =  get_command(drive, rq_data_dir(rq));
+	args.cmd =  get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -211,7 +211,7 @@
 
 	args.taskfile.device_head = ((block >> 8) & 0x0f);
 	args.taskfile.device_head |= drive->select.all;
-	args.taskfile.command = get_command(drive, rq_data_dir(rq));
+	args.cmd = get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -264,7 +264,7 @@
 	args.hobfile.high_cylinder = (block >>= 8);	/* hi  lba */
 	args.hobfile.device_head = drive->select.all;
 
-	args.taskfile.command = get_command(drive, rq_data_dir(rq));
+	args.cmd = get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -355,7 +355,7 @@
 
 		memset(&args, 0, sizeof(args));
 
-		args.taskfile.command = WIN_DOORLOCK;
+		args.cmd = WIN_DOORLOCK;
 		ide_cmd_type_parser(&args);
 
 		/*
@@ -377,9 +377,9 @@
 	memset(&args, 0, sizeof(args));
 
 	if (drive->id->cfs_enable_2 & 0x2400)
-		args.taskfile.command = WIN_FLUSH_CACHE_EXT;
+		args.cmd = WIN_FLUSH_CACHE_EXT;
 	else
-		args.taskfile.command = WIN_FLUSH_CACHE;
+		args.cmd = WIN_FLUSH_CACHE;
 
 	ide_cmd_type_parser(&args);
 
@@ -395,7 +395,7 @@
 		invalidate_bdev(inode->i_bdev, 0);
 
 		memset(&args, 0, sizeof(args));
-		args.taskfile.command = WIN_DOORUNLOCK;
+		args.cmd = WIN_DOORUNLOCK;
 		ide_cmd_type_parser(&args);
 
 		if (drive->doorlocking &&
@@ -444,7 +444,7 @@
 
 	memset(&args, 0, sizeof(args));
 	args.taskfile.sector_count = arg;
-	args.taskfile.command	= WIN_SETMULT;
+	args.cmd = WIN_SETMULT;
 	ide_cmd_type_parser(&args);
 
 	if (!ide_raw_taskfile(drive, &args)) {
@@ -475,7 +475,7 @@
 
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature	= (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
-	args.taskfile.command	= WIN_SETFEATURES;
+	args.cmd = WIN_SETFEATURES;
 	ide_cmd_type_parser(&args);
 	ide_raw_taskfile(drive, &args);
 
@@ -489,7 +489,7 @@
 	struct ata_taskfile args;
 
 	memset(&args, 0, sizeof(args));
-	args.taskfile.command = WIN_STANDBYNOW1;
+	args.cmd = WIN_STANDBYNOW1;
 	ide_cmd_type_parser(&args);
 
 	return ide_raw_taskfile(drive, &args);
@@ -502,7 +502,7 @@
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
 	args.taskfile.sector_count = arg;
-	args.taskfile.command = WIN_SETFEATURES;
+	args.cmd = WIN_SETFEATURES;
 	ide_cmd_type_parser(&args);
 	ide_raw_taskfile(drive, &args);
 
@@ -622,14 +622,14 @@
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(args));
 	args.taskfile.device_head = 0x40;
-	args.taskfile.command = WIN_READ_NATIVE_MAX;
+	args.cmd = WIN_READ_NATIVE_MAX;
 	args.handler = task_no_data_intr;
 
 	/* submit command request */
 	ide_raw_taskfile(drive, &args);
 
 	/* if OK, compute maximum address value */
-	if ((args.taskfile.command & 0x01) == 0) {
+	if ((args.cmd & 0x01) == 0) {
 		addr = ((args.taskfile.device_head & 0x0f) << 24)
 		     | (args.taskfile.high_cylinder << 16)
 		     | (args.taskfile.low_cylinder <<  8)
@@ -650,14 +650,14 @@
 	memset(&args, 0, sizeof(args));
 
 	args.taskfile.device_head = 0x40;
-	args.taskfile.command = WIN_READ_NATIVE_MAX_EXT;
+	args.cmd = WIN_READ_NATIVE_MAX_EXT;
 	args.handler = task_no_data_intr;
 
         /* submit command request */
         ide_raw_taskfile(drive, &args);
 
 	/* if OK, compute maximum address value */
-	if ((args.taskfile.command & 0x01) == 0) {
+	if ((args.cmd & 0x01) == 0) {
 		u32 high = (args.hobfile.high_cylinder << 16) |
 			   (args.hobfile.low_cylinder << 8) |
 			    args.hobfile.sector_number;
@@ -691,12 +691,12 @@
 	args.taskfile.high_cylinder = (addr_req >> 16);
 
 	args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
-	args.taskfile.command = WIN_SET_MAX;
+	args.cmd = WIN_SET_MAX;
 	args.handler = task_no_data_intr;
 	/* submit command request */
 	ide_raw_taskfile(drive, &args);
 	/* if OK, read new maximum address value */
-	if ((args.taskfile.command & 0x01) == 0) {
+	if ((args.cmd & 0x01) == 0) {
 		addr_set = ((args.taskfile.device_head & 0x0f) << 24)
 			 | (args.taskfile.high_cylinder << 16)
 			 | (args.taskfile.low_cylinder <<  8)
@@ -719,7 +719,7 @@
 	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.cmd = WIN_SET_MAX_EXT;
 
 	args.hobfile.sector_number = (addr_req >>= 8);
 	args.hobfile.low_cylinder = (addr_req >>= 8);
@@ -731,7 +731,7 @@
 	/* submit command request */
 	ide_raw_taskfile(drive, &args);
 	/* if OK, compute maximum address value */
-	if ((args.taskfile.command & 0x01) == 0) {
+	if ((args.cmd & 0x01) == 0) {
 		u32 high = (args.hobfile.high_cylinder << 16) |
 			   (args.hobfile.low_cylinder << 8) |
 			    args.hobfile.sector_number;
diff -urN linux-2.5.19/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.19/drivers/ide/ide-floppy.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c	2002-06-02 06:51:41.000000000 +0200
@@ -620,7 +620,7 @@
 
 #if IDEFLOPPY_DEBUG_LOG
 	printk (KERN_INFO "Reached idefloppy_end_request\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+#endif
 
 	switch (uptodate) {
 		case 0: error = IDEFLOPPY_ERROR_GENERAL; break;
@@ -632,12 +632,16 @@
 	/* Why does this happen? */
 	if (!rq)
 		return 0;
+
 	if (!(rq->flags & IDEFLOPPY_RQ)) {
 		ide_end_request(drive, rq, uptodate);
 		return 0;
 	}
+
 	rq->errors = error;
-	ide_end_drive_cmd (drive, rq, 0);
+	blkdev_dequeue_request(rq);
+	drive->rq = NULL;
+	end_that_request_last(rq);
 
 	return 0;
 }
diff -urN linux-2.5.19/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.19/drivers/ide/ide-tape.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/ide/ide-tape.c	2002-06-02 06:52:11.000000000 +0200
@@ -1864,9 +1864,12 @@
 				idetape_increase_max_pipeline_stages (drive);
 		}
 	}
-	ide_end_drive_cmd(drive, rq, 0);
+	blkdev_dequeue_request(rq);
+	drive->rq = NULL;
+	end_that_request_last(rq);
+
 	if (remove_stage)
-		idetape_remove_stage_head (drive);
+		idetape_remove_stage_head(drive);
 	if (tape->active_data_request == NULL)
 		clear_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags);
 	spin_unlock_irqrestore(&tape->spinlock, flags);
diff -urN linux-2.5.19/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.19/drivers/ide/ide-taskfile.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-06-02 07:07:28.000000000 +0200
@@ -311,34 +311,34 @@
 }
 
 ide_startstop_t ata_taskfile(struct ata_device *drive,
-		struct ata_taskfile *args, struct request *rq)
+		struct ata_taskfile *ar, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
 
 	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (args->handler != task_mulout_intr) {
+	if (ar->handler != task_mulout_intr) {
 		ata_irq_enable(drive, 1);
 		ata_mask(drive);
 	}
 
 	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) &&
 	    (drive->addressing == 1))
-		ata_out_regfile(drive, &args->hobfile);
+		ata_out_regfile(drive, &ar->hobfile);
 
-	ata_out_regfile(drive, &args->taskfile);
+	ata_out_regfile(drive, &ar->taskfile);
 
 	{
 		u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
-		OUT_BYTE((args->taskfile.device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
+		OUT_BYTE((ar->taskfile.device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
 	}
-	if (args->handler != NULL) {
+	if (ar->handler != NULL) {
 
 		/* This is apparently supposed to reset the wait timeout for
 		 * the interrupt to accur.
 		 */
 
-		ide_set_handler(drive, args->handler, WAIT_CMD, NULL);
-		OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+		ide_set_handler(drive, ar->handler, WAIT_CMD, NULL);
+		OUT_BYTE(ar->cmd, IDE_COMMAND_REG);
 
 		/*
 		 * Warning check for race between handler and prehandler for
@@ -346,8 +346,8 @@
 		 * inside the boundaries of the seek, we should be okay.
 		 */
 
-		if (args->prehandler != NULL)
-			return args->prehandler(drive, rq);
+		if (ar->prehandler != NULL)
+			return ar->prehandler(drive, rq);
 	} else {
 		/*
 		 * FIXME: this is a gross hack, need to unify tcq dma proc and
@@ -358,21 +358,20 @@
 			return ide_started;
 
 		/* for dma commands we don't set the handler */
-		if (args->taskfile.command == WIN_WRITEDMA
-		 || args->taskfile.command == WIN_WRITEDMA_EXT)
+		if (ar->cmd == WIN_WRITEDMA  || ar->cmd == WIN_WRITEDMA_EXT)
 			return !udma_write(drive, rq);
-		else if (args->taskfile.command == WIN_READDMA
-		      || args->taskfile.command == WIN_READDMA_EXT)
+		else if (ar->cmd == WIN_READDMA
+		      || ar->cmd == WIN_READDMA_EXT)
 			return !udma_read(drive, rq);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
-		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
-		      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
-		      || args->taskfile.command == WIN_READDMA_QUEUED
-		      || args->taskfile.command == WIN_READDMA_QUEUED_EXT)
+		else if (ar->cmd == WIN_WRITEDMA_QUEUED
+		      || ar->cmd == WIN_WRITEDMA_QUEUED_EXT
+		      || ar->cmd == WIN_READDMA_QUEUED
+		      || ar->cmd == WIN_READDMA_QUEUED_EXT)
 			return udma_tcq_taskfile(drive, rq);
 #endif
 		else {
-			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
+			printk("ata_taskfile: unknown command %x\n", ar->cmd);
 			return ide_stopped;
 		}
 	}
@@ -396,18 +395,18 @@
  */
 ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
 {
-	struct ata_taskfile *args = rq->special;
+	struct ata_taskfile *ar = rq->special;
 
 	ide__sti();	/* local CPU only */
 
 	if (!ata_status(drive, READY_STAT, BAD_STAT)) {
 		/* Keep quiet for NOP because it is expected to fail. */
-		if (args && args->taskfile.command != WIN_NOP)
+		if (ar && ar->cmd != WIN_NOP)
 			return ata_error(drive, rq, __FUNCTION__);
 	}
 
-	if (args)
-		ide_end_drive_cmd(drive, rq, GET_ERR());
+	if (ar)
+		ide_end_drive_cmd(drive, rq);
 
 	return ide_stopped;
 }
@@ -466,8 +465,8 @@
 	}
 
 	/* (ks/hs): Fixed Multi Write */
-	if ((args->taskfile.command != WIN_MULTWRITE) &&
-	    (args->taskfile.command != WIN_MULTWRITE_EXT)) {
+	if ((args->cmd != WIN_MULTWRITE) &&
+	    (args->cmd != WIN_MULTWRITE_EXT)) {
 		unsigned long flags;
 		char *buf = ide_map_rq(rq, &flags);
 		/* For Write_sectors we need to stuff the first sector */
@@ -569,7 +568,7 @@
 	args->prehandler = NULL;
 	args->handler = NULL;
 
-	switch(args->taskfile.command) {
+	switch (args->cmd) {
 		case WIN_IDENTIFY:
 		case WIN_PIDENTIFY:
 			args->handler = task_in_intr;
@@ -817,13 +816,6 @@
 
 	memset(&rq, 0, sizeof(rq));
 	rq.flags = REQ_DRIVE_ACB;
-
-#if 0
-	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
-		rq.current_nr_sectors = rq.nr_sectors
-			= (args->hobfile.sector_count << 8)
-			| args->taskfile.sector_count;
-#endif
 	rq.special = args;
 
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
diff -urN linux-2.5.19/drivers/ide/ioctl.c linux/drivers/ide/ioctl.c
--- linux-2.5.19/drivers/ide/ioctl.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/ide/ioctl.c	2002-06-02 07:10:02.000000000 +0200
@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/blkpg.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 #include <linux/cdrom.h>
 #include <linux/device.h>
 
@@ -33,42 +34,67 @@
 #include "ioctl.h"
 
 /*
+ * Invoked on completion of a special DRIVE_CMD.
+ */
+static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *rq)
+{
+	struct ata_taskfile *ar = rq->special;
+
+	ide__sti();	/* local CPU only */
+	if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) {
+		int retries = 10;
+
+		ata_read(drive, rq->buffer, ar->taskfile.sector_number * SECTOR_WORDS);
+
+		while (!ata_status(drive, 0, BUSY_STAT) && retries--)
+			udelay(100);
+	}
+
+	if (!ata_status(drive, READY_STAT, BAD_STAT))
+		return ata_error(drive, rq, __FUNCTION__); /* already calls ide_end_drive_cmd */
+	ide_end_drive_cmd(drive, rq);
+
+	return ide_stopped;
+}
+
+/*
  * Implement generic ioctls invoked from userspace to imlpement specific
  * functionality.
  *
  * Unfortunately every single low level programm out there is using this
  * interface.
  */
-static int cmd_ioctl(struct ata_device *drive, unsigned long arg)
+static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
 {
 	int err = 0;
 	u8 vals[4];
 	u8 *argbuf = vals;
-	u8 pio = 0;
 	int argsize = 4;
 	struct ata_taskfile args;
 	struct request rq;
 
-	memset(&rq, 0, sizeof(rq));
-	rq.flags = REQ_DRIVE_CMD;
-
-	/* If empty parameter file - wait for drive ready.
-	 */
-	if (!arg)
-		return ide_do_drive_cmd(drive, &rq, ide_wait);
-
 	/* Second phase.
 	 */
 	if (copy_from_user(vals, (void *)arg, 4))
 		return -EFAULT;
 
+	memset(&rq, 0, sizeof(rq));
+	rq.flags = REQ_DRIVE_ACB;
+
+	memset(&args, 0, sizeof(args));
+
 	args.taskfile.feature = vals[2];
-	args.taskfile.sector_count = vals[3];
-	args.taskfile.sector_number = vals[1];
-	args.taskfile.low_cylinder = 0x00;
-	args.taskfile.high_cylinder = 0x00;
+	args.taskfile.sector_count = vals[1];
+	args.taskfile.sector_number = vals[3];
+	if (vals[0] == WIN_SMART) {
+		args.taskfile.low_cylinder = 0x4f;
+		args.taskfile.high_cylinder = 0xc2;
+	} else {
+		args.taskfile.low_cylinder = 0x00;
+		args.taskfile.high_cylinder = 0x00;
+	}
 	args.taskfile.device_head = 0x00;
-	args.taskfile.command = vals[0];
+	args.cmd = vals[0];
 
 	if (vals[3]) {
 		argsize = 4 + (SECTOR_WORDS * 4 * vals[3]);
@@ -79,63 +105,18 @@
 		memset(argbuf + 4, 0, argsize - 4);
 	}
 
-	/*
-	 * Always make sure the transfer reate has been setup.
-	 *
-	 * FIXME: what about setting up the drive with ->tuneproc?
-	 *
-	 * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
-	 * 1 : Safe to update drive->id DMA registers.
-	 * 0 : OOPs not allowed.
-	 */
-	if ((args.taskfile.command == WIN_SETFEATURES) &&
-	    (args.taskfile.sector_number >= XFER_SW_DMA_0) &&
-	    (args.taskfile.feature == SETFEATURES_XFER) &&
-	    (drive->id->dma_ultra ||
-	     drive->id->dma_mword ||
-	     drive->id->dma_1word)) {
-		pio = vals[1];
-		/*
-		 * Verify that we are doing an approved SETFEATURES_XFER with
-		 * respect to the hardware being able to support request.
-		 * Since some hardware can improperly report capabilties, we
-		 * check to see if the host adapter in combination with the
-		 * device (usually a disk) properly detect and acknowledge each
-		 * end of the ribbon.
-		 */
-		if (args.taskfile.sector_number > XFER_UDMA_2) {
-			if (!drive->channel->udma_four) {
-				printk(KERN_WARNING "%s: Speed warnings UDMA > 2 is not functional.\n",
-						drive->channel->name);
-				goto abort;
-			}
-#ifndef CONFIG_IDEDMA_IVB
-			if (!(drive->id->hw_config & 0x6000))
-#else
-			if (!(drive->id->hw_config & 0x2000) ||
-			    !(drive->id->hw_config & 0x4000))
-#endif
-			{
-				printk(KERN_WARNING "%s: Speed warnings UDMA > 2 is not functional.\n",
-						drive->name);
-				goto abort;
-			}
-		}
-	}
-
 	/* Issue ATA command and wait for completion.
 	 */
-	rq.buffer = argbuf;
+	args.handler = drive_cmd_intr;
+
+	rq.buffer = argbuf + 4;
+	rq.special = &args;
 	err = ide_do_drive_cmd(drive, &rq, ide_wait);
 
-	if (!err && pio) {
-		/* active-retuning-calls future */
-		/* FIXME: what about the setup for the drive?! */
-		if (drive->channel->speedproc)
-			drive->channel->speedproc(drive, pio);
-	}
+	argbuf[0] = drive->status;
+	argbuf[1] = args.taskfile.feature;
+	argbuf[2] = args.taskfile.sector_count;
 
-abort:
 	if (copy_to_user((void *)arg, argbuf, argsize))
 		err = -EFAULT;
 
@@ -153,7 +134,6 @@
 {
 	unsigned int major, minor;
 	struct ata_device *drive;
-//	struct request rq;
 	kdev_t dev;
 
 	dev = inode->i_rdev;
@@ -354,10 +334,14 @@
 			return 0;
 
 		case HDIO_DRIVE_CMD:
-			if (!capable(CAP_SYS_RAWIO))
-				return -EACCES;
+			if (!arg) {
+				if (ide_spin_wait_hwgroup(drive))
+					return -EBUSY;
+				else
+					return 0;
+			}
 
-			return cmd_ioctl(drive, arg);
+			return do_cmd_ioctl(drive, arg);
 
 		/*
 		 * uniform packet command handling
diff -urN linux-2.5.19/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c
--- linux-2.5.19/drivers/ide/pcidma.c	2002-06-01 23:17:28.000000000 +0200
+++ linux/drivers/ide/pcidma.c	2002-06-02 07:11:16.000000000 +0200
@@ -541,9 +541,10 @@
 
 	ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
 	if ((rq->flags & REQ_DRIVE_ACB) && (drive->addressing == 1)) {
+		/* FIXME: this should never happen */
 		struct ata_taskfile *args = rq->special;
 
-		outb(args->taskfile.command, IDE_COMMAND_REG);
+		outb(args->cmd, IDE_COMMAND_REG);
 	} else if (drive->addressing) {
 		outb(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
 	} else {
diff -urN linux-2.5.19/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.19/drivers/ide/pdc4030.c	2002-06-01 23:17:28.000000000 +0200
+++ linux/drivers/ide/pdc4030.c	2002-06-02 07:13:34.000000000 +0200
@@ -630,7 +630,7 @@
 	outb(taskfile->low_cylinder, IDE_LCYL_REG);
 	outb(taskfile->high_cylinder, IDE_HCYL_REG);
 	outb(taskfile->device_head, IDE_SELECT_REG);
-	outb(taskfile->command, IDE_COMMAND_REG);
+	outb(args->cmd, IDE_COMMAND_REG);
 
 	switch (rq_data_dir(rq)) {
 	case READ:
@@ -708,7 +708,7 @@
 	args.taskfile.low_cylinder	= (block>>=8);
 	args.taskfile.high_cylinder	= (block>>=8);
 	args.taskfile.device_head	= ((block>>8)&0x0f)|drive->select.all;
-	args.taskfile.command		= (rq_data_dir(rq)==READ)?PROMISE_READ:PROMISE_WRITE;
+	args.cmd			= (rq_data_dir(rq)==READ)?PROMISE_READ:PROMISE_WRITE;
 
 	/* We can't call ide_cmd_type_parser here, since it won't understand
 	   our command, but that doesn't matter, since we don't use the
diff -urN linux-2.5.19/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.19/drivers/ide/tcq.c	2002-06-01 23:17:28.000000000 +0200
+++ linux/drivers/ide/tcq.c	2002-06-02 07:12:17.000000000 +0200
@@ -60,7 +60,7 @@
 	struct ata_taskfile *args = rq->special;
 
 	ide__sti();
-	ide_end_drive_cmd(drive, rq, GET_ERR());
+	ide_end_drive_cmd(drive, rq);
 	kfree(args);
 
 	return ide_stopped;
@@ -118,7 +118,7 @@
 	BUG_ON(!rq);
 
 	rq->special = args;
-	args->taskfile.command = WIN_NOP;
+	args->cmd = WIN_NOP;
 	args->handler = tcq_nop_handler;
 	args->command_type = IDE_DRIVE_TASK_NO_DATA;
 
@@ -407,7 +407,7 @@
 	memset(&args, 0, sizeof(args));
 
 	args.taskfile.feature = 0x01;
-	args.taskfile.command = WIN_NOP;
+	args.cmd = WIN_NOP;
 	ide_cmd_type_parser(&args);
 
 	/*
@@ -442,7 +442,7 @@
 
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = SETFEATURES_EN_WCACHE;
-	args.taskfile.command = WIN_SETFEATURES;
+	args.cmd = WIN_SETFEATURES;
 	ide_cmd_type_parser(&args);
 
 	if (ide_raw_taskfile(drive, &args)) {
@@ -456,7 +456,7 @@
 	 */
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = SETFEATURES_DIS_RI;
-	args.taskfile.command = WIN_SETFEATURES;
+	args.cmd = WIN_SETFEATURES;
 	ide_cmd_type_parser(&args);
 
 	if (ide_raw_taskfile(drive, &args)) {
@@ -470,7 +470,7 @@
 	 */
 	memset(&args, 0, sizeof(args));
 	args.taskfile.feature = SETFEATURES_EN_SI;
-	args.taskfile.command = WIN_SETFEATURES;
+	args.cmd = WIN_SETFEATURES;
 	ide_cmd_type_parser(&args);
 
 	if (ide_raw_taskfile(drive, &args)) {
@@ -554,7 +554,7 @@
 	ata_irq_enable(drive, 0);
 #endif
 
-	OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+	OUT_BYTE(args->cmd, IDE_COMMAND_REG);
 
 	if (wait_altstat(drive, &stat, BUSY_STAT)) {
 		ide_dump_status(drive, rq, "queued start", stat);
diff -urN linux-2.5.19/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.19/drivers/scsi/ide-scsi.c	2002-06-02 07:28:28.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c	2002-06-02 04:48:47.000000000 +0200
@@ -242,7 +242,11 @@
 		ide_end_request(drive, rq, uptodate);
 		return 0;
 	}
-	ide_end_drive_cmd(drive, rq, 0);
+
+	blkdev_dequeue_request(rq);
+	drive->rq = NULL;
+	end_that_request_last(rq);
+
 	if (rq->errors >= ERROR_MAX) {
 		pc->s.scsi_cmd->result = DID_ERROR << 16;
 		if (log)
diff -urN linux-2.5.19/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.5.19/include/linux/blkdev.h	2002-05-29 20:42:49.000000000 +0200
+++ linux/include/linux/blkdev.h	2002-06-02 06:33:55.000000000 +0200
@@ -81,7 +81,6 @@
 	/*
 	 * for ATA/ATAPI devices
 	 */
-	__REQ_DRIVE_CMD,
 	__REQ_DRIVE_ACB,
 
 	__REQ_PC,	/* packet command (special) */
@@ -101,7 +100,6 @@
 #define REQ_STARTED	(1 << __REQ_STARTED)
 #define REQ_DONTPREP	(1 << __REQ_DONTPREP)
 #define REQ_QUEUED	(1 << __REQ_QUEUED)
-#define REQ_DRIVE_CMD	(1 << __REQ_DRIVE_CMD)
 #define REQ_DRIVE_ACB	(1 << __REQ_DRIVE_ACB)
 #define REQ_PC		(1 << __REQ_PC)
 #define REQ_BLOCK_PC	(1 << __REQ_BLOCK_PC)
diff -urN linux-2.5.19/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.5.19/include/linux/hdreg.h	2002-06-02 07:28:28.000000000 +0200
+++ linux/include/linux/hdreg.h	2002-06-02 07:20:57.000000000 +0200
@@ -74,16 +74,12 @@
 #define IDE_DRIVE_TASK_RAW_WRITE	4
 
 struct hd_drive_task_hdr {
-	u8 data;
 	u8 feature;
 	u8 sector_count;
 	u8 sector_number;
 	u8 low_cylinder;
 	u8 high_cylinder;
 	u8 device_head;
-
-	/* FXIME: Consider moving this out from here. */
-	u8 command;
 } __attribute__((packed));
 
 /*
diff -urN linux-2.5.19/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.19/include/linux/ide.h	2002-06-02 07:28:28.000000000 +0200
+++ linux/include/linux/ide.h	2002-06-02 07:21:08.000000000 +0200
@@ -253,11 +253,11 @@
 	unsigned all			: 8;	/* all of the bits together */
 	struct {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-		unsigned XXX_head	: 4;	/* always zeros here */
+		unsigned head		: 4;	/* always zeros here */
 		unsigned unit		: 1;	/* drive select number: 0/1 */
-		unsigned XXX_bit5	: 1;	/* always 1 */
+		unsigned bit5		: 1;	/* always 1 */
 		unsigned lba		: 1;	/* using LBA instead of CHS */
-		unsigned XXX_bit7	: 1;	/* always 1 */
+		unsigned bit7		: 1;	/* always 1 */
 #elif defined(__BIG_ENDIAN_BITFIELD)
 		unsigned bit7		: 1;
 		unsigned lba		: 1;
@@ -666,11 +666,12 @@
 /*
  * Clean up after success/failure of an explicit drive cmd.
  */
-extern void ide_end_drive_cmd(struct ata_device *, struct request *, u8);
+extern void ide_end_drive_cmd(struct ata_device *, struct request *);
 
 struct ata_taskfile {
 	struct hd_drive_task_hdr taskfile;
 	struct hd_drive_task_hdr  hobfile;
+	u8 cmd;					/* actual ATA command */
 	int command_type;
 	ide_startstop_t (*prehandler)(struct ata_device *, struct request *);
 	ide_startstop_t (*handler)(struct ata_device *, struct request *);

  parent reply	other threads:[~2002-06-02  7:06 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-05-29 18:50 Linux 2.5.19 Linus Torvalds
2002-05-29 19:42 ` Jason Lunz
2002-05-29 20:17 ` Russell King
2002-05-29 20:38   ` Eli Carter
2002-05-29 20:44   ` James Simmons
2002-05-29 20:44     ` James Simmons
2002-05-29 20:47     ` Russell King
2002-05-29 20:47       ` Russell King
2002-05-29 22:22       ` Martin Dalecki
2002-05-29 22:22         ` Martin Dalecki
2002-05-29 23:25         ` Russell King
2002-05-29 23:25           ` Russell King
2002-05-29 22:42           ` Martin Dalecki
2002-05-29 22:42             ` Martin Dalecki
2002-05-29 23:52             ` Russell King
2002-05-29 23:52               ` Russell King
2002-05-29 23:00               ` Martin Dalecki
2002-05-29 23:00                 ` Martin Dalecki
2002-05-29 22:43       ` James Simmons
2002-05-29 22:43         ` James Simmons
2002-05-29 22:29         ` Martin Dalecki
2002-05-29 22:29           ` Martin Dalecki
2002-05-29 23:31           ` Russell King
2002-05-29 23:31             ` Russell King
2002-05-30  5:10             ` Framebuffer policy [ was Re: Linux 2.5.19] James Simmons
2002-05-30  5:10               ` James Simmons
2002-05-29 20:37 ` [PATCH] Missing include in drivers/base/bus.c and drivers/pci/pci-driver.c Tom Rini
2002-05-29 22:24 ` Linux 2.5.19 Tom Rini
2002-05-30  1:29   ` Rusty Russell
2002-05-29 23:01 ` Matthias Andree
2002-05-29 23:35 ` J.A. Magallon
2002-05-30 14:15 ` [PATCH] 2.5.19 blk.h and more about the ugly kids Martin Dalecki
2002-05-31 11:09 ` [PATCH] 2.5.19 IDE 76 Martin Dalecki
2002-05-31 18:17 ` [PATCH] 2.5.19 IDE 77 Martin Dalecki
2002-06-02  6:04 ` [PATCH] 2.5.19 IDE 78 Martin Dalecki
2002-06-02  8:16   ` Paul Dickson
2002-06-02  9:21   ` Paul Mackerras
2002-06-02 19:34     ` Martin Dalecki
2002-06-02 21:36       ` Bartlomiej Zolnierkiewicz
2002-06-02 21:59       ` Paul Mackerras
2002-06-03  4:47         ` Martin Dalecki
2002-06-02  6:06 ` [PATCH} 2.5.19 IDE 79 Martin Dalecki
2002-06-02  6:07 ` Martin Dalecki [this message]
2002-06-02 19:45 ` [PATCH] 2.5.19 IDE 81 Martin Dalecki
2002-06-02 20:13 ` [PATCH] 2.5.19 IDE 82 Martin Dalecki

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=3CF9B60C.3080506@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.