public inbox for linux-kernel@vger.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.7 IDE 23
Date: Thu, 28 Mar 2002 10:21:56 +0100	[thread overview]
Message-ID: <3CA2E0B4.9010006@evision-ventures.com> (raw)
In-Reply-To: <Pine.LNX.4.33.0203181243210.10517-100000@penguin.transmeta.com>

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

Mon Mar 18 19:02:07 CET 2002 ide-clean-23

- Support for additional Promise controller id's (PDC20276).

- Remove code duplication between do_rw_taskfile and do_taskfile.
   This will evolve into a more reasonable ata_command() function
   finally. The ata_taskfile function has far too many arguments, but
   I favour this over having two different code paths for getting
   actual data to the drive.

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

diff -urN linux-2.5.7-pre2/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.7-pre2/drivers/ide/ide-disk.c	Tue Mar 19 03:32:11 2002
+++ linux/drivers/ide/ide-disk.c	Tue Mar 19 03:25:58 2002
@@ -106,50 +106,6 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
-static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
-static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
-static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block);
-
-/*
- * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
- * 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)
-{
-	/*
-	 * Wait until all request have bin finished.
-	 */
-
-	while (drive->blocked) {
-		yield();
-		// panic("ide: Request while drive blocked?");
-	}
-
-	if (!(rq->flags & REQ_CMD)) {
-		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
-		ide_end_request(drive, 0);
-		return ide_stopped;
-	}
-
-	if (IS_PDC4030_DRIVE) {
-		extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
-
-		return promise_rw_disk(drive, rq, block);
-	}
-
-	/* 48-bit LBA */
-	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
-		return lba48_do_request(drive, rq, block);
-
-	/* 28-bit LBA */
-	if (drive->select.b.lba)
-		return lba28_do_request(drive, rq, block);
-
-	/* 28-bit CHS */
-	return chs_do_request(drive, rq, block);
-}
-
 static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
@@ -158,20 +114,38 @@
 	lba48bit = drive->addressing;
 #endif
 
-	if (cmd == READ) {
-		if (drive->using_dma)
-			return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
-		else if (drive->mult_count)
-			return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
-		else
-			return (lba48bit) ? WIN_READ_EXT : WIN_READ;
-	} else if (cmd == WRITE) {
-		if (drive->using_dma)
-			return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-		else if (drive->mult_count)
-			return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
-		else
-			return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
+	if (lba48bit) {
+		if (cmd == READ) {
+			if (drive->using_dma)
+				return WIN_READDMA_EXT;
+			else if (drive->mult_count)
+				return WIN_MULTREAD_EXT;
+			else
+				return WIN_READ_EXT;
+		} else if (cmd == WRITE) {
+			if (drive->using_dma)
+				return WIN_WRITEDMA_EXT;
+			else if (drive->mult_count)
+				return WIN_MULTWRITE_EXT;
+			else
+				return WIN_WRITE_EXT;
+		}
+	} else {
+		if (cmd == READ) {
+			if (drive->using_dma)
+				return WIN_READDMA;
+			else if (drive->mult_count)
+				return WIN_MULTREAD;
+			else
+				return WIN_READ;
+		} else if (cmd == WRITE) {
+			if (drive->using_dma)
+				return WIN_WRITEDMA;
+			else if (drive->mult_count)
+				return WIN_MULTWRITE;
+			else
+				return WIN_WRITE;
+		}
 	}
 	return WIN_NOP;
 }
@@ -183,8 +157,6 @@
 	ide_task_t			args;
 	int				sectors;
 
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
-
 	unsigned int track	= (block / drive->sect);
 	unsigned int sect	= (block % drive->sect) + 1;
 	unsigned int head	= (track % drive->head);
@@ -203,7 +175,7 @@
 	taskfile.high_cylinder	= (cyl>>8);
 	taskfile.device_head	= head;
 	taskfile.device_head	|= drive->select.all;
-	taskfile.command	= command;
+	taskfile.command	=  get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -221,7 +193,12 @@
 	args.block = block;
 	rq->special = &args;
 
-	return do_rw_taskfile(drive, &args);
+	return ata_taskfile(drive,
+			(struct hd_drive_task_hdr *) &args.tfRegister,
+			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			args.handler,
+			args.prehandler,
+			args.rq);
 }
 
 static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
@@ -231,8 +208,6 @@
 	ide_task_t			args;
 	int				sectors;
 
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
-
 	sectors = rq->nr_sectors;
 	if (sectors == 256)
 		sectors = 0;
@@ -246,7 +221,7 @@
 	taskfile.high_cylinder	= (block>>=8);
 	taskfile.device_head	= ((block>>8)&0x0f);
 	taskfile.device_head	|= drive->select.all;
-	taskfile.command	= command;
+	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -264,7 +239,12 @@
 	args.block = block;
 	rq->special = &args;
 
-	return do_rw_taskfile(drive, &args);
+	return ata_taskfile(drive,
+			(struct hd_drive_task_hdr *) &args.tfRegister,
+			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			args.handler,
+			args.prehandler,
+			args.rq);
 }
 
 /*
@@ -280,8 +260,6 @@
 	ide_task_t			args;
 	int				sectors;
 
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
-
 	memset(&taskfile, 0, sizeof(task_struct_t));
 	memset(&hobfile, 0, sizeof(hob_struct_t));
 
@@ -306,7 +284,7 @@
 	taskfile.device_head	= drive->select.all;
 	hobfile.device_head	= taskfile.device_head;
 	hobfile.control		= (drive->ctl|0x80);
-	taskfile.command	= command;
+	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -324,7 +302,52 @@
 	args.block = block;
 	rq->special = &args;
 
-	return do_rw_taskfile(drive, &args);
+	return ata_taskfile(drive,
+			(struct hd_drive_task_hdr *) &args.tfRegister,
+			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			args.handler,
+			args.prehandler,
+			args.rq);
+}
+
+/*
+ * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
+ * 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)
+{
+	/*
+	 * Wait until all request have bin finished.
+	 */
+
+	while (drive->blocked) {
+		yield();
+		// panic("ide: Request while drive blocked?");
+	}
+
+	if (!(rq->flags & REQ_CMD)) {
+		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
+		ide_end_request(drive, 0);
+		return ide_stopped;
+	}
+
+	if (IS_PDC4030_DRIVE) {
+		extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
+
+		return promise_rw_disk(drive, rq, block);
+	}
+
+	/* 48-bit LBA */
+	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
+		return lba48_do_request(drive, rq, block);
+
+	/* 28-bit LBA */
+	if (drive->select.b.lba)
+		return lba28_do_request(drive, rq, block);
+
+	/* 28-bit CHS */
+	return chs_do_request(drive, rq, block);
 }
 
 static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
@@ -333,10 +356,13 @@
 	if (drive->removable && drive->usage == 1) {
 		struct hd_drive_task_hdr taskfile;
 		struct hd_drive_hob_hdr hobfile;
+
 		memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
 		check_disk_change(inode->i_rdev);
 		taskfile.command = WIN_DOORLOCK;
+
 		/*
 		 * Ignore the return code from door_lock,
 		 * since the open() has already succeeded,
@@ -355,11 +381,10 @@
 	struct hd_drive_hob_hdr hobfile;
 	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
-	if (drive->id->cfs_enable_2 & 0x2400) {
+	if (drive->id->cfs_enable_2 & 0x2400)
 		taskfile.command	= WIN_FLUSH_CACHE_EXT;
-	} else {
+	else
 		taskfile.command	= WIN_FLUSH_CACHE;
-	}
 	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
 }
 
@@ -643,7 +668,7 @@
 			taskfile.command = WIN_SPECIFY;
 			handler	= set_geometry_intr;;
 		}
-		do_taskfile(drive, &taskfile, &hobfile, handler);
+		ata_taskfile(drive, &taskfile, &hobfile, handler, NULL, NULL);
 	} else if (s->b.recalibrate) {
 		s->b.recalibrate = 0;
 		if (!IS_PDC4030_DRIVE) {
@@ -653,7 +678,7 @@
 			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 			taskfile.sector_count	= drive->sect;
 			taskfile.command	= WIN_RESTORE;
-			do_taskfile(drive, &taskfile, &hobfile, recal_intr);
+			ata_taskfile(drive, &taskfile, &hobfile, recal_intr, NULL, NULL);
 		}
 	} else if (s->b.set_multmode) {
 		s->b.set_multmode = 0;
@@ -666,7 +691,7 @@
 			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 			taskfile.sector_count	= drive->mult_req;
 			taskfile.command	= WIN_SETMULT;
-			do_taskfile(drive, &taskfile, &hobfile, &set_multmode_intr);
+			ata_taskfile(drive, &taskfile, &hobfile, set_multmode_intr, NULL, NULL);
 		}
 	} else if (s->all) {
 		int special = s->all;
diff -urN linux-2.5.7-pre2/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.5.7-pre2/drivers/ide/ide-pci.c	Tue Mar 19 03:32:11 2002
+++ linux/drivers/ide/ide-pci.c	Tue Mar 19 00:52:41 2002
@@ -229,6 +229,7 @@
 	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ  | ATA_F_DMA },
 	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
 	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, pci_init_pdc202xx, ata66_pdc202xx,	ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
+	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, pci_init_pdc202xx, ata66_pdc202xx,	ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
 #endif
 #ifdef CONFIG_BLK_DEV_RZ1000
 	{PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, NULL, NULL,	ide_init_rz1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
diff -urN linux-2.5.7-pre2/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.7-pre2/drivers/ide/ide-taskfile.c	Tue Mar 19 03:32:12 2002
+++ linux/drivers/ide/ide-taskfile.c	Tue Mar 19 03:26:14 2002
@@ -48,7 +48,7 @@
 	if (rq->bio)
 		return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
 	else
-		return rq->buffer + task_rq_offset(rq);
+		return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
 }
 
 static inline void ide_unmap_rq(struct request *rq, char *to,
@@ -341,27 +341,37 @@
 	pBuf = ide_map_rq(rq, &flags);
 	DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
 		pBuf, nsect, rq->current_nr_sectors);
+
 	drive->io_32bit = 0;
 	taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+
 	ide_unmap_rq(rq, pBuf, &flags);
+
 	drive->io_32bit = io_32bit;
+
 	rq->errors = 0;
 	/* Are we sure that this as all been already transfered? */
 	rq->current_nr_sectors -= nsect;
+
 	if (hwgroup->handler == NULL)
 		ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+
 	return ide_started;
 }
 
-ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t ata_taskfile(ide_drive_t *drive,
+		struct hd_drive_task_hdr *taskfile,
+		struct hd_drive_hob_hdr *hobfile,
+		ide_handler_t *handler,
+		ide_pre_handler_t *prehandler,
+		struct request *rq
+		)
 {
-	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
-	hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
 	struct hd_driveid *id = drive->id;
-	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
+	u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
 	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (task->handler != task_mulout_intr && task->handler != bio_mulout_intr) {
+	if (handler != task_mulout_intr && handler != bio_mulout_intr) {
 		if (IDE_CONTROL_REG)
 			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
 		SELECT_MASK(HWIF(drive), drive, 0);
@@ -386,17 +396,16 @@
 	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
 
 	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
-	if (task->handler != NULL) {
-		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+	if (handler != NULL) {
+		ide_set_handler(drive, handler, WAIT_CMD, NULL);
 		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
 		/*
 		 * Warning check for race between handler and prehandler for
 		 * writing first block of data.  however since we are well
 		 * inside the boundaries of the seek, we should be okay.
 		 */
-		if (task->prehandler != NULL) {
-			return task->prehandler(drive, task->rq);
-		}
+		if (prehandler != NULL)
+			return prehandler(drive, rq);
 	} else {
 		/* for dma commands we down set the handler */
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
@@ -405,48 +414,6 @@
 	return ide_started;
 }
 
-void do_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile,
-		struct hd_drive_hob_hdr *hobfile,
-		ide_handler_t *handler)
-{
-	struct hd_driveid *id = drive->id;
-	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
-
-	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (*handler != task_mulout_intr && handler != bio_mulout_intr) {
-		if (IDE_CONTROL_REG)
-			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
-		SELECT_MASK(HWIF(drive), drive, 0);
-	}
-
-	if ((id->command_set_2 & 0x0400) &&
-	    (id->cfs_enable_2 & 0x0400) &&
-	    (drive->addressing == 1)) {
-		OUT_BYTE(hobfile->feature, IDE_FEATURE_REG);
-		OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
-		OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
-		OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
-		OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
-	}
-
-	OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
-	OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
-	/* refers to number of sectors to transfer */
-	OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
-	/* refers to sector offset or start sector */
-	OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
-	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
-
-	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
-	if (handler != NULL) {
-		ide_set_handler (drive, handler, WAIT_CMD, NULL);
-		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-	} else {
-		/* for dma commands we down set the handler */
-		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
-	}
-}
-
 /*
  * This is invoked on completion of a WIN_SETMULT cmd.
  */
@@ -1162,8 +1129,7 @@
 EXPORT_SYMBOL(atapi_output_bytes);
 EXPORT_SYMBOL(taskfile_input_data);
 EXPORT_SYMBOL(taskfile_output_data);
-EXPORT_SYMBOL(do_rw_taskfile);
-EXPORT_SYMBOL(do_taskfile);
+EXPORT_SYMBOL(ata_taskfile);
 
 EXPORT_SYMBOL(recal_intr);
 EXPORT_SYMBOL(set_geometry_intr);
diff -urN linux-2.5.7-pre2/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.7-pre2/drivers/ide/ide.c	Mon Mar 18 16:15:28 2002
+++ linux/drivers/ide/ide.c	Tue Mar 19 03:14:40 2002
@@ -978,7 +978,7 @@
  * setting a timer to wake up at half second intervals thereafter,
  * until timeout is achieved, before timing out.
  */
-int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
 	byte stat;
 	int i;
 	unsigned long flags;
@@ -1020,90 +1020,6 @@
 }
 
 /*
- * execute_drive_cmd() issues a special drive command,
- * usually initiated by ioctl() from the external hdparm program.
- */
-static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
-{
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-
-		if (!(args))
-			goto args_error;
-
-		do_taskfile(drive,
-				(struct hd_drive_task_hdr *)&args->tfRegister,
-				(struct hd_drive_hob_hdr *)&args->hobRegister,
-				args->handler);
-
-		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;
-
-		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;
-		}
-		OUT_BYTE(args[2],IDE_FEATURE_REG);
-		ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
-		return ide_started;
-	}
-
-args_error:
-	/*
-	 * NULL is actually a valid 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;
-}
-
-/*
  * start_request() initiates handling of a new I/O request
  */
 static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
@@ -1150,9 +1066,100 @@
 		printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
 		return startstop;
 	}
+
+	/* FIXME: We can see nicely here that all commands should be submitted
+	 * through the request queue and that the special field in drive should
+	 * go as soon as possible!
+	 */
+
 	if (!drive->special.all) {
-		if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE))
-			return execute_drive_cmd(drive, rq);
+		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 (rq->flags & REQ_DRIVE_TASKFILE) {
+				ide_task_t *args = rq->special;
+
+				if (!(args))
+					goto args_error;
+
+				ata_taskfile(drive,
+						(struct hd_drive_task_hdr *)&args->tfRegister,
+						(struct hd_drive_hob_hdr *)&args->hobRegister,
+						args->handler, NULL, 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;
+
+			} else if (rq->flags & REQ_DRIVE_TASK) {
+				byte *args = rq->buffer;
+				byte sel;
+
+				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;
+				}
+				OUT_BYTE(args[2],IDE_FEATURE_REG);
+				ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
+				return ide_started;
+			}
+
+args_error:
+			/*
+			 * NULL is actually a valid 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;
+		}
+
+		/* The normal way of execution is to pass execute the request
+		 * handler.
+		 */
 
 		if (ata_ops(drive)) {
 			if (ata_ops(drive)->do_request)
@@ -1699,31 +1706,29 @@
 }
 
 /*
- * This function issues a special IDE device request
- * onto the request queue.
+ * This function issues a special IDE device request onto the request queue.
  *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
+ * If action is ide_wait, then the rq is queued at the end of the request
+ * queue, and the function sleeps until it has been processed.  This is for use
+ * when invoked from an ioctl handler.
  *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
+ * If action is ide_preempt, then the rq is queued at the head of the request
+ * queue, displacing the currently-being-processed request and this function
+ * returns immediately without waiting for the new rq to be completed.  This is
+ * VERY DANGEROUS, and is intended for careful use by the ATAPI tape/cdrom
+ * driver code.
  *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
+ * If action is ide_next, then the rq is queued immediately after the
+ * currently-being-processed-request (if any), and the function returns without
+ * waiting for the new rq to be completed.  As above, This is VERY DANGEROUS,
+ * and is intended for careful use by the ATAPI tape/cdrom driver code.
  *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
+ * If action is ide_end, then the rq is queued at the end of the request queue,
+ * and the function returns immediately without waiting for the new rq to be
+ * completed. This is again intended for careful use by the ATAPI tape/cdrom
+ * driver code.
  */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
+int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action)
 {
 	unsigned long flags;
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
@@ -2403,7 +2408,7 @@
 	ide_init_drive_cmd(&rq);
 	drive->tune_req = (byte) arg;
 	drive->special.b.set_tune = 1;
-	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
+	ide_do_drive_cmd(drive, &rq, ide_wait);
 	return 0;
 }
 
diff -urN linux-2.5.7-pre2/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.7-pre2/drivers/ide/pdc202xx.c	Mon Mar 18 16:15:28 2002
+++ linux/drivers/ide/pdc202xx.c	Tue Mar 19 00:49:59 2002
@@ -217,6 +217,9 @@
 		case PCI_DEVICE_ID_PROMISE_20275:
 			p += sprintf(p, "\n                                PDC20275 Chipset.\n");
 			break;
+		case PCI_DEVICE_ID_PROMISE_20276:
+			p += sprintf(p, "\n                                PDC20276 Chipset.\n");
+			break;
 		case PCI_DEVICE_ID_PROMISE_20269:
 			p += sprintf(p, "\n                                PDC20269 TX2 Chipset.\n");
 			break;
@@ -236,6 +239,7 @@
 	char *p = buffer;
 	switch(bmide_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
@@ -732,6 +736,7 @@
 
 	switch(dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 			udma_133 = (udma_66) ? 1 : 0;
 			udma_100 = (udma_66) ? 1 : 0;
@@ -989,6 +994,7 @@
 
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268R:
 		case PCI_DEVICE_ID_PROMISE_20268:
@@ -1121,6 +1127,7 @@
 
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268R:
 		case PCI_DEVICE_ID_PROMISE_20268:
@@ -1215,6 +1222,7 @@
 
         switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
@@ -1233,6 +1241,7 @@
 
         switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
diff -urN linux-2.5.7-pre2/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- linux-2.5.7-pre2/drivers/pci/pci.ids	Tue Mar 19 03:32:12 2002
+++ linux/drivers/pci/pci.ids	Tue Mar 19 00:55:59 2002
@@ -1108,12 +1108,14 @@
 1059  Teknor Industrial Computers Inc
 105a  Promise Technology, Inc.
 	0d30  20265
+	1275  20275
 	4d30  20267
 	4d33  20246
 	4d38  20262
 	4d68  20268
 	6268  20268R
 	4d69  20269
+	5275  20276
 	5300  DC5300
 105b  Foxconn International, Inc.
 105c  Wipro Infotech Limited
diff -urN linux-2.5.7-pre2/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.7-pre2/include/linux/ide.h	Tue Mar 19 03:32:12 2002
+++ linux/include/linux/ide.h	Tue Mar 19 03:21:55 2002
@@ -771,35 +771,7 @@
  */
 #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
 
-#define task_rq_offset(rq) \
-	(((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
-
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
- */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action);
+extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
 
 /*
  * Clean up after success/failure of an explicit drive cmd.
@@ -827,15 +799,12 @@
 void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
 void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
 
-/*
- * taskfile io for disks for now...
- */
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task);
-
-/*
- * Builds request from ide_ioctl
- */
-void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler);
+extern ide_startstop_t ata_taskfile(ide_drive_t *drive,
+		struct hd_drive_task_hdr *taskfile,
+		struct hd_drive_hob_hdr *hobfile,
+		ide_handler_t *handler,
+		ide_pre_handler_t *prehandler,
+		struct request *rq);
 
 /*
  * Special Flagged Register Validation Caller
@@ -871,7 +840,7 @@
  * idedisk_input_data() is a wrapper around ide_input_data() which copes
  * with byte-swapping the input data if required.
  */
-inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+extern void idedisk_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount);
 
 /*
  * ide_stall_queue() can be used by a drive to give excess bandwidth back
diff -urN linux-2.5.7-pre2/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux-2.5.7-pre2/include/linux/pci_ids.h	Tue Mar 19 03:32:12 2002
+++ linux/include/linux/pci_ids.h	Tue Mar 19 00:44:14 2002
@@ -608,6 +608,7 @@
 #define PCI_DEVICE_ID_PROMISE_20268R	0x6268
 #define PCI_DEVICE_ID_PROMISE_20269	0x4d69
 #define PCI_DEVICE_ID_PROMISE_20275	0x1275
+#define PCI_DEVICE_ID_PROMISE_20276	0x5275
 #define PCI_DEVICE_ID_PROMISE_5300	0x5300
 
 #define PCI_VENDOR_ID_N9		0x105d

  parent reply	other threads:[~2002-03-28  9:24 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
2002-03-18 21:57 ` Xavier Bestel
2002-03-28  9:21 ` Martin Dalecki [this message]
2002-03-28  9:23 ` PATCH 2.5.7 IDE 24 Martin Dalecki
2002-03-28  9:29   ` Zwane Mwaikambo
2002-03-28  9:25 ` [PATCH] 2.5.7 IDE 25 Martin Dalecki
2002-03-28  9:29 ` [PATCH] 2.5.7 IDE 26 Martin Dalecki
2002-03-28 20:34   ` Vojtech Pavlik
2002-03-28 20:58     ` Anton Altaparmakov
2002-03-29 13:53       ` Martin Dalecki
2002-03-28  9:31 ` [PATCH] 2.5.7 IDE 27 Martin Dalecki
2002-03-28 18:01   ` Davide Libenzi
2002-03-29 13:49     ` Martin Dalecki
2002-03-29 20:39       ` Davide Libenzi
2002-03-28  9:32 ` [PATCH] 2.5.7 IDE 28a Martin Dalecki
2002-04-15  7:42 ` [PATCH] 2.5.8 IDE 34 Martin Dalecki
2002-04-15  8:51   ` Jens Axboe
2002-04-15  8:11     ` Martin Dalecki
2002-04-22 15:36 ` [PATCH] 2.5.8 IDE 40 Martin Dalecki
2002-04-25 14:32 ` [PATCH] 2.5.10 IDE 41 Martin Dalecki
2002-04-25 17:39   ` Jens Axboe
2002-04-25 17:18     ` Martin Dalecki
2002-04-29  8:21       ` Jens Axboe
2002-04-30  8:09 ` [PATCH] 2.5.11 IDE 46 Martin Dalecki
2002-04-30  8:11 ` Linux 2.5.7 Martin Dalecki
2002-04-30  8:45 ` [PATCH] 2.5.11 IDE 47 Martin Dalecki
2002-04-30 15:16 ` [PATCH] 2.5.11 IDE 48 Martin Dalecki
2002-05-02  8:39 ` [PATCH] 2.5.12 IDE 49 Martin Dalecki
2002-05-02  8:42 ` Linux 2.5.7 Martin Dalecki
2002-05-02 13:22   ` Dave Jones
2002-05-02 12:44     ` Martin Dalecki
2002-05-02 13:54       ` David Woodhouse
2002-05-02 13:02         ` Martin Dalecki
2002-05-02 14:06           ` David Woodhouse
2002-05-03 12:59 ` [PATCH] 2.5.13 IDE 50 Martin Dalecki
2002-05-03 18:12   ` Tim Schmielau
2002-05-04 23:53     ` Martin Dalecki
2002-05-05 17:08       ` Denis Vlasenko
2002-05-03 14:48 ` [PATCH] 2.5.13 IDE 51 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=3CA2E0B4.9010006@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox