[git pull] IDE updates part 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



First IDE updates in 2009, this time:
* Fix IDE to not process commands in IRQ-context and than switch the  subsystem to use per-device request queue locks instead of (ab)using  hwgroup locks for this purpose.  Besides being obvious IRQ-latency  and scalability improvement this decreases complexity of core code  greatly (~100 LOC of very tricky code gone) and makes maintainance  work much easier.
  [ Thanks to Elias Oltmanns for his work on reviewing these changes    and catching some issues early. ]
* Scheduled removal of deprecated ide-scsi device driver.
  We've been discouraging using ide-scsi since early 2.5.x days as the  driver contains unfixable problems with error handling and lifetimes  of IDE/SCSI objects.  There is now consensus between IDE/SCSI people  that both (recently rewritten) native ide-{cd,gd,tape} drivers from  IDE side and proper ATA-SCSI emulation (libata) from SCSI side offer  a better alternative.
  The driver has been officially orphaned for a year and then scheduled  for removal for the last 4 months so this shouldn't come as surprise  (I didn't got a single user complaint about this and ide-scsi has even  been broken by some unrelated kernel changes for few kernel releases  in the past without anybody noticing).  
  (from FUJITA Tomonori and Borislav Petkov)
* Fix multiple nested big stack usage in ide-floppy.c.
  (from Linus himself, testing/merging handled by Borislav)
* Preparations to switch ide-cd device driver to use generic ATAPI code  which will happen in the next IDE updates pull request.
  (from Borislav)
* Misc fixups/cleanups.
All above changes have been in linux-next for some time now...

Linus, please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git/
to receive the following updates:
 Documentation/feature-removal-schedule.txt |    9 - MAINTAINERS                                |    5 - drivers/ide/Kconfig                        |   18 +- drivers/ide/Makefile                       |    2 +- drivers/ide/ide-atapi.c                    |  248 +++++---- drivers/ide/ide-cd.c                       |   99 +--- drivers/ide/ide-cd.h                       |   12 +- drivers/ide/ide-floppy.c                   |   28 +- drivers/ide/ide-floppy_ioctl.c             |   58 +- drivers/ide/ide-io.c                       |  282 +++------- drivers/ide/ide-ioctls.c                   |    3 +- drivers/ide/ide-park.c                     |   13 +- drivers/ide/ide-probe.c                    |  223 +++----- drivers/ide/ide-sysfs.c                    |  125 ++++ drivers/ide/ide-tape.c                     |    2 +- drivers/ide/ide.c                          |   72 +--- drivers/ide/tx4938ide.c                    |   11 +- drivers/ide/tx4939ide.c                    |   43 +- drivers/scsi/Kconfig                       |    8 +- drivers/scsi/Makefile                      |    1 - drivers/scsi/ide-scsi.c                    |  840 ---------------------------- include/linux/ide.h                        |  121 +++-- 22 files changed, 614 insertions(+), 1609 deletions(-) create mode 100644 drivers/ide/ide-sysfs.c delete mode 100644 drivers/scsi/ide-scsi.c

Bartlomiej Zolnierkiewicz (10):      tx493x: fix indentation      ide: remove chipset type fixup from ide_host_register()      ide: small ide_register_port() cleanup      ide: factor out device type classifying from do_identify()      ide: move sysfs support to ide-sysfs.c      ide: don't execute the next queued command from the hard-IRQ context (v2)      ide: remove IDE PM hack from do_ide_request()      ide: remove "paranoia" checks for hwgroup->busy      ide: add ide_[un]lock_hwgroup() helpers      ide: use per-device request queue locks (v2)
Borislav Petkov (20):      ide-cd: move debug defines into header      ide: make IDE_AFLAG_.. numbering continuous again      ide-atapi: add a dev_is_idecd-inline      ide-atapi: combine drive-specific assignments      ide-atapi: setup dma for ide-cd      ide-atapi: accomodate transfer length calculation for ide-cd      ide-atapi: teach ide atapi about drive->waiting_for_dma      ide-cd: move cdrom_timer_expiry to ide-atapi.c      ide-atapi: remove ide-scsi remnants from ide_issue_pc      ide-atapi: remove ide-scsi remnants from ide_transfer_pc()      ide-atapi: remove ide-scsi remnants from ide_pc_intr()      ide: remove the last ide-scsi remnants      ide-atapi: compute cmd_len based on device type in ide_transfer_pc      ide-atapi: assign expiry and timeout based on device type      ide-atapi: split drive-specific functionality in ide_issue_pc      ide-cd: remove xferlen arg to cdrom_start_packet_command      ide-cd: remove handler wrappers      ide-atapi: remove timeout arg to ide_issue_pc      ide-atapi: put the rest of non-ide-cd code into the else-clause of ide_transfer_pc      ide-atapi: start dma in a drive-specific way
FUJITA Tomonori (1):      remove ide-scsi
Linus Torvalds (1):      ide-floppy: allocate only toplevel packet commands

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txtindex dc7c681..df18d87 100644--- a/Documentation/feature-removal-schedule.txt+++ b/Documentation/feature-removal-schedule.txt@@ -310,15 +310,6 @@ Who:  Krzysztof Piotr Oledzki <ole@xxxxxx>  --------------------------- -What: ide-scsi (BLK_DEV_IDESCSI)-When: 2.6.29-Why:  The 2.6 kernel supports direct writing to ide CD drives, which-      eliminates the need for ide-scsi. The new method is more-      efficient in every way.-Who:  FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx>------------------------------ What:	i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() When:	2.6.29 (ideally) or 2.6.30 (more likely) Why:	Deprecated by the new (standard) device driver binding model. Usediff --git a/MAINTAINERS b/MAINTAINERSindex ceb32ee..144766c 100644--- a/MAINTAINERS+++ b/MAINTAINERS@@ -2146,11 +2146,6 @@ M:	Gadi Oxman <gadio@xxxxxxxxxxxxxxxx> L:	linux-kernel@xxxxxxxxxxxxxxx S:	Maintained -IDE-SCSI DRIVER-L:	linux-ide@xxxxxxxxxxxxxxxxx:	linux-scsi@xxxxxxxxxxxxxxxxx:	Orphan- IDLE-I7300 P:	Andy Henroid M:	andrew.d.henroid@xxxxxxxxxxxxx --git a/drivers/ide/Kconfig b/drivers/ide/Kconfigindex c9f21e3..4ee85fc 100644--- a/drivers/ide/Kconfig+++ b/drivers/ide/Kconfig@@ -137,6 +137,7 @@ config BLK_DEV_DELKIN  config BLK_DEV_IDECD 	tristate "Include IDE/ATAPI CDROM support"+	select IDE_ATAPI 	---help--- 	  If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is 	  a newer protocol used by IDE CD-ROM and TAPE drives, similar to the@@ -185,23 +186,6 @@ config BLK_DEV_IDETAPE 	  To compile this driver as a module, choose M here: the 	  module will be called ide-tape. -config BLK_DEV_IDESCSI-	tristate "SCSI emulation support (DEPRECATED)"-	depends on SCSI-	select IDE_ATAPI-	---help----	  WARNING: ide-scsi is no longer needed for cd writing applications!-	  The 2.6 kernel supports direct writing to ide-cd, which eliminates-	  the need for ide-scsi + the entire scsi stack just for writing a-	  cd. The new method is more efficient in every way.--	  This will provide SCSI host adapter emulation for IDE ATAPI devices,-	  and will allow you to use a SCSI device driver instead of a native-	  ATAPI driver.--	  If both this SCSI emulation and native ATAPI support are compiled-	  into the kernel, the native support will be used.- config BLK_DEV_IDEACPI 	bool "IDE ACPI support" 	depends on ACPIdiff --git a/drivers/ide/Makefile b/drivers/ide/Makefileindex 177e3f8..4107289 100644--- a/drivers/ide/Makefile+++ b/drivers/ide/Makefile@@ -5,7 +5,7 @@ EXTRA_CFLAGS				+= -Idrivers/ide  ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \-	      ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o+	      ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o  # core IDE code ide-core-$(CONFIG_IDE_TIMINGS)		+= ide-timings.odiff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.cindex 4e58b9e..e8688c0 100644--- a/drivers/ide/ide-atapi.c+++ b/drivers/ide/ide-atapi.c@@ -3,6 +3,7 @@  */  #include <linux/kernel.h>+#include <linux/cdrom.h> #include <linux/delay.h> #include <linux/ide.h> #include <scsi/scsi.h>@@ -14,6 +15,13 @@ #define debug_log(fmt, args...) do {} while (0) #endif +#define ATAPI_MIN_CDB_BYTES	12++static inline int dev_is_idecd(ide_drive_t *drive)+{+	return drive->media == ide_cdrom || drive->media == ide_optical;+}+ /*  * Check whether we can support a device,  * based on the ATAPI IDENTIFY command results.@@ -233,18 +241,49 @@ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) } EXPORT_SYMBOL_GPL(ide_retry_pc); -int ide_scsi_expiry(ide_drive_t *drive)+int ide_cd_expiry(ide_drive_t *drive) {-	struct ide_atapi_pc *pc = drive->pc;+	struct request *rq = HWGROUP(drive)->rq;+	unsigned long wait = 0; -	debug_log("%s called for %lu at %lu\n", __func__,-		  pc->scsi_cmd->serial_number, jiffies);+	debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); -	pc->flags |= PC_FLAG_TIMEDOUT;+	/*+	 * Some commands are *slow* and normally take a long time to complete.+	 * Usually we can use the ATAPI "disconnect" to bypass this, but not all+	 * commands/drives support that. Let ide_timer_expiry keep polling us+	 * for these.+	 */+	switch (rq->cmd[0]) {+	case GPCMD_BLANK:+	case GPCMD_FORMAT_UNIT:+	case GPCMD_RESERVE_RZONE_TRACK:+	case GPCMD_CLOSE_TRACK:+	case GPCMD_FLUSH_CACHE:+		wait = ATAPI_WAIT_PC;+		break;+	default:+		if (!(rq->cmd_flags & REQ_QUIET))+			printk(KERN_INFO "cmd 0x%x timed out\n",+					 rq->cmd[0]);+		wait = 0;+		break;+	}+	return wait;+}+EXPORT_SYMBOL_GPL(ide_cd_expiry); -	return 0; /* we do not want the IDE subsystem to retry */+int ide_cd_get_xferlen(struct request *rq)+{+	if (blk_fs_request(rq))+		return 32768;+	else if (blk_sense_request(rq) || blk_pc_request(rq) ||+			 rq->cmd_type == REQ_TYPE_ATA_PC)+		return rq->data_len;+	else+		return 0; }-EXPORT_SYMBOL_GPL(ide_scsi_expiry);+EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);  /*  * This is the usual interrupt handler which will be called during a packet@@ -258,21 +297,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) 	struct request *rq = hwif->hwgroup->rq; 	const struct ide_tp_ops *tp_ops = hwif->tp_ops; 	xfer_func_t *xferfunc;-	ide_expiry_t *expiry; 	unsigned int timeout, temp; 	u16 bcount;-	u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;+	u8 stat, ireason, dsc = 0;  	debug_log("Enter %s - interrupt handler\n", __func__); -	if (scsi) {-		timeout = ide_scsi_get_timeout(pc);-		expiry = ide_scsi_expiry;-	} else {-		timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD-						       : WAIT_TAPE_CMD;-		expiry = NULL;-	}+	timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD+					       : WAIT_TAPE_CMD;  	if (pc->flags & PC_FLAG_TIMEDOUT) { 		drive->pc_callback(drive, 0);@@ -284,8 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)  	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { 		if (hwif->dma_ops->dma_end(drive) ||-		    (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) {-			if (drive->media == ide_floppy && !scsi)+		    (drive->media == ide_tape && (stat & ATA_ERR))) {+			if (drive->media == ide_floppy) 				printk(KERN_ERR "%s: DMA %s error\n", 					drive->name, rq_data_dir(pc->rq) 						     ? "write" : "read");@@ -307,7 +339,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)  		local_irq_enable_in_hardirq(); -		if (drive->media == ide_tape && !scsi &&+		if (drive->media == ide_tape && 		    (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) 			stat &= ~ATA_ERR; @@ -315,11 +347,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) 			/* Error detected */ 			debug_log("%s: I/O error\n", drive->name); -			if (drive->media != ide_tape || scsi) {+			if (drive->media != ide_tape) 				pc->rq->errors++;-				if (scsi)-					goto cmd_finished;-			}  			if (rq->cmd[0] == REQUEST_SENSE) { 				printk(KERN_ERR "%s: I/O error in request sense"@@ -335,7 +364,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) 			/* queued, but not started */ 			return ide_stopped; 		}-cmd_finished: 		pc->error = 0;  		if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)@@ -382,25 +410,8 @@ cmd_finished: 						"us more data than expected - " 						"discarding data\n", 						drive->name);-				if (scsi)-					temp = pc->buf_size - pc->xferred;-				else-					temp = 0;-				if (temp) {-					if (pc->sg)-						drive->pc_io_buffers(drive, pc,-								     temp, 0);-					else-						tp_ops->input_data(drive, NULL,-							pc->cur_pos, temp);-					printk(KERN_ERR "%s: transferred %d of "-							"%d bytes\n",-							drive->name,-							temp, bcount);-				}-				pc->xferred += temp;-				pc->cur_pos += temp;-				ide_pad_transfer(drive, 0, bcount - temp);++				ide_pad_transfer(drive, 0, bcount); 				goto next_irq; 			} 			debug_log("The device wants to send us more data than "@@ -410,14 +421,13 @@ cmd_finished: 	} else 		xferfunc = tp_ops->output_data; -	if ((drive->media == ide_floppy && !scsi && !pc->buf) ||-	    (drive->media == ide_tape && !scsi && pc->bh) ||-	    (scsi && pc->sg)) {+	if ((drive->media == ide_floppy && !pc->buf) ||+	    (drive->media == ide_tape && pc->bh)) { 		int done = drive->pc_io_buffers(drive, pc, bcount, 				  !!(pc->flags & PC_FLAG_WRITING));  		/* FIXME: don't do partial completions */-		if (drive->media == ide_floppy && !scsi)+		if (drive->media == ide_floppy) 			ide_end_request(drive, 1, done >> 9); 	} else 		xferfunc(drive, NULL, pc->cur_pos, bcount);@@ -430,7 +440,7 @@ cmd_finished: 		  rq->cmd[0], bcount); next_irq: 	/* And set the interrupt handler again */-	ide_set_handler(drive, ide_pc_intr, timeout, expiry);+	ide_set_handler(drive, ide_pc_intr, timeout, NULL); 	return ide_started; } @@ -479,11 +489,12 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive)  static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) {-	struct ide_atapi_pc *pc = drive->pc;+	struct ide_atapi_pc *uninitialized_var(pc); 	ide_hwif_t *hwif = drive->hwif; 	struct request *rq = hwif->hwgroup->rq; 	ide_expiry_t *expiry; 	unsigned int timeout;+	int cmd_len; 	ide_startstop_t startstop; 	u8 ireason; @@ -493,101 +504,124 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) 		return startstop; 	} -	ireason = ide_read_ireason(drive);-	if (drive->media == ide_tape &&-	    (drive->dev_flags & IDE_DFLAG_SCSI) == 0)-		ireason = ide_wait_ireason(drive, ireason);--	if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {-		printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "-				"a packet command\n", drive->name);-		return ide_do_reset(drive);+	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {+		if (drive->dma)+			drive->waiting_for_dma = 1; 	} -	/*-	 * If necessary schedule the packet transfer to occur 'timeout'-	 * miliseconds later in ide_delayed_transfer_pc() after the device-	 * says it's ready for a packet.-	 */-	if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {-		timeout = drive->pc_delay;-		expiry = &ide_delayed_transfer_pc;+	if (dev_is_idecd(drive)) {+		/* ATAPI commands get padded out to 12 bytes minimum */+		cmd_len = COMMAND_SIZE(rq->cmd[0]);+		if (cmd_len < ATAPI_MIN_CDB_BYTES)+			cmd_len = ATAPI_MIN_CDB_BYTES;++		timeout = rq->timeout;+		expiry  = ide_cd_expiry; 	} else {-		if (drive->dev_flags & IDE_DFLAG_SCSI) {-			timeout = ide_scsi_get_timeout(pc);-			expiry = ide_scsi_expiry;+		pc = drive->pc;++		cmd_len = ATAPI_MIN_CDB_BYTES;++		/*+		 * If necessary schedule the packet transfer to occur 'timeout'+		 * miliseconds later in ide_delayed_transfer_pc() after the+		 * device says it's ready for a packet.+		 */+		if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {+			timeout = drive->pc_delay;+			expiry = &ide_delayed_transfer_pc; 		} else { 			timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD 							       : WAIT_TAPE_CMD; 			expiry = NULL; 		}++		ireason = ide_read_ireason(drive);+		if (drive->media == ide_tape)+			ireason = ide_wait_ireason(drive, ireason);++		if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {+			printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "+					"a packet command\n", drive->name);++			return ide_do_reset(drive);+		} 	}  	/* Set the interrupt routine */ 	ide_set_handler(drive, ide_pc_intr, timeout, expiry);  	/* Begin DMA, if necessary */-	if (pc->flags & PC_FLAG_DMA_OK) {-		pc->flags |= PC_FLAG_DMA_IN_PROGRESS;-		hwif->dma_ops->dma_start(drive);+	if (dev_is_idecd(drive)) {+		if (drive->dma)+			hwif->dma_ops->dma_start(drive);+	} else {+		if (pc->flags & PC_FLAG_DMA_OK) {+			pc->flags |= PC_FLAG_DMA_IN_PROGRESS;+			hwif->dma_ops->dma_start(drive);+		} 	}  	/* Send the actual packet */ 	if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)-		hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12);+		hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);  	return ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,-			     ide_expiry_t *expiry)+ide_startstop_t ide_issue_pc(ide_drive_t *drive) {-	struct ide_atapi_pc *pc = drive->pc;+	struct ide_atapi_pc *pc; 	ide_hwif_t *hwif = drive->hwif;+	ide_expiry_t *expiry = NULL;+	unsigned int timeout; 	u32 tf_flags; 	u16 bcount;-	u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); -	/* We haven't transferred any data yet */-	pc->xferred = 0;-	pc->cur_pos = pc->buf;+	if (dev_is_idecd(drive)) {+		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;+		bcount = ide_cd_get_xferlen(hwif->hwgroup->rq);+		expiry = ide_cd_expiry;+		timeout = ATAPI_WAIT_PC; -	/* Request to transfer the entire buffer at once */-	if (drive->media == ide_tape && scsi == 0)-		bcount = pc->req_xfer;-	else-		bcount = min(pc->req_xfer, 63 * 1024);+		if (drive->dma)+			drive->dma = !hwif->dma_ops->dma_setup(drive);+	} else {+		pc = drive->pc; -	if (pc->flags & PC_FLAG_DMA_ERROR) {-		pc->flags &= ~PC_FLAG_DMA_ERROR;-		ide_dma_off(drive);-	}+		/* We haven't transferred any data yet */+		pc->xferred = 0;+		pc->cur_pos = pc->buf; -	if ((pc->flags & PC_FLAG_DMA_OK) &&-	    (drive->dev_flags & IDE_DFLAG_USING_DMA)) {-		if (scsi)-			hwif->sg_mapped = 1;-		drive->dma = !hwif->dma_ops->dma_setup(drive);-		if (scsi)-			hwif->sg_mapped = 0;-	}+		tf_flags = IDE_TFLAG_OUT_DEVICE;+		bcount = ((drive->media == ide_tape) ?+				pc->req_xfer :+				min(pc->req_xfer, 63 * 1024)); -	if (!drive->dma)-		pc->flags &= ~PC_FLAG_DMA_OK;+		if (pc->flags & PC_FLAG_DMA_ERROR) {+			pc->flags &= ~PC_FLAG_DMA_ERROR;+			ide_dma_off(drive);+		} -	if (scsi)-		tf_flags = 0;-	else if (drive->media == ide_cdrom || drive->media == ide_optical)-		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;-	else-		tf_flags = IDE_TFLAG_OUT_DEVICE;+		if ((pc->flags & PC_FLAG_DMA_OK) &&+		     (drive->dev_flags & IDE_DFLAG_USING_DMA))+			drive->dma = !hwif->dma_ops->dma_setup(drive);++		if (!drive->dma)+			pc->flags &= ~PC_FLAG_DMA_OK;++		timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD+						       : WAIT_TAPE_CMD;+	}  	ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);  	/* Issue the packet command */ 	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {+		if (drive->dma)+			drive->waiting_for_dma = 0; 		ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,-				    timeout, NULL);+				    timeout, expiry); 		return ide_started; 	} else { 		ide_execute_pkt_cmd(drive);diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.cindex 5daa4dd..1a7410f 100644--- a/drivers/ide/ide-cd.c+++ b/drivers/ide/ide-cd.c@@ -53,14 +53,6 @@  #include "ide-cd.h" -#define IDECD_DEBUG_LOG		1--#if IDECD_DEBUG_LOG-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)-#else-#define ide_debug_log(lvl, fmt, args...) do {} while (0)-#endif- static DEFINE_MUTEX(idecd_ref_mutex);  static void ide_cd_release(struct kref *);@@ -519,37 +511,8 @@ end_request: 	return 1; } -static int cdrom_timer_expiry(ide_drive_t *drive)-{-	struct request *rq = HWGROUP(drive)->rq;-	unsigned long wait = 0;--	ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__,-		      rq->cmd[0]);--	/*-	 * Some commands are *slow* and normally take a long time to complete.-	 * Usually we can use the ATAPI "disconnect" to bypass this, but not all-	 * commands/drives support that. Let ide_timer_expiry keep polling us-	 * for these.-	 */-	switch (rq->cmd[0]) {-	case GPCMD_BLANK:-	case GPCMD_FORMAT_UNIT:-	case GPCMD_RESERVE_RZONE_TRACK:-	case GPCMD_CLOSE_TRACK:-	case GPCMD_FLUSH_CACHE:-		wait = ATAPI_WAIT_PC;-		break;-	default:-		if (!(rq->cmd_flags & REQ_QUIET))-			printk(KERN_INFO PFX "cmd 0x%x timed out\n",-					 rq->cmd[0]);-		wait = 0;-		break;-	}-	return wait;-}+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *);+static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);  /*  * Set up the device registers for transferring a packet command on DEV,@@ -559,11 +522,13 @@ static int cdrom_timer_expiry(ide_drive_t *drive)  * called when the interrupt from the drive arrives.  Otherwise, HANDLER  * will be called immediately after the drive is prepared for the transfer.  */-static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,-						  int xferlen,-						  ide_handler_t *handler)+static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive) { 	ide_hwif_t *hwif = drive->hwif;+	struct request *rq = hwif->hwgroup->rq;+	int xferlen;++	xferlen = ide_cd_get_xferlen(rq);  	ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); @@ -581,13 +546,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, 			drive->waiting_for_dma = 0;  		/* packet command */-		ide_execute_command(drive, ATA_CMD_PACKET, handler,-				    ATAPI_WAIT_PC, cdrom_timer_expiry);+		ide_execute_command(drive, ATA_CMD_PACKET,+				    cdrom_transfer_packet_command,+				    ATAPI_WAIT_PC, ide_cd_expiry); 		return ide_started; 	} else { 		ide_execute_pkt_cmd(drive); -		return (*handler) (drive);+		return cdrom_transfer_packet_command(drive); 	} } @@ -598,11 +564,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,  * there's data ready.  */ #define ATAPI_MIN_CDB_BYTES 12-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,-					  struct request *rq,-					  ide_handler_t *handler)+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive) { 	ide_hwif_t *hwif = drive->hwif;+	struct request *rq = hwif->hwgroup->rq; 	int cmd_len; 	ide_startstop_t startstop; @@ -629,7 +594,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, 	}  	/* arm the interrupt handler */-	ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);+	ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry);  	/* ATAPI commands get padded out to 12 bytes minimum */ 	cmd_len = COMMAND_SIZE(rq->cmd[0]);@@ -717,8 +682,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) 	return 1; } -static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);- static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, 						 struct request *rq) {@@ -761,20 +724,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, }  /*- * Routine to send a read/write packet command to the drive. This is usually- * called directly from cdrom_start_{read,write}(). However, for drq_interrupt- * devices, it is called from an interrupt when the drive is ready to accept- * the command.- */-static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)-{-	struct request *rq = drive->hwif->hwgroup->rq;--	/* send the command to the drive and return */-	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);-}--/*  * Fix up a possibly partially-processed request so that we can start it over  * entirely, or even put it back on the request queue.  */@@ -1096,7 +1045,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) 	} else { 		timeout = ATAPI_WAIT_PC; 		if (!blk_fs_request(rq))-			expiry = cdrom_timer_expiry;+			expiry = ide_cd_expiry; 	}  	ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);@@ -1163,13 +1112,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) 	return ide_started; } -static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)-{-	struct request *rq = HWGROUP(drive)->rq;--	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);-}- static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { @@ -1214,18 +1156,12 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, 					sector_t block) {-	ide_handler_t *fn;-	int xferlen;- 	ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " 		      "rq->cmd_type: 0x%x, block: %llu\n", 		      __func__, rq->cmd[0], rq->cmd_type, 		      (unsigned long long)block);  	if (blk_fs_request(rq)) {-		xferlen = 32768;-		fn = cdrom_start_rw_cont;- 		if (cdrom_start_rw(drive, rq) == ide_stopped) 			return ide_stopped; @@ -1233,9 +1169,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, 			return ide_stopped; 	} else if (blk_sense_request(rq) || blk_pc_request(rq) || 		   rq->cmd_type == REQ_TYPE_ATA_PC) {-		xferlen = rq->data_len;-		fn = cdrom_do_newpc_cont;- 		if (!rq->timeout) 			rq->timeout = ATAPI_WAIT_PC; @@ -1250,7 +1183,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, 		return ide_stopped; 	} -	return cdrom_start_packet_command(drive, xferlen, fn);+	return cdrom_start_packet_command(drive); }  /*diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.hindex d5ce336..bf676b2 100644--- a/drivers/ide/ide-cd.h+++ b/drivers/ide/ide-cd.h@@ -8,10 +8,14 @@ #include <linux/cdrom.h> #include <asm/byteorder.h> -/*- * typical timeout for packet command- */-#define ATAPI_WAIT_PC		(60 * HZ)+#define IDECD_DEBUG_LOG		0++#if IDECD_DEBUG_LOG+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)+#else+#define ide_debug_log(lvl, fmt, args...) do {} while (0)+#endif+ #define ATAPI_WAIT_WRITE_BUSY	(10 * HZ)  /************************************************************************/diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.cindex aeb1ad7..0a48e2d 100644--- a/drivers/ide/ide-floppy.c+++ b/drivers/ide/ide-floppy.c@@ -197,7 +197,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,  	pc->retries++; -	return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);+	return ide_issue_pc(drive); }  void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)@@ -342,38 +342,38 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,  * Look at the flexible disk page parameters. We ignore the CHS capacity  * parameters and use the LBA parameters instead.  */-static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)+static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,+					     struct ide_atapi_pc *pc) { 	struct ide_disk_obj *floppy = drive->driver_data; 	struct gendisk *disk = floppy->disk;-	struct ide_atapi_pc pc; 	u8 *page; 	int capacity, lba_capacity; 	u16 transfer_rate, sector_size, cyls, rpm; 	u8 heads, sectors; -	ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);+	ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); -	if (ide_queue_pc_tail(drive, disk, &pc)) {+	if (ide_queue_pc_tail(drive, disk, pc)) { 		printk(KERN_ERR PFX "Can't get flexible disk page params\n"); 		return 1; 	} -	if (pc.buf[3] & 0x80)+	if (pc->buf[3] & 0x80) 		drive->dev_flags |= IDE_DFLAG_WP; 	else 		drive->dev_flags &= ~IDE_DFLAG_WP;  	set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); -	page = &pc.buf[8];+	page = &pc->buf[8]; -	transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);-	sector_size   = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);-	cyls          = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);-	rpm           = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);-	heads         = pc.buf[8 + 4];-	sectors       = pc.buf[8 + 5];+	transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]);+	sector_size   = be16_to_cpup((__be16 *)&pc->buf[8 + 6]);+	cyls          = be16_to_cpup((__be16 *)&pc->buf[8 + 8]);+	rpm           = be16_to_cpup((__be16 *)&pc->buf[8 + 28]);+	heads         = pc->buf[8 + 4];+	sectors       = pc->buf[8 + 5];  	capacity = cyls * heads * sectors * sector_size; @@ -499,7 +499,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)  	/* Clik! disk does not support get_flexible_disk_page */ 	if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))-		(void) ide_floppy_get_flexible_disk_page(drive);+		(void) ide_floppy_get_flexible_disk_page(drive, &pc);  	return rc; }diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.cindex 2bc51ff..8f8be85 100644--- a/drivers/ide/ide-floppy_ioctl.c+++ b/drivers/ide/ide-floppy_ioctl.c@@ -31,10 +31,11 @@  * On exit we set nformats to the number of records we've actually initialized.  */ -static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)+static int ide_floppy_get_format_capacities(ide_drive_t *drive,+					    struct ide_atapi_pc *pc,+					    int __user *arg) { 	struct ide_disk_obj *floppy = drive->driver_data;-	struct ide_atapi_pc pc; 	u8 header_len, desc_cnt; 	int i, blocks, length, u_array_size, u_index; 	int __user *argp;@@ -45,13 +46,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) 	if (u_array_size <= 0) 		return -EINVAL; -	ide_floppy_create_read_capacity_cmd(&pc);-	if (ide_queue_pc_tail(drive, floppy->disk, &pc)) {+	ide_floppy_create_read_capacity_cmd(pc);+	if (ide_queue_pc_tail(drive, floppy->disk, pc)) { 		printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); 		return -EIO; 	} -	header_len = pc.buf[3];+	header_len = pc->buf[3]; 	desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */  	u_index = 0;@@ -68,8 +69,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) 		if (u_index >= u_array_size) 			break;	/* User-supplied buffer too small */ -		blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);-		length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);+		blocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]);+		length = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]);  		if (put_user(blocks, argp)) 			return -EFAULT;@@ -111,29 +112,28 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, 	pc->flags |= PC_FLAG_WRITING; } -static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)+static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc) { 	struct ide_disk_obj *floppy = drive->driver_data;-	struct ide_atapi_pc pc;  	drive->atapi_flags &= ~IDE_AFLAG_SRFP; -	ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);-	pc.flags |= PC_FLAG_SUPPRESS_ERROR;+	ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE);+	pc->flags |= PC_FLAG_SUPPRESS_ERROR; -	if (ide_queue_pc_tail(drive, floppy->disk, &pc))+	if (ide_queue_pc_tail(drive, floppy->disk, pc)) 		return 1; -	if (pc.buf[8 + 2] & 0x40)+	if (pc->buf[8 + 2] & 0x40) 		drive->atapi_flags |= IDE_AFLAG_SRFP;  	return 0; } -static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)+static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,+				  int __user *arg) { 	struct ide_disk_obj *floppy = drive->driver_data;-	struct ide_atapi_pc pc; 	int blocks, length, flags, err = 0;  	if (floppy->openers > 1) {@@ -166,10 +166,10 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) 		goto out; 	} -	(void)ide_floppy_get_sfrp_bit(drive);-	ide_floppy_create_format_unit_cmd(&pc, blocks, length, flags);+	ide_floppy_get_sfrp_bit(drive, pc);+	ide_floppy_create_format_unit_cmd(pc, blocks, length, flags); -	if (ide_queue_pc_tail(drive, floppy->disk, &pc))+	if (ide_queue_pc_tail(drive, floppy->disk, pc)) 		err = -EIO;  out:@@ -188,15 +188,16 @@ out:  * the dsc bit, and return either 0 or 65536.  */ -static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)+static int ide_floppy_get_format_progress(ide_drive_t *drive,+					  struct ide_atapi_pc *pc,+					  int __user *arg) { 	struct ide_disk_obj *floppy = drive->driver_data;-	struct ide_atapi_pc pc; 	int progress_indication = 0x10000;  	if (drive->atapi_flags & IDE_AFLAG_SRFP) {-		ide_create_request_sense_cmd(drive, &pc);-		if (ide_queue_pc_tail(drive, floppy->disk, &pc))+		ide_create_request_sense_cmd(drive, pc);+		if (ide_queue_pc_tail(drive, floppy->disk, pc)) 			return -EIO;  		if (floppy->sense_key == 2 &&@@ -241,20 +242,21 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, 	return 0; } -static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode,-				   unsigned int cmd, void __user *argp)+static int ide_floppy_format_ioctl(ide_drive_t *drive, struct ide_atapi_pc *pc,+				   fmode_t mode, unsigned int cmd,+				   void __user *argp) { 	switch (cmd) { 	case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: 		return 0; 	case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:-		return ide_floppy_get_format_capacities(drive, argp);+		return ide_floppy_get_format_capacities(drive, pc, argp); 	case IDEFLOPPY_IOCTL_FORMAT_START: 		if (!(mode & FMODE_WRITE)) 			return -EPERM;-		return ide_floppy_format_unit(drive, (int __user *)argp);+		return ide_floppy_format_unit(drive, pc, (int __user *)argp); 	case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:-		return ide_floppy_get_format_progress(drive, argp);+		return ide_floppy_get_format_progress(drive, pc, argp); 	default: 		return -ENOTTY; 	}@@ -270,7 +272,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, 	if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) 		return ide_floppy_lockdoor(drive, &pc, arg, cmd); -	err = ide_floppy_format_ioctl(drive, mode, cmd, argp);+	err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp); 	if (err != -ENOTTY) 		return err; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.cindex ecacc00..1c36a8e 100644--- a/drivers/ide/ide-io.c+++ b/drivers/ide/ide-io.c@@ -426,9 +426,6 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq) 	ide_hwif_t *hwif = drive->hwif; 	struct scatterlist *sg = hwif->sg_table; -	if (hwif->sg_mapped)	/* needed by ide-scsi */-		return;- 	if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { 		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); 	} else {@@ -667,85 +664,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) 	drive->sleep = timeout + jiffies; 	drive->dev_flags |= IDE_DFLAG_SLEEPING; }- EXPORT_SYMBOL(ide_stall_queue); -#define WAKEUP(drive)	((drive)->service_start + 2 * (drive)->service_time)--/**- *	choose_drive		-	select a drive to service- *	@hwgroup: hardware group to select on- *- *	choose_drive() selects the next drive which will be serviced.- *	This is necessary because the IDE layer can't issue commands- *	to both drives on the same cable, unlike SCSI.- */- -static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)-{-	ide_drive_t *drive, *best;--repeat:	-	best = NULL;-	drive = hwgroup->drive;--	/*-	 * drive is doing pre-flush, ordered write, post-flush sequence. even-	 * though that is 3 requests, it must be seen as a single transaction.-	 * we must not preempt this drive until that is complete-	 */-	if (blk_queue_flushing(drive->queue)) {-		/*-		 * small race where queue could get replugged during-		 * the 3-request flush cycle, just yank the plug since-		 * we want it to finish asap-		 */-		blk_remove_plug(drive->queue);-		return drive;-	}--	do {-		u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING);-		u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING));--		if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) &&-		    !elv_queue_empty(drive->queue)) {-			if (best == NULL ||-			    (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) ||-			    (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) {-				if (!blk_queue_plugged(drive->queue))-					best = drive;-			}-		}-	} while ((drive = drive->next) != hwgroup->drive);--	if (best && (best->dev_flags & IDE_DFLAG_NICE1) &&-	    (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 &&-	    best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {-		long t = (signed long)(WAKEUP(best) - jiffies);-		if (t >= WAIT_MIN_SLEEP) {-		/*-		 * We *may* have some time to spare, but first let's see if-		 * someone can potentially benefit from our nice mood today..-		 */-			drive = best->next;-			do {-				if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0-				 && time_before(jiffies - best->service_time, WAKEUP(drive))-				 && time_before(WAKEUP(drive), jiffies + t))-				{-					ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));-					goto repeat;-				}-			} while ((drive = drive->next) != best);-		}-	}-	return best;-}- /*  * Issue a new request to a drive from hwgroup- * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..);  *  * A hwgroup is a serialized group of IDE interfaces.  Usually there is  * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)@@ -757,8 +679,7 @@ repeat:  * possibly along with many other devices.  This is especially common in  * PCI-based systems with off-board IDE controller cards.  *- * The IDE driver uses a per-hwgroup spinlock to protect- * access to the request queues, and to protect the hwgroup->busy flag.+ * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.  *  * The first thread into the driver for a particular hwgroup sets the  * hwgroup->busy flag to indicate that this hwgroup is now active,@@ -778,69 +699,41 @@ repeat:  * the driver.  This makes the driver much more friendlier to shared IRQs  * than previous designs, while remaining 100% (?) SMP safe and capable.  */-static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)+void do_ide_request(struct request_queue *q) {-	ide_drive_t	*drive;-	ide_hwif_t	*hwif;+	ide_drive_t	*drive = q->queuedata;+	ide_hwif_t	*hwif = drive->hwif;+	ide_hwgroup_t	*hwgroup = hwif->hwgroup; 	struct request	*rq; 	ide_startstop_t	startstop;-	int             loops = 0;--	/* caller must own hwgroup->lock */-	BUG_ON(!irqs_disabled());--	while (!hwgroup->busy) {-		hwgroup->busy = 1;-		/* for atari only */-		ide_get_lock(ide_intr, hwgroup);-		drive = choose_drive(hwgroup);-		if (drive == NULL) {-			int sleeping = 0;-			unsigned long sleep = 0; /* shut up, gcc */-			hwgroup->rq = NULL;-			drive = hwgroup->drive;-			do {-				if ((drive->dev_flags & IDE_DFLAG_SLEEPING) &&-				    (sleeping == 0 ||-				     time_before(drive->sleep, sleep))) {-					sleeping = 1;-					sleep = drive->sleep;-				}-			} while ((drive = drive->next) != hwgroup->drive);-			if (sleeping) {++	/*+	 * drive is doing pre-flush, ordered write, post-flush sequence. even+	 * though that is 3 requests, it must be seen as a single transaction.+	 * we must not preempt this drive until that is complete+	 */+	if (blk_queue_flushing(q)) 		/*-		 * Take a short snooze, and then wake up this hwgroup again.-		 * This gives other hwgroups on the same a chance to-		 * play fairly with us, just in case there are big differences-		 * in relative throughputs.. don't want to hog the cpu too much.+		 * small race where queue could get replugged during+		 * the 3-request flush cycle, just yank the plug since+		 * we want it to finish asap 		 */-				if (time_before(sleep, jiffies + WAIT_MIN_SLEEP))-					sleep = jiffies + WAIT_MIN_SLEEP;-#if 1-				if (timer_pending(&hwgroup->timer))-					printk(KERN_CRIT "ide_set_handler: timer already active\n");-#endif-				/* so that ide_timer_expiry knows what to do */-				hwgroup->sleeping = 1;-				hwgroup->req_gen_timer = hwgroup->req_gen;-				mod_timer(&hwgroup->timer, sleep);-				/* we purposely leave hwgroup->busy==1-				 * while sleeping */-			} else {-				/* Ugly, but how can we sleep for the lock-				 * otherwise? perhaps from tq_disk?-				 */+		blk_remove_plug(q); -				/* for atari only */-				ide_release_lock();-				hwgroup->busy = 0;-			}+	spin_unlock_irq(q->queue_lock);+	spin_lock_irq(&hwgroup->lock);++	if (!ide_lock_hwgroup(hwgroup)) {+repeat:+		hwgroup->rq = NULL; -			/* no more work for this hwgroup (for now) */-			return;+		if (drive->dev_flags & IDE_DFLAG_SLEEPING) {+			if (time_before(drive->sleep, jiffies)) {+				ide_unlock_hwgroup(hwgroup);+				goto plug_device;+			} 		}-	again:-		hwif = HWIF(drive);+ 		if (hwif != hwgroup->hwif) { 			/* 			 * set nIEN for previous hwif, drives in the@@ -852,16 +745,20 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) 		hwgroup->hwif = hwif; 		hwgroup->drive = drive; 		drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);-		drive->service_start = jiffies; +		spin_unlock_irq(&hwgroup->lock);+		spin_lock_irq(q->queue_lock); 		/* 		 * we know that the queue isn't empty, but this can happen 		 * if the q->prep_rq_fn() decides to kill a request 		 */ 		rq = elv_next_request(drive->queue);+		spin_unlock_irq(q->queue_lock);+		spin_lock_irq(&hwgroup->lock);+ 		if (!rq) {-			hwgroup->busy = 0;-			break;+			ide_unlock_hwgroup(hwgroup);+			goto out; 		}  		/*@@ -876,53 +773,36 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) 		 * though. I hope that doesn't happen too much, hopefully not 		 * unless the subdriver triggers such a thing in its own PM 		 * state machine.-		 *-		 * We count how many times we loop here to make sure we service-		 * all drives in the hwgroup without looping for ever 		 */ 		if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && 		    blk_pm_request(rq) == 0 && 		    (rq->cmd_flags & REQ_PREEMPT) == 0) {-			drive = drive->next ? drive->next : hwgroup->drive;-			if (loops++ < 4 && !blk_queue_plugged(drive->queue))-				goto again;-			/* We clear busy, there should be no pending ATA command at this point. */-			hwgroup->busy = 0;-			break;+			/* there should be no pending command at this point */+			ide_unlock_hwgroup(hwgroup);+			goto plug_device; 		}  		hwgroup->rq = rq; -		/*-		 * Some systems have trouble with IDE IRQs arriving while-		 * the driver is still setting things up.  So, here we disable-		 * the IRQ used by this interface while the request is being started.-		 * This may look bad at first, but pretty much the same thing-		 * happens anyway when any interrupt comes in, IDE or otherwise-		 *  -- the kernel masks the IRQ while it is being handled.-		 */-		if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)-			disable_irq_nosync(hwif->irq);-		spin_unlock(&hwgroup->lock);-		local_irq_enable_in_hardirq();-			/* allow other IRQs while we start this request */+		spin_unlock_irq(&hwgroup->lock); 		startstop = start_request(drive, rq); 		spin_lock_irq(&hwgroup->lock);-		if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)-			enable_irq(hwif->irq);+ 		if (startstop == ide_stopped)-			hwgroup->busy = 0;-	}-}+			goto repeat;+	} else+		goto plug_device;+out:+	spin_unlock_irq(&hwgroup->lock);+	spin_lock_irq(q->queue_lock);+	return; -/*- * Passes the stuff to ide_do_request- */-void do_ide_request(struct request_queue *q)-{-	ide_drive_t *drive = q->queuedata;+plug_device:+	spin_unlock_irq(&hwgroup->lock);+	spin_lock_irq(q->queue_lock); -	ide_do_request(HWGROUP(drive), IDE_NO_IRQ);+	if (!elv_queue_empty(q))+		blk_plug_device(q); }  /*@@ -983,6 +863,17 @@ out: 	return ret; } +static void ide_plug_device(ide_drive_t *drive)+{+	struct request_queue *q = drive->queue;+	unsigned long flags;++	spin_lock_irqsave(q->queue_lock, flags);+	if (!elv_queue_empty(q))+		blk_plug_device(q);+	spin_unlock_irqrestore(q->queue_lock, flags);+}+ /**  *	ide_timer_expiry	-	handle lack of an IDE interrupt  *	@data: timer callback magic (hwgroup)@@ -1000,10 +891,12 @@ out: void ide_timer_expiry (unsigned long data) { 	ide_hwgroup_t	*hwgroup = (ide_hwgroup_t *) data;+	ide_drive_t	*uninitialized_var(drive); 	ide_handler_t	*handler; 	ide_expiry_t	*expiry; 	unsigned long	flags; 	unsigned long	wait = -1;+	int		plug_device = 0;  	spin_lock_irqsave(&hwgroup->lock, flags); @@ -1015,22 +908,15 @@ void ide_timer_expiry (unsigned long data) 		 * or we were "sleeping" to give other devices a chance. 		 * Either way, we don't really want to complain about anything. 		 */-		if (hwgroup->sleeping) {-			hwgroup->sleeping = 0;-			hwgroup->busy = 0;-		} 	} else {-		ide_drive_t *drive = hwgroup->drive;+		drive = hwgroup->drive; 		if (!drive) { 			printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); 			hwgroup->handler = NULL; 		} else { 			ide_hwif_t *hwif; 			ide_startstop_t startstop = ide_stopped;-			if (!hwgroup->busy) {-				hwgroup->busy = 1;	/* paranoia */-				printk(KERN_ERR "%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name);-			}+ 			if ((expiry = hwgroup->expiry) != NULL) { 				/* continue */ 				if ((wait = expiry(drive)) > 0) {@@ -1071,15 +957,18 @@ void ide_timer_expiry (unsigned long data) 					ide_error(drive, "irq timeout", 						  hwif->tp_ops->read_status(hwif)); 			}-			drive->service_time = jiffies - drive->service_start; 			spin_lock_irq(&hwgroup->lock); 			enable_irq(hwif->irq);-			if (startstop == ide_stopped)-				hwgroup->busy = 0;+			if (startstop == ide_stopped) {+				ide_unlock_hwgroup(hwgroup);+				plug_device = 1;+			} 		} 	}-	ide_do_request(hwgroup, IDE_NO_IRQ); 	spin_unlock_irqrestore(&hwgroup->lock, flags);++	if (plug_device)+		ide_plug_device(drive); }  /**@@ -1173,10 +1062,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) 	unsigned long flags; 	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; 	ide_hwif_t *hwif = hwgroup->hwif;-	ide_drive_t *drive;+	ide_drive_t *uninitialized_var(drive); 	ide_handler_t *handler; 	ide_startstop_t startstop; 	irqreturn_t irq_ret = IRQ_NONE;+	int plug_device = 0;  	spin_lock_irqsave(&hwgroup->lock, flags); @@ -1241,10 +1131,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) 		 */ 		goto out; -	if (!hwgroup->busy) {-		hwgroup->busy = 1;	/* paranoia */-		printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);-	} 	hwgroup->handler = NULL; 	hwgroup->req_gen++; 	del_timer(&hwgroup->timer);@@ -1267,20 +1153,22 @@ irqreturn_t ide_intr (int irq, void *dev_id) 	 * same irq as is currently being serviced here, and Linux 	 * won't allow another of the same (on any CPU) until we return. 	 */-	drive->service_time = jiffies - drive->service_start; 	if (startstop == ide_stopped) { 		if (hwgroup->handler == NULL) {	/* paranoia */-			hwgroup->busy = 0;-			ide_do_request(hwgroup, hwif->irq);-		} else {-			printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler "-				"on exit\n", drive->name);-		}+			ide_unlock_hwgroup(hwgroup);+			plug_device = 1;+		} else+			printk(KERN_ERR "%s: %s: huh? expected NULL handler "+					"on exit\n", __func__, drive->name); 	} out_handled: 	irq_ret = IRQ_HANDLED; out: 	spin_unlock_irqrestore(&hwgroup->lock, flags);++	if (plug_device)+		ide_plug_device(drive);+ 	return irq_ret; } diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.cindex 28232c6..1be263e 100644--- a/drivers/ide/ide-ioctls.c+++ b/drivers/ide/ide-ioctls.c@@ -95,8 +95,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) 		return -EPERM;  	if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) &&-	    (drive->media != ide_tape ||-	     (drive->dev_flags & IDE_DFLAG_SCSI)))+	    (drive->media != ide_tape)) 		return -EPERM;  	if ((arg >> IDE_NICE_DSC_OVERLAP) & 1)diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.cindex 63d01c5..678454a 100644--- a/drivers/ide/ide-park.c+++ b/drivers/ide/ide-park.c@@ -16,16 +16,19 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) 	spin_lock_irq(&hwgroup->lock); 	if (drive->dev_flags & IDE_DFLAG_PARKED) { 		int reset_timer = time_before(timeout, drive->sleep);+		int start_queue = 0;  		drive->sleep = timeout; 		wake_up_all(&ide_park_wq);-		if (reset_timer && hwgroup->sleeping &&-		    del_timer(&hwgroup->timer)) {-			hwgroup->sleeping = 0;-			hwgroup->busy = 0;+		if (reset_timer && del_timer(&hwgroup->timer))+			start_queue = 1;+		spin_unlock_irq(&hwgroup->lock);++		if (start_queue) {+			spin_lock_irq(q->queue_lock); 			blk_start_queueing(q);+			spin_unlock_irq(q->queue_lock); 		}-		spin_unlock_irq(&hwgroup->lock); 		return; 	} 	spin_unlock_irq(&hwgroup->lock);diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.cindex a64ec25..c5adb7b 100644--- a/drivers/ide/ide-probe.c+++ b/drivers/ide/ide-probe.c@@ -101,6 +101,82 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) 	} } +static void ide_classify_ata_dev(ide_drive_t *drive)+{+	u16 *id = drive->id;+	char *m = (char *)&id[ATA_ID_PROD];+	int is_cfa = ata_id_is_cfa(id);++	/* CF devices are *not* removable in Linux definition of the term */+	if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))+		drive->dev_flags |= IDE_DFLAG_REMOVABLE;++	drive->media = ide_disk;++	if (!ata_id_has_unload(drive->id))+		drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;++	printk(KERN_INFO "%s: %s, %s DISK drive\n", drive->name, m,+		is_cfa ? "CFA" : "ATA");+}++static void ide_classify_atapi_dev(ide_drive_t *drive)+{+	u16 *id = drive->id;+	char *m = (char *)&id[ATA_ID_PROD];+	u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;++	printk(KERN_INFO "%s: %s, ATAPI ", drive->name, m);+	switch (type) {+	case ide_floppy:+		if (!strstr(m, "CD-ROM")) {+			if (!strstr(m, "oppy") &&+			    !strstr(m, "poyp") &&+			    !strstr(m, "ZIP"))+				printk(KERN_CONT "cdrom or floppy?, assuming ");+			if (drive->media != ide_cdrom) {+				printk(KERN_CONT "FLOPPY");+				drive->dev_flags |= IDE_DFLAG_REMOVABLE;+				break;+			}+		}+		/* Early cdrom models used zero */+		type = ide_cdrom;+	case ide_cdrom:+		drive->dev_flags |= IDE_DFLAG_REMOVABLE;+#ifdef CONFIG_PPC+		/* kludge for Apple PowerBook internal zip */+		if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) {+			printk(KERN_CONT "FLOPPY");+			type = ide_floppy;+			break;+		}+#endif+		printk(KERN_CONT "CD/DVD-ROM");+		break;+	case ide_tape:+		printk(KERN_CONT "TAPE");+		break;+	case ide_optical:+		printk(KERN_CONT "OPTICAL");+		drive->dev_flags |= IDE_DFLAG_REMOVABLE;+		break;+	default:+		printk(KERN_CONT "UNKNOWN (type %d)", type);+		break;+	}++	printk(KERN_CONT " drive\n");+	drive->media = type;+	/* an ATAPI device ignores DRDY */+	drive->ready_stat = 0;+	if (ata_id_cdb_intr(id))+		drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;+	drive->dev_flags |= IDE_DFLAG_DOORLOCKING;+	/* we don't do head unloading on ATAPI devices */+	drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;+}+ /**  *	do_identify	-	identify a drive  *	@drive: drive to identify @@ -117,7 +193,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd) 	u16 *id = drive->id; 	char *m = (char *)&id[ATA_ID_PROD]; 	unsigned long flags;-	int bswap = 1, is_cfa;+	int bswap = 1;  	/* local CPU only; some systems need this */ 	local_irq_save(flags);@@ -154,91 +230,23 @@ static void do_identify(ide_drive_t *drive, u8 cmd) 	if (strstr(m, "E X A B Y T E N E S T")) 		goto err_misc; -	printk(KERN_INFO "%s: %s, ", drive->name, m);- 	drive->dev_flags |= IDE_DFLAG_PRESENT; 	drive->dev_flags &= ~IDE_DFLAG_DEAD;  	/* 	 * Check for an ATAPI device 	 */-	if (cmd == ATA_CMD_ID_ATAPI) {-		u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;--		printk(KERN_CONT "ATAPI ");-		switch (type) {-			case ide_floppy:-				if (!strstr(m, "CD-ROM")) {-					if (!strstr(m, "oppy") &&-					    !strstr(m, "poyp") &&-					    !strstr(m, "ZIP"))-						printk(KERN_CONT "cdrom or floppy?, assuming ");-					if (drive->media != ide_cdrom) {-						printk(KERN_CONT "FLOPPY");-						drive->dev_flags |= IDE_DFLAG_REMOVABLE;-						break;-					}-				}-				/* Early cdrom models used zero */-				type = ide_cdrom;-			case ide_cdrom:-				drive->dev_flags |= IDE_DFLAG_REMOVABLE;-#ifdef CONFIG_PPC-				/* kludge for Apple PowerBook internal zip */-				if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) {-					printk(KERN_CONT "FLOPPY");-					type = ide_floppy;-					break;-				}-#endif-				printk(KERN_CONT "CD/DVD-ROM");-				break;-			case ide_tape:-				printk(KERN_CONT "TAPE");-				break;-			case ide_optical:-				printk(KERN_CONT "OPTICAL");-				drive->dev_flags |= IDE_DFLAG_REMOVABLE;-				break;-			default:-				printk(KERN_CONT "UNKNOWN (type %d)", type);-				break;-		}-		printk(KERN_CONT " drive\n");-		drive->media = type;-		/* an ATAPI device ignores DRDY */-		drive->ready_stat = 0;-		if (ata_id_cdb_intr(id))-			drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;-		drive->dev_flags |= IDE_DFLAG_DOORLOCKING;-		/* we don't do head unloading on ATAPI devices */-		drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;-		return;-	}-+	if (cmd == ATA_CMD_ID_ATAPI)+		ide_classify_atapi_dev(drive);+	else 	/* 	 * Not an ATAPI device: looks like a "regular" hard disk 	 */--	is_cfa = ata_id_is_cfa(id);--	/* CF devices are *not* removable in Linux definition of the term */-	if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))-		drive->dev_flags |= IDE_DFLAG_REMOVABLE;--	drive->media = ide_disk;--	if (!ata_id_has_unload(drive->id))-		drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;--	printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA");-+		ide_classify_ata_dev(drive); 	return;- err_misc: 	kfree(id); 	drive->dev_flags &= ~IDE_DFLAG_PRESENT;-	return; }  /**@@ -641,14 +649,9 @@ static int ide_register_port(ide_hwif_t *hwif) 	/* register with global device tree */ 	dev_set_name(&hwif->gendev, hwif->name); 	hwif->gendev.driver_data = hwif;-	if (hwif->gendev.parent == NULL) {-		if (hwif->dev)-			hwif->gendev.parent = hwif->dev;-		else-			/* Would like to do = &device_legacy */-			hwif->gendev.parent = NULL;-	}+	hwif->gendev.parent = hwif->dev; 	hwif->gendev.release = hwif_release_dev;+ 	ret = device_register(&hwif->gendev); 	if (ret < 0) { 		printk(KERN_WARNING "IDE: %s: device_register error: %d\n",@@ -878,8 +881,7 @@ static int ide_init_queue(ide_drive_t *drive) 	 *	do not. 	 */ -	q = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock,-				hwif_to_node(hwif));+	q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif)); 	if (!q) 		return 1; @@ -1139,8 +1141,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data)  	if (drive->media == ide_disk) 		request_module("ide-disk");-	if (drive->dev_flags & IDE_DFLAG_SCSI)-		request_module("ide-scsi"); 	if (drive->media == ide_cdrom || drive->media == ide_optical) 		request_module("ide-cd"); 	if (drive->media == ide_tape)@@ -1417,58 +1417,6 @@ static void ide_port_cable_detect(ide_hwif_t *hwif) 	} } -static ssize_t store_delete_devices(struct device *portdev,-				    struct device_attribute *attr,-				    const char *buf, size_t n)-{-	ide_hwif_t *hwif = dev_get_drvdata(portdev);--	if (strncmp(buf, "1", n))-		return -EINVAL;--	ide_port_unregister_devices(hwif);--	return n;-};--static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);--static ssize_t store_scan(struct device *portdev,-			  struct device_attribute *attr,-			  const char *buf, size_t n)-{-	ide_hwif_t *hwif = dev_get_drvdata(portdev);--	if (strncmp(buf, "1", n))-		return -EINVAL;--	ide_port_unregister_devices(hwif);-	ide_port_scan(hwif);--	return n;-};--static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);--static struct device_attribute *ide_port_attrs[] = {-	&dev_attr_delete_devices,-	&dev_attr_scan,-	NULL-};--static int ide_sysfs_register_port(ide_hwif_t *hwif)-{-	int i, uninitialized_var(rc);--	for (i = 0; ide_port_attrs[i]; i++) {-		rc = device_create_file(hwif->portdev, ide_port_attrs[i]);-		if (rc)-			break;-	}--	return rc;-}- static unsigned int ide_indexes;  /**@@ -1655,9 +1603,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, 		if (hwif == NULL) 			continue; -		if (hwif->chipset == ide_unknown)-			hwif->chipset = ide_generic;- 		if (hwif->present) 			hwif_register_devices(hwif); 	}diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.cnew file mode 100644index 0000000..883ffac--- /dev/null+++ b/drivers/ide/ide-sysfs.c@@ -0,0 +1,125 @@+#include <linux/kernel.h>+#include <linux/ide.h>++char *ide_media_string(ide_drive_t *drive)+{+	switch (drive->media) {+	case ide_disk:+		return "disk";+	case ide_cdrom:+		return "cdrom";+	case ide_tape:+		return "tape";+	case ide_floppy:+		return "floppy";+	case ide_optical:+		return "optical";+	default:+		return "UNKNOWN";+	}+}++static ssize_t media_show(struct device *dev, struct device_attribute *attr,+			  char *buf)+{+	ide_drive_t *drive = to_ide_device(dev);+	return sprintf(buf, "%s\n", ide_media_string(drive));+}++static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,+			      char *buf)+{+	ide_drive_t *drive = to_ide_device(dev);+	return sprintf(buf, "%s\n", drive->name);+}++static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,+			     char *buf)+{+	ide_drive_t *drive = to_ide_device(dev);+	return sprintf(buf, "ide:m-%s\n", ide_media_string(drive));+}++static ssize_t model_show(struct device *dev, struct device_attribute *attr,+			  char *buf)+{+	ide_drive_t *drive = to_ide_device(dev);+	return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);+}++static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,+			     char *buf)+{+	ide_drive_t *drive = to_ide_device(dev);+	return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);+}++static ssize_t serial_show(struct device *dev, struct device_attribute *attr,+			   char *buf)+{+	ide_drive_t *drive = to_ide_device(dev);+	return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);+}++struct device_attribute ide_dev_attrs[] = {+	__ATTR_RO(media),+	__ATTR_RO(drivename),+	__ATTR_RO(modalias),+	__ATTR_RO(model),+	__ATTR_RO(firmware),+	__ATTR(serial, 0400, serial_show, NULL),+	__ATTR(unload_heads, 0644, ide_park_show, ide_park_store),+	__ATTR_NULL+};++static ssize_t store_delete_devices(struct device *portdev,+				    struct device_attribute *attr,+				    const char *buf, size_t n)+{+	ide_hwif_t *hwif = dev_get_drvdata(portdev);++	if (strncmp(buf, "1", n))+		return -EINVAL;++	ide_port_unregister_devices(hwif);++	return n;+};++static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);++static ssize_t store_scan(struct device *portdev,+			  struct device_attribute *attr,+			  const char *buf, size_t n)+{+	ide_hwif_t *hwif = dev_get_drvdata(portdev);++	if (strncmp(buf, "1", n))+		return -EINVAL;++	ide_port_unregister_devices(hwif);+	ide_port_scan(hwif);++	return n;+};++static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);++static struct device_attribute *ide_port_attrs[] = {+	&dev_attr_delete_devices,+	&dev_attr_scan,+	NULL+};++int ide_sysfs_register_port(ide_hwif_t *hwif)+{+	int i, uninitialized_var(rc);++	for (i = 0; ide_port_attrs[i]; i++) {+		rc = device_create_file(hwif->portdev, ide_port_attrs[i]);+		if (rc)+			break;+	}++	return rc;+}diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.cindex a2d470e..5d2aa22 100644--- a/drivers/ide/ide-tape.c+++ b/drivers/ide/ide-tape.c@@ -694,7 +694,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,  	pc->retries++; -	return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL);+	return ide_issue_pc(drive); }  /* A mode sense command is used to "sense" tape parameters. */diff --git a/drivers/ide/ide.c b/drivers/ide/ide.cindex f0f09f7..46a2d4c 100644--- a/drivers/ide/ide.c+++ b/drivers/ide/ide.c@@ -440,81 +440,13 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv) 	return 1; } -static char *media_string(ide_drive_t *drive)-{-	switch (drive->media) {-	case ide_disk:-		return "disk";-	case ide_cdrom:-		return "cdrom";-	case ide_tape:-		return "tape";-	case ide_floppy:-		return "floppy";-	case ide_optical:-		return "optical";-	default:-		return "UNKNOWN";-	}-}--static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)-{-	ide_drive_t *drive = to_ide_device(dev);-	return sprintf(buf, "%s\n", media_string(drive));-}--static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)-{-	ide_drive_t *drive = to_ide_device(dev);-	return sprintf(buf, "%s\n", drive->name);-}--static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)-{-	ide_drive_t *drive = to_ide_device(dev);-	return sprintf(buf, "ide:m-%s\n", media_string(drive));-}--static ssize_t model_show(struct device *dev, struct device_attribute *attr,-			  char *buf)-{-	ide_drive_t *drive = to_ide_device(dev);-	return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);-}--static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,-			     char *buf)-{-	ide_drive_t *drive = to_ide_device(dev);-	return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);-}--static ssize_t serial_show(struct device *dev, struct device_attribute *attr,-			   char *buf)-{-	ide_drive_t *drive = to_ide_device(dev);-	return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);-}--static struct device_attribute ide_dev_attrs[] = {-	__ATTR_RO(media),-	__ATTR_RO(drivename),-	__ATTR_RO(modalias),-	__ATTR_RO(model),-	__ATTR_RO(firmware),-	__ATTR(serial, 0400, serial_show, NULL),-	__ATTR(unload_heads, 0644, ide_park_show, ide_park_store),-	__ATTR_NULL-};- static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) { 	ide_drive_t *drive = to_ide_device(dev); -	add_uevent_var(env, "MEDIA=%s", media_string(drive));+	add_uevent_var(env, "MEDIA=%s", ide_media_string(drive)); 	add_uevent_var(env, "DRIVENAME=%s", drive->name);-	add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive));+	add_uevent_var(env, "MODALIAS=ide:m-%s", ide_media_string(drive)); 	return 0; } diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.cindex 13b63e7..b4ef218 100644--- a/drivers/ide/tx4938ide.c+++ b/drivers/ide/tx4938ide.c@@ -216,16 +216,17 @@ static const struct ide_tp_ops tx4938ide_tp_ops = { #endif	/* __BIG_ENDIAN */  static const struct ide_port_ops tx4938ide_port_ops = {-	.set_pio_mode = tx4938ide_set_pio_mode,+	.set_pio_mode		= tx4938ide_set_pio_mode, };  static const struct ide_port_info tx4938ide_port_info __initdata = {-	.port_ops = &tx4938ide_port_ops,+	.port_ops		= &tx4938ide_port_ops, #ifdef __BIG_ENDIAN-	.tp_ops = &tx4938ide_tp_ops,+	.tp_ops			= &tx4938ide_tp_ops, #endif-	.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,-	.pio_mask = ATA_PIO5,+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,+	.pio_mask		= ATA_PIO5,+	.chipset		= ide_generic, };  static int __init tx4938ide_probe(struct platform_device *pdev)diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.cindex 97cd9e0..4a8c5a2 100644--- a/drivers/ide/tx4939ide.c+++ b/drivers/ide/tx4939ide.c@@ -623,33 +623,34 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { #endif	/* __LITTLE_ENDIAN */  static const struct ide_port_ops tx4939ide_port_ops = {-	.set_pio_mode = tx4939ide_set_pio_mode,-	.set_dma_mode = tx4939ide_set_dma_mode,-	.clear_irq = tx4939ide_clear_irq,-	.cable_detect = tx4939ide_cable_detect,+	.set_pio_mode		= tx4939ide_set_pio_mode,+	.set_dma_mode		= tx4939ide_set_dma_mode,+	.clear_irq		= tx4939ide_clear_irq,+	.cable_detect		= tx4939ide_cable_detect, };  static const struct ide_dma_ops tx4939ide_dma_ops = {-	.dma_host_set = tx4939ide_dma_host_set,-	.dma_setup = tx4939ide_dma_setup,-	.dma_exec_cmd = ide_dma_exec_cmd,-	.dma_start = ide_dma_start,-	.dma_end = tx4939ide_dma_end,-	.dma_test_irq = tx4939ide_dma_test_irq,-	.dma_lost_irq = ide_dma_lost_irq,-	.dma_timeout = ide_dma_timeout,+	.dma_host_set		= tx4939ide_dma_host_set,+	.dma_setup		= tx4939ide_dma_setup,+	.dma_exec_cmd		= ide_dma_exec_cmd,+	.dma_start		= ide_dma_start,+	.dma_end		= tx4939ide_dma_end,+	.dma_test_irq		= tx4939ide_dma_test_irq,+	.dma_lost_irq		= ide_dma_lost_irq,+	.dma_timeout		= ide_dma_timeout, };  static const struct ide_port_info tx4939ide_port_info __initdata = {-	.init_hwif = tx4939ide_init_hwif,-	.init_dma = tx4939ide_init_dma,-	.port_ops = &tx4939ide_port_ops,-	.dma_ops = &tx4939ide_dma_ops,-	.tp_ops = &tx4939ide_tp_ops,-	.host_flags = IDE_HFLAG_MMIO,-	.pio_mask = ATA_PIO4,-	.mwdma_mask = ATA_MWDMA2,-	.udma_mask = ATA_UDMA5,+	.init_hwif		= tx4939ide_init_hwif,+	.init_dma		= tx4939ide_init_dma,+	.port_ops		= &tx4939ide_port_ops,+	.dma_ops		= &tx4939ide_dma_ops,+	.tp_ops			= &tx4939ide_tp_ops,+	.host_flags		= IDE_HFLAG_MMIO,+	.pio_mask		= ATA_PIO4,+	.mwdma_mask		= ATA_MWDMA2,+	.udma_mask		= ATA_UDMA5,+	.chipset		= ide_generic, };  static int __init tx4939ide_probe(struct platform_device *pdev)diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfigindex 152d4aa..b732297 100644--- a/drivers/scsi/Kconfig+++ b/drivers/scsi/Kconfig@@ -21,7 +21,7 @@ config SCSI 	  You also need to say Y here if you have a device which speaks 	  the SCSI protocol.  Examples of this include the parallel port 	  version of the IOMEGA ZIP drive, USB storage devices, Fibre-	  Channel, FireWire storage and the IDE-SCSI emulation driver.+	  Channel, and FireWire storage.  	  To compile this driver as a module, choose M here and read 	  <file:Documentation/scsi/scsi.txt>.@@ -101,9 +101,9 @@ config CHR_DEV_OSST 	---help--- 	  The OnStream SC-x0 SCSI tape drives cannot be driven by the 	  standard st driver, but instead need this special osst driver and-	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage-	  and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives-	  as well.  Note that there is also a second generation of OnStream+	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage,+	  you may be able to drive the USB-x0 and DI-x0 drives as well.+	  Note that there is also a second generation of OnStream 	  tape drives (ADR-x0) that supports the standard SCSI-2 commands for 	  tapes (QIC-157) and can be driven by the standard driver st. 	  For more information, you may have a look at the SCSI-HOWTOdiff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefileindex 1410697..7461eb0 100644--- a/drivers/scsi/Makefile+++ b/drivers/scsi/Makefile@@ -105,7 +105,6 @@ obj-$(CONFIG_SCSI_GDTH)		+= gdth.o obj-$(CONFIG_SCSI_INITIO)	+= initio.o obj-$(CONFIG_SCSI_INIA100)	+= a100u2w.o obj-$(CONFIG_SCSI_QLOGICPTI)	+= qlogicpti.o-obj-$(CONFIG_BLK_DEV_IDESCSI)	+= ide-scsi.o obj-$(CONFIG_SCSI_MESH)		+= mesh.o obj-$(CONFIG_SCSI_MAC53C94)	+= mac53c94.o obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.odiff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.cdeleted file mode 100644index c24140a..0000000--- a/drivers/scsi/ide-scsi.c+++ /dev/null@@ -1,840 +0,0 @@-/*- * Copyright (C) 1996-1999  Gadi Oxman <gadio@xxxxxxxxxxxxxxxx>- * Copyright (C) 2004-2005  Bartlomiej Zolnierkiewicz- */--/*- * Emulation of a SCSI host adapter for IDE ATAPI devices.- *- * With this driver, one can use the Linux SCSI drivers instead of the- * native IDE ATAPI drivers.- *- * Ver 0.1   Dec  3 96   Initial version.- * Ver 0.2   Jan 26 97   Fixed bug in cleanup_module() and added emulation- *                        of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks- *                        to Janos Farkas for pointing this out.- *                       Avoid using bitfields in structures for m68k.- *                       Added Scatter/Gather and DMA support.- * Ver 0.4   Dec  7 97   Add support for ATAPI PD/CD drives.- *                       Use variable timeout for each command.- * Ver 0.5   Jan  2 98   Fix previous PD/CD support.- *                       Allow disabling of SCSI-6 to SCSI-10 transformation.- * Ver 0.6   Jan 27 98   Allow disabling of SCSI command translation layer- *                        for access through /dev/sg.- *                       Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation.- * Ver 0.7   Dec 04 98   Ignore commands where lun != 0 to avoid multiple- *                        detection of devices with CONFIG_SCSI_MULTI_LUN- * Ver 0.8   Feb 05 99   Optical media need translation too. Reverse 0.7.- * Ver 0.9   Jul 04 99   Fix a bug in SG_SET_TRANSFORM.- * Ver 0.91  Jun 10 02   Fix "off by one" error in transforms- * Ver 0.92  Dec 31 02   Implement new SCSI mid level API- */--#define IDESCSI_VERSION "0.92"--#include <linux/module.h>-#include <linux/types.h>-#include <linux/string.h>-#include <linux/kernel.h>-#include <linux/mm.h>-#include <linux/ioport.h>-#include <linux/blkdev.h>-#include <linux/errno.h>-#include <linux/slab.h>-#include <linux/ide.h>-#include <linux/scatterlist.h>-#include <linux/delay.h>-#include <linux/mutex.h>-#include <linux/bitops.h>--#include <asm/io.h>-#include <asm/uaccess.h>--#include <scsi/scsi.h>-#include <scsi/scsi_cmnd.h>-#include <scsi/scsi_device.h>-#include <scsi/scsi_host.h>-#include <scsi/scsi_tcq.h>-#include <scsi/sg.h>--#define IDESCSI_DEBUG_LOG		0--#if IDESCSI_DEBUG_LOG-#define debug_log(fmt, args...) \-	printk(KERN_INFO "ide-scsi: " fmt, ## args)-#else-#define debug_log(fmt, args...) do {} while (0)-#endif--/*- *	SCSI command transformation layer- */-#define IDESCSI_SG_TRANSFORM		1	/* /dev/sg transformation */--/*- *	Log flags- */-#define IDESCSI_LOG_CMD			0	/* Log SCSI commands */--typedef struct ide_scsi_obj {-	ide_drive_t		*drive;-	ide_driver_t		*driver;-	struct gendisk		*disk;-	struct Scsi_Host	*host;--	unsigned long transform;		/* SCSI cmd translation layer */-	unsigned long log;			/* log flags */-} idescsi_scsi_t;--static DEFINE_MUTEX(idescsi_ref_mutex);-/* Set by module param to skip cd */-static int idescsi_nocd;--#define ide_scsi_g(disk) \-	container_of((disk)->private_data, struct ide_scsi_obj, driver)--static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)-{-	struct ide_scsi_obj *scsi = NULL;--	mutex_lock(&idescsi_ref_mutex);-	scsi = ide_scsi_g(disk);-	if (scsi) {-		if (ide_device_get(scsi->drive))-			scsi = NULL;-		else-			scsi_host_get(scsi->host);-	}-	mutex_unlock(&idescsi_ref_mutex);-	return scsi;-}--static void ide_scsi_put(struct ide_scsi_obj *scsi)-{-	ide_drive_t *drive = scsi->drive;--	mutex_lock(&idescsi_ref_mutex);-	scsi_host_put(scsi->host);-	ide_device_put(drive);-	mutex_unlock(&idescsi_ref_mutex);-}--static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)-{-	return (idescsi_scsi_t*) (&host[1]);-}--static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)-{-	return scsihost_to_idescsi(ide_drive->driver_data);-}--static void ide_scsi_hex_dump(u8 *data, int len)-{-	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);-}--static int idescsi_end_request(ide_drive_t *, int, int);--static void ide_scsi_callback(ide_drive_t *drive, int dsc)-{-	idescsi_scsi_t *scsi = drive_to_idescsi(drive);-	struct ide_atapi_pc *pc = drive->pc;--	if (pc->flags & PC_FLAG_TIMEDOUT)-		debug_log("%s: got timed out packet %lu at %lu\n", __func__,-			  pc->scsi_cmd->serial_number, jiffies);-		/* end this request now - scsi should retry it*/-	else if (test_bit(IDESCSI_LOG_CMD, &scsi->log))-		printk(KERN_INFO "Packet command completed, %d bytes"-				 " transferred\n", pc->xferred);--	idescsi_end_request(drive, 1, 0);-}--static int idescsi_check_condition(ide_drive_t *drive,-		struct request *failed_cmd)-{-	idescsi_scsi_t *scsi = drive_to_idescsi(drive);-	struct ide_atapi_pc   *pc;-	struct request *rq;-	u8             *buf;--	/* stuff a sense request in front of our current request */-	pc = kzalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);-	rq = blk_get_request(drive->queue, READ, GFP_ATOMIC);-	buf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);-	if (!pc || !rq || !buf) {-		kfree(buf);-		if (rq)-			blk_put_request(rq);-		kfree(pc);-		return -ENOMEM;-	}-	rq->special = (char *) pc;-	pc->rq = rq;-	pc->buf = buf;-	pc->c[0] = REQUEST_SENSE;-	pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;-	rq->cmd_type = REQ_TYPE_SENSE;-	rq->cmd_flags |= REQ_PREEMPT;-	pc->timeout = jiffies + WAIT_READY;-	/* NOTE! Save the failed packet command in "rq->buffer" */-	rq->buffer = (void *) failed_cmd->special;-	pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;-	if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {-		printk ("ide-scsi: %s: queue cmd = ", drive->name);-		ide_scsi_hex_dump(pc->c, 6);-	}-	rq->rq_disk = scsi->disk;-	rq->ref_count++;-	memcpy(rq->cmd, pc->c, 12);-	ide_do_drive_cmd(drive, rq);-	return 0;-}--static ide_startstop_t-idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)-{-	ide_hwif_t *hwif = drive->hwif;--	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))-		/* force an abort */-		hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);--	rq->errors++;--	idescsi_end_request(drive, 0, 0);--	return ide_stopped;-}--static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)-{-	idescsi_scsi_t *scsi = drive_to_idescsi(drive);-	struct request *rq = HWGROUP(drive)->rq;-	struct ide_atapi_pc *pc = (struct ide_atapi_pc *) rq->special;-	int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);-	struct Scsi_Host *host;-	int errors = rq->errors;-	unsigned long flags;--	if (!blk_special_request(rq) && !blk_sense_request(rq)) {-		ide_end_request(drive, uptodate, nrsecs);-		return 0;-	}-	ide_end_drive_cmd (drive, 0, 0);-	if (blk_sense_request(rq)) {-		struct ide_atapi_pc *opc = (struct ide_atapi_pc *) rq->buffer;-		if (log) {-			printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number);-			ide_scsi_hex_dump(pc->buf, 16);-		}-		memcpy((void *) opc->scsi_cmd->sense_buffer, pc->buf,-			SCSI_SENSE_BUFFERSIZE);-		kfree(pc->buf);-		kfree(pc);-		blk_put_request(rq);-		pc = opc;-		rq = pc->rq;-		pc->scsi_cmd->result = (CHECK_CONDITION << 1) |-				(((pc->flags & PC_FLAG_TIMEDOUT) ?-				  DID_TIME_OUT :-				  DID_OK) << 16);-	} else if (pc->flags & PC_FLAG_TIMEDOUT) {-		if (log)-			printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n",-					drive->name, pc->scsi_cmd->serial_number);-		pc->scsi_cmd->result = DID_TIME_OUT << 16;-	} else if (errors >= ERROR_MAX) {-		pc->scsi_cmd->result = DID_ERROR << 16;-		if (log)-			printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);-	} else if (errors) {-		if (log)-			printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);-		if (!idescsi_check_condition(drive, rq))-			/* we started a request sense, so we'll be back, exit for now */-			return 0;-		pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);-	} else {-		pc->scsi_cmd->result = DID_OK << 16;-	}-	host = pc->scsi_cmd->device->host;-	spin_lock_irqsave(host->host_lock, flags);-	pc->done(pc->scsi_cmd);-	spin_unlock_irqrestore(host->host_lock, flags);-	kfree(pc);-	blk_put_request(rq);-	drive->pc = NULL;-	return 0;-}--static inline int idescsi_set_direction(struct ide_atapi_pc *pc)-{-	switch (pc->c[0]) {-		case READ_6: case READ_10: case READ_12:-			pc->flags &= ~PC_FLAG_WRITING;-			return 0;-		case WRITE_6: case WRITE_10: case WRITE_12:-			pc->flags |= PC_FLAG_WRITING;-			return 0;-		default:-			return 1;-	}-}--static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc)-{-	ide_hwif_t *hwif = drive->hwif;-	struct scatterlist *sg, *scsi_sg;-	int segments;--	if (!pc->req_xfer || pc->req_xfer % 1024)-		return 1;--	if (idescsi_set_direction(pc))-		return 1;--	sg = hwif->sg_table;-	scsi_sg = scsi_sglist(pc->scsi_cmd);-	segments = scsi_sg_count(pc->scsi_cmd);--	if (segments > hwif->sg_max_nents)-		return 1;--	hwif->sg_nents = segments;-	memcpy(sg, scsi_sg, sizeof(*sg) * segments);--	return 0;-}--static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,-		struct ide_atapi_pc *pc)-{-	/* Set the current packet command */-	drive->pc = pc;--	return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry);-}--/*- *	idescsi_do_request is our request handling function.- */-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)-{-	debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,-		  rq->cmd[0], rq->errors);-	debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",-		  rq->sector, rq->nr_sectors, rq->current_nr_sectors);--	if (blk_sense_request(rq) || blk_special_request(rq)) {-		struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;--		if ((drive->dev_flags & IDE_DFLAG_USING_DMA) &&-		    idescsi_map_sg(drive, pc) == 0)-			pc->flags |= PC_FLAG_DMA_OK;--		return idescsi_issue_pc(drive, pc);-	}-	blk_dump_rq_flags(rq, "ide-scsi: unsup command");-	idescsi_end_request (drive, 0, 0);-	return ide_stopped;-}--#ifdef CONFIG_IDE_PROC_FS-static ide_proc_entry_t idescsi_proc[] = {-	{ "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },-	{ NULL, 0, NULL, NULL }-};--#define ide_scsi_devset_get(name, field) \-static int get_##name(ide_drive_t *drive) \-{ \-	idescsi_scsi_t *scsi = drive_to_idescsi(drive); \-	return scsi->field; \-}--#define ide_scsi_devset_set(name, field) \-static int set_##name(ide_drive_t *drive, int arg) \-{ \-	idescsi_scsi_t *scsi = drive_to_idescsi(drive); \-	scsi->field = arg; \-	return 0; \-}--#define ide_scsi_devset_rw_field(_name, _field) \-ide_scsi_devset_get(_name, _field); \-ide_scsi_devset_set(_name, _field); \-IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name);--ide_devset_rw_field(bios_cyl, bios_cyl);-ide_devset_rw_field(bios_head, bios_head);-ide_devset_rw_field(bios_sect, bios_sect);--ide_scsi_devset_rw_field(transform, transform);-ide_scsi_devset_rw_field(log, log);--static const struct ide_proc_devset idescsi_settings[] = {-	IDE_PROC_DEVSET(bios_cyl,  0, 1023),-	IDE_PROC_DEVSET(bios_head, 0,  255),-	IDE_PROC_DEVSET(bios_sect, 0,	63),-	IDE_PROC_DEVSET(log,	   0,	 1),-	IDE_PROC_DEVSET(transform, 0,	 3),-	{ 0 },-};--static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive)-{-	return idescsi_proc;-}--static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive)-{-	return idescsi_settings;-}-#endif--/*- *	Driver initialization.- */-static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)-{-	clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);-#if IDESCSI_DEBUG_LOG-	set_bit(IDESCSI_LOG_CMD, &scsi->log);-#endif /* IDESCSI_DEBUG_LOG */--	drive->pc_callback	 = ide_scsi_callback;-	drive->pc_update_buffers = NULL;-	drive->pc_io_buffers	 = ide_io_buffers;--	ide_proc_register_driver(drive, scsi->driver);-}--static void ide_scsi_remove(ide_drive_t *drive)-{-	struct Scsi_Host *scsihost = drive->driver_data;-	struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);-	struct gendisk *g = scsi->disk;--	scsi_remove_host(scsihost);-	ide_proc_unregister_driver(drive, scsi->driver);--	ide_unregister_region(g);--	drive->driver_data = NULL;-	g->private_data = NULL;-	put_disk(g);--	ide_scsi_put(scsi);--	drive->dev_flags &= ~IDE_DFLAG_SCSI;-}--static int ide_scsi_probe(ide_drive_t *);--static ide_driver_t idescsi_driver = {-	.gen_driver = {-		.owner		= THIS_MODULE,-		.name		= "ide-scsi",-		.bus		= &ide_bus_type,-	},-	.probe			= ide_scsi_probe,-	.remove			= ide_scsi_remove,-	.version		= IDESCSI_VERSION,-	.do_request		= idescsi_do_request,-	.end_request		= idescsi_end_request,-	.error                  = idescsi_atapi_error,-#ifdef CONFIG_IDE_PROC_FS-	.proc_entries		= ide_scsi_proc_entries,-	.proc_devsets		= ide_scsi_proc_devsets,-#endif-};--static int idescsi_ide_open(struct block_device *bdev, fmode_t mode)-{-	struct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk);--	if (!scsi)-		return -ENXIO;--	return 0;-}--static int idescsi_ide_release(struct gendisk *disk, fmode_t mode)-{-	ide_scsi_put(ide_scsi_g(disk));-	return 0;-}--static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode,-			unsigned int cmd, unsigned long arg)-{-	struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk);-	return generic_ide_ioctl(scsi->drive, bdev, cmd, arg);-}--static struct block_device_operations idescsi_ops = {-	.owner		= THIS_MODULE,-	.open		= idescsi_ide_open,-	.release	= idescsi_ide_release,-	.locked_ioctl	= idescsi_ide_ioctl,-};--static int idescsi_slave_configure(struct scsi_device * sdp)-{-	/* Configure detected device */-	sdp->use_10_for_rw = 1;-	sdp->use_10_for_ms = 1;-	scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);-	return 0;-}--static const char *idescsi_info (struct Scsi_Host *host)-{-	return "SCSI host adapter emulation for IDE ATAPI devices";-}--static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)-{-	idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host);--	if (cmd == SG_SET_TRANSFORM) {-		if (arg)-			set_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);-		else-			clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);-		return 0;-	} else if (cmd == SG_GET_TRANSFORM)-		return put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg);-	return -EINVAL;-}--static int idescsi_queue (struct scsi_cmnd *cmd,-		void (*done)(struct scsi_cmnd *))-{-	struct Scsi_Host *host = cmd->device->host;-	idescsi_scsi_t *scsi = scsihost_to_idescsi(host);-	ide_drive_t *drive = scsi->drive;-	struct request *rq = NULL;-	struct ide_atapi_pc *pc = NULL;-	int write = cmd->sc_data_direction == DMA_TO_DEVICE;--	if (!drive) {-		scmd_printk (KERN_ERR, cmd, "drive not present\n");-		goto abort;-	}-	scsi = drive_to_idescsi(drive);-	pc = kmalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);-	rq = blk_get_request(drive->queue, write, GFP_ATOMIC);-	if (rq == NULL || pc == NULL) {-		printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name);-		goto abort;-	}--	memset (pc->c, 0, 12);-	pc->flags = 0;-	if (cmd->sc_data_direction == DMA_TO_DEVICE)-		pc->flags |= PC_FLAG_WRITING;-	pc->rq = rq;-	memcpy (pc->c, cmd->cmnd, cmd->cmd_len);-	pc->buf = NULL;-	pc->sg = scsi_sglist(cmd);-	pc->sg_cnt = scsi_sg_count(cmd);-	pc->b_count = 0;-	pc->req_xfer = pc->buf_size = scsi_bufflen(cmd);-	pc->scsi_cmd = cmd;-	pc->done = done;-	pc->timeout = jiffies + cmd->request->timeout;--	if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {-		printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);-		ide_scsi_hex_dump(cmd->cmnd, cmd->cmd_len);-		if (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) {-			printk ("ide-scsi: %s: que %lu, tsl = ", drive->name, cmd->serial_number);-			ide_scsi_hex_dump(pc->c, 12);-		}-	}--	rq->special = (char *) pc;-	rq->cmd_type = REQ_TYPE_SPECIAL;-	spin_unlock_irq(host->host_lock);-	rq->ref_count++;-	memcpy(rq->cmd, pc->c, 12);-	blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);-	spin_lock_irq(host->host_lock);-	return 0;-abort:-	kfree (pc);-	if (rq)-		blk_put_request(rq);-	cmd->result = DID_ERROR << 16;-	done(cmd);-	return 0;-}--static int idescsi_eh_abort (struct scsi_cmnd *cmd)-{-	idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);-	ide_drive_t    *drive = scsi->drive;-	ide_hwif_t     *hwif;-	ide_hwgroup_t  *hwgroup;-	int		busy;-	int             ret   = FAILED;--	struct ide_atapi_pc *pc;--	/* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */--	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))-		printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number);--	if (!drive) {-		printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n");-		WARN_ON(1);-		goto no_drive;-	}--	hwif = drive->hwif;-	hwgroup = hwif->hwgroup;--	/* First give it some more time, how much is "right" is hard to say :-(-	   FIXME - uses mdelay which causes latency? */-	busy = ide_wait_not_busy(hwif, 100);-	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))-		printk (KERN_WARNING "ide-scsi: drive did%s become ready\n", busy?" not":"");--	spin_lock_irq(&hwgroup->lock);--	/* If there is no pc running we're done (our interrupt took care of it) */-	pc = drive->pc;-	if (pc == NULL) {-		ret = SUCCESS;-		goto ide_unlock;-	}--	/* It's somewhere in flight. Does ide subsystem agree? */-	if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&-	    elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) {-		/*-		 * FIXME - not sure this condition can ever occur-		 */-		printk (KERN_ERR "ide-scsi: cmd aborted!\n");--		if (blk_sense_request(pc->rq))-			kfree(pc->buf);-		/* we need to call blk_put_request twice. */-		blk_put_request(pc->rq);-		blk_put_request(pc->rq);-		kfree(pc);-		drive->pc = NULL;--		ret = SUCCESS;-	}--ide_unlock:-	spin_unlock_irq(&hwgroup->lock);-no_drive:-	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))-		printk (KERN_WARNING "ide-scsi: abort returns %s\n", ret == SUCCESS?"success":"failed");--	return ret;-}--static int idescsi_eh_reset (struct scsi_cmnd *cmd)-{-	struct request *req;-	idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);-	ide_drive_t    *drive = scsi->drive;-	ide_hwgroup_t  *hwgroup;-	int             ready = 0;-	int             ret   = SUCCESS;--	struct ide_atapi_pc *pc;--	/* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */--	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))-		printk (KERN_WARNING "ide-scsi: reset called for %lu\n", cmd->serial_number);--	if (!drive) {-		printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_reset\n");-		WARN_ON(1);-		return FAILED;-	}--	hwgroup = drive->hwif->hwgroup;--	spin_lock_irq(cmd->device->host->host_lock);-	spin_lock(&hwgroup->lock);--	pc = drive->pc;-	if (pc)-		req = pc->rq;--	if (pc == NULL || req != hwgroup->rq || hwgroup->handler == NULL) {-		printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n");-		spin_unlock(&hwgroup->lock);-		spin_unlock_irq(cmd->device->host->host_lock);-		return FAILED;-	}--	/* kill current request */-	if (__blk_end_request(req, -EIO, 0))-		BUG();-	if (blk_sense_request(req))-		kfree(pc->buf);-	kfree(pc);-	drive->pc = NULL;-	blk_put_request(req);--	/* now nuke the drive queue */-	while ((req = elv_next_request(drive->queue))) {-		if (__blk_end_request(req, -EIO, 0))-			BUG();-	}--	hwgroup->rq = NULL;-	hwgroup->handler = NULL;-	hwgroup->busy = 1; /* will set this to zero when ide reset finished */-	spin_unlock(&hwgroup->lock);--	ide_do_reset(drive);--	/* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */--	do {-		spin_unlock_irq(cmd->device->host->host_lock);-		msleep(50);-		spin_lock_irq(cmd->device->host->host_lock);-	} while ( HWGROUP(drive)->handler );--	ready = drive_is_ready(drive);-	HWGROUP(drive)->busy--;-	if (!ready) {-		printk (KERN_ERR "ide-scsi: reset failed!\n");-		ret = FAILED;-	}--	spin_unlock_irq(cmd->device->host->host_lock);-	return ret;-}--static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,-		sector_t capacity, int *parm)-{-	idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host);-	ide_drive_t *drive = idescsi->drive;--	if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {-		parm[0] = drive->bios_head;-		parm[1] = drive->bios_sect;-		parm[2] = drive->bios_cyl;-	}-	return 0;-}--static struct scsi_host_template idescsi_template = {-	.module			= THIS_MODULE,-	.name			= "idescsi",-	.info			= idescsi_info,-	.slave_configure        = idescsi_slave_configure,-	.ioctl			= idescsi_ioctl,-	.queuecommand		= idescsi_queue,-	.eh_abort_handler	= idescsi_eh_abort,-	.eh_host_reset_handler  = idescsi_eh_reset,-	.bios_param		= idescsi_bios,-	.can_queue		= 40,-	.this_id		= -1,-	.sg_tablesize		= 256,-	.cmd_per_lun		= 5,-	.max_sectors		= 128,-	.use_clustering		= DISABLE_CLUSTERING,-	.emulated		= 1,-	.proc_name		= "ide-scsi",-};--static int ide_scsi_probe(ide_drive_t *drive)-{-	idescsi_scsi_t *idescsi;-	struct Scsi_Host *host;-	struct gendisk *g;-	static int warned;-	int err = -ENOMEM;-	u16 last_lun;--	if (!warned && drive->media == ide_cdrom) {-		printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n");-		warned = 1;-	}--	if (idescsi_nocd && drive->media == ide_cdrom)-		return -ENODEV;--	if (!strstr("ide-scsi", drive->driver_req) ||-	    drive->media == ide_disk ||-	    !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))-		return -ENODEV;--	drive->dev_flags |= IDE_DFLAG_SCSI;--	g = alloc_disk(1 << PARTN_BITS);-	if (!g)-		goto out_host_put;--	ide_init_disk(g, drive);--	host->max_id = 1;--	last_lun = drive->id[ATA_ID_LAST_LUN];-	if (last_lun)-		debug_log("%s: last_lun=%u\n", drive->name, last_lun);--	if ((last_lun & 7) != 7)-		host->max_lun = (last_lun & 7) + 1;-	else-		host->max_lun = 1;--	drive->driver_data = host;-	idescsi = scsihost_to_idescsi(host);-	idescsi->drive = drive;-	idescsi->driver = &idescsi_driver;-	idescsi->host = host;-	idescsi->disk = g;-	g->private_data = &idescsi->driver;-	err = 0;-	idescsi_setup(drive, idescsi);-	g->fops = &idescsi_ops;-	ide_register_region(g);-	err = scsi_add_host(host, &drive->gendev);-	if (!err) {-		scsi_scan_host(host);-		return 0;-	}-	/* fall through on error */-	ide_unregister_region(g);-	ide_proc_unregister_driver(drive, &idescsi_driver);--	put_disk(g);-out_host_put:-	drive->dev_flags &= ~IDE_DFLAG_SCSI;-	scsi_host_put(host);-	return err;-}--static int __init init_idescsi_module(void)-{-	return driver_register(&idescsi_driver.gen_driver);-}--static void __exit exit_idescsi_module(void)-{-	driver_unregister(&idescsi_driver.gen_driver);-}--module_param(idescsi_nocd, int, 0600);-MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd");-module_init(init_idescsi_module);-module_exit(exit_idescsi_module);-MODULE_LICENSE("GPL");diff --git a/include/linux/ide.h b/include/linux/ide.hindex e99c56d..db5ef8a 100644--- a/include/linux/ide.h+++ b/include/linux/ide.h@@ -32,13 +32,6 @@ # define SUPPORT_VLB_SYNC 1 #endif -/*- * Used to indicate "no IRQ", should be a value that cannot be an IRQ- * number.- */- -#define IDE_NO_IRQ		(-1)- typedef unsigned char	byte;	/* used everywhere */  /*@@ -403,6 +396,7 @@ enum {  * This is used for several packet commands (not for READ/WRITE commands).  */ #define IDE_PC_BUFFER_SIZE	256+#define ATAPI_WAIT_PC		(60 * HZ)  struct ide_atapi_pc { 	/* actual packet bytes */@@ -480,53 +474,53 @@ enum {  	/* ide-cd */ 	/* Drive cannot eject the disc. */-	IDE_AFLAG_NO_EJECT		= (1 << 3),+	IDE_AFLAG_NO_EJECT		= (1 << 1), 	/* Drive is a pre ATAPI 1.2 drive. */-	IDE_AFLAG_PRE_ATAPI12		= (1 << 4),+	IDE_AFLAG_PRE_ATAPI12		= (1 << 2), 	/* TOC addresses are in BCD. */-	IDE_AFLAG_TOCADDR_AS_BCD	= (1 << 5),+	IDE_AFLAG_TOCADDR_AS_BCD	= (1 << 3), 	/* TOC track numbers are in BCD. */-	IDE_AFLAG_TOCTRACKS_AS_BCD	= (1 << 6),+	IDE_AFLAG_TOCTRACKS_AS_BCD	= (1 << 4), 	/* 	 * Drive does not provide data in multiples of SECTOR_SIZE 	 * when more than one interrupt is needed. 	 */-	IDE_AFLAG_LIMIT_NFRAMES		= (1 << 7),+	IDE_AFLAG_LIMIT_NFRAMES		= (1 << 5), 	/* Saved TOC information is current. */-	IDE_AFLAG_TOC_VALID		= (1 << 9),+	IDE_AFLAG_TOC_VALID		= (1 << 6), 	/* We think that the drive door is locked. */-	IDE_AFLAG_DOOR_LOCKED		= (1 << 10),+	IDE_AFLAG_DOOR_LOCKED		= (1 << 7), 	/* SET_CD_SPEED command is unsupported. */-	IDE_AFLAG_NO_SPEED_SELECT	= (1 << 11),-	IDE_AFLAG_VERTOS_300_SSD	= (1 << 12),-	IDE_AFLAG_VERTOS_600_ESD	= (1 << 13),-	IDE_AFLAG_SANYO_3CD		= (1 << 14),-	IDE_AFLAG_FULL_CAPS_PAGE	= (1 << 15),-	IDE_AFLAG_PLAY_AUDIO_OK		= (1 << 16),-	IDE_AFLAG_LE_SPEED_FIELDS	= (1 << 17),+	IDE_AFLAG_NO_SPEED_SELECT	= (1 << 8),+	IDE_AFLAG_VERTOS_300_SSD	= (1 << 9),+	IDE_AFLAG_VERTOS_600_ESD	= (1 << 10),+	IDE_AFLAG_SANYO_3CD		= (1 << 11),+	IDE_AFLAG_FULL_CAPS_PAGE	= (1 << 12),+	IDE_AFLAG_PLAY_AUDIO_OK		= (1 << 13),+	IDE_AFLAG_LE_SPEED_FIELDS	= (1 << 14),  	/* ide-floppy */ 	/* Avoid commands not supported in Clik drive */-	IDE_AFLAG_CLIK_DRIVE		= (1 << 19),+	IDE_AFLAG_CLIK_DRIVE		= (1 << 15), 	/* Requires BH algorithm for packets */-	IDE_AFLAG_ZIP_DRIVE		= (1 << 20),+	IDE_AFLAG_ZIP_DRIVE		= (1 << 16), 	/* Supports format progress report */-	IDE_AFLAG_SRFP			= (1 << 22),+	IDE_AFLAG_SRFP			= (1 << 17),  	/* ide-tape */-	IDE_AFLAG_IGNORE_DSC		= (1 << 23),+	IDE_AFLAG_IGNORE_DSC		= (1 << 18), 	/* 0 When the tape position is unknown */-	IDE_AFLAG_ADDRESS_VALID		= (1 <<	24),+	IDE_AFLAG_ADDRESS_VALID		= (1 <<	19), 	/* Device already opened */-	IDE_AFLAG_BUSY			= (1 << 25),+	IDE_AFLAG_BUSY			= (1 << 20), 	/* Attempt to auto-detect the current user block size */-	IDE_AFLAG_DETECT_BS		= (1 << 26),+	IDE_AFLAG_DETECT_BS		= (1 << 21), 	/* Currently on a filemark */-	IDE_AFLAG_FILEMARK		= (1 << 27),+	IDE_AFLAG_FILEMARK		= (1 << 22), 	/* 0 = no tape is loaded, so we don't rewind after ejecting */-	IDE_AFLAG_MEDIUM_PRESENT	= (1 << 28),+	IDE_AFLAG_MEDIUM_PRESENT	= (1 << 23), -	IDE_AFLAG_NO_AUTOCLOSE		= (1 << 29),+	IDE_AFLAG_NO_AUTOCLOSE		= (1 << 24), };  /* device flags */@@ -565,28 +559,26 @@ enum { 	IDE_DFLAG_NODMA			= (1 << 16), 	/* powermanagment told us not to do anything, so sleep nicely */ 	IDE_DFLAG_BLOCKED		= (1 << 17),-	/* ide-scsi emulation */-	IDE_DFLAG_SCSI			= (1 << 18), 	/* sleeping & sleep field valid */-	IDE_DFLAG_SLEEPING		= (1 << 19),-	IDE_DFLAG_POST_RESET		= (1 << 20),-	IDE_DFLAG_UDMA33_WARNED		= (1 << 21),-	IDE_DFLAG_LBA48			= (1 << 22),+	IDE_DFLAG_SLEEPING		= (1 << 18),+	IDE_DFLAG_POST_RESET		= (1 << 19),+	IDE_DFLAG_UDMA33_WARNED		= (1 << 20),+	IDE_DFLAG_LBA48			= (1 << 21), 	/* status of write cache */-	IDE_DFLAG_WCACHE		= (1 << 23),+	IDE_DFLAG_WCACHE		= (1 << 22), 	/* used for ignoring ATA_DF */-	IDE_DFLAG_NOWERR		= (1 << 24),+	IDE_DFLAG_NOWERR		= (1 << 23), 	/* retrying in PIO */-	IDE_DFLAG_DMA_PIO_RETRY		= (1 << 25),-	IDE_DFLAG_LBA			= (1 << 26),+	IDE_DFLAG_DMA_PIO_RETRY		= (1 << 24),+	IDE_DFLAG_LBA			= (1 << 25), 	/* don't unload heads */-	IDE_DFLAG_NO_UNLOAD		= (1 << 27),+	IDE_DFLAG_NO_UNLOAD		= (1 << 26), 	/* heads unloaded, please don't reset port */-	IDE_DFLAG_PARKED		= (1 << 28),-	IDE_DFLAG_MEDIA_CHANGED		= (1 << 29),+	IDE_DFLAG_PARKED		= (1 << 27),+	IDE_DFLAG_MEDIA_CHANGED		= (1 << 28), 	/* write protect */-	IDE_DFLAG_WP			= (1 << 30),-	IDE_DFLAG_FORMAT_IN_PROGRESS	= (1 << 31),+	IDE_DFLAG_WP			= (1 << 29),+	IDE_DFLAG_FORMAT_IN_PROGRESS	= (1 << 30), };  struct ide_drive_s {@@ -610,8 +602,6 @@ struct ide_drive_s { 	unsigned long dev_flags;  	unsigned long sleep;		/* sleep until this time */-	unsigned long service_start;	/* time we started last request */-	unsigned long service_time;	/* service time of last request */ 	unsigned long timeout;		/* max time to wait for irq */  	special_t	special;	/* special action flags */@@ -879,8 +869,6 @@ typedef struct hwgroup_s {  		/* BOOL: protects all fields below */ 	volatile int busy;-		/* BOOL: wake us up on timer expiry */-	unsigned int sleeping	: 1; 		/* BOOL: polling active & poll_timeout field valid */ 	unsigned int polling	: 1; @@ -1258,14 +1246,11 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); void ide_retry_pc(ide_drive_t *, struct gendisk *); -static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc)-{-	return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);-}+int ide_cd_expiry(ide_drive_t *); -int ide_scsi_expiry(ide_drive_t *);+int ide_cd_get_xferlen(struct request *); -ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *);+ide_startstop_t ide_issue_pc(ide_drive_t *);  ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); @@ -1287,6 +1272,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);  extern void ide_timer_expiry(unsigned long); extern irqreturn_t ide_intr(int irq, void *dev_id);++static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)+{+	if (hwgroup->busy)+		return 1;++	hwgroup->busy = 1;+	/* for atari only */+	ide_get_lock(ide_intr, hwgroup);++	return 0;+}++static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)+{+	/* for atari only */+	ide_release_lock();+	hwgroup->busy = 0;+}+ extern void do_ide_request(struct request_queue *);  void ide_init_disk(struct gendisk *, ide_drive_t *);@@ -1533,6 +1538,7 @@ void ide_unregister_region(struct gendisk *); void ide_undecoded_slave(ide_drive_t *);  void ide_port_apply_params(ide_hwif_t *);+int ide_sysfs_register_port(ide_hwif_t *);  struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); void ide_host_free(struct ide_host *);@@ -1627,6 +1633,9 @@ extern struct mutex ide_cfg_mtx;  #define local_irq_set(flags)	do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) +char *ide_media_string(ide_drive_t *);++extern struct device_attribute ide_dev_attrs[]; extern struct bus_type ide_bus_type; extern struct class *ide_port_class; ÿôèº{.nÇ+?·?®?­?+%?Ëÿ±éݶ¥?wÿº{.nÇ+?·¥?{±þ'^þ)í?æèw*jg¬±¨¶????Ý¢jÿ¾«þG«?éÿ¢¸¢·¦j:+v?¨?wèjØm¶?ÿþø¯ù®w¥þ?àþf£¢·h??â?úÿ?Ù¥


[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux