diff for duplicates of <200901021759.46260.bzolnier@gmail.com> diff --git a/a/1.txt b/N1/1.txt index 1421c52..c6b1ed9 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,3266 +1,25 @@ 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. ] - +* 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). - + 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. - +* 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 - 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 - +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.txt -index dc7c681..df18d87 100644 ---- a/Documentation/feature-removal-schedule.txt -+++ b/Documentation/feature-removal-schedule.txt -@@ -310,15 +310,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl> - - --------------------------- - --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@lab.ntt.co.jp> -- ----------------------------- -- - 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. Use -diff --git a/MAINTAINERS b/MAINTAINERS -index ceb32ee..144766c 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2146,11 +2146,6 @@ M: Gadi Oxman <gadio@netvision.net.il> - L: linux-kernel@vger.kernel.org - S: Maintained - --IDE-SCSI DRIVER --L: linux-ide@vger.kernel.org --L: linux-scsi@vger.kernel.org --S: Orphan -- - IDLE-I7300 - P: Andy Henroid - M: andrew.d.henroid@intel.com -diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig -index 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 ACPI -diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile -index 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.o -diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c -index 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.c -index 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.h -index 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.c -index 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.c -index 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.c -index 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.c -index 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.c -index 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.c -index 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.c -new file mode 100644 -index 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.c -index 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.c -index 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.c -index 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.c -index 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/Kconfig -index 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-HOWTO -diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile -index 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.o -diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c -deleted file mode 100644 -index c24140a..0000000 ---- a/drivers/scsi/ide-scsi.c -+++ /dev/null -@@ -1,840 +0,0 @@ --/* -- * Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il> -- * 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.h -index 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; - -\0 +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@ans.pl> --------------------------- -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@lab.ntt.co.jp>------------------------------ 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@netvision.net.il> L: linux-kernel@vger.kernel.org S: Maintained -IDE-SCSI DRIVER-L: linux-ide@vger.kernel.org-L: linux-scsi@vger.kernel.org-S: Orphan- IDLE-I7300 P: Andy Henroid M: andrew.d.henroid@intel.comdiff --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@netvision.net.il>- * 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; \0ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥ diff --git a/a/content_digest b/N1/content_digest index 635c79e..f2f2cf7 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -9,3270 +9,29 @@ "\00:1\0" "b\0" "First IDE updates in 2009, this time:\n" - "\n" - "* Fix IDE to not process commands in IRQ-context and than switch the\n" - " subsystem to use per-device request queue locks instead of (ab)using\n" - " hwgroup locks for this purpose. Besides being obvious IRQ-latency\n" - " and scalability improvement this decreases complexity of core code\n" - " greatly (~100 LOC of very tricky code gone) and makes maintainance\n" - " work much easier.\n" - "\n" - " [ Thanks to Elias Oltmanns for his work on reviewing these changes\n" - " and catching some issues early. ]\n" - "\n" + "* 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.\n" + " [ Thanks to Elias Oltmanns for his work on reviewing these changes and catching some issues early. ]\n" "* Scheduled removal of deprecated ide-scsi device driver.\n" - "\n" - " We've been discouraging using ide-scsi since early 2.5.x days as the\n" - " driver contains unfixable problems with error handling and lifetimes\n" - " of IDE/SCSI objects. There is now consensus between IDE/SCSI people\n" - " that both (recently rewritten) native ide-{cd,gd,tape} drivers from\n" - " IDE side and proper ATA-SCSI emulation (libata) from SCSI side offer\n" - " a better alternative.\n" - "\n" - " The driver has been officially orphaned for a year and then scheduled\n" - " for removal for the last 4 months so this shouldn't come as surprise\n" - " (I didn't got a single user complaint about this and ide-scsi has even\n" - " been broken by some unrelated kernel changes for few kernel releases\n" - " in the past without anybody noticing). \n" - "\n" + " 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.\n" + " 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). \n" " (from FUJITA Tomonori and Borislav Petkov)\n" - "\n" "* Fix multiple nested big stack usage in ide-floppy.c.\n" - "\n" " (from Linus himself, testing/merging handled by Borislav)\n" - "\n" - "* Preparations to switch ide-cd device driver to use generic ATAPI code\n" - " which will happen in the next IDE updates pull request.\n" - "\n" + "* Preparations to switch ide-cd device driver to use generic ATAPI code which will happen in the next IDE updates pull request.\n" " (from Borislav)\n" - "\n" "* Misc fixups/cleanups.\n" - "\n" "All above changes have been in linux-next for some time now...\n" "\n" - "\n" "Linus, please pull from:\n" - "\n" "master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git/\n" - "\n" "to receive the following updates:\n" + " 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\n" "\n" - " Documentation/feature-removal-schedule.txt | 9 -\n" - " MAINTAINERS | 5 -\n" - " drivers/ide/Kconfig | 18 +-\n" - " drivers/ide/Makefile | 2 +-\n" - " drivers/ide/ide-atapi.c | 248 +++++----\n" - " drivers/ide/ide-cd.c | 99 +---\n" - " drivers/ide/ide-cd.h | 12 +-\n" - " drivers/ide/ide-floppy.c | 28 +-\n" - " drivers/ide/ide-floppy_ioctl.c | 58 +-\n" - " drivers/ide/ide-io.c | 282 +++-------\n" - " drivers/ide/ide-ioctls.c | 3 +-\n" - " drivers/ide/ide-park.c | 13 +-\n" - " drivers/ide/ide-probe.c | 223 +++-----\n" - " drivers/ide/ide-sysfs.c | 125 ++++\n" - " drivers/ide/ide-tape.c | 2 +-\n" - " drivers/ide/ide.c | 72 +---\n" - " drivers/ide/tx4938ide.c | 11 +-\n" - " drivers/ide/tx4939ide.c | 43 +-\n" - " drivers/scsi/Kconfig | 8 +-\n" - " drivers/scsi/Makefile | 1 -\n" - " drivers/scsi/ide-scsi.c | 840 ----------------------------\n" - " include/linux/ide.h | 121 +++--\n" - " 22 files changed, 614 insertions(+), 1609 deletions(-)\n" - " create mode 100644 drivers/ide/ide-sysfs.c\n" - " delete mode 100644 drivers/scsi/ide-scsi.c\n" - "\n" - "\n" - "Bartlomiej Zolnierkiewicz (10):\n" - " tx493x: fix indentation\n" - " ide: remove chipset type fixup from ide_host_register()\n" - " ide: small ide_register_port() cleanup\n" - " ide: factor out device type classifying from do_identify()\n" - " ide: move sysfs support to ide-sysfs.c\n" - " ide: don't execute the next queued command from the hard-IRQ context (v2)\n" - " ide: remove IDE PM hack from do_ide_request()\n" - " ide: remove \"paranoia\" checks for hwgroup->busy\n" - " ide: add ide_[un]lock_hwgroup() helpers\n" - " ide: use per-device request queue locks (v2)\n" - "\n" - "Borislav Petkov (20):\n" - " ide-cd: move debug defines into header\n" - " ide: make IDE_AFLAG_.. numbering continuous again\n" - " ide-atapi: add a dev_is_idecd-inline\n" - " ide-atapi: combine drive-specific assignments\n" - " ide-atapi: setup dma for ide-cd\n" - " ide-atapi: accomodate transfer length calculation for ide-cd\n" - " ide-atapi: teach ide atapi about drive->waiting_for_dma\n" - " ide-cd: move cdrom_timer_expiry to ide-atapi.c\n" - " ide-atapi: remove ide-scsi remnants from ide_issue_pc\n" - " ide-atapi: remove ide-scsi remnants from ide_transfer_pc()\n" - " ide-atapi: remove ide-scsi remnants from ide_pc_intr()\n" - " ide: remove the last ide-scsi remnants\n" - " ide-atapi: compute cmd_len based on device type in ide_transfer_pc\n" - " ide-atapi: assign expiry and timeout based on device type\n" - " ide-atapi: split drive-specific functionality in ide_issue_pc\n" - " ide-cd: remove xferlen arg to cdrom_start_packet_command\n" - " ide-cd: remove handler wrappers\n" - " ide-atapi: remove timeout arg to ide_issue_pc\n" - " ide-atapi: put the rest of non-ide-cd code into the else-clause of ide_transfer_pc\n" - " ide-atapi: start dma in a drive-specific way\n" - "\n" - "FUJITA Tomonori (1):\n" - " remove ide-scsi\n" - "\n" - "Linus Torvalds (1):\n" - " ide-floppy: allocate only toplevel packet commands\n" - "\n" + "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)\n" + "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\n" + "FUJITA Tomonori (1): remove ide-scsi\n" + "Linus Torvalds (1): ide-floppy: allocate only toplevel packet commands\n" "\n" - "diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt\n" - "index dc7c681..df18d87 100644\n" - "--- a/Documentation/feature-removal-schedule.txt\n" - "+++ b/Documentation/feature-removal-schedule.txt\n" - "@@ -310,15 +310,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>\n" - " \n" - " ---------------------------\n" - " \n" - "-What: ide-scsi (BLK_DEV_IDESCSI)\n" - "-When: 2.6.29\n" - "-Why: The 2.6 kernel supports direct writing to ide CD drives, which\n" - "- eliminates the need for ide-scsi. The new method is more\n" - "- efficient in every way.\n" - "-Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>\n" - "-\n" - "----------------------------\n" - "-\n" - " What:\ti2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()\n" - " When:\t2.6.29 (ideally) or 2.6.30 (more likely)\n" - " Why:\tDeprecated by the new (standard) device driver binding model. Use\n" - "diff --git a/MAINTAINERS b/MAINTAINERS\n" - "index ceb32ee..144766c 100644\n" - "--- a/MAINTAINERS\n" - "+++ b/MAINTAINERS\n" - "@@ -2146,11 +2146,6 @@ M:\tGadi Oxman <gadio@netvision.net.il>\n" - " L:\tlinux-kernel@vger.kernel.org\n" - " S:\tMaintained\n" - " \n" - "-IDE-SCSI DRIVER\n" - "-L:\tlinux-ide@vger.kernel.org\n" - "-L:\tlinux-scsi@vger.kernel.org\n" - "-S:\tOrphan\n" - "-\n" - " IDLE-I7300\n" - " P:\tAndy Henroid\n" - " M:\tandrew.d.henroid@intel.com\n" - "diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig\n" - "index c9f21e3..4ee85fc 100644\n" - "--- a/drivers/ide/Kconfig\n" - "+++ b/drivers/ide/Kconfig\n" - "@@ -137,6 +137,7 @@ config BLK_DEV_DELKIN\n" - " \n" - " config BLK_DEV_IDECD\n" - " \ttristate \"Include IDE/ATAPI CDROM support\"\n" - "+\tselect IDE_ATAPI\n" - " \t---help---\n" - " \t If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is\n" - " \t a newer protocol used by IDE CD-ROM and TAPE drives, similar to the\n" - "@@ -185,23 +186,6 @@ config BLK_DEV_IDETAPE\n" - " \t To compile this driver as a module, choose M here: the\n" - " \t module will be called ide-tape.\n" - " \n" - "-config BLK_DEV_IDESCSI\n" - "-\ttristate \"SCSI emulation support (DEPRECATED)\"\n" - "-\tdepends on SCSI\n" - "-\tselect IDE_ATAPI\n" - "-\t---help---\n" - "-\t WARNING: ide-scsi is no longer needed for cd writing applications!\n" - "-\t The 2.6 kernel supports direct writing to ide-cd, which eliminates\n" - "-\t the need for ide-scsi + the entire scsi stack just for writing a\n" - "-\t cd. The new method is more efficient in every way.\n" - "-\n" - "-\t This will provide SCSI host adapter emulation for IDE ATAPI devices,\n" - "-\t and will allow you to use a SCSI device driver instead of a native\n" - "-\t ATAPI driver.\n" - "-\n" - "-\t If both this SCSI emulation and native ATAPI support are compiled\n" - "-\t into the kernel, the native support will be used.\n" - "-\n" - " config BLK_DEV_IDEACPI\n" - " \tbool \"IDE ACPI support\"\n" - " \tdepends on ACPI\n" - "diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile\n" - "index 177e3f8..4107289 100644\n" - "--- a/drivers/ide/Makefile\n" - "+++ b/drivers/ide/Makefile\n" - "@@ -5,7 +5,7 @@\n" - " EXTRA_CFLAGS\t\t\t\t+= -Idrivers/ide\n" - " \n" - " ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \\\n" - "-\t ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o\n" - "+\t ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o\n" - " \n" - " # core IDE code\n" - " ide-core-$(CONFIG_IDE_TIMINGS)\t\t+= ide-timings.o\n" - "diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c\n" - "index 4e58b9e..e8688c0 100644\n" - "--- a/drivers/ide/ide-atapi.c\n" - "+++ b/drivers/ide/ide-atapi.c\n" - "@@ -3,6 +3,7 @@\n" - " */\n" - " \n" - " #include <linux/kernel.h>\n" - "+#include <linux/cdrom.h>\n" - " #include <linux/delay.h>\n" - " #include <linux/ide.h>\n" - " #include <scsi/scsi.h>\n" - "@@ -14,6 +15,13 @@\n" - " #define debug_log(fmt, args...) do {} while (0)\n" - " #endif\n" - " \n" - "+#define ATAPI_MIN_CDB_BYTES\t12\n" - "+\n" - "+static inline int dev_is_idecd(ide_drive_t *drive)\n" - "+{\n" - "+\treturn drive->media == ide_cdrom || drive->media == ide_optical;\n" - "+}\n" - "+\n" - " /*\n" - " * Check whether we can support a device,\n" - " * based on the ATAPI IDENTIFY command results.\n" - "@@ -233,18 +241,49 @@ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)\n" - " }\n" - " EXPORT_SYMBOL_GPL(ide_retry_pc);\n" - " \n" - "-int ide_scsi_expiry(ide_drive_t *drive)\n" - "+int ide_cd_expiry(ide_drive_t *drive)\n" - " {\n" - "-\tstruct ide_atapi_pc *pc = drive->pc;\n" - "+\tstruct request *rq = HWGROUP(drive)->rq;\n" - "+\tunsigned long wait = 0;\n" - " \n" - "-\tdebug_log(\"%s called for %lu at %lu\\n\", __func__,\n" - "-\t\t pc->scsi_cmd->serial_number, jiffies);\n" - "+\tdebug_log(\"%s: rq->cmd[0]: 0x%x\\n\", __func__, rq->cmd[0]);\n" - " \n" - "-\tpc->flags |= PC_FLAG_TIMEDOUT;\n" - "+\t/*\n" - "+\t * Some commands are *slow* and normally take a long time to complete.\n" - "+\t * Usually we can use the ATAPI \"disconnect\" to bypass this, but not all\n" - "+\t * commands/drives support that. Let ide_timer_expiry keep polling us\n" - "+\t * for these.\n" - "+\t */\n" - "+\tswitch (rq->cmd[0]) {\n" - "+\tcase GPCMD_BLANK:\n" - "+\tcase GPCMD_FORMAT_UNIT:\n" - "+\tcase GPCMD_RESERVE_RZONE_TRACK:\n" - "+\tcase GPCMD_CLOSE_TRACK:\n" - "+\tcase GPCMD_FLUSH_CACHE:\n" - "+\t\twait = ATAPI_WAIT_PC;\n" - "+\t\tbreak;\n" - "+\tdefault:\n" - "+\t\tif (!(rq->cmd_flags & REQ_QUIET))\n" - "+\t\t\tprintk(KERN_INFO \"cmd 0x%x timed out\\n\",\n" - "+\t\t\t\t\t rq->cmd[0]);\n" - "+\t\twait = 0;\n" - "+\t\tbreak;\n" - "+\t}\n" - "+\treturn wait;\n" - "+}\n" - "+EXPORT_SYMBOL_GPL(ide_cd_expiry);\n" - " \n" - "-\treturn 0; /* we do not want the IDE subsystem to retry */\n" - "+int ide_cd_get_xferlen(struct request *rq)\n" - "+{\n" - "+\tif (blk_fs_request(rq))\n" - "+\t\treturn 32768;\n" - "+\telse if (blk_sense_request(rq) || blk_pc_request(rq) ||\n" - "+\t\t\t rq->cmd_type == REQ_TYPE_ATA_PC)\n" - "+\t\treturn rq->data_len;\n" - "+\telse\n" - "+\t\treturn 0;\n" - " }\n" - "-EXPORT_SYMBOL_GPL(ide_scsi_expiry);\n" - "+EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);\n" - " \n" - " /*\n" - " * This is the usual interrupt handler which will be called during a packet\n" - "@@ -258,21 +297,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)\n" - " \tstruct request *rq = hwif->hwgroup->rq;\n" - " \tconst struct ide_tp_ops *tp_ops = hwif->tp_ops;\n" - " \txfer_func_t *xferfunc;\n" - "-\tide_expiry_t *expiry;\n" - " \tunsigned int timeout, temp;\n" - " \tu16 bcount;\n" - "-\tu8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;\n" - "+\tu8 stat, ireason, dsc = 0;\n" - " \n" - " \tdebug_log(\"Enter %s - interrupt handler\\n\", __func__);\n" - " \n" - "-\tif (scsi) {\n" - "-\t\ttimeout = ide_scsi_get_timeout(pc);\n" - "-\t\texpiry = ide_scsi_expiry;\n" - "-\t} else {\n" - "-\t\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD\n" - "-\t\t\t\t\t\t : WAIT_TAPE_CMD;\n" - "-\t\texpiry = NULL;\n" - "-\t}\n" - "+\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD\n" - "+\t\t\t\t\t : WAIT_TAPE_CMD;\n" - " \n" - " \tif (pc->flags & PC_FLAG_TIMEDOUT) {\n" - " \t\tdrive->pc_callback(drive, 0);\n" - "@@ -284,8 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)\n" - " \n" - " \tif (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {\n" - " \t\tif (hwif->dma_ops->dma_end(drive) ||\n" - "-\t\t (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) {\n" - "-\t\t\tif (drive->media == ide_floppy && !scsi)\n" - "+\t\t (drive->media == ide_tape && (stat & ATA_ERR))) {\n" - "+\t\t\tif (drive->media == ide_floppy)\n" - " \t\t\t\tprintk(KERN_ERR \"%s: DMA %s error\\n\",\n" - " \t\t\t\t\tdrive->name, rq_data_dir(pc->rq)\n" - " \t\t\t\t\t\t ? \"write\" : \"read\");\n" - "@@ -307,7 +339,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)\n" - " \n" - " \t\tlocal_irq_enable_in_hardirq();\n" - " \n" - "-\t\tif (drive->media == ide_tape && !scsi &&\n" - "+\t\tif (drive->media == ide_tape &&\n" - " \t\t (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE)\n" - " \t\t\tstat &= ~ATA_ERR;\n" - " \n" - "@@ -315,11 +347,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)\n" - " \t\t\t/* Error detected */\n" - " \t\t\tdebug_log(\"%s: I/O error\\n\", drive->name);\n" - " \n" - "-\t\t\tif (drive->media != ide_tape || scsi) {\n" - "+\t\t\tif (drive->media != ide_tape)\n" - " \t\t\t\tpc->rq->errors++;\n" - "-\t\t\t\tif (scsi)\n" - "-\t\t\t\t\tgoto cmd_finished;\n" - "-\t\t\t}\n" - " \n" - " \t\t\tif (rq->cmd[0] == REQUEST_SENSE) {\n" - " \t\t\t\tprintk(KERN_ERR \"%s: I/O error in request sense\"\n" - "@@ -335,7 +364,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)\n" - " \t\t\t/* queued, but not started */\n" - " \t\t\treturn ide_stopped;\n" - " \t\t}\n" - "-cmd_finished:\n" - " \t\tpc->error = 0;\n" - " \n" - " \t\tif ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)\n" - "@@ -382,25 +410,8 @@ cmd_finished:\n" - " \t\t\t\t\t\t\"us more data than expected - \"\n" - " \t\t\t\t\t\t\"discarding data\\n\",\n" - " \t\t\t\t\t\tdrive->name);\n" - "-\t\t\t\tif (scsi)\n" - "-\t\t\t\t\ttemp = pc->buf_size - pc->xferred;\n" - "-\t\t\t\telse\n" - "-\t\t\t\t\ttemp = 0;\n" - "-\t\t\t\tif (temp) {\n" - "-\t\t\t\t\tif (pc->sg)\n" - "-\t\t\t\t\t\tdrive->pc_io_buffers(drive, pc,\n" - "-\t\t\t\t\t\t\t\t temp, 0);\n" - "-\t\t\t\t\telse\n" - "-\t\t\t\t\t\ttp_ops->input_data(drive, NULL,\n" - "-\t\t\t\t\t\t\tpc->cur_pos, temp);\n" - "-\t\t\t\t\tprintk(KERN_ERR \"%s: transferred %d of \"\n" - "-\t\t\t\t\t\t\t\"%d bytes\\n\",\n" - "-\t\t\t\t\t\t\tdrive->name,\n" - "-\t\t\t\t\t\t\ttemp, bcount);\n" - "-\t\t\t\t}\n" - "-\t\t\t\tpc->xferred += temp;\n" - "-\t\t\t\tpc->cur_pos += temp;\n" - "-\t\t\t\tide_pad_transfer(drive, 0, bcount - temp);\n" - "+\n" - "+\t\t\t\tide_pad_transfer(drive, 0, bcount);\n" - " \t\t\t\tgoto next_irq;\n" - " \t\t\t}\n" - " \t\t\tdebug_log(\"The device wants to send us more data than \"\n" - "@@ -410,14 +421,13 @@ cmd_finished:\n" - " \t} else\n" - " \t\txferfunc = tp_ops->output_data;\n" - " \n" - "-\tif ((drive->media == ide_floppy && !scsi && !pc->buf) ||\n" - "-\t (drive->media == ide_tape && !scsi && pc->bh) ||\n" - "-\t (scsi && pc->sg)) {\n" - "+\tif ((drive->media == ide_floppy && !pc->buf) ||\n" - "+\t (drive->media == ide_tape && pc->bh)) {\n" - " \t\tint done = drive->pc_io_buffers(drive, pc, bcount,\n" - " \t\t\t\t !!(pc->flags & PC_FLAG_WRITING));\n" - " \n" - " \t\t/* FIXME: don't do partial completions */\n" - "-\t\tif (drive->media == ide_floppy && !scsi)\n" - "+\t\tif (drive->media == ide_floppy)\n" - " \t\t\tide_end_request(drive, 1, done >> 9);\n" - " \t} else\n" - " \t\txferfunc(drive, NULL, pc->cur_pos, bcount);\n" - "@@ -430,7 +440,7 @@ cmd_finished:\n" - " \t\t rq->cmd[0], bcount);\n" - " next_irq:\n" - " \t/* And set the interrupt handler again */\n" - "-\tide_set_handler(drive, ide_pc_intr, timeout, expiry);\n" - "+\tide_set_handler(drive, ide_pc_intr, timeout, NULL);\n" - " \treturn ide_started;\n" - " }\n" - " \n" - "@@ -479,11 +489,12 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive)\n" - " \n" - " static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)\n" - " {\n" - "-\tstruct ide_atapi_pc *pc = drive->pc;\n" - "+\tstruct ide_atapi_pc *uninitialized_var(pc);\n" - " \tide_hwif_t *hwif = drive->hwif;\n" - " \tstruct request *rq = hwif->hwgroup->rq;\n" - " \tide_expiry_t *expiry;\n" - " \tunsigned int timeout;\n" - "+\tint cmd_len;\n" - " \tide_startstop_t startstop;\n" - " \tu8 ireason;\n" - " \n" - "@@ -493,101 +504,124 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)\n" - " \t\treturn startstop;\n" - " \t}\n" - " \n" - "-\tireason = ide_read_ireason(drive);\n" - "-\tif (drive->media == ide_tape &&\n" - "-\t (drive->dev_flags & IDE_DFLAG_SCSI) == 0)\n" - "-\t\tireason = ide_wait_ireason(drive, ireason);\n" - "-\n" - "-\tif ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {\n" - "-\t\tprintk(KERN_ERR \"%s: (IO,CoD) != (0,1) while issuing \"\n" - "-\t\t\t\t\"a packet command\\n\", drive->name);\n" - "-\t\treturn ide_do_reset(drive);\n" - "+\tif (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {\n" - "+\t\tif (drive->dma)\n" - "+\t\t\tdrive->waiting_for_dma = 1;\n" - " \t}\n" - " \n" - "-\t/*\n" - "-\t * If necessary schedule the packet transfer to occur 'timeout'\n" - "-\t * miliseconds later in ide_delayed_transfer_pc() after the device\n" - "-\t * says it's ready for a packet.\n" - "-\t */\n" - "-\tif (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {\n" - "-\t\ttimeout = drive->pc_delay;\n" - "-\t\texpiry = &ide_delayed_transfer_pc;\n" - "+\tif (dev_is_idecd(drive)) {\n" - "+\t\t/* ATAPI commands get padded out to 12 bytes minimum */\n" - "+\t\tcmd_len = COMMAND_SIZE(rq->cmd[0]);\n" - "+\t\tif (cmd_len < ATAPI_MIN_CDB_BYTES)\n" - "+\t\t\tcmd_len = ATAPI_MIN_CDB_BYTES;\n" - "+\n" - "+\t\ttimeout = rq->timeout;\n" - "+\t\texpiry = ide_cd_expiry;\n" - " \t} else {\n" - "-\t\tif (drive->dev_flags & IDE_DFLAG_SCSI) {\n" - "-\t\t\ttimeout = ide_scsi_get_timeout(pc);\n" - "-\t\t\texpiry = ide_scsi_expiry;\n" - "+\t\tpc = drive->pc;\n" - "+\n" - "+\t\tcmd_len = ATAPI_MIN_CDB_BYTES;\n" - "+\n" - "+\t\t/*\n" - "+\t\t * If necessary schedule the packet transfer to occur 'timeout'\n" - "+\t\t * miliseconds later in ide_delayed_transfer_pc() after the\n" - "+\t\t * device says it's ready for a packet.\n" - "+\t\t */\n" - "+\t\tif (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {\n" - "+\t\t\ttimeout = drive->pc_delay;\n" - "+\t\t\texpiry = &ide_delayed_transfer_pc;\n" - " \t\t} else {\n" - " \t\t\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD\n" - " \t\t\t\t\t\t\t : WAIT_TAPE_CMD;\n" - " \t\t\texpiry = NULL;\n" - " \t\t}\n" - "+\n" - "+\t\tireason = ide_read_ireason(drive);\n" - "+\t\tif (drive->media == ide_tape)\n" - "+\t\t\tireason = ide_wait_ireason(drive, ireason);\n" - "+\n" - "+\t\tif ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {\n" - "+\t\t\tprintk(KERN_ERR \"%s: (IO,CoD) != (0,1) while issuing \"\n" - "+\t\t\t\t\t\"a packet command\\n\", drive->name);\n" - "+\n" - "+\t\t\treturn ide_do_reset(drive);\n" - "+\t\t}\n" - " \t}\n" - " \n" - " \t/* Set the interrupt routine */\n" - " \tide_set_handler(drive, ide_pc_intr, timeout, expiry);\n" - " \n" - " \t/* Begin DMA, if necessary */\n" - "-\tif (pc->flags & PC_FLAG_DMA_OK) {\n" - "-\t\tpc->flags |= PC_FLAG_DMA_IN_PROGRESS;\n" - "-\t\thwif->dma_ops->dma_start(drive);\n" - "+\tif (dev_is_idecd(drive)) {\n" - "+\t\tif (drive->dma)\n" - "+\t\t\thwif->dma_ops->dma_start(drive);\n" - "+\t} else {\n" - "+\t\tif (pc->flags & PC_FLAG_DMA_OK) {\n" - "+\t\t\tpc->flags |= PC_FLAG_DMA_IN_PROGRESS;\n" - "+\t\t\thwif->dma_ops->dma_start(drive);\n" - "+\t\t}\n" - " \t}\n" - " \n" - " \t/* Send the actual packet */\n" - " \tif ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)\n" - "-\t\thwif->tp_ops->output_data(drive, NULL, rq->cmd, 12);\n" - "+\t\thwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);\n" - " \n" - " \treturn ide_started;\n" - " }\n" - " \n" - "-ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,\n" - "-\t\t\t ide_expiry_t *expiry)\n" - "+ide_startstop_t ide_issue_pc(ide_drive_t *drive)\n" - " {\n" - "-\tstruct ide_atapi_pc *pc = drive->pc;\n" - "+\tstruct ide_atapi_pc *pc;\n" - " \tide_hwif_t *hwif = drive->hwif;\n" - "+\tide_expiry_t *expiry = NULL;\n" - "+\tunsigned int timeout;\n" - " \tu32 tf_flags;\n" - " \tu16 bcount;\n" - "-\tu8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI);\n" - " \n" - "-\t/* We haven't transferred any data yet */\n" - "-\tpc->xferred = 0;\n" - "-\tpc->cur_pos = pc->buf;\n" - "+\tif (dev_is_idecd(drive)) {\n" - "+\t\ttf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;\n" - "+\t\tbcount = ide_cd_get_xferlen(hwif->hwgroup->rq);\n" - "+\t\texpiry = ide_cd_expiry;\n" - "+\t\ttimeout = ATAPI_WAIT_PC;\n" - " \n" - "-\t/* Request to transfer the entire buffer at once */\n" - "-\tif (drive->media == ide_tape && scsi == 0)\n" - "-\t\tbcount = pc->req_xfer;\n" - "-\telse\n" - "-\t\tbcount = min(pc->req_xfer, 63 * 1024);\n" - "+\t\tif (drive->dma)\n" - "+\t\t\tdrive->dma = !hwif->dma_ops->dma_setup(drive);\n" - "+\t} else {\n" - "+\t\tpc = drive->pc;\n" - " \n" - "-\tif (pc->flags & PC_FLAG_DMA_ERROR) {\n" - "-\t\tpc->flags &= ~PC_FLAG_DMA_ERROR;\n" - "-\t\tide_dma_off(drive);\n" - "-\t}\n" - "+\t\t/* We haven't transferred any data yet */\n" - "+\t\tpc->xferred = 0;\n" - "+\t\tpc->cur_pos = pc->buf;\n" - " \n" - "-\tif ((pc->flags & PC_FLAG_DMA_OK) &&\n" - "-\t (drive->dev_flags & IDE_DFLAG_USING_DMA)) {\n" - "-\t\tif (scsi)\n" - "-\t\t\thwif->sg_mapped = 1;\n" - "-\t\tdrive->dma = !hwif->dma_ops->dma_setup(drive);\n" - "-\t\tif (scsi)\n" - "-\t\t\thwif->sg_mapped = 0;\n" - "-\t}\n" - "+\t\ttf_flags = IDE_TFLAG_OUT_DEVICE;\n" - "+\t\tbcount = ((drive->media == ide_tape) ?\n" - "+\t\t\t\tpc->req_xfer :\n" - "+\t\t\t\tmin(pc->req_xfer, 63 * 1024));\n" - " \n" - "-\tif (!drive->dma)\n" - "-\t\tpc->flags &= ~PC_FLAG_DMA_OK;\n" - "+\t\tif (pc->flags & PC_FLAG_DMA_ERROR) {\n" - "+\t\t\tpc->flags &= ~PC_FLAG_DMA_ERROR;\n" - "+\t\t\tide_dma_off(drive);\n" - "+\t\t}\n" - " \n" - "-\tif (scsi)\n" - "-\t\ttf_flags = 0;\n" - "-\telse if (drive->media == ide_cdrom || drive->media == ide_optical)\n" - "-\t\ttf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;\n" - "-\telse\n" - "-\t\ttf_flags = IDE_TFLAG_OUT_DEVICE;\n" - "+\t\tif ((pc->flags & PC_FLAG_DMA_OK) &&\n" - "+\t\t (drive->dev_flags & IDE_DFLAG_USING_DMA))\n" - "+\t\t\tdrive->dma = !hwif->dma_ops->dma_setup(drive);\n" - "+\n" - "+\t\tif (!drive->dma)\n" - "+\t\t\tpc->flags &= ~PC_FLAG_DMA_OK;\n" - "+\n" - "+\t\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD\n" - "+\t\t\t\t\t\t : WAIT_TAPE_CMD;\n" - "+\t}\n" - " \n" - " \tide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);\n" - " \n" - " \t/* Issue the packet command */\n" - " \tif (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {\n" - "+\t\tif (drive->dma)\n" - "+\t\t\tdrive->waiting_for_dma = 0;\n" - " \t\tide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,\n" - "-\t\t\t\t timeout, NULL);\n" - "+\t\t\t\t timeout, expiry);\n" - " \t\treturn ide_started;\n" - " \t} else {\n" - " \t\tide_execute_pkt_cmd(drive);\n" - "diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c\n" - "index 5daa4dd..1a7410f 100644\n" - "--- a/drivers/ide/ide-cd.c\n" - "+++ b/drivers/ide/ide-cd.c\n" - "@@ -53,14 +53,6 @@\n" - " \n" - " #include \"ide-cd.h\"\n" - " \n" - "-#define IDECD_DEBUG_LOG\t\t1\n" - "-\n" - "-#if IDECD_DEBUG_LOG\n" - "-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)\n" - "-#else\n" - "-#define ide_debug_log(lvl, fmt, args...) do {} while (0)\n" - "-#endif\n" - "-\n" - " static DEFINE_MUTEX(idecd_ref_mutex);\n" - " \n" - " static void ide_cd_release(struct kref *);\n" - "@@ -519,37 +511,8 @@ end_request:\n" - " \treturn 1;\n" - " }\n" - " \n" - "-static int cdrom_timer_expiry(ide_drive_t *drive)\n" - "-{\n" - "-\tstruct request *rq = HWGROUP(drive)->rq;\n" - "-\tunsigned long wait = 0;\n" - "-\n" - "-\tide_debug_log(IDE_DBG_RQ, \"Call %s: rq->cmd[0]: 0x%x\\n\", __func__,\n" - "-\t\t rq->cmd[0]);\n" - "-\n" - "-\t/*\n" - "-\t * Some commands are *slow* and normally take a long time to complete.\n" - "-\t * Usually we can use the ATAPI \"disconnect\" to bypass this, but not all\n" - "-\t * commands/drives support that. Let ide_timer_expiry keep polling us\n" - "-\t * for these.\n" - "-\t */\n" - "-\tswitch (rq->cmd[0]) {\n" - "-\tcase GPCMD_BLANK:\n" - "-\tcase GPCMD_FORMAT_UNIT:\n" - "-\tcase GPCMD_RESERVE_RZONE_TRACK:\n" - "-\tcase GPCMD_CLOSE_TRACK:\n" - "-\tcase GPCMD_FLUSH_CACHE:\n" - "-\t\twait = ATAPI_WAIT_PC;\n" - "-\t\tbreak;\n" - "-\tdefault:\n" - "-\t\tif (!(rq->cmd_flags & REQ_QUIET))\n" - "-\t\t\tprintk(KERN_INFO PFX \"cmd 0x%x timed out\\n\",\n" - "-\t\t\t\t\t rq->cmd[0]);\n" - "-\t\twait = 0;\n" - "-\t\tbreak;\n" - "-\t}\n" - "-\treturn wait;\n" - "-}\n" - "+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *);\n" - "+static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);\n" - " \n" - " /*\n" - " * Set up the device registers for transferring a packet command on DEV,\n" - "@@ -559,11 +522,13 @@ static int cdrom_timer_expiry(ide_drive_t *drive)\n" - " * called when the interrupt from the drive arrives. Otherwise, HANDLER\n" - " * will be called immediately after the drive is prepared for the transfer.\n" - " */\n" - "-static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,\n" - "-\t\t\t\t\t\t int xferlen,\n" - "-\t\t\t\t\t\t ide_handler_t *handler)\n" - "+static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive)\n" - " {\n" - " \tide_hwif_t *hwif = drive->hwif;\n" - "+\tstruct request *rq = hwif->hwgroup->rq;\n" - "+\tint xferlen;\n" - "+\n" - "+\txferlen = ide_cd_get_xferlen(rq);\n" - " \n" - " \tide_debug_log(IDE_DBG_PC, \"Call %s, xferlen: %d\\n\", __func__, xferlen);\n" - " \n" - "@@ -581,13 +546,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,\n" - " \t\t\tdrive->waiting_for_dma = 0;\n" - " \n" - " \t\t/* packet command */\n" - "-\t\tide_execute_command(drive, ATA_CMD_PACKET, handler,\n" - "-\t\t\t\t ATAPI_WAIT_PC, cdrom_timer_expiry);\n" - "+\t\tide_execute_command(drive, ATA_CMD_PACKET,\n" - "+\t\t\t\t cdrom_transfer_packet_command,\n" - "+\t\t\t\t ATAPI_WAIT_PC, ide_cd_expiry);\n" - " \t\treturn ide_started;\n" - " \t} else {\n" - " \t\tide_execute_pkt_cmd(drive);\n" - " \n" - "-\t\treturn (*handler) (drive);\n" - "+\t\treturn cdrom_transfer_packet_command(drive);\n" - " \t}\n" - " }\n" - " \n" - "@@ -598,11 +564,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,\n" - " * there's data ready.\n" - " */\n" - " #define ATAPI_MIN_CDB_BYTES 12\n" - "-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,\n" - "-\t\t\t\t\t struct request *rq,\n" - "-\t\t\t\t\t ide_handler_t *handler)\n" - "+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive)\n" - " {\n" - " \tide_hwif_t *hwif = drive->hwif;\n" - "+\tstruct request *rq = hwif->hwgroup->rq;\n" - " \tint cmd_len;\n" - " \tide_startstop_t startstop;\n" - " \n" - "@@ -629,7 +594,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,\n" - " \t}\n" - " \n" - " \t/* arm the interrupt handler */\n" - "-\tide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);\n" - "+\tide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry);\n" - " \n" - " \t/* ATAPI commands get padded out to 12 bytes minimum */\n" - " \tcmd_len = COMMAND_SIZE(rq->cmd[0]);\n" - "@@ -717,8 +682,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)\n" - " \treturn 1;\n" - " }\n" - " \n" - "-static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);\n" - "-\n" - " static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,\n" - " \t\t\t\t\t\t struct request *rq)\n" - " {\n" - "@@ -761,20 +724,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,\n" - " }\n" - " \n" - " /*\n" - "- * Routine to send a read/write packet command to the drive. This is usually\n" - "- * called directly from cdrom_start_{read,write}(). However, for drq_interrupt\n" - "- * devices, it is called from an interrupt when the drive is ready to accept\n" - "- * the command.\n" - "- */\n" - "-static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)\n" - "-{\n" - "-\tstruct request *rq = drive->hwif->hwgroup->rq;\n" - "-\n" - "-\t/* send the command to the drive and return */\n" - "-\treturn cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);\n" - "-}\n" - "-\n" - "-/*\n" - " * Fix up a possibly partially-processed request so that we can start it over\n" - " * entirely, or even put it back on the request queue.\n" - " */\n" - "@@ -1096,7 +1045,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)\n" - " \t} else {\n" - " \t\ttimeout = ATAPI_WAIT_PC;\n" - " \t\tif (!blk_fs_request(rq))\n" - "-\t\t\texpiry = cdrom_timer_expiry;\n" - "+\t\t\texpiry = ide_cd_expiry;\n" - " \t}\n" - " \n" - " \tide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);\n" - "@@ -1163,13 +1112,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)\n" - " \treturn ide_started;\n" - " }\n" - " \n" - "-static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)\n" - "-{\n" - "-\tstruct request *rq = HWGROUP(drive)->rq;\n" - "-\n" - "-\treturn cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);\n" - "-}\n" - "-\n" - " static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)\n" - " {\n" - " \n" - "@@ -1214,18 +1156,12 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)\n" - " static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,\n" - " \t\t\t\t\tsector_t block)\n" - " {\n" - "-\tide_handler_t *fn;\n" - "-\tint xferlen;\n" - "-\n" - " \tide_debug_log(IDE_DBG_RQ, \"Call %s, rq->cmd[0]: 0x%x, \"\n" - " \t\t \"rq->cmd_type: 0x%x, block: %llu\\n\",\n" - " \t\t __func__, rq->cmd[0], rq->cmd_type,\n" - " \t\t (unsigned long long)block);\n" - " \n" - " \tif (blk_fs_request(rq)) {\n" - "-\t\txferlen = 32768;\n" - "-\t\tfn = cdrom_start_rw_cont;\n" - "-\n" - " \t\tif (cdrom_start_rw(drive, rq) == ide_stopped)\n" - " \t\t\treturn ide_stopped;\n" - " \n" - "@@ -1233,9 +1169,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,\n" - " \t\t\treturn ide_stopped;\n" - " \t} else if (blk_sense_request(rq) || blk_pc_request(rq) ||\n" - " \t\t rq->cmd_type == REQ_TYPE_ATA_PC) {\n" - "-\t\txferlen = rq->data_len;\n" - "-\t\tfn = cdrom_do_newpc_cont;\n" - "-\n" - " \t\tif (!rq->timeout)\n" - " \t\t\trq->timeout = ATAPI_WAIT_PC;\n" - " \n" - "@@ -1250,7 +1183,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,\n" - " \t\treturn ide_stopped;\n" - " \t}\n" - " \n" - "-\treturn cdrom_start_packet_command(drive, xferlen, fn);\n" - "+\treturn cdrom_start_packet_command(drive);\n" - " }\n" - " \n" - " /*\n" - "diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h\n" - "index d5ce336..bf676b2 100644\n" - "--- a/drivers/ide/ide-cd.h\n" - "+++ b/drivers/ide/ide-cd.h\n" - "@@ -8,10 +8,14 @@\n" - " #include <linux/cdrom.h>\n" - " #include <asm/byteorder.h>\n" - " \n" - "-/*\n" - "- * typical timeout for packet command\n" - "- */\n" - "-#define ATAPI_WAIT_PC\t\t(60 * HZ)\n" - "+#define IDECD_DEBUG_LOG\t\t0\n" - "+\n" - "+#if IDECD_DEBUG_LOG\n" - "+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)\n" - "+#else\n" - "+#define ide_debug_log(lvl, fmt, args...) do {} while (0)\n" - "+#endif\n" - "+\n" - " #define ATAPI_WAIT_WRITE_BUSY\t(10 * HZ)\n" - " \n" - " /************************************************************************/\n" - "diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c\n" - "index aeb1ad7..0a48e2d 100644\n" - "--- a/drivers/ide/ide-floppy.c\n" - "+++ b/drivers/ide/ide-floppy.c\n" - "@@ -197,7 +197,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,\n" - " \n" - " \tpc->retries++;\n" - " \n" - "-\treturn ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);\n" - "+\treturn ide_issue_pc(drive);\n" - " }\n" - " \n" - " void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)\n" - "@@ -342,38 +342,38 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,\n" - " * Look at the flexible disk page parameters. We ignore the CHS capacity\n" - " * parameters and use the LBA parameters instead.\n" - " */\n" - "-static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)\n" - "+static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,\n" - "+\t\t\t\t\t struct ide_atapi_pc *pc)\n" - " {\n" - " \tstruct ide_disk_obj *floppy = drive->driver_data;\n" - " \tstruct gendisk *disk = floppy->disk;\n" - "-\tstruct ide_atapi_pc pc;\n" - " \tu8 *page;\n" - " \tint capacity, lba_capacity;\n" - " \tu16 transfer_rate, sector_size, cyls, rpm;\n" - " \tu8 heads, sectors;\n" - " \n" - "-\tide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);\n" - "+\tide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);\n" - " \n" - "-\tif (ide_queue_pc_tail(drive, disk, &pc)) {\n" - "+\tif (ide_queue_pc_tail(drive, disk, pc)) {\n" - " \t\tprintk(KERN_ERR PFX \"Can't get flexible disk page params\\n\");\n" - " \t\treturn 1;\n" - " \t}\n" - " \n" - "-\tif (pc.buf[3] & 0x80)\n" - "+\tif (pc->buf[3] & 0x80)\n" - " \t\tdrive->dev_flags |= IDE_DFLAG_WP;\n" - " \telse\n" - " \t\tdrive->dev_flags &= ~IDE_DFLAG_WP;\n" - " \n" - " \tset_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP));\n" - " \n" - "-\tpage = &pc.buf[8];\n" - "+\tpage = &pc->buf[8];\n" - " \n" - "-\ttransfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);\n" - "-\tsector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);\n" - "-\tcyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);\n" - "-\trpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);\n" - "-\theads = pc.buf[8 + 4];\n" - "-\tsectors = pc.buf[8 + 5];\n" - "+\ttransfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]);\n" - "+\tsector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]);\n" - "+\tcyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]);\n" - "+\trpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]);\n" - "+\theads = pc->buf[8 + 4];\n" - "+\tsectors = pc->buf[8 + 5];\n" - " \n" - " \tcapacity = cyls * heads * sectors * sector_size;\n" - " \n" - "@@ -499,7 +499,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)\n" - " \n" - " \t/* Clik! disk does not support get_flexible_disk_page */\n" - " \tif (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))\n" - "-\t\t(void) ide_floppy_get_flexible_disk_page(drive);\n" - "+\t\t(void) ide_floppy_get_flexible_disk_page(drive, &pc);\n" - " \n" - " \treturn rc;\n" - " }\n" - "diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c\n" - "index 2bc51ff..8f8be85 100644\n" - "--- a/drivers/ide/ide-floppy_ioctl.c\n" - "+++ b/drivers/ide/ide-floppy_ioctl.c\n" - "@@ -31,10 +31,11 @@\n" - " * On exit we set nformats to the number of records we've actually initialized.\n" - " */\n" - " \n" - "-static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)\n" - "+static int ide_floppy_get_format_capacities(ide_drive_t *drive,\n" - "+\t\t\t\t\t struct ide_atapi_pc *pc,\n" - "+\t\t\t\t\t int __user *arg)\n" - " {\n" - " \tstruct ide_disk_obj *floppy = drive->driver_data;\n" - "-\tstruct ide_atapi_pc pc;\n" - " \tu8 header_len, desc_cnt;\n" - " \tint i, blocks, length, u_array_size, u_index;\n" - " \tint __user *argp;\n" - "@@ -45,13 +46,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)\n" - " \tif (u_array_size <= 0)\n" - " \t\treturn -EINVAL;\n" - " \n" - "-\tide_floppy_create_read_capacity_cmd(&pc);\n" - "-\tif (ide_queue_pc_tail(drive, floppy->disk, &pc)) {\n" - "+\tide_floppy_create_read_capacity_cmd(pc);\n" - "+\tif (ide_queue_pc_tail(drive, floppy->disk, pc)) {\n" - " \t\tprintk(KERN_ERR \"ide-floppy: Can't get floppy parameters\\n\");\n" - " \t\treturn -EIO;\n" - " \t}\n" - " \n" - "-\theader_len = pc.buf[3];\n" - "+\theader_len = pc->buf[3];\n" - " \tdesc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */\n" - " \n" - " \tu_index = 0;\n" - "@@ -68,8 +69,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)\n" - " \t\tif (u_index >= u_array_size)\n" - " \t\t\tbreak;\t/* User-supplied buffer too small */\n" - " \n" - "-\t\tblocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);\n" - "-\t\tlength = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);\n" - "+\t\tblocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]);\n" - "+\t\tlength = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]);\n" - " \n" - " \t\tif (put_user(blocks, argp))\n" - " \t\t\treturn -EFAULT;\n" - "@@ -111,29 +112,28 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,\n" - " \tpc->flags |= PC_FLAG_WRITING;\n" - " }\n" - " \n" - "-static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)\n" - "+static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc)\n" - " {\n" - " \tstruct ide_disk_obj *floppy = drive->driver_data;\n" - "-\tstruct ide_atapi_pc pc;\n" - " \n" - " \tdrive->atapi_flags &= ~IDE_AFLAG_SRFP;\n" - " \n" - "-\tide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);\n" - "-\tpc.flags |= PC_FLAG_SUPPRESS_ERROR;\n" - "+\tide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE);\n" - "+\tpc->flags |= PC_FLAG_SUPPRESS_ERROR;\n" - " \n" - "-\tif (ide_queue_pc_tail(drive, floppy->disk, &pc))\n" - "+\tif (ide_queue_pc_tail(drive, floppy->disk, pc))\n" - " \t\treturn 1;\n" - " \n" - "-\tif (pc.buf[8 + 2] & 0x40)\n" - "+\tif (pc->buf[8 + 2] & 0x40)\n" - " \t\tdrive->atapi_flags |= IDE_AFLAG_SRFP;\n" - " \n" - " \treturn 0;\n" - " }\n" - " \n" - "-static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)\n" - "+static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,\n" - "+\t\t\t\t int __user *arg)\n" - " {\n" - " \tstruct ide_disk_obj *floppy = drive->driver_data;\n" - "-\tstruct ide_atapi_pc pc;\n" - " \tint blocks, length, flags, err = 0;\n" - " \n" - " \tif (floppy->openers > 1) {\n" - "@@ -166,10 +166,10 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)\n" - " \t\tgoto out;\n" - " \t}\n" - " \n" - "-\t(void)ide_floppy_get_sfrp_bit(drive);\n" - "-\tide_floppy_create_format_unit_cmd(&pc, blocks, length, flags);\n" - "+\tide_floppy_get_sfrp_bit(drive, pc);\n" - "+\tide_floppy_create_format_unit_cmd(pc, blocks, length, flags);\n" - " \n" - "-\tif (ide_queue_pc_tail(drive, floppy->disk, &pc))\n" - "+\tif (ide_queue_pc_tail(drive, floppy->disk, pc))\n" - " \t\terr = -EIO;\n" - " \n" - " out:\n" - "@@ -188,15 +188,16 @@ out:\n" - " * the dsc bit, and return either 0 or 65536.\n" - " */\n" - " \n" - "-static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)\n" - "+static int ide_floppy_get_format_progress(ide_drive_t *drive,\n" - "+\t\t\t\t\t struct ide_atapi_pc *pc,\n" - "+\t\t\t\t\t int __user *arg)\n" - " {\n" - " \tstruct ide_disk_obj *floppy = drive->driver_data;\n" - "-\tstruct ide_atapi_pc pc;\n" - " \tint progress_indication = 0x10000;\n" - " \n" - " \tif (drive->atapi_flags & IDE_AFLAG_SRFP) {\n" - "-\t\tide_create_request_sense_cmd(drive, &pc);\n" - "-\t\tif (ide_queue_pc_tail(drive, floppy->disk, &pc))\n" - "+\t\tide_create_request_sense_cmd(drive, pc);\n" - "+\t\tif (ide_queue_pc_tail(drive, floppy->disk, pc))\n" - " \t\t\treturn -EIO;\n" - " \n" - " \t\tif (floppy->sense_key == 2 &&\n" - "@@ -241,20 +242,21 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,\n" - " \treturn 0;\n" - " }\n" - " \n" - "-static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode,\n" - "-\t\t\t\t unsigned int cmd, void __user *argp)\n" - "+static int ide_floppy_format_ioctl(ide_drive_t *drive, struct ide_atapi_pc *pc,\n" - "+\t\t\t\t fmode_t mode, unsigned int cmd,\n" - "+\t\t\t\t void __user *argp)\n" - " {\n" - " \tswitch (cmd) {\n" - " \tcase IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:\n" - " \t\treturn 0;\n" - " \tcase IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:\n" - "-\t\treturn ide_floppy_get_format_capacities(drive, argp);\n" - "+\t\treturn ide_floppy_get_format_capacities(drive, pc, argp);\n" - " \tcase IDEFLOPPY_IOCTL_FORMAT_START:\n" - " \t\tif (!(mode & FMODE_WRITE))\n" - " \t\t\treturn -EPERM;\n" - "-\t\treturn ide_floppy_format_unit(drive, (int __user *)argp);\n" - "+\t\treturn ide_floppy_format_unit(drive, pc, (int __user *)argp);\n" - " \tcase IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:\n" - "-\t\treturn ide_floppy_get_format_progress(drive, argp);\n" - "+\t\treturn ide_floppy_get_format_progress(drive, pc, argp);\n" - " \tdefault:\n" - " \t\treturn -ENOTTY;\n" - " \t}\n" - "@@ -270,7 +272,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,\n" - " \tif (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR)\n" - " \t\treturn ide_floppy_lockdoor(drive, &pc, arg, cmd);\n" - " \n" - "-\terr = ide_floppy_format_ioctl(drive, mode, cmd, argp);\n" - "+\terr = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp);\n" - " \tif (err != -ENOTTY)\n" - " \t\treturn err;\n" - " \n" - "diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c\n" - "index ecacc00..1c36a8e 100644\n" - "--- a/drivers/ide/ide-io.c\n" - "+++ b/drivers/ide/ide-io.c\n" - "@@ -426,9 +426,6 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq)\n" - " \tide_hwif_t *hwif = drive->hwif;\n" - " \tstruct scatterlist *sg = hwif->sg_table;\n" - " \n" - "-\tif (hwif->sg_mapped)\t/* needed by ide-scsi */\n" - "-\t\treturn;\n" - "-\n" - " \tif (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) {\n" - " \t\thwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);\n" - " \t} else {\n" - "@@ -667,85 +664,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)\n" - " \tdrive->sleep = timeout + jiffies;\n" - " \tdrive->dev_flags |= IDE_DFLAG_SLEEPING;\n" - " }\n" - "-\n" - " EXPORT_SYMBOL(ide_stall_queue);\n" - " \n" - "-#define WAKEUP(drive)\t((drive)->service_start + 2 * (drive)->service_time)\n" - "-\n" - "-/**\n" - "- *\tchoose_drive\t\t-\tselect a drive to service\n" - "- *\t@hwgroup: hardware group to select on\n" - "- *\n" - "- *\tchoose_drive() selects the next drive which will be serviced.\n" - "- *\tThis is necessary because the IDE layer can't issue commands\n" - "- *\tto both drives on the same cable, unlike SCSI.\n" - "- */\n" - "- \n" - "-static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)\n" - "-{\n" - "-\tide_drive_t *drive, *best;\n" - "-\n" - "-repeat:\t\n" - "-\tbest = NULL;\n" - "-\tdrive = hwgroup->drive;\n" - "-\n" - "-\t/*\n" - "-\t * drive is doing pre-flush, ordered write, post-flush sequence. even\n" - "-\t * though that is 3 requests, it must be seen as a single transaction.\n" - "-\t * we must not preempt this drive until that is complete\n" - "-\t */\n" - "-\tif (blk_queue_flushing(drive->queue)) {\n" - "-\t\t/*\n" - "-\t\t * small race where queue could get replugged during\n" - "-\t\t * the 3-request flush cycle, just yank the plug since\n" - "-\t\t * we want it to finish asap\n" - "-\t\t */\n" - "-\t\tblk_remove_plug(drive->queue);\n" - "-\t\treturn drive;\n" - "-\t}\n" - "-\n" - "-\tdo {\n" - "-\t\tu8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING);\n" - "-\t\tu8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING));\n" - "-\n" - "-\t\tif ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) &&\n" - "-\t\t !elv_queue_empty(drive->queue)) {\n" - "-\t\t\tif (best == NULL ||\n" - "-\t\t\t (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) ||\n" - "-\t\t\t (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) {\n" - "-\t\t\t\tif (!blk_queue_plugged(drive->queue))\n" - "-\t\t\t\t\tbest = drive;\n" - "-\t\t\t}\n" - "-\t\t}\n" - "-\t} while ((drive = drive->next) != hwgroup->drive);\n" - "-\n" - "-\tif (best && (best->dev_flags & IDE_DFLAG_NICE1) &&\n" - "-\t (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 &&\n" - "-\t best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {\n" - "-\t\tlong t = (signed long)(WAKEUP(best) - jiffies);\n" - "-\t\tif (t >= WAIT_MIN_SLEEP) {\n" - "-\t\t/*\n" - "-\t\t * We *may* have some time to spare, but first let's see if\n" - "-\t\t * someone can potentially benefit from our nice mood today..\n" - "-\t\t */\n" - "-\t\t\tdrive = best->next;\n" - "-\t\t\tdo {\n" - "-\t\t\t\tif ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0\n" - "-\t\t\t\t && time_before(jiffies - best->service_time, WAKEUP(drive))\n" - "-\t\t\t\t && time_before(WAKEUP(drive), jiffies + t))\n" - "-\t\t\t\t{\n" - "-\t\t\t\t\tide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));\n" - "-\t\t\t\t\tgoto repeat;\n" - "-\t\t\t\t}\n" - "-\t\t\t} while ((drive = drive->next) != best);\n" - "-\t\t}\n" - "-\t}\n" - "-\treturn best;\n" - "-}\n" - "-\n" - " /*\n" - " * Issue a new request to a drive from hwgroup\n" - "- * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..);\n" - " *\n" - " * A hwgroup is a serialized group of IDE interfaces. Usually there is\n" - " * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)\n" - "@@ -757,8 +679,7 @@ repeat:\n" - " * possibly along with many other devices. This is especially common in\n" - " * PCI-based systems with off-board IDE controller cards.\n" - " *\n" - "- * The IDE driver uses a per-hwgroup spinlock to protect\n" - "- * access to the request queues, and to protect the hwgroup->busy flag.\n" - "+ * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.\n" - " *\n" - " * The first thread into the driver for a particular hwgroup sets the\n" - " * hwgroup->busy flag to indicate that this hwgroup is now active,\n" - "@@ -778,69 +699,41 @@ repeat:\n" - " * the driver. This makes the driver much more friendlier to shared IRQs\n" - " * than previous designs, while remaining 100% (?) SMP safe and capable.\n" - " */\n" - "-static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)\n" - "+void do_ide_request(struct request_queue *q)\n" - " {\n" - "-\tide_drive_t\t*drive;\n" - "-\tide_hwif_t\t*hwif;\n" - "+\tide_drive_t\t*drive = q->queuedata;\n" - "+\tide_hwif_t\t*hwif = drive->hwif;\n" - "+\tide_hwgroup_t\t*hwgroup = hwif->hwgroup;\n" - " \tstruct request\t*rq;\n" - " \tide_startstop_t\tstartstop;\n" - "-\tint loops = 0;\n" - "-\n" - "-\t/* caller must own hwgroup->lock */\n" - "-\tBUG_ON(!irqs_disabled());\n" - "-\n" - "-\twhile (!hwgroup->busy) {\n" - "-\t\thwgroup->busy = 1;\n" - "-\t\t/* for atari only */\n" - "-\t\tide_get_lock(ide_intr, hwgroup);\n" - "-\t\tdrive = choose_drive(hwgroup);\n" - "-\t\tif (drive == NULL) {\n" - "-\t\t\tint sleeping = 0;\n" - "-\t\t\tunsigned long sleep = 0; /* shut up, gcc */\n" - "-\t\t\thwgroup->rq = NULL;\n" - "-\t\t\tdrive = hwgroup->drive;\n" - "-\t\t\tdo {\n" - "-\t\t\t\tif ((drive->dev_flags & IDE_DFLAG_SLEEPING) &&\n" - "-\t\t\t\t (sleeping == 0 ||\n" - "-\t\t\t\t time_before(drive->sleep, sleep))) {\n" - "-\t\t\t\t\tsleeping = 1;\n" - "-\t\t\t\t\tsleep = drive->sleep;\n" - "-\t\t\t\t}\n" - "-\t\t\t} while ((drive = drive->next) != hwgroup->drive);\n" - "-\t\t\tif (sleeping) {\n" - "+\n" - "+\t/*\n" - "+\t * drive is doing pre-flush, ordered write, post-flush sequence. even\n" - "+\t * though that is 3 requests, it must be seen as a single transaction.\n" - "+\t * we must not preempt this drive until that is complete\n" - "+\t */\n" - "+\tif (blk_queue_flushing(q))\n" - " \t\t/*\n" - "-\t\t * Take a short snooze, and then wake up this hwgroup again.\n" - "-\t\t * This gives other hwgroups on the same a chance to\n" - "-\t\t * play fairly with us, just in case there are big differences\n" - "-\t\t * in relative throughputs.. don't want to hog the cpu too much.\n" - "+\t\t * small race where queue could get replugged during\n" - "+\t\t * the 3-request flush cycle, just yank the plug since\n" - "+\t\t * we want it to finish asap\n" - " \t\t */\n" - "-\t\t\t\tif (time_before(sleep, jiffies + WAIT_MIN_SLEEP))\n" - "-\t\t\t\t\tsleep = jiffies + WAIT_MIN_SLEEP;\n" - "-#if 1\n" - "-\t\t\t\tif (timer_pending(&hwgroup->timer))\n" - "-\t\t\t\t\tprintk(KERN_CRIT \"ide_set_handler: timer already active\\n\");\n" - "-#endif\n" - "-\t\t\t\t/* so that ide_timer_expiry knows what to do */\n" - "-\t\t\t\thwgroup->sleeping = 1;\n" - "-\t\t\t\thwgroup->req_gen_timer = hwgroup->req_gen;\n" - "-\t\t\t\tmod_timer(&hwgroup->timer, sleep);\n" - "-\t\t\t\t/* we purposely leave hwgroup->busy==1\n" - "-\t\t\t\t * while sleeping */\n" - "-\t\t\t} else {\n" - "-\t\t\t\t/* Ugly, but how can we sleep for the lock\n" - "-\t\t\t\t * otherwise? perhaps from tq_disk?\n" - "-\t\t\t\t */\n" - "+\t\tblk_remove_plug(q);\n" - " \n" - "-\t\t\t\t/* for atari only */\n" - "-\t\t\t\tide_release_lock();\n" - "-\t\t\t\thwgroup->busy = 0;\n" - "-\t\t\t}\n" - "+\tspin_unlock_irq(q->queue_lock);\n" - "+\tspin_lock_irq(&hwgroup->lock);\n" - "+\n" - "+\tif (!ide_lock_hwgroup(hwgroup)) {\n" - "+repeat:\n" - "+\t\thwgroup->rq = NULL;\n" - " \n" - "-\t\t\t/* no more work for this hwgroup (for now) */\n" - "-\t\t\treturn;\n" - "+\t\tif (drive->dev_flags & IDE_DFLAG_SLEEPING) {\n" - "+\t\t\tif (time_before(drive->sleep, jiffies)) {\n" - "+\t\t\t\tide_unlock_hwgroup(hwgroup);\n" - "+\t\t\t\tgoto plug_device;\n" - "+\t\t\t}\n" - " \t\t}\n" - "-\tagain:\n" - "-\t\thwif = HWIF(drive);\n" - "+\n" - " \t\tif (hwif != hwgroup->hwif) {\n" - " \t\t\t/*\n" - " \t\t\t * set nIEN for previous hwif, drives in the\n" - "@@ -852,16 +745,20 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)\n" - " \t\thwgroup->hwif = hwif;\n" - " \t\thwgroup->drive = drive;\n" - " \t\tdrive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);\n" - "-\t\tdrive->service_start = jiffies;\n" - " \n" - "+\t\tspin_unlock_irq(&hwgroup->lock);\n" - "+\t\tspin_lock_irq(q->queue_lock);\n" - " \t\t/*\n" - " \t\t * we know that the queue isn't empty, but this can happen\n" - " \t\t * if the q->prep_rq_fn() decides to kill a request\n" - " \t\t */\n" - " \t\trq = elv_next_request(drive->queue);\n" - "+\t\tspin_unlock_irq(q->queue_lock);\n" - "+\t\tspin_lock_irq(&hwgroup->lock);\n" - "+\n" - " \t\tif (!rq) {\n" - "-\t\t\thwgroup->busy = 0;\n" - "-\t\t\tbreak;\n" - "+\t\t\tide_unlock_hwgroup(hwgroup);\n" - "+\t\t\tgoto out;\n" - " \t\t}\n" - " \n" - " \t\t/*\n" - "@@ -876,53 +773,36 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)\n" - " \t\t * though. I hope that doesn't happen too much, hopefully not\n" - " \t\t * unless the subdriver triggers such a thing in its own PM\n" - " \t\t * state machine.\n" - "-\t\t *\n" - "-\t\t * We count how many times we loop here to make sure we service\n" - "-\t\t * all drives in the hwgroup without looping for ever\n" - " \t\t */\n" - " \t\tif ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&\n" - " \t\t blk_pm_request(rq) == 0 &&\n" - " \t\t (rq->cmd_flags & REQ_PREEMPT) == 0) {\n" - "-\t\t\tdrive = drive->next ? drive->next : hwgroup->drive;\n" - "-\t\t\tif (loops++ < 4 && !blk_queue_plugged(drive->queue))\n" - "-\t\t\t\tgoto again;\n" - "-\t\t\t/* We clear busy, there should be no pending ATA command at this point. */\n" - "-\t\t\thwgroup->busy = 0;\n" - "-\t\t\tbreak;\n" - "+\t\t\t/* there should be no pending command at this point */\n" - "+\t\t\tide_unlock_hwgroup(hwgroup);\n" - "+\t\t\tgoto plug_device;\n" - " \t\t}\n" - " \n" - " \t\thwgroup->rq = rq;\n" - " \n" - "-\t\t/*\n" - "-\t\t * Some systems have trouble with IDE IRQs arriving while\n" - "-\t\t * the driver is still setting things up. So, here we disable\n" - "-\t\t * the IRQ used by this interface while the request is being started.\n" - "-\t\t * This may look bad at first, but pretty much the same thing\n" - "-\t\t * happens anyway when any interrupt comes in, IDE or otherwise\n" - "-\t\t * -- the kernel masks the IRQ while it is being handled.\n" - "-\t\t */\n" - "-\t\tif (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)\n" - "-\t\t\tdisable_irq_nosync(hwif->irq);\n" - "-\t\tspin_unlock(&hwgroup->lock);\n" - "-\t\tlocal_irq_enable_in_hardirq();\n" - "-\t\t\t/* allow other IRQs while we start this request */\n" - "+\t\tspin_unlock_irq(&hwgroup->lock);\n" - " \t\tstartstop = start_request(drive, rq);\n" - " \t\tspin_lock_irq(&hwgroup->lock);\n" - "-\t\tif (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)\n" - "-\t\t\tenable_irq(hwif->irq);\n" - "+\n" - " \t\tif (startstop == ide_stopped)\n" - "-\t\t\thwgroup->busy = 0;\n" - "-\t}\n" - "-}\n" - "+\t\t\tgoto repeat;\n" - "+\t} else\n" - "+\t\tgoto plug_device;\n" - "+out:\n" - "+\tspin_unlock_irq(&hwgroup->lock);\n" - "+\tspin_lock_irq(q->queue_lock);\n" - "+\treturn;\n" - " \n" - "-/*\n" - "- * Passes the stuff to ide_do_request\n" - "- */\n" - "-void do_ide_request(struct request_queue *q)\n" - "-{\n" - "-\tide_drive_t *drive = q->queuedata;\n" - "+plug_device:\n" - "+\tspin_unlock_irq(&hwgroup->lock);\n" - "+\tspin_lock_irq(q->queue_lock);\n" - " \n" - "-\tide_do_request(HWGROUP(drive), IDE_NO_IRQ);\n" - "+\tif (!elv_queue_empty(q))\n" - "+\t\tblk_plug_device(q);\n" - " }\n" - " \n" - " /*\n" - "@@ -983,6 +863,17 @@ out:\n" - " \treturn ret;\n" - " }\n" - " \n" - "+static void ide_plug_device(ide_drive_t *drive)\n" - "+{\n" - "+\tstruct request_queue *q = drive->queue;\n" - "+\tunsigned long flags;\n" - "+\n" - "+\tspin_lock_irqsave(q->queue_lock, flags);\n" - "+\tif (!elv_queue_empty(q))\n" - "+\t\tblk_plug_device(q);\n" - "+\tspin_unlock_irqrestore(q->queue_lock, flags);\n" - "+}\n" - "+\n" - " /**\n" - " *\tide_timer_expiry\t-\thandle lack of an IDE interrupt\n" - " *\t@data: timer callback magic (hwgroup)\n" - "@@ -1000,10 +891,12 @@ out:\n" - " void ide_timer_expiry (unsigned long data)\n" - " {\n" - " \tide_hwgroup_t\t*hwgroup = (ide_hwgroup_t *) data;\n" - "+\tide_drive_t\t*uninitialized_var(drive);\n" - " \tide_handler_t\t*handler;\n" - " \tide_expiry_t\t*expiry;\n" - " \tunsigned long\tflags;\n" - " \tunsigned long\twait = -1;\n" - "+\tint\t\tplug_device = 0;\n" - " \n" - " \tspin_lock_irqsave(&hwgroup->lock, flags);\n" - " \n" - "@@ -1015,22 +908,15 @@ void ide_timer_expiry (unsigned long data)\n" - " \t\t * or we were \"sleeping\" to give other devices a chance.\n" - " \t\t * Either way, we don't really want to complain about anything.\n" - " \t\t */\n" - "-\t\tif (hwgroup->sleeping) {\n" - "-\t\t\thwgroup->sleeping = 0;\n" - "-\t\t\thwgroup->busy = 0;\n" - "-\t\t}\n" - " \t} else {\n" - "-\t\tide_drive_t *drive = hwgroup->drive;\n" - "+\t\tdrive = hwgroup->drive;\n" - " \t\tif (!drive) {\n" - " \t\t\tprintk(KERN_ERR \"ide_timer_expiry: hwgroup->drive was NULL\\n\");\n" - " \t\t\thwgroup->handler = NULL;\n" - " \t\t} else {\n" - " \t\t\tide_hwif_t *hwif;\n" - " \t\t\tide_startstop_t startstop = ide_stopped;\n" - "-\t\t\tif (!hwgroup->busy) {\n" - "-\t\t\t\thwgroup->busy = 1;\t/* paranoia */\n" - "-\t\t\t\tprintk(KERN_ERR \"%s: ide_timer_expiry: hwgroup->busy was 0 ??\\n\", drive->name);\n" - "-\t\t\t}\n" - "+\n" - " \t\t\tif ((expiry = hwgroup->expiry) != NULL) {\n" - " \t\t\t\t/* continue */\n" - " \t\t\t\tif ((wait = expiry(drive)) > 0) {\n" - "@@ -1071,15 +957,18 @@ void ide_timer_expiry (unsigned long data)\n" - " \t\t\t\t\tide_error(drive, \"irq timeout\",\n" - " \t\t\t\t\t\t hwif->tp_ops->read_status(hwif));\n" - " \t\t\t}\n" - "-\t\t\tdrive->service_time = jiffies - drive->service_start;\n" - " \t\t\tspin_lock_irq(&hwgroup->lock);\n" - " \t\t\tenable_irq(hwif->irq);\n" - "-\t\t\tif (startstop == ide_stopped)\n" - "-\t\t\t\thwgroup->busy = 0;\n" - "+\t\t\tif (startstop == ide_stopped) {\n" - "+\t\t\t\tide_unlock_hwgroup(hwgroup);\n" - "+\t\t\t\tplug_device = 1;\n" - "+\t\t\t}\n" - " \t\t}\n" - " \t}\n" - "-\tide_do_request(hwgroup, IDE_NO_IRQ);\n" - " \tspin_unlock_irqrestore(&hwgroup->lock, flags);\n" - "+\n" - "+\tif (plug_device)\n" - "+\t\tide_plug_device(drive);\n" - " }\n" - " \n" - " /**\n" - "@@ -1173,10 +1062,11 @@ irqreturn_t ide_intr (int irq, void *dev_id)\n" - " \tunsigned long flags;\n" - " \tide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;\n" - " \tide_hwif_t *hwif = hwgroup->hwif;\n" - "-\tide_drive_t *drive;\n" - "+\tide_drive_t *uninitialized_var(drive);\n" - " \tide_handler_t *handler;\n" - " \tide_startstop_t startstop;\n" - " \tirqreturn_t irq_ret = IRQ_NONE;\n" - "+\tint plug_device = 0;\n" - " \n" - " \tspin_lock_irqsave(&hwgroup->lock, flags);\n" - " \n" - "@@ -1241,10 +1131,6 @@ irqreturn_t ide_intr (int irq, void *dev_id)\n" - " \t\t */\n" - " \t\tgoto out;\n" - " \n" - "-\tif (!hwgroup->busy) {\n" - "-\t\thwgroup->busy = 1;\t/* paranoia */\n" - "-\t\tprintk(KERN_ERR \"%s: ide_intr: hwgroup->busy was 0 ??\\n\", drive->name);\n" - "-\t}\n" - " \thwgroup->handler = NULL;\n" - " \thwgroup->req_gen++;\n" - " \tdel_timer(&hwgroup->timer);\n" - "@@ -1267,20 +1153,22 @@ irqreturn_t ide_intr (int irq, void *dev_id)\n" - " \t * same irq as is currently being serviced here, and Linux\n" - " \t * won't allow another of the same (on any CPU) until we return.\n" - " \t */\n" - "-\tdrive->service_time = jiffies - drive->service_start;\n" - " \tif (startstop == ide_stopped) {\n" - " \t\tif (hwgroup->handler == NULL) {\t/* paranoia */\n" - "-\t\t\thwgroup->busy = 0;\n" - "-\t\t\tide_do_request(hwgroup, hwif->irq);\n" - "-\t\t} else {\n" - "-\t\t\tprintk(KERN_ERR \"%s: ide_intr: huh? expected NULL handler \"\n" - "-\t\t\t\t\"on exit\\n\", drive->name);\n" - "-\t\t}\n" - "+\t\t\tide_unlock_hwgroup(hwgroup);\n" - "+\t\t\tplug_device = 1;\n" - "+\t\t} else\n" - "+\t\t\tprintk(KERN_ERR \"%s: %s: huh? expected NULL handler \"\n" - "+\t\t\t\t\t\"on exit\\n\", __func__, drive->name);\n" - " \t}\n" - " out_handled:\n" - " \tirq_ret = IRQ_HANDLED;\n" - " out:\n" - " \tspin_unlock_irqrestore(&hwgroup->lock, flags);\n" - "+\n" - "+\tif (plug_device)\n" - "+\t\tide_plug_device(drive);\n" - "+\n" - " \treturn irq_ret;\n" - " }\n" - " \n" - "diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c\n" - "index 28232c6..1be263e 100644\n" - "--- a/drivers/ide/ide-ioctls.c\n" - "+++ b/drivers/ide/ide-ioctls.c\n" - "@@ -95,8 +95,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)\n" - " \t\treturn -EPERM;\n" - " \n" - " \tif (((arg >> IDE_NICE_DSC_OVERLAP) & 1) &&\n" - "-\t (drive->media != ide_tape ||\n" - "-\t (drive->dev_flags & IDE_DFLAG_SCSI)))\n" - "+\t (drive->media != ide_tape))\n" - " \t\treturn -EPERM;\n" - " \n" - " \tif ((arg >> IDE_NICE_DSC_OVERLAP) & 1)\n" - "diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c\n" - "index 63d01c5..678454a 100644\n" - "--- a/drivers/ide/ide-park.c\n" - "+++ b/drivers/ide/ide-park.c\n" - "@@ -16,16 +16,19 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)\n" - " \tspin_lock_irq(&hwgroup->lock);\n" - " \tif (drive->dev_flags & IDE_DFLAG_PARKED) {\n" - " \t\tint reset_timer = time_before(timeout, drive->sleep);\n" - "+\t\tint start_queue = 0;\n" - " \n" - " \t\tdrive->sleep = timeout;\n" - " \t\twake_up_all(&ide_park_wq);\n" - "-\t\tif (reset_timer && hwgroup->sleeping &&\n" - "-\t\t del_timer(&hwgroup->timer)) {\n" - "-\t\t\thwgroup->sleeping = 0;\n" - "-\t\t\thwgroup->busy = 0;\n" - "+\t\tif (reset_timer && del_timer(&hwgroup->timer))\n" - "+\t\t\tstart_queue = 1;\n" - "+\t\tspin_unlock_irq(&hwgroup->lock);\n" - "+\n" - "+\t\tif (start_queue) {\n" - "+\t\t\tspin_lock_irq(q->queue_lock);\n" - " \t\t\tblk_start_queueing(q);\n" - "+\t\t\tspin_unlock_irq(q->queue_lock);\n" - " \t\t}\n" - "-\t\tspin_unlock_irq(&hwgroup->lock);\n" - " \t\treturn;\n" - " \t}\n" - " \tspin_unlock_irq(&hwgroup->lock);\n" - "diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c\n" - "index a64ec25..c5adb7b 100644\n" - "--- a/drivers/ide/ide-probe.c\n" - "+++ b/drivers/ide/ide-probe.c\n" - "@@ -101,6 +101,82 @@ static void ide_disk_init_mult_count(ide_drive_t *drive)\n" - " \t}\n" - " }\n" - " \n" - "+static void ide_classify_ata_dev(ide_drive_t *drive)\n" - "+{\n" - "+\tu16 *id = drive->id;\n" - "+\tchar *m = (char *)&id[ATA_ID_PROD];\n" - "+\tint is_cfa = ata_id_is_cfa(id);\n" - "+\n" - "+\t/* CF devices are *not* removable in Linux definition of the term */\n" - "+\tif (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))\n" - "+\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "+\n" - "+\tdrive->media = ide_disk;\n" - "+\n" - "+\tif (!ata_id_has_unload(drive->id))\n" - "+\t\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;\n" - "+\n" - "+\tprintk(KERN_INFO \"%s: %s, %s DISK drive\\n\", drive->name, m,\n" - "+\t\tis_cfa ? \"CFA\" : \"ATA\");\n" - "+}\n" - "+\n" - "+static void ide_classify_atapi_dev(ide_drive_t *drive)\n" - "+{\n" - "+\tu16 *id = drive->id;\n" - "+\tchar *m = (char *)&id[ATA_ID_PROD];\n" - "+\tu8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;\n" - "+\n" - "+\tprintk(KERN_INFO \"%s: %s, ATAPI \", drive->name, m);\n" - "+\tswitch (type) {\n" - "+\tcase ide_floppy:\n" - "+\t\tif (!strstr(m, \"CD-ROM\")) {\n" - "+\t\t\tif (!strstr(m, \"oppy\") &&\n" - "+\t\t\t !strstr(m, \"poyp\") &&\n" - "+\t\t\t !strstr(m, \"ZIP\"))\n" - "+\t\t\t\tprintk(KERN_CONT \"cdrom or floppy?, assuming \");\n" - "+\t\t\tif (drive->media != ide_cdrom) {\n" - "+\t\t\t\tprintk(KERN_CONT \"FLOPPY\");\n" - "+\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "+\t\t\t\tbreak;\n" - "+\t\t\t}\n" - "+\t\t}\n" - "+\t\t/* Early cdrom models used zero */\n" - "+\t\ttype = ide_cdrom;\n" - "+\tcase ide_cdrom:\n" - "+\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "+#ifdef CONFIG_PPC\n" - "+\t\t/* kludge for Apple PowerBook internal zip */\n" - "+\t\tif (!strstr(m, \"CD-ROM\") && strstr(m, \"ZIP\")) {\n" - "+\t\t\tprintk(KERN_CONT \"FLOPPY\");\n" - "+\t\t\ttype = ide_floppy;\n" - "+\t\t\tbreak;\n" - "+\t\t}\n" - "+#endif\n" - "+\t\tprintk(KERN_CONT \"CD/DVD-ROM\");\n" - "+\t\tbreak;\n" - "+\tcase ide_tape:\n" - "+\t\tprintk(KERN_CONT \"TAPE\");\n" - "+\t\tbreak;\n" - "+\tcase ide_optical:\n" - "+\t\tprintk(KERN_CONT \"OPTICAL\");\n" - "+\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "+\t\tbreak;\n" - "+\tdefault:\n" - "+\t\tprintk(KERN_CONT \"UNKNOWN (type %d)\", type);\n" - "+\t\tbreak;\n" - "+\t}\n" - "+\n" - "+\tprintk(KERN_CONT \" drive\\n\");\n" - "+\tdrive->media = type;\n" - "+\t/* an ATAPI device ignores DRDY */\n" - "+\tdrive->ready_stat = 0;\n" - "+\tif (ata_id_cdb_intr(id))\n" - "+\t\tdrive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;\n" - "+\tdrive->dev_flags |= IDE_DFLAG_DOORLOCKING;\n" - "+\t/* we don't do head unloading on ATAPI devices */\n" - "+\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;\n" - "+}\n" - "+\n" - " /**\n" - " *\tdo_identify\t-\tidentify a drive\n" - " *\t@drive: drive to identify \n" - "@@ -117,7 +193,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd)\n" - " \tu16 *id = drive->id;\n" - " \tchar *m = (char *)&id[ATA_ID_PROD];\n" - " \tunsigned long flags;\n" - "-\tint bswap = 1, is_cfa;\n" - "+\tint bswap = 1;\n" - " \n" - " \t/* local CPU only; some systems need this */\n" - " \tlocal_irq_save(flags);\n" - "@@ -154,91 +230,23 @@ static void do_identify(ide_drive_t *drive, u8 cmd)\n" - " \tif (strstr(m, \"E X A B Y T E N E S T\"))\n" - " \t\tgoto err_misc;\n" - " \n" - "-\tprintk(KERN_INFO \"%s: %s, \", drive->name, m);\n" - "-\n" - " \tdrive->dev_flags |= IDE_DFLAG_PRESENT;\n" - " \tdrive->dev_flags &= ~IDE_DFLAG_DEAD;\n" - " \n" - " \t/*\n" - " \t * Check for an ATAPI device\n" - " \t */\n" - "-\tif (cmd == ATA_CMD_ID_ATAPI) {\n" - "-\t\tu8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;\n" - "-\n" - "-\t\tprintk(KERN_CONT \"ATAPI \");\n" - "-\t\tswitch (type) {\n" - "-\t\t\tcase ide_floppy:\n" - "-\t\t\t\tif (!strstr(m, \"CD-ROM\")) {\n" - "-\t\t\t\t\tif (!strstr(m, \"oppy\") &&\n" - "-\t\t\t\t\t !strstr(m, \"poyp\") &&\n" - "-\t\t\t\t\t !strstr(m, \"ZIP\"))\n" - "-\t\t\t\t\t\tprintk(KERN_CONT \"cdrom or floppy?, assuming \");\n" - "-\t\t\t\t\tif (drive->media != ide_cdrom) {\n" - "-\t\t\t\t\t\tprintk(KERN_CONT \"FLOPPY\");\n" - "-\t\t\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "-\t\t\t\t\t\tbreak;\n" - "-\t\t\t\t\t}\n" - "-\t\t\t\t}\n" - "-\t\t\t\t/* Early cdrom models used zero */\n" - "-\t\t\t\ttype = ide_cdrom;\n" - "-\t\t\tcase ide_cdrom:\n" - "-\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "-#ifdef CONFIG_PPC\n" - "-\t\t\t\t/* kludge for Apple PowerBook internal zip */\n" - "-\t\t\t\tif (!strstr(m, \"CD-ROM\") && strstr(m, \"ZIP\")) {\n" - "-\t\t\t\t\tprintk(KERN_CONT \"FLOPPY\");\n" - "-\t\t\t\t\ttype = ide_floppy;\n" - "-\t\t\t\t\tbreak;\n" - "-\t\t\t\t}\n" - "-#endif\n" - "-\t\t\t\tprintk(KERN_CONT \"CD/DVD-ROM\");\n" - "-\t\t\t\tbreak;\n" - "-\t\t\tcase ide_tape:\n" - "-\t\t\t\tprintk(KERN_CONT \"TAPE\");\n" - "-\t\t\t\tbreak;\n" - "-\t\t\tcase ide_optical:\n" - "-\t\t\t\tprintk(KERN_CONT \"OPTICAL\");\n" - "-\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "-\t\t\t\tbreak;\n" - "-\t\t\tdefault:\n" - "-\t\t\t\tprintk(KERN_CONT \"UNKNOWN (type %d)\", type);\n" - "-\t\t\t\tbreak;\n" - "-\t\t}\n" - "-\t\tprintk(KERN_CONT \" drive\\n\");\n" - "-\t\tdrive->media = type;\n" - "-\t\t/* an ATAPI device ignores DRDY */\n" - "-\t\tdrive->ready_stat = 0;\n" - "-\t\tif (ata_id_cdb_intr(id))\n" - "-\t\t\tdrive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;\n" - "-\t\tdrive->dev_flags |= IDE_DFLAG_DOORLOCKING;\n" - "-\t\t/* we don't do head unloading on ATAPI devices */\n" - "-\t\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;\n" - "-\t\treturn;\n" - "-\t}\n" - "-\n" - "+\tif (cmd == ATA_CMD_ID_ATAPI)\n" - "+\t\tide_classify_atapi_dev(drive);\n" - "+\telse\n" - " \t/*\n" - " \t * Not an ATAPI device: looks like a \"regular\" hard disk\n" - " \t */\n" - "-\n" - "-\tis_cfa = ata_id_is_cfa(id);\n" - "-\n" - "-\t/* CF devices are *not* removable in Linux definition of the term */\n" - "-\tif (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))\n" - "-\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;\n" - "-\n" - "-\tdrive->media = ide_disk;\n" - "-\n" - "-\tif (!ata_id_has_unload(drive->id))\n" - "-\t\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;\n" - "-\n" - "-\tprintk(KERN_CONT \"%s DISK drive\\n\", is_cfa ? \"CFA\" : \"ATA\");\n" - "-\n" - "+\t\tide_classify_ata_dev(drive);\n" - " \treturn;\n" - "-\n" - " err_misc:\n" - " \tkfree(id);\n" - " \tdrive->dev_flags &= ~IDE_DFLAG_PRESENT;\n" - "-\treturn;\n" - " }\n" - " \n" - " /**\n" - "@@ -641,14 +649,9 @@ static int ide_register_port(ide_hwif_t *hwif)\n" - " \t/* register with global device tree */\n" - " \tdev_set_name(&hwif->gendev, hwif->name);\n" - " \thwif->gendev.driver_data = hwif;\n" - "-\tif (hwif->gendev.parent == NULL) {\n" - "-\t\tif (hwif->dev)\n" - "-\t\t\thwif->gendev.parent = hwif->dev;\n" - "-\t\telse\n" - "-\t\t\t/* Would like to do = &device_legacy */\n" - "-\t\t\thwif->gendev.parent = NULL;\n" - "-\t}\n" - "+\thwif->gendev.parent = hwif->dev;\n" - " \thwif->gendev.release = hwif_release_dev;\n" - "+\n" - " \tret = device_register(&hwif->gendev);\n" - " \tif (ret < 0) {\n" - " \t\tprintk(KERN_WARNING \"IDE: %s: device_register error: %d\\n\",\n" - "@@ -878,8 +881,7 @@ static int ide_init_queue(ide_drive_t *drive)\n" - " \t *\tdo not.\n" - " \t */\n" - " \n" - "-\tq = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock,\n" - "-\t\t\t\thwif_to_node(hwif));\n" - "+\tq = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif));\n" - " \tif (!q)\n" - " \t\treturn 1;\n" - " \n" - "@@ -1139,8 +1141,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data)\n" - " \n" - " \tif (drive->media == ide_disk)\n" - " \t\trequest_module(\"ide-disk\");\n" - "-\tif (drive->dev_flags & IDE_DFLAG_SCSI)\n" - "-\t\trequest_module(\"ide-scsi\");\n" - " \tif (drive->media == ide_cdrom || drive->media == ide_optical)\n" - " \t\trequest_module(\"ide-cd\");\n" - " \tif (drive->media == ide_tape)\n" - "@@ -1417,58 +1417,6 @@ static void ide_port_cable_detect(ide_hwif_t *hwif)\n" - " \t}\n" - " }\n" - " \n" - "-static ssize_t store_delete_devices(struct device *portdev,\n" - "-\t\t\t\t struct device_attribute *attr,\n" - "-\t\t\t\t const char *buf, size_t n)\n" - "-{\n" - "-\tide_hwif_t *hwif = dev_get_drvdata(portdev);\n" - "-\n" - "-\tif (strncmp(buf, \"1\", n))\n" - "-\t\treturn -EINVAL;\n" - "-\n" - "-\tide_port_unregister_devices(hwif);\n" - "-\n" - "-\treturn n;\n" - "-};\n" - "-\n" - "-static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);\n" - "-\n" - "-static ssize_t store_scan(struct device *portdev,\n" - "-\t\t\t struct device_attribute *attr,\n" - "-\t\t\t const char *buf, size_t n)\n" - "-{\n" - "-\tide_hwif_t *hwif = dev_get_drvdata(portdev);\n" - "-\n" - "-\tif (strncmp(buf, \"1\", n))\n" - "-\t\treturn -EINVAL;\n" - "-\n" - "-\tide_port_unregister_devices(hwif);\n" - "-\tide_port_scan(hwif);\n" - "-\n" - "-\treturn n;\n" - "-};\n" - "-\n" - "-static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);\n" - "-\n" - "-static struct device_attribute *ide_port_attrs[] = {\n" - "-\t&dev_attr_delete_devices,\n" - "-\t&dev_attr_scan,\n" - "-\tNULL\n" - "-};\n" - "-\n" - "-static int ide_sysfs_register_port(ide_hwif_t *hwif)\n" - "-{\n" - "-\tint i, uninitialized_var(rc);\n" - "-\n" - "-\tfor (i = 0; ide_port_attrs[i]; i++) {\n" - "-\t\trc = device_create_file(hwif->portdev, ide_port_attrs[i]);\n" - "-\t\tif (rc)\n" - "-\t\t\tbreak;\n" - "-\t}\n" - "-\n" - "-\treturn rc;\n" - "-}\n" - "-\n" - " static unsigned int ide_indexes;\n" - " \n" - " /**\n" - "@@ -1655,9 +1603,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,\n" - " \t\tif (hwif == NULL)\n" - " \t\t\tcontinue;\n" - " \n" - "-\t\tif (hwif->chipset == ide_unknown)\n" - "-\t\t\thwif->chipset = ide_generic;\n" - "-\n" - " \t\tif (hwif->present)\n" - " \t\t\thwif_register_devices(hwif);\n" - " \t}\n" - "diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.c\n" - "new file mode 100644\n" - "index 0000000..883ffac\n" - "--- /dev/null\n" - "+++ b/drivers/ide/ide-sysfs.c\n" - "@@ -0,0 +1,125 @@\n" - "+#include <linux/kernel.h>\n" - "+#include <linux/ide.h>\n" - "+\n" - "+char *ide_media_string(ide_drive_t *drive)\n" - "+{\n" - "+\tswitch (drive->media) {\n" - "+\tcase ide_disk:\n" - "+\t\treturn \"disk\";\n" - "+\tcase ide_cdrom:\n" - "+\t\treturn \"cdrom\";\n" - "+\tcase ide_tape:\n" - "+\t\treturn \"tape\";\n" - "+\tcase ide_floppy:\n" - "+\t\treturn \"floppy\";\n" - "+\tcase ide_optical:\n" - "+\t\treturn \"optical\";\n" - "+\tdefault:\n" - "+\t\treturn \"UNKNOWN\";\n" - "+\t}\n" - "+}\n" - "+\n" - "+static ssize_t media_show(struct device *dev, struct device_attribute *attr,\n" - "+\t\t\t char *buf)\n" - "+{\n" - "+\tide_drive_t *drive = to_ide_device(dev);\n" - "+\treturn sprintf(buf, \"%s\\n\", ide_media_string(drive));\n" - "+}\n" - "+\n" - "+static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,\n" - "+\t\t\t char *buf)\n" - "+{\n" - "+\tide_drive_t *drive = to_ide_device(dev);\n" - "+\treturn sprintf(buf, \"%s\\n\", drive->name);\n" - "+}\n" - "+\n" - "+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,\n" - "+\t\t\t char *buf)\n" - "+{\n" - "+\tide_drive_t *drive = to_ide_device(dev);\n" - "+\treturn sprintf(buf, \"ide:m-%s\\n\", ide_media_string(drive));\n" - "+}\n" - "+\n" - "+static ssize_t model_show(struct device *dev, struct device_attribute *attr,\n" - "+\t\t\t char *buf)\n" - "+{\n" - "+\tide_drive_t *drive = to_ide_device(dev);\n" - "+\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_PROD]);\n" - "+}\n" - "+\n" - "+static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,\n" - "+\t\t\t char *buf)\n" - "+{\n" - "+\tide_drive_t *drive = to_ide_device(dev);\n" - "+\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_FW_REV]);\n" - "+}\n" - "+\n" - "+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,\n" - "+\t\t\t char *buf)\n" - "+{\n" - "+\tide_drive_t *drive = to_ide_device(dev);\n" - "+\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_SERNO]);\n" - "+}\n" - "+\n" - "+struct device_attribute ide_dev_attrs[] = {\n" - "+\t__ATTR_RO(media),\n" - "+\t__ATTR_RO(drivename),\n" - "+\t__ATTR_RO(modalias),\n" - "+\t__ATTR_RO(model),\n" - "+\t__ATTR_RO(firmware),\n" - "+\t__ATTR(serial, 0400, serial_show, NULL),\n" - "+\t__ATTR(unload_heads, 0644, ide_park_show, ide_park_store),\n" - "+\t__ATTR_NULL\n" - "+};\n" - "+\n" - "+static ssize_t store_delete_devices(struct device *portdev,\n" - "+\t\t\t\t struct device_attribute *attr,\n" - "+\t\t\t\t const char *buf, size_t n)\n" - "+{\n" - "+\tide_hwif_t *hwif = dev_get_drvdata(portdev);\n" - "+\n" - "+\tif (strncmp(buf, \"1\", n))\n" - "+\t\treturn -EINVAL;\n" - "+\n" - "+\tide_port_unregister_devices(hwif);\n" - "+\n" - "+\treturn n;\n" - "+};\n" - "+\n" - "+static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);\n" - "+\n" - "+static ssize_t store_scan(struct device *portdev,\n" - "+\t\t\t struct device_attribute *attr,\n" - "+\t\t\t const char *buf, size_t n)\n" - "+{\n" - "+\tide_hwif_t *hwif = dev_get_drvdata(portdev);\n" - "+\n" - "+\tif (strncmp(buf, \"1\", n))\n" - "+\t\treturn -EINVAL;\n" - "+\n" - "+\tide_port_unregister_devices(hwif);\n" - "+\tide_port_scan(hwif);\n" - "+\n" - "+\treturn n;\n" - "+};\n" - "+\n" - "+static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);\n" - "+\n" - "+static struct device_attribute *ide_port_attrs[] = {\n" - "+\t&dev_attr_delete_devices,\n" - "+\t&dev_attr_scan,\n" - "+\tNULL\n" - "+};\n" - "+\n" - "+int ide_sysfs_register_port(ide_hwif_t *hwif)\n" - "+{\n" - "+\tint i, uninitialized_var(rc);\n" - "+\n" - "+\tfor (i = 0; ide_port_attrs[i]; i++) {\n" - "+\t\trc = device_create_file(hwif->portdev, ide_port_attrs[i]);\n" - "+\t\tif (rc)\n" - "+\t\t\tbreak;\n" - "+\t}\n" - "+\n" - "+\treturn rc;\n" - "+}\n" - "diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c\n" - "index a2d470e..5d2aa22 100644\n" - "--- a/drivers/ide/ide-tape.c\n" - "+++ b/drivers/ide/ide-tape.c\n" - "@@ -694,7 +694,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,\n" - " \n" - " \tpc->retries++;\n" - " \n" - "-\treturn ide_issue_pc(drive, WAIT_TAPE_CMD, NULL);\n" - "+\treturn ide_issue_pc(drive);\n" - " }\n" - " \n" - " /* A mode sense command is used to \"sense\" tape parameters. */\n" - "diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c\n" - "index f0f09f7..46a2d4c 100644\n" - "--- a/drivers/ide/ide.c\n" - "+++ b/drivers/ide/ide.c\n" - "@@ -440,81 +440,13 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)\n" - " \treturn 1;\n" - " }\n" - " \n" - "-static char *media_string(ide_drive_t *drive)\n" - "-{\n" - "-\tswitch (drive->media) {\n" - "-\tcase ide_disk:\n" - "-\t\treturn \"disk\";\n" - "-\tcase ide_cdrom:\n" - "-\t\treturn \"cdrom\";\n" - "-\tcase ide_tape:\n" - "-\t\treturn \"tape\";\n" - "-\tcase ide_floppy:\n" - "-\t\treturn \"floppy\";\n" - "-\tcase ide_optical:\n" - "-\t\treturn \"optical\";\n" - "-\tdefault:\n" - "-\t\treturn \"UNKNOWN\";\n" - "-\t}\n" - "-}\n" - "-\n" - "-static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)\n" - "-{\n" - "-\tide_drive_t *drive = to_ide_device(dev);\n" - "-\treturn sprintf(buf, \"%s\\n\", media_string(drive));\n" - "-}\n" - "-\n" - "-static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)\n" - "-{\n" - "-\tide_drive_t *drive = to_ide_device(dev);\n" - "-\treturn sprintf(buf, \"%s\\n\", drive->name);\n" - "-}\n" - "-\n" - "-static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)\n" - "-{\n" - "-\tide_drive_t *drive = to_ide_device(dev);\n" - "-\treturn sprintf(buf, \"ide:m-%s\\n\", media_string(drive));\n" - "-}\n" - "-\n" - "-static ssize_t model_show(struct device *dev, struct device_attribute *attr,\n" - "-\t\t\t char *buf)\n" - "-{\n" - "-\tide_drive_t *drive = to_ide_device(dev);\n" - "-\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_PROD]);\n" - "-}\n" - "-\n" - "-static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,\n" - "-\t\t\t char *buf)\n" - "-{\n" - "-\tide_drive_t *drive = to_ide_device(dev);\n" - "-\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_FW_REV]);\n" - "-}\n" - "-\n" - "-static ssize_t serial_show(struct device *dev, struct device_attribute *attr,\n" - "-\t\t\t char *buf)\n" - "-{\n" - "-\tide_drive_t *drive = to_ide_device(dev);\n" - "-\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_SERNO]);\n" - "-}\n" - "-\n" - "-static struct device_attribute ide_dev_attrs[] = {\n" - "-\t__ATTR_RO(media),\n" - "-\t__ATTR_RO(drivename),\n" - "-\t__ATTR_RO(modalias),\n" - "-\t__ATTR_RO(model),\n" - "-\t__ATTR_RO(firmware),\n" - "-\t__ATTR(serial, 0400, serial_show, NULL),\n" - "-\t__ATTR(unload_heads, 0644, ide_park_show, ide_park_store),\n" - "-\t__ATTR_NULL\n" - "-};\n" - "-\n" - " static int ide_uevent(struct device *dev, struct kobj_uevent_env *env)\n" - " {\n" - " \tide_drive_t *drive = to_ide_device(dev);\n" - " \n" - "-\tadd_uevent_var(env, \"MEDIA=%s\", media_string(drive));\n" - "+\tadd_uevent_var(env, \"MEDIA=%s\", ide_media_string(drive));\n" - " \tadd_uevent_var(env, \"DRIVENAME=%s\", drive->name);\n" - "-\tadd_uevent_var(env, \"MODALIAS=ide:m-%s\", media_string(drive));\n" - "+\tadd_uevent_var(env, \"MODALIAS=ide:m-%s\", ide_media_string(drive));\n" - " \treturn 0;\n" - " }\n" - " \n" - "diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c\n" - "index 13b63e7..b4ef218 100644\n" - "--- a/drivers/ide/tx4938ide.c\n" - "+++ b/drivers/ide/tx4938ide.c\n" - "@@ -216,16 +216,17 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {\n" - " #endif\t/* __BIG_ENDIAN */\n" - " \n" - " static const struct ide_port_ops tx4938ide_port_ops = {\n" - "-\t.set_pio_mode = tx4938ide_set_pio_mode,\n" - "+\t.set_pio_mode\t\t= tx4938ide_set_pio_mode,\n" - " };\n" - " \n" - " static const struct ide_port_info tx4938ide_port_info __initdata = {\n" - "-\t.port_ops = &tx4938ide_port_ops,\n" - "+\t.port_ops\t\t= &tx4938ide_port_ops,\n" - " #ifdef __BIG_ENDIAN\n" - "-\t.tp_ops = &tx4938ide_tp_ops,\n" - "+\t.tp_ops\t\t\t= &tx4938ide_tp_ops,\n" - " #endif\n" - "-\t.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,\n" - "-\t.pio_mask = ATA_PIO5,\n" - "+\t.host_flags\t\t= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,\n" - "+\t.pio_mask\t\t= ATA_PIO5,\n" - "+\t.chipset\t\t= ide_generic,\n" - " };\n" - " \n" - " static int __init tx4938ide_probe(struct platform_device *pdev)\n" - "diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c\n" - "index 97cd9e0..4a8c5a2 100644\n" - "--- a/drivers/ide/tx4939ide.c\n" - "+++ b/drivers/ide/tx4939ide.c\n" - "@@ -623,33 +623,34 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {\n" - " #endif\t/* __LITTLE_ENDIAN */\n" - " \n" - " static const struct ide_port_ops tx4939ide_port_ops = {\n" - "-\t.set_pio_mode = tx4939ide_set_pio_mode,\n" - "-\t.set_dma_mode = tx4939ide_set_dma_mode,\n" - "-\t.clear_irq = tx4939ide_clear_irq,\n" - "-\t.cable_detect = tx4939ide_cable_detect,\n" - "+\t.set_pio_mode\t\t= tx4939ide_set_pio_mode,\n" - "+\t.set_dma_mode\t\t= tx4939ide_set_dma_mode,\n" - "+\t.clear_irq\t\t= tx4939ide_clear_irq,\n" - "+\t.cable_detect\t\t= tx4939ide_cable_detect,\n" - " };\n" - " \n" - " static const struct ide_dma_ops tx4939ide_dma_ops = {\n" - "-\t.dma_host_set = tx4939ide_dma_host_set,\n" - "-\t.dma_setup = tx4939ide_dma_setup,\n" - "-\t.dma_exec_cmd = ide_dma_exec_cmd,\n" - "-\t.dma_start = ide_dma_start,\n" - "-\t.dma_end = tx4939ide_dma_end,\n" - "-\t.dma_test_irq = tx4939ide_dma_test_irq,\n" - "-\t.dma_lost_irq = ide_dma_lost_irq,\n" - "-\t.dma_timeout = ide_dma_timeout,\n" - "+\t.dma_host_set\t\t= tx4939ide_dma_host_set,\n" - "+\t.dma_setup\t\t= tx4939ide_dma_setup,\n" - "+\t.dma_exec_cmd\t\t= ide_dma_exec_cmd,\n" - "+\t.dma_start\t\t= ide_dma_start,\n" - "+\t.dma_end\t\t= tx4939ide_dma_end,\n" - "+\t.dma_test_irq\t\t= tx4939ide_dma_test_irq,\n" - "+\t.dma_lost_irq\t\t= ide_dma_lost_irq,\n" - "+\t.dma_timeout\t\t= ide_dma_timeout,\n" - " };\n" - " \n" - " static const struct ide_port_info tx4939ide_port_info __initdata = {\n" - "-\t.init_hwif = tx4939ide_init_hwif,\n" - "-\t.init_dma = tx4939ide_init_dma,\n" - "-\t.port_ops = &tx4939ide_port_ops,\n" - "-\t.dma_ops = &tx4939ide_dma_ops,\n" - "-\t.tp_ops = &tx4939ide_tp_ops,\n" - "-\t.host_flags = IDE_HFLAG_MMIO,\n" - "-\t.pio_mask = ATA_PIO4,\n" - "-\t.mwdma_mask = ATA_MWDMA2,\n" - "-\t.udma_mask = ATA_UDMA5,\n" - "+\t.init_hwif\t\t= tx4939ide_init_hwif,\n" - "+\t.init_dma\t\t= tx4939ide_init_dma,\n" - "+\t.port_ops\t\t= &tx4939ide_port_ops,\n" - "+\t.dma_ops\t\t= &tx4939ide_dma_ops,\n" - "+\t.tp_ops\t\t\t= &tx4939ide_tp_ops,\n" - "+\t.host_flags\t\t= IDE_HFLAG_MMIO,\n" - "+\t.pio_mask\t\t= ATA_PIO4,\n" - "+\t.mwdma_mask\t\t= ATA_MWDMA2,\n" - "+\t.udma_mask\t\t= ATA_UDMA5,\n" - "+\t.chipset\t\t= ide_generic,\n" - " };\n" - " \n" - " static int __init tx4939ide_probe(struct platform_device *pdev)\n" - "diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig\n" - "index 152d4aa..b732297 100644\n" - "--- a/drivers/scsi/Kconfig\n" - "+++ b/drivers/scsi/Kconfig\n" - "@@ -21,7 +21,7 @@ config SCSI\n" - " \t You also need to say Y here if you have a device which speaks\n" - " \t the SCSI protocol. Examples of this include the parallel port\n" - " \t version of the IOMEGA ZIP drive, USB storage devices, Fibre\n" - "-\t Channel, FireWire storage and the IDE-SCSI emulation driver.\n" - "+\t Channel, and FireWire storage.\n" - " \n" - " \t To compile this driver as a module, choose M here and read\n" - " \t <file:Documentation/scsi/scsi.txt>.\n" - "@@ -101,9 +101,9 @@ config CHR_DEV_OSST\n" - " \t---help---\n" - " \t The OnStream SC-x0 SCSI tape drives cannot be driven by the\n" - " \t standard st driver, but instead need this special osst driver and\n" - "-\t use the /dev/osstX char device nodes (major 206). Via usb-storage\n" - "-\t and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives\n" - "-\t as well. Note that there is also a second generation of OnStream\n" - "+\t use the /dev/osstX char device nodes (major 206). Via usb-storage,\n" - "+\t you may be able to drive the USB-x0 and DI-x0 drives as well.\n" - "+\t Note that there is also a second generation of OnStream\n" - " \t tape drives (ADR-x0) that supports the standard SCSI-2 commands for\n" - " \t tapes (QIC-157) and can be driven by the standard driver st.\n" - " \t For more information, you may have a look at the SCSI-HOWTO\n" - "diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile\n" - "index 1410697..7461eb0 100644\n" - "--- a/drivers/scsi/Makefile\n" - "+++ b/drivers/scsi/Makefile\n" - "@@ -105,7 +105,6 @@ obj-$(CONFIG_SCSI_GDTH)\t\t+= gdth.o\n" - " obj-$(CONFIG_SCSI_INITIO)\t+= initio.o\n" - " obj-$(CONFIG_SCSI_INIA100)\t+= a100u2w.o\n" - " obj-$(CONFIG_SCSI_QLOGICPTI)\t+= qlogicpti.o\n" - "-obj-$(CONFIG_BLK_DEV_IDESCSI)\t+= ide-scsi.o\n" - " obj-$(CONFIG_SCSI_MESH)\t\t+= mesh.o\n" - " obj-$(CONFIG_SCSI_MAC53C94)\t+= mac53c94.o\n" - " obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o\n" - "diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c\n" - "deleted file mode 100644\n" - "index c24140a..0000000\n" - "--- a/drivers/scsi/ide-scsi.c\n" - "+++ /dev/null\n" - "@@ -1,840 +0,0 @@\n" - "-/*\n" - "- * Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il>\n" - "- * Copyright (C) 2004-2005 Bartlomiej Zolnierkiewicz\n" - "- */\n" - "-\n" - "-/*\n" - "- * Emulation of a SCSI host adapter for IDE ATAPI devices.\n" - "- *\n" - "- * With this driver, one can use the Linux SCSI drivers instead of the\n" - "- * native IDE ATAPI drivers.\n" - "- *\n" - "- * Ver 0.1 Dec 3 96 Initial version.\n" - "- * Ver 0.2 Jan 26 97 Fixed bug in cleanup_module() and added emulation\n" - "- * of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks\n" - "- * to Janos Farkas for pointing this out.\n" - "- * Avoid using bitfields in structures for m68k.\n" - "- * Added Scatter/Gather and DMA support.\n" - "- * Ver 0.4 Dec 7 97 Add support for ATAPI PD/CD drives.\n" - "- * Use variable timeout for each command.\n" - "- * Ver 0.5 Jan 2 98 Fix previous PD/CD support.\n" - "- * Allow disabling of SCSI-6 to SCSI-10 transformation.\n" - "- * Ver 0.6 Jan 27 98 Allow disabling of SCSI command translation layer\n" - "- * for access through /dev/sg.\n" - "- * Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation.\n" - "- * Ver 0.7 Dec 04 98 Ignore commands where lun != 0 to avoid multiple\n" - "- * detection of devices with CONFIG_SCSI_MULTI_LUN\n" - "- * Ver 0.8 Feb 05 99 Optical media need translation too. Reverse 0.7.\n" - "- * Ver 0.9 Jul 04 99 Fix a bug in SG_SET_TRANSFORM.\n" - "- * Ver 0.91 Jun 10 02 Fix \"off by one\" error in transforms\n" - "- * Ver 0.92 Dec 31 02 Implement new SCSI mid level API\n" - "- */\n" - "-\n" - "-#define IDESCSI_VERSION \"0.92\"\n" - "-\n" - "-#include <linux/module.h>\n" - "-#include <linux/types.h>\n" - "-#include <linux/string.h>\n" - "-#include <linux/kernel.h>\n" - "-#include <linux/mm.h>\n" - "-#include <linux/ioport.h>\n" - "-#include <linux/blkdev.h>\n" - "-#include <linux/errno.h>\n" - "-#include <linux/slab.h>\n" - "-#include <linux/ide.h>\n" - "-#include <linux/scatterlist.h>\n" - "-#include <linux/delay.h>\n" - "-#include <linux/mutex.h>\n" - "-#include <linux/bitops.h>\n" - "-\n" - "-#include <asm/io.h>\n" - "-#include <asm/uaccess.h>\n" - "-\n" - "-#include <scsi/scsi.h>\n" - "-#include <scsi/scsi_cmnd.h>\n" - "-#include <scsi/scsi_device.h>\n" - "-#include <scsi/scsi_host.h>\n" - "-#include <scsi/scsi_tcq.h>\n" - "-#include <scsi/sg.h>\n" - "-\n" - "-#define IDESCSI_DEBUG_LOG\t\t0\n" - "-\n" - "-#if IDESCSI_DEBUG_LOG\n" - "-#define debug_log(fmt, args...) \\\n" - "-\tprintk(KERN_INFO \"ide-scsi: \" fmt, ## args)\n" - "-#else\n" - "-#define debug_log(fmt, args...) do {} while (0)\n" - "-#endif\n" - "-\n" - "-/*\n" - "- *\tSCSI command transformation layer\n" - "- */\n" - "-#define IDESCSI_SG_TRANSFORM\t\t1\t/* /dev/sg transformation */\n" - "-\n" - "-/*\n" - "- *\tLog flags\n" - "- */\n" - "-#define IDESCSI_LOG_CMD\t\t\t0\t/* Log SCSI commands */\n" - "-\n" - "-typedef struct ide_scsi_obj {\n" - "-\tide_drive_t\t\t*drive;\n" - "-\tide_driver_t\t\t*driver;\n" - "-\tstruct gendisk\t\t*disk;\n" - "-\tstruct Scsi_Host\t*host;\n" - "-\n" - "-\tunsigned long transform;\t\t/* SCSI cmd translation layer */\n" - "-\tunsigned long log;\t\t\t/* log flags */\n" - "-} idescsi_scsi_t;\n" - "-\n" - "-static DEFINE_MUTEX(idescsi_ref_mutex);\n" - "-/* Set by module param to skip cd */\n" - "-static int idescsi_nocd;\n" - "-\n" - "-#define ide_scsi_g(disk) \\\n" - "-\tcontainer_of((disk)->private_data, struct ide_scsi_obj, driver)\n" - "-\n" - "-static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)\n" - "-{\n" - "-\tstruct ide_scsi_obj *scsi = NULL;\n" - "-\n" - "-\tmutex_lock(&idescsi_ref_mutex);\n" - "-\tscsi = ide_scsi_g(disk);\n" - "-\tif (scsi) {\n" - "-\t\tif (ide_device_get(scsi->drive))\n" - "-\t\t\tscsi = NULL;\n" - "-\t\telse\n" - "-\t\t\tscsi_host_get(scsi->host);\n" - "-\t}\n" - "-\tmutex_unlock(&idescsi_ref_mutex);\n" - "-\treturn scsi;\n" - "-}\n" - "-\n" - "-static void ide_scsi_put(struct ide_scsi_obj *scsi)\n" - "-{\n" - "-\tide_drive_t *drive = scsi->drive;\n" - "-\n" - "-\tmutex_lock(&idescsi_ref_mutex);\n" - "-\tscsi_host_put(scsi->host);\n" - "-\tide_device_put(drive);\n" - "-\tmutex_unlock(&idescsi_ref_mutex);\n" - "-}\n" - "-\n" - "-static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)\n" - "-{\n" - "-\treturn (idescsi_scsi_t*) (&host[1]);\n" - "-}\n" - "-\n" - "-static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)\n" - "-{\n" - "-\treturn scsihost_to_idescsi(ide_drive->driver_data);\n" - "-}\n" - "-\n" - "-static void ide_scsi_hex_dump(u8 *data, int len)\n" - "-{\n" - "-\tprint_hex_dump(KERN_CONT, \"\", DUMP_PREFIX_NONE, 16, 1, data, len, 0);\n" - "-}\n" - "-\n" - "-static int idescsi_end_request(ide_drive_t *, int, int);\n" - "-\n" - "-static void ide_scsi_callback(ide_drive_t *drive, int dsc)\n" - "-{\n" - "-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive);\n" - "-\tstruct ide_atapi_pc *pc = drive->pc;\n" - "-\n" - "-\tif (pc->flags & PC_FLAG_TIMEDOUT)\n" - "-\t\tdebug_log(\"%s: got timed out packet %lu at %lu\\n\", __func__,\n" - "-\t\t\t pc->scsi_cmd->serial_number, jiffies);\n" - "-\t\t/* end this request now - scsi should retry it*/\n" - "-\telse if (test_bit(IDESCSI_LOG_CMD, &scsi->log))\n" - "-\t\tprintk(KERN_INFO \"Packet command completed, %d bytes\"\n" - "-\t\t\t\t \" transferred\\n\", pc->xferred);\n" - "-\n" - "-\tidescsi_end_request(drive, 1, 0);\n" - "-}\n" - "-\n" - "-static int idescsi_check_condition(ide_drive_t *drive,\n" - "-\t\tstruct request *failed_cmd)\n" - "-{\n" - "-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive);\n" - "-\tstruct ide_atapi_pc *pc;\n" - "-\tstruct request *rq;\n" - "-\tu8 *buf;\n" - "-\n" - "-\t/* stuff a sense request in front of our current request */\n" - "-\tpc = kzalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);\n" - "-\trq = blk_get_request(drive->queue, READ, GFP_ATOMIC);\n" - "-\tbuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);\n" - "-\tif (!pc || !rq || !buf) {\n" - "-\t\tkfree(buf);\n" - "-\t\tif (rq)\n" - "-\t\t\tblk_put_request(rq);\n" - "-\t\tkfree(pc);\n" - "-\t\treturn -ENOMEM;\n" - "-\t}\n" - "-\trq->special = (char *) pc;\n" - "-\tpc->rq = rq;\n" - "-\tpc->buf = buf;\n" - "-\tpc->c[0] = REQUEST_SENSE;\n" - "-\tpc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;\n" - "-\trq->cmd_type = REQ_TYPE_SENSE;\n" - "-\trq->cmd_flags |= REQ_PREEMPT;\n" - "-\tpc->timeout = jiffies + WAIT_READY;\n" - "-\t/* NOTE! Save the failed packet command in \"rq->buffer\" */\n" - "-\trq->buffer = (void *) failed_cmd->special;\n" - "-\tpc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;\n" - "-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {\n" - "-\t\tprintk (\"ide-scsi: %s: queue cmd = \", drive->name);\n" - "-\t\tide_scsi_hex_dump(pc->c, 6);\n" - "-\t}\n" - "-\trq->rq_disk = scsi->disk;\n" - "-\trq->ref_count++;\n" - "-\tmemcpy(rq->cmd, pc->c, 12);\n" - "-\tide_do_drive_cmd(drive, rq);\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static ide_startstop_t\n" - "-idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)\n" - "-{\n" - "-\tide_hwif_t *hwif = drive->hwif;\n" - "-\n" - "-\tif (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))\n" - "-\t\t/* force an abort */\n" - "-\t\thwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);\n" - "-\n" - "-\trq->errors++;\n" - "-\n" - "-\tidescsi_end_request(drive, 0, 0);\n" - "-\n" - "-\treturn ide_stopped;\n" - "-}\n" - "-\n" - "-static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)\n" - "-{\n" - "-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive);\n" - "-\tstruct request *rq = HWGROUP(drive)->rq;\n" - "-\tstruct ide_atapi_pc *pc = (struct ide_atapi_pc *) rq->special;\n" - "-\tint log = test_bit(IDESCSI_LOG_CMD, &scsi->log);\n" - "-\tstruct Scsi_Host *host;\n" - "-\tint errors = rq->errors;\n" - "-\tunsigned long flags;\n" - "-\n" - "-\tif (!blk_special_request(rq) && !blk_sense_request(rq)) {\n" - "-\t\tide_end_request(drive, uptodate, nrsecs);\n" - "-\t\treturn 0;\n" - "-\t}\n" - "-\tide_end_drive_cmd (drive, 0, 0);\n" - "-\tif (blk_sense_request(rq)) {\n" - "-\t\tstruct ide_atapi_pc *opc = (struct ide_atapi_pc *) rq->buffer;\n" - "-\t\tif (log) {\n" - "-\t\t\tprintk (\"ide-scsi: %s: wrap up check %lu, rst = \", drive->name, opc->scsi_cmd->serial_number);\n" - "-\t\t\tide_scsi_hex_dump(pc->buf, 16);\n" - "-\t\t}\n" - "-\t\tmemcpy((void *) opc->scsi_cmd->sense_buffer, pc->buf,\n" - "-\t\t\tSCSI_SENSE_BUFFERSIZE);\n" - "-\t\tkfree(pc->buf);\n" - "-\t\tkfree(pc);\n" - "-\t\tblk_put_request(rq);\n" - "-\t\tpc = opc;\n" - "-\t\trq = pc->rq;\n" - "-\t\tpc->scsi_cmd->result = (CHECK_CONDITION << 1) |\n" - "-\t\t\t\t(((pc->flags & PC_FLAG_TIMEDOUT) ?\n" - "-\t\t\t\t DID_TIME_OUT :\n" - "-\t\t\t\t DID_OK) << 16);\n" - "-\t} else if (pc->flags & PC_FLAG_TIMEDOUT) {\n" - "-\t\tif (log)\n" - "-\t\t\tprintk (KERN_WARNING \"ide-scsi: %s: timed out for %lu\\n\",\n" - "-\t\t\t\t\tdrive->name, pc->scsi_cmd->serial_number);\n" - "-\t\tpc->scsi_cmd->result = DID_TIME_OUT << 16;\n" - "-\t} else if (errors >= ERROR_MAX) {\n" - "-\t\tpc->scsi_cmd->result = DID_ERROR << 16;\n" - "-\t\tif (log)\n" - "-\t\t\tprintk (\"ide-scsi: %s: I/O error for %lu\\n\", drive->name, pc->scsi_cmd->serial_number);\n" - "-\t} else if (errors) {\n" - "-\t\tif (log)\n" - "-\t\t\tprintk (\"ide-scsi: %s: check condition for %lu\\n\", drive->name, pc->scsi_cmd->serial_number);\n" - "-\t\tif (!idescsi_check_condition(drive, rq))\n" - "-\t\t\t/* we started a request sense, so we'll be back, exit for now */\n" - "-\t\t\treturn 0;\n" - "-\t\tpc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);\n" - "-\t} else {\n" - "-\t\tpc->scsi_cmd->result = DID_OK << 16;\n" - "-\t}\n" - "-\thost = pc->scsi_cmd->device->host;\n" - "-\tspin_lock_irqsave(host->host_lock, flags);\n" - "-\tpc->done(pc->scsi_cmd);\n" - "-\tspin_unlock_irqrestore(host->host_lock, flags);\n" - "-\tkfree(pc);\n" - "-\tblk_put_request(rq);\n" - "-\tdrive->pc = NULL;\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static inline int idescsi_set_direction(struct ide_atapi_pc *pc)\n" - "-{\n" - "-\tswitch (pc->c[0]) {\n" - "-\t\tcase READ_6: case READ_10: case READ_12:\n" - "-\t\t\tpc->flags &= ~PC_FLAG_WRITING;\n" - "-\t\t\treturn 0;\n" - "-\t\tcase WRITE_6: case WRITE_10: case WRITE_12:\n" - "-\t\t\tpc->flags |= PC_FLAG_WRITING;\n" - "-\t\t\treturn 0;\n" - "-\t\tdefault:\n" - "-\t\t\treturn 1;\n" - "-\t}\n" - "-}\n" - "-\n" - "-static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc)\n" - "-{\n" - "-\tide_hwif_t *hwif = drive->hwif;\n" - "-\tstruct scatterlist *sg, *scsi_sg;\n" - "-\tint segments;\n" - "-\n" - "-\tif (!pc->req_xfer || pc->req_xfer % 1024)\n" - "-\t\treturn 1;\n" - "-\n" - "-\tif (idescsi_set_direction(pc))\n" - "-\t\treturn 1;\n" - "-\n" - "-\tsg = hwif->sg_table;\n" - "-\tscsi_sg = scsi_sglist(pc->scsi_cmd);\n" - "-\tsegments = scsi_sg_count(pc->scsi_cmd);\n" - "-\n" - "-\tif (segments > hwif->sg_max_nents)\n" - "-\t\treturn 1;\n" - "-\n" - "-\thwif->sg_nents = segments;\n" - "-\tmemcpy(sg, scsi_sg, sizeof(*sg) * segments);\n" - "-\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,\n" - "-\t\tstruct ide_atapi_pc *pc)\n" - "-{\n" - "-\t/* Set the current packet command */\n" - "-\tdrive->pc = pc;\n" - "-\n" - "-\treturn ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry);\n" - "-}\n" - "-\n" - "-/*\n" - "- *\tidescsi_do_request is our request handling function.\n" - "- */\n" - "-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)\n" - "-{\n" - "-\tdebug_log(\"dev: %s, cmd: %x, errors: %d\\n\", rq->rq_disk->disk_name,\n" - "-\t\t rq->cmd[0], rq->errors);\n" - "-\tdebug_log(\"sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\\n\",\n" - "-\t\t rq->sector, rq->nr_sectors, rq->current_nr_sectors);\n" - "-\n" - "-\tif (blk_sense_request(rq) || blk_special_request(rq)) {\n" - "-\t\tstruct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;\n" - "-\n" - "-\t\tif ((drive->dev_flags & IDE_DFLAG_USING_DMA) &&\n" - "-\t\t idescsi_map_sg(drive, pc) == 0)\n" - "-\t\t\tpc->flags |= PC_FLAG_DMA_OK;\n" - "-\n" - "-\t\treturn idescsi_issue_pc(drive, pc);\n" - "-\t}\n" - "-\tblk_dump_rq_flags(rq, \"ide-scsi: unsup command\");\n" - "-\tidescsi_end_request (drive, 0, 0);\n" - "-\treturn ide_stopped;\n" - "-}\n" - "-\n" - "-#ifdef CONFIG_IDE_PROC_FS\n" - "-static ide_proc_entry_t idescsi_proc[] = {\n" - "-\t{ \"capacity\", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },\n" - "-\t{ NULL, 0, NULL, NULL }\n" - "-};\n" - "-\n" - "-#define ide_scsi_devset_get(name, field) \\\n" - "-static int get_##name(ide_drive_t *drive) \\\n" - "-{ \\\n" - "-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive); \\\n" - "-\treturn scsi->field; \\\n" - "-}\n" - "-\n" - "-#define ide_scsi_devset_set(name, field) \\\n" - "-static int set_##name(ide_drive_t *drive, int arg) \\\n" - "-{ \\\n" - "-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive); \\\n" - "-\tscsi->field = arg; \\\n" - "-\treturn 0; \\\n" - "-}\n" - "-\n" - "-#define ide_scsi_devset_rw_field(_name, _field) \\\n" - "-ide_scsi_devset_get(_name, _field); \\\n" - "-ide_scsi_devset_set(_name, _field); \\\n" - "-IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name);\n" - "-\n" - "-ide_devset_rw_field(bios_cyl, bios_cyl);\n" - "-ide_devset_rw_field(bios_head, bios_head);\n" - "-ide_devset_rw_field(bios_sect, bios_sect);\n" - "-\n" - "-ide_scsi_devset_rw_field(transform, transform);\n" - "-ide_scsi_devset_rw_field(log, log);\n" - "-\n" - "-static const struct ide_proc_devset idescsi_settings[] = {\n" - "-\tIDE_PROC_DEVSET(bios_cyl, 0, 1023),\n" - "-\tIDE_PROC_DEVSET(bios_head, 0, 255),\n" - "-\tIDE_PROC_DEVSET(bios_sect, 0,\t63),\n" - "-\tIDE_PROC_DEVSET(log,\t 0,\t 1),\n" - "-\tIDE_PROC_DEVSET(transform, 0,\t 3),\n" - "-\t{ 0 },\n" - "-};\n" - "-\n" - "-static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive)\n" - "-{\n" - "-\treturn idescsi_proc;\n" - "-}\n" - "-\n" - "-static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive)\n" - "-{\n" - "-\treturn idescsi_settings;\n" - "-}\n" - "-#endif\n" - "-\n" - "-/*\n" - "- *\tDriver initialization.\n" - "- */\n" - "-static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)\n" - "-{\n" - "-\tclear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);\n" - "-#if IDESCSI_DEBUG_LOG\n" - "-\tset_bit(IDESCSI_LOG_CMD, &scsi->log);\n" - "-#endif /* IDESCSI_DEBUG_LOG */\n" - "-\n" - "-\tdrive->pc_callback\t = ide_scsi_callback;\n" - "-\tdrive->pc_update_buffers = NULL;\n" - "-\tdrive->pc_io_buffers\t = ide_io_buffers;\n" - "-\n" - "-\tide_proc_register_driver(drive, scsi->driver);\n" - "-}\n" - "-\n" - "-static void ide_scsi_remove(ide_drive_t *drive)\n" - "-{\n" - "-\tstruct Scsi_Host *scsihost = drive->driver_data;\n" - "-\tstruct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);\n" - "-\tstruct gendisk *g = scsi->disk;\n" - "-\n" - "-\tscsi_remove_host(scsihost);\n" - "-\tide_proc_unregister_driver(drive, scsi->driver);\n" - "-\n" - "-\tide_unregister_region(g);\n" - "-\n" - "-\tdrive->driver_data = NULL;\n" - "-\tg->private_data = NULL;\n" - "-\tput_disk(g);\n" - "-\n" - "-\tide_scsi_put(scsi);\n" - "-\n" - "-\tdrive->dev_flags &= ~IDE_DFLAG_SCSI;\n" - "-}\n" - "-\n" - "-static int ide_scsi_probe(ide_drive_t *);\n" - "-\n" - "-static ide_driver_t idescsi_driver = {\n" - "-\t.gen_driver = {\n" - "-\t\t.owner\t\t= THIS_MODULE,\n" - "-\t\t.name\t\t= \"ide-scsi\",\n" - "-\t\t.bus\t\t= &ide_bus_type,\n" - "-\t},\n" - "-\t.probe\t\t\t= ide_scsi_probe,\n" - "-\t.remove\t\t\t= ide_scsi_remove,\n" - "-\t.version\t\t= IDESCSI_VERSION,\n" - "-\t.do_request\t\t= idescsi_do_request,\n" - "-\t.end_request\t\t= idescsi_end_request,\n" - "-\t.error = idescsi_atapi_error,\n" - "-#ifdef CONFIG_IDE_PROC_FS\n" - "-\t.proc_entries\t\t= ide_scsi_proc_entries,\n" - "-\t.proc_devsets\t\t= ide_scsi_proc_devsets,\n" - "-#endif\n" - "-};\n" - "-\n" - "-static int idescsi_ide_open(struct block_device *bdev, fmode_t mode)\n" - "-{\n" - "-\tstruct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk);\n" - "-\n" - "-\tif (!scsi)\n" - "-\t\treturn -ENXIO;\n" - "-\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static int idescsi_ide_release(struct gendisk *disk, fmode_t mode)\n" - "-{\n" - "-\tide_scsi_put(ide_scsi_g(disk));\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode,\n" - "-\t\t\tunsigned int cmd, unsigned long arg)\n" - "-{\n" - "-\tstruct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk);\n" - "-\treturn generic_ide_ioctl(scsi->drive, bdev, cmd, arg);\n" - "-}\n" - "-\n" - "-static struct block_device_operations idescsi_ops = {\n" - "-\t.owner\t\t= THIS_MODULE,\n" - "-\t.open\t\t= idescsi_ide_open,\n" - "-\t.release\t= idescsi_ide_release,\n" - "-\t.locked_ioctl\t= idescsi_ide_ioctl,\n" - "-};\n" - "-\n" - "-static int idescsi_slave_configure(struct scsi_device * sdp)\n" - "-{\n" - "-\t/* Configure detected device */\n" - "-\tsdp->use_10_for_rw = 1;\n" - "-\tsdp->use_10_for_ms = 1;\n" - "-\tscsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static const char *idescsi_info (struct Scsi_Host *host)\n" - "-{\n" - "-\treturn \"SCSI host adapter emulation for IDE ATAPI devices\";\n" - "-}\n" - "-\n" - "-static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)\n" - "-{\n" - "-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host);\n" - "-\n" - "-\tif (cmd == SG_SET_TRANSFORM) {\n" - "-\t\tif (arg)\n" - "-\t\t\tset_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);\n" - "-\t\telse\n" - "-\t\t\tclear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);\n" - "-\t\treturn 0;\n" - "-\t} else if (cmd == SG_GET_TRANSFORM)\n" - "-\t\treturn put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg);\n" - "-\treturn -EINVAL;\n" - "-}\n" - "-\n" - "-static int idescsi_queue (struct scsi_cmnd *cmd,\n" - "-\t\tvoid (*done)(struct scsi_cmnd *))\n" - "-{\n" - "-\tstruct Scsi_Host *host = cmd->device->host;\n" - "-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(host);\n" - "-\tide_drive_t *drive = scsi->drive;\n" - "-\tstruct request *rq = NULL;\n" - "-\tstruct ide_atapi_pc *pc = NULL;\n" - "-\tint write = cmd->sc_data_direction == DMA_TO_DEVICE;\n" - "-\n" - "-\tif (!drive) {\n" - "-\t\tscmd_printk (KERN_ERR, cmd, \"drive not present\\n\");\n" - "-\t\tgoto abort;\n" - "-\t}\n" - "-\tscsi = drive_to_idescsi(drive);\n" - "-\tpc = kmalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);\n" - "-\trq = blk_get_request(drive->queue, write, GFP_ATOMIC);\n" - "-\tif (rq == NULL || pc == NULL) {\n" - "-\t\tprintk (KERN_ERR \"ide-scsi: %s: out of memory\\n\", drive->name);\n" - "-\t\tgoto abort;\n" - "-\t}\n" - "-\n" - "-\tmemset (pc->c, 0, 12);\n" - "-\tpc->flags = 0;\n" - "-\tif (cmd->sc_data_direction == DMA_TO_DEVICE)\n" - "-\t\tpc->flags |= PC_FLAG_WRITING;\n" - "-\tpc->rq = rq;\n" - "-\tmemcpy (pc->c, cmd->cmnd, cmd->cmd_len);\n" - "-\tpc->buf = NULL;\n" - "-\tpc->sg = scsi_sglist(cmd);\n" - "-\tpc->sg_cnt = scsi_sg_count(cmd);\n" - "-\tpc->b_count = 0;\n" - "-\tpc->req_xfer = pc->buf_size = scsi_bufflen(cmd);\n" - "-\tpc->scsi_cmd = cmd;\n" - "-\tpc->done = done;\n" - "-\tpc->timeout = jiffies + cmd->request->timeout;\n" - "-\n" - "-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {\n" - "-\t\tprintk (\"ide-scsi: %s: que %lu, cmd = \", drive->name, cmd->serial_number);\n" - "-\t\tide_scsi_hex_dump(cmd->cmnd, cmd->cmd_len);\n" - "-\t\tif (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) {\n" - "-\t\t\tprintk (\"ide-scsi: %s: que %lu, tsl = \", drive->name, cmd->serial_number);\n" - "-\t\t\tide_scsi_hex_dump(pc->c, 12);\n" - "-\t\t}\n" - "-\t}\n" - "-\n" - "-\trq->special = (char *) pc;\n" - "-\trq->cmd_type = REQ_TYPE_SPECIAL;\n" - "-\tspin_unlock_irq(host->host_lock);\n" - "-\trq->ref_count++;\n" - "-\tmemcpy(rq->cmd, pc->c, 12);\n" - "-\tblk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);\n" - "-\tspin_lock_irq(host->host_lock);\n" - "-\treturn 0;\n" - "-abort:\n" - "-\tkfree (pc);\n" - "-\tif (rq)\n" - "-\t\tblk_put_request(rq);\n" - "-\tcmd->result = DID_ERROR << 16;\n" - "-\tdone(cmd);\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static int idescsi_eh_abort (struct scsi_cmnd *cmd)\n" - "-{\n" - "-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host);\n" - "-\tide_drive_t *drive = scsi->drive;\n" - "-\tide_hwif_t *hwif;\n" - "-\tide_hwgroup_t *hwgroup;\n" - "-\tint\t\tbusy;\n" - "-\tint ret = FAILED;\n" - "-\n" - "-\tstruct ide_atapi_pc *pc;\n" - "-\n" - "-\t/* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */\n" - "-\n" - "-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: abort called for %lu\\n\", cmd->serial_number);\n" - "-\n" - "-\tif (!drive) {\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: Drive not set in idescsi_eh_abort\\n\");\n" - "-\t\tWARN_ON(1);\n" - "-\t\tgoto no_drive;\n" - "-\t}\n" - "-\n" - "-\thwif = drive->hwif;\n" - "-\thwgroup = hwif->hwgroup;\n" - "-\n" - "-\t/* First give it some more time, how much is \"right\" is hard to say :-(\n" - "-\t FIXME - uses mdelay which causes latency? */\n" - "-\tbusy = ide_wait_not_busy(hwif, 100);\n" - "-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: drive did%s become ready\\n\", busy?\" not\":\"\");\n" - "-\n" - "-\tspin_lock_irq(&hwgroup->lock);\n" - "-\n" - "-\t/* If there is no pc running we're done (our interrupt took care of it) */\n" - "-\tpc = drive->pc;\n" - "-\tif (pc == NULL) {\n" - "-\t\tret = SUCCESS;\n" - "-\t\tgoto ide_unlock;\n" - "-\t}\n" - "-\n" - "-\t/* It's somewhere in flight. Does ide subsystem agree? */\n" - "-\tif (pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&\n" - "-\t elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) {\n" - "-\t\t/*\n" - "-\t\t * FIXME - not sure this condition can ever occur\n" - "-\t\t */\n" - "-\t\tprintk (KERN_ERR \"ide-scsi: cmd aborted!\\n\");\n" - "-\n" - "-\t\tif (blk_sense_request(pc->rq))\n" - "-\t\t\tkfree(pc->buf);\n" - "-\t\t/* we need to call blk_put_request twice. */\n" - "-\t\tblk_put_request(pc->rq);\n" - "-\t\tblk_put_request(pc->rq);\n" - "-\t\tkfree(pc);\n" - "-\t\tdrive->pc = NULL;\n" - "-\n" - "-\t\tret = SUCCESS;\n" - "-\t}\n" - "-\n" - "-ide_unlock:\n" - "-\tspin_unlock_irq(&hwgroup->lock);\n" - "-no_drive:\n" - "-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: abort returns %s\\n\", ret == SUCCESS?\"success\":\"failed\");\n" - "-\n" - "-\treturn ret;\n" - "-}\n" - "-\n" - "-static int idescsi_eh_reset (struct scsi_cmnd *cmd)\n" - "-{\n" - "-\tstruct request *req;\n" - "-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host);\n" - "-\tide_drive_t *drive = scsi->drive;\n" - "-\tide_hwgroup_t *hwgroup;\n" - "-\tint ready = 0;\n" - "-\tint ret = SUCCESS;\n" - "-\n" - "-\tstruct ide_atapi_pc *pc;\n" - "-\n" - "-\t/* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */\n" - "-\n" - "-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: reset called for %lu\\n\", cmd->serial_number);\n" - "-\n" - "-\tif (!drive) {\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: Drive not set in idescsi_eh_reset\\n\");\n" - "-\t\tWARN_ON(1);\n" - "-\t\treturn FAILED;\n" - "-\t}\n" - "-\n" - "-\thwgroup = drive->hwif->hwgroup;\n" - "-\n" - "-\tspin_lock_irq(cmd->device->host->host_lock);\n" - "-\tspin_lock(&hwgroup->lock);\n" - "-\n" - "-\tpc = drive->pc;\n" - "-\tif (pc)\n" - "-\t\treq = pc->rq;\n" - "-\n" - "-\tif (pc == NULL || req != hwgroup->rq || hwgroup->handler == NULL) {\n" - "-\t\tprintk (KERN_WARNING \"ide-scsi: No active request in idescsi_eh_reset\\n\");\n" - "-\t\tspin_unlock(&hwgroup->lock);\n" - "-\t\tspin_unlock_irq(cmd->device->host->host_lock);\n" - "-\t\treturn FAILED;\n" - "-\t}\n" - "-\n" - "-\t/* kill current request */\n" - "-\tif (__blk_end_request(req, -EIO, 0))\n" - "-\t\tBUG();\n" - "-\tif (blk_sense_request(req))\n" - "-\t\tkfree(pc->buf);\n" - "-\tkfree(pc);\n" - "-\tdrive->pc = NULL;\n" - "-\tblk_put_request(req);\n" - "-\n" - "-\t/* now nuke the drive queue */\n" - "-\twhile ((req = elv_next_request(drive->queue))) {\n" - "-\t\tif (__blk_end_request(req, -EIO, 0))\n" - "-\t\t\tBUG();\n" - "-\t}\n" - "-\n" - "-\thwgroup->rq = NULL;\n" - "-\thwgroup->handler = NULL;\n" - "-\thwgroup->busy = 1; /* will set this to zero when ide reset finished */\n" - "-\tspin_unlock(&hwgroup->lock);\n" - "-\n" - "-\tide_do_reset(drive);\n" - "-\n" - "-\t/* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */\n" - "-\n" - "-\tdo {\n" - "-\t\tspin_unlock_irq(cmd->device->host->host_lock);\n" - "-\t\tmsleep(50);\n" - "-\t\tspin_lock_irq(cmd->device->host->host_lock);\n" - "-\t} while ( HWGROUP(drive)->handler );\n" - "-\n" - "-\tready = drive_is_ready(drive);\n" - "-\tHWGROUP(drive)->busy--;\n" - "-\tif (!ready) {\n" - "-\t\tprintk (KERN_ERR \"ide-scsi: reset failed!\\n\");\n" - "-\t\tret = FAILED;\n" - "-\t}\n" - "-\n" - "-\tspin_unlock_irq(cmd->device->host->host_lock);\n" - "-\treturn ret;\n" - "-}\n" - "-\n" - "-static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,\n" - "-\t\tsector_t capacity, int *parm)\n" - "-{\n" - "-\tidescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host);\n" - "-\tide_drive_t *drive = idescsi->drive;\n" - "-\n" - "-\tif (drive->bios_cyl && drive->bios_head && drive->bios_sect) {\n" - "-\t\tparm[0] = drive->bios_head;\n" - "-\t\tparm[1] = drive->bios_sect;\n" - "-\t\tparm[2] = drive->bios_cyl;\n" - "-\t}\n" - "-\treturn 0;\n" - "-}\n" - "-\n" - "-static struct scsi_host_template idescsi_template = {\n" - "-\t.module\t\t\t= THIS_MODULE,\n" - "-\t.name\t\t\t= \"idescsi\",\n" - "-\t.info\t\t\t= idescsi_info,\n" - "-\t.slave_configure = idescsi_slave_configure,\n" - "-\t.ioctl\t\t\t= idescsi_ioctl,\n" - "-\t.queuecommand\t\t= idescsi_queue,\n" - "-\t.eh_abort_handler\t= idescsi_eh_abort,\n" - "-\t.eh_host_reset_handler = idescsi_eh_reset,\n" - "-\t.bios_param\t\t= idescsi_bios,\n" - "-\t.can_queue\t\t= 40,\n" - "-\t.this_id\t\t= -1,\n" - "-\t.sg_tablesize\t\t= 256,\n" - "-\t.cmd_per_lun\t\t= 5,\n" - "-\t.max_sectors\t\t= 128,\n" - "-\t.use_clustering\t\t= DISABLE_CLUSTERING,\n" - "-\t.emulated\t\t= 1,\n" - "-\t.proc_name\t\t= \"ide-scsi\",\n" - "-};\n" - "-\n" - "-static int ide_scsi_probe(ide_drive_t *drive)\n" - "-{\n" - "-\tidescsi_scsi_t *idescsi;\n" - "-\tstruct Scsi_Host *host;\n" - "-\tstruct gendisk *g;\n" - "-\tstatic int warned;\n" - "-\tint err = -ENOMEM;\n" - "-\tu16 last_lun;\n" - "-\n" - "-\tif (!warned && drive->media == ide_cdrom) {\n" - "-\t\tprintk(KERN_WARNING \"ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\\n\");\n" - "-\t\twarned = 1;\n" - "-\t}\n" - "-\n" - "-\tif (idescsi_nocd && drive->media == ide_cdrom)\n" - "-\t\treturn -ENODEV;\n" - "-\n" - "-\tif (!strstr(\"ide-scsi\", drive->driver_req) ||\n" - "-\t drive->media == ide_disk ||\n" - "-\t !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))\n" - "-\t\treturn -ENODEV;\n" - "-\n" - "-\tdrive->dev_flags |= IDE_DFLAG_SCSI;\n" - "-\n" - "-\tg = alloc_disk(1 << PARTN_BITS);\n" - "-\tif (!g)\n" - "-\t\tgoto out_host_put;\n" - "-\n" - "-\tide_init_disk(g, drive);\n" - "-\n" - "-\thost->max_id = 1;\n" - "-\n" - "-\tlast_lun = drive->id[ATA_ID_LAST_LUN];\n" - "-\tif (last_lun)\n" - "-\t\tdebug_log(\"%s: last_lun=%u\\n\", drive->name, last_lun);\n" - "-\n" - "-\tif ((last_lun & 7) != 7)\n" - "-\t\thost->max_lun = (last_lun & 7) + 1;\n" - "-\telse\n" - "-\t\thost->max_lun = 1;\n" - "-\n" - "-\tdrive->driver_data = host;\n" - "-\tidescsi = scsihost_to_idescsi(host);\n" - "-\tidescsi->drive = drive;\n" - "-\tidescsi->driver = &idescsi_driver;\n" - "-\tidescsi->host = host;\n" - "-\tidescsi->disk = g;\n" - "-\tg->private_data = &idescsi->driver;\n" - "-\terr = 0;\n" - "-\tidescsi_setup(drive, idescsi);\n" - "-\tg->fops = &idescsi_ops;\n" - "-\tide_register_region(g);\n" - "-\terr = scsi_add_host(host, &drive->gendev);\n" - "-\tif (!err) {\n" - "-\t\tscsi_scan_host(host);\n" - "-\t\treturn 0;\n" - "-\t}\n" - "-\t/* fall through on error */\n" - "-\tide_unregister_region(g);\n" - "-\tide_proc_unregister_driver(drive, &idescsi_driver);\n" - "-\n" - "-\tput_disk(g);\n" - "-out_host_put:\n" - "-\tdrive->dev_flags &= ~IDE_DFLAG_SCSI;\n" - "-\tscsi_host_put(host);\n" - "-\treturn err;\n" - "-}\n" - "-\n" - "-static int __init init_idescsi_module(void)\n" - "-{\n" - "-\treturn driver_register(&idescsi_driver.gen_driver);\n" - "-}\n" - "-\n" - "-static void __exit exit_idescsi_module(void)\n" - "-{\n" - "-\tdriver_unregister(&idescsi_driver.gen_driver);\n" - "-}\n" - "-\n" - "-module_param(idescsi_nocd, int, 0600);\n" - "-MODULE_PARM_DESC(idescsi_nocd, \"Disable handling of CD-ROMs so they may be driven by ide-cd\");\n" - "-module_init(init_idescsi_module);\n" - "-module_exit(exit_idescsi_module);\n" - "-MODULE_LICENSE(\"GPL\");\n" - "diff --git a/include/linux/ide.h b/include/linux/ide.h\n" - "index e99c56d..db5ef8a 100644\n" - "--- a/include/linux/ide.h\n" - "+++ b/include/linux/ide.h\n" - "@@ -32,13 +32,6 @@\n" - " # define SUPPORT_VLB_SYNC 1\n" - " #endif\n" - " \n" - "-/*\n" - "- * Used to indicate \"no IRQ\", should be a value that cannot be an IRQ\n" - "- * number.\n" - "- */\n" - "- \n" - "-#define IDE_NO_IRQ\t\t(-1)\n" - "-\n" - " typedef unsigned char\tbyte;\t/* used everywhere */\n" - " \n" - " /*\n" - "@@ -403,6 +396,7 @@ enum {\n" - " * This is used for several packet commands (not for READ/WRITE commands).\n" - " */\n" - " #define IDE_PC_BUFFER_SIZE\t256\n" - "+#define ATAPI_WAIT_PC\t\t(60 * HZ)\n" - " \n" - " struct ide_atapi_pc {\n" - " \t/* actual packet bytes */\n" - "@@ -480,53 +474,53 @@ enum {\n" - " \n" - " \t/* ide-cd */\n" - " \t/* Drive cannot eject the disc. */\n" - "-\tIDE_AFLAG_NO_EJECT\t\t= (1 << 3),\n" - "+\tIDE_AFLAG_NO_EJECT\t\t= (1 << 1),\n" - " \t/* Drive is a pre ATAPI 1.2 drive. */\n" - "-\tIDE_AFLAG_PRE_ATAPI12\t\t= (1 << 4),\n" - "+\tIDE_AFLAG_PRE_ATAPI12\t\t= (1 << 2),\n" - " \t/* TOC addresses are in BCD. */\n" - "-\tIDE_AFLAG_TOCADDR_AS_BCD\t= (1 << 5),\n" - "+\tIDE_AFLAG_TOCADDR_AS_BCD\t= (1 << 3),\n" - " \t/* TOC track numbers are in BCD. */\n" - "-\tIDE_AFLAG_TOCTRACKS_AS_BCD\t= (1 << 6),\n" - "+\tIDE_AFLAG_TOCTRACKS_AS_BCD\t= (1 << 4),\n" - " \t/*\n" - " \t * Drive does not provide data in multiples of SECTOR_SIZE\n" - " \t * when more than one interrupt is needed.\n" - " \t */\n" - "-\tIDE_AFLAG_LIMIT_NFRAMES\t\t= (1 << 7),\n" - "+\tIDE_AFLAG_LIMIT_NFRAMES\t\t= (1 << 5),\n" - " \t/* Saved TOC information is current. */\n" - "-\tIDE_AFLAG_TOC_VALID\t\t= (1 << 9),\n" - "+\tIDE_AFLAG_TOC_VALID\t\t= (1 << 6),\n" - " \t/* We think that the drive door is locked. */\n" - "-\tIDE_AFLAG_DOOR_LOCKED\t\t= (1 << 10),\n" - "+\tIDE_AFLAG_DOOR_LOCKED\t\t= (1 << 7),\n" - " \t/* SET_CD_SPEED command is unsupported. */\n" - "-\tIDE_AFLAG_NO_SPEED_SELECT\t= (1 << 11),\n" - "-\tIDE_AFLAG_VERTOS_300_SSD\t= (1 << 12),\n" - "-\tIDE_AFLAG_VERTOS_600_ESD\t= (1 << 13),\n" - "-\tIDE_AFLAG_SANYO_3CD\t\t= (1 << 14),\n" - "-\tIDE_AFLAG_FULL_CAPS_PAGE\t= (1 << 15),\n" - "-\tIDE_AFLAG_PLAY_AUDIO_OK\t\t= (1 << 16),\n" - "-\tIDE_AFLAG_LE_SPEED_FIELDS\t= (1 << 17),\n" - "+\tIDE_AFLAG_NO_SPEED_SELECT\t= (1 << 8),\n" - "+\tIDE_AFLAG_VERTOS_300_SSD\t= (1 << 9),\n" - "+\tIDE_AFLAG_VERTOS_600_ESD\t= (1 << 10),\n" - "+\tIDE_AFLAG_SANYO_3CD\t\t= (1 << 11),\n" - "+\tIDE_AFLAG_FULL_CAPS_PAGE\t= (1 << 12),\n" - "+\tIDE_AFLAG_PLAY_AUDIO_OK\t\t= (1 << 13),\n" - "+\tIDE_AFLAG_LE_SPEED_FIELDS\t= (1 << 14),\n" - " \n" - " \t/* ide-floppy */\n" - " \t/* Avoid commands not supported in Clik drive */\n" - "-\tIDE_AFLAG_CLIK_DRIVE\t\t= (1 << 19),\n" - "+\tIDE_AFLAG_CLIK_DRIVE\t\t= (1 << 15),\n" - " \t/* Requires BH algorithm for packets */\n" - "-\tIDE_AFLAG_ZIP_DRIVE\t\t= (1 << 20),\n" - "+\tIDE_AFLAG_ZIP_DRIVE\t\t= (1 << 16),\n" - " \t/* Supports format progress report */\n" - "-\tIDE_AFLAG_SRFP\t\t\t= (1 << 22),\n" - "+\tIDE_AFLAG_SRFP\t\t\t= (1 << 17),\n" - " \n" - " \t/* ide-tape */\n" - "-\tIDE_AFLAG_IGNORE_DSC\t\t= (1 << 23),\n" - "+\tIDE_AFLAG_IGNORE_DSC\t\t= (1 << 18),\n" - " \t/* 0 When the tape position is unknown */\n" - "-\tIDE_AFLAG_ADDRESS_VALID\t\t= (1 <<\t24),\n" - "+\tIDE_AFLAG_ADDRESS_VALID\t\t= (1 <<\t19),\n" - " \t/* Device already opened */\n" - "-\tIDE_AFLAG_BUSY\t\t\t= (1 << 25),\n" - "+\tIDE_AFLAG_BUSY\t\t\t= (1 << 20),\n" - " \t/* Attempt to auto-detect the current user block size */\n" - "-\tIDE_AFLAG_DETECT_BS\t\t= (1 << 26),\n" - "+\tIDE_AFLAG_DETECT_BS\t\t= (1 << 21),\n" - " \t/* Currently on a filemark */\n" - "-\tIDE_AFLAG_FILEMARK\t\t= (1 << 27),\n" - "+\tIDE_AFLAG_FILEMARK\t\t= (1 << 22),\n" - " \t/* 0 = no tape is loaded, so we don't rewind after ejecting */\n" - "-\tIDE_AFLAG_MEDIUM_PRESENT\t= (1 << 28),\n" - "+\tIDE_AFLAG_MEDIUM_PRESENT\t= (1 << 23),\n" - " \n" - "-\tIDE_AFLAG_NO_AUTOCLOSE\t\t= (1 << 29),\n" - "+\tIDE_AFLAG_NO_AUTOCLOSE\t\t= (1 << 24),\n" - " };\n" - " \n" - " /* device flags */\n" - "@@ -565,28 +559,26 @@ enum {\n" - " \tIDE_DFLAG_NODMA\t\t\t= (1 << 16),\n" - " \t/* powermanagment told us not to do anything, so sleep nicely */\n" - " \tIDE_DFLAG_BLOCKED\t\t= (1 << 17),\n" - "-\t/* ide-scsi emulation */\n" - "-\tIDE_DFLAG_SCSI\t\t\t= (1 << 18),\n" - " \t/* sleeping & sleep field valid */\n" - "-\tIDE_DFLAG_SLEEPING\t\t= (1 << 19),\n" - "-\tIDE_DFLAG_POST_RESET\t\t= (1 << 20),\n" - "-\tIDE_DFLAG_UDMA33_WARNED\t\t= (1 << 21),\n" - "-\tIDE_DFLAG_LBA48\t\t\t= (1 << 22),\n" - "+\tIDE_DFLAG_SLEEPING\t\t= (1 << 18),\n" - "+\tIDE_DFLAG_POST_RESET\t\t= (1 << 19),\n" - "+\tIDE_DFLAG_UDMA33_WARNED\t\t= (1 << 20),\n" - "+\tIDE_DFLAG_LBA48\t\t\t= (1 << 21),\n" - " \t/* status of write cache */\n" - "-\tIDE_DFLAG_WCACHE\t\t= (1 << 23),\n" - "+\tIDE_DFLAG_WCACHE\t\t= (1 << 22),\n" - " \t/* used for ignoring ATA_DF */\n" - "-\tIDE_DFLAG_NOWERR\t\t= (1 << 24),\n" - "+\tIDE_DFLAG_NOWERR\t\t= (1 << 23),\n" - " \t/* retrying in PIO */\n" - "-\tIDE_DFLAG_DMA_PIO_RETRY\t\t= (1 << 25),\n" - "-\tIDE_DFLAG_LBA\t\t\t= (1 << 26),\n" - "+\tIDE_DFLAG_DMA_PIO_RETRY\t\t= (1 << 24),\n" - "+\tIDE_DFLAG_LBA\t\t\t= (1 << 25),\n" - " \t/* don't unload heads */\n" - "-\tIDE_DFLAG_NO_UNLOAD\t\t= (1 << 27),\n" - "+\tIDE_DFLAG_NO_UNLOAD\t\t= (1 << 26),\n" - " \t/* heads unloaded, please don't reset port */\n" - "-\tIDE_DFLAG_PARKED\t\t= (1 << 28),\n" - "-\tIDE_DFLAG_MEDIA_CHANGED\t\t= (1 << 29),\n" - "+\tIDE_DFLAG_PARKED\t\t= (1 << 27),\n" - "+\tIDE_DFLAG_MEDIA_CHANGED\t\t= (1 << 28),\n" - " \t/* write protect */\n" - "-\tIDE_DFLAG_WP\t\t\t= (1 << 30),\n" - "-\tIDE_DFLAG_FORMAT_IN_PROGRESS\t= (1 << 31),\n" - "+\tIDE_DFLAG_WP\t\t\t= (1 << 29),\n" - "+\tIDE_DFLAG_FORMAT_IN_PROGRESS\t= (1 << 30),\n" - " };\n" - " \n" - " struct ide_drive_s {\n" - "@@ -610,8 +602,6 @@ struct ide_drive_s {\n" - " \tunsigned long dev_flags;\n" - " \n" - " \tunsigned long sleep;\t\t/* sleep until this time */\n" - "-\tunsigned long service_start;\t/* time we started last request */\n" - "-\tunsigned long service_time;\t/* service time of last request */\n" - " \tunsigned long timeout;\t\t/* max time to wait for irq */\n" - " \n" - " \tspecial_t\tspecial;\t/* special action flags */\n" - "@@ -879,8 +869,6 @@ typedef struct hwgroup_s {\n" - " \n" - " \t\t/* BOOL: protects all fields below */\n" - " \tvolatile int busy;\n" - "-\t\t/* BOOL: wake us up on timer expiry */\n" - "-\tunsigned int sleeping\t: 1;\n" - " \t\t/* BOOL: polling active & poll_timeout field valid */\n" - " \tunsigned int polling\t: 1;\n" - " \n" - "@@ -1258,14 +1246,11 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);\n" - " void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);\n" - " void ide_retry_pc(ide_drive_t *, struct gendisk *);\n" - " \n" - "-static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc)\n" - "-{\n" - "-\treturn max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);\n" - "-}\n" - "+int ide_cd_expiry(ide_drive_t *);\n" - " \n" - "-int ide_scsi_expiry(ide_drive_t *);\n" - "+int ide_cd_get_xferlen(struct request *);\n" - " \n" - "-ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *);\n" - "+ide_startstop_t ide_issue_pc(ide_drive_t *);\n" - " \n" - " ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);\n" - " \n" - "@@ -1287,6 +1272,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);\n" - " \n" - " extern void ide_timer_expiry(unsigned long);\n" - " extern irqreturn_t ide_intr(int irq, void *dev_id);\n" - "+\n" - "+static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)\n" - "+{\n" - "+\tif (hwgroup->busy)\n" - "+\t\treturn 1;\n" - "+\n" - "+\thwgroup->busy = 1;\n" - "+\t/* for atari only */\n" - "+\tide_get_lock(ide_intr, hwgroup);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)\n" - "+{\n" - "+\t/* for atari only */\n" - "+\tide_release_lock();\n" - "+\thwgroup->busy = 0;\n" - "+}\n" - "+\n" - " extern void do_ide_request(struct request_queue *);\n" - " \n" - " void ide_init_disk(struct gendisk *, ide_drive_t *);\n" - "@@ -1533,6 +1538,7 @@ void ide_unregister_region(struct gendisk *);\n" - " void ide_undecoded_slave(ide_drive_t *);\n" - " \n" - " void ide_port_apply_params(ide_hwif_t *);\n" - "+int ide_sysfs_register_port(ide_hwif_t *);\n" - " \n" - " struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **);\n" - " void ide_host_free(struct ide_host *);\n" - "@@ -1627,6 +1633,9 @@ extern struct mutex ide_cfg_mtx;\n" - " \n" - " #define local_irq_set(flags)\tdo { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)\n" - " \n" - "+char *ide_media_string(ide_drive_t *);\n" - "+\n" - "+extern struct device_attribute ide_dev_attrs[];\n" - " extern struct bus_type ide_bus_type;\n" - " extern struct class *ide_port_class;\n" - " \n" - "\0" + "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@ans.pl> --------------------------- -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@lab.ntt.co.jp>------------------------------ What:\ti2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() When:\t2.6.29 (ideally) or 2.6.30 (more likely) Why:\tDeprecated 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:\tGadi Oxman <gadio@netvision.net.il> L:\tlinux-kernel@vger.kernel.org S:\tMaintained -IDE-SCSI DRIVER-L:\tlinux-ide@vger.kernel.org-L:\tlinux-scsi@vger.kernel.org-S:\tOrphan- IDLE-I7300 P:\tAndy Henroid M:\tandrew.d.henroid@intel.comdiff --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 \ttristate \"Include IDE/ATAPI CDROM support\"+\tselect IDE_ATAPI \t---help--- \t If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is \t a newer protocol used by IDE CD-ROM and TAPE drives, similar to the@@ -185,23 +186,6 @@ config BLK_DEV_IDETAPE \t To compile this driver as a module, choose M here: the \t module will be called ide-tape. -config BLK_DEV_IDESCSI-\ttristate \"SCSI emulation support (DEPRECATED)\"-\tdepends on SCSI-\tselect IDE_ATAPI-\t---help----\t WARNING: ide-scsi is no longer needed for cd writing applications!-\t The 2.6 kernel supports direct writing to ide-cd, which eliminates-\t the need for ide-scsi + the entire scsi stack just for writing a-\t cd. The new method is more efficient in every way.--\t This will provide SCSI host adapter emulation for IDE ATAPI devices,-\t and will allow you to use a SCSI device driver instead of a native-\t ATAPI driver.--\t If both this SCSI emulation and native ATAPI support are compiled-\t into the kernel, the native support will be used.- config BLK_DEV_IDEACPI \tbool \"IDE ACPI support\" \tdepends 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\t\t\t\t+= -Idrivers/ide ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \\-\t ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o+\t ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o # core IDE code ide-core-$(CONFIG_IDE_TIMINGS)\t\t+= 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\t12++static inline int dev_is_idecd(ide_drive_t *drive)+{+\treturn 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) {-\tstruct ide_atapi_pc *pc = drive->pc;+\tstruct request *rq = HWGROUP(drive)->rq;+\tunsigned long wait = 0; -\tdebug_log(\"%s called for %lu at %lu\\n\", __func__,-\t\t pc->scsi_cmd->serial_number, jiffies);+\tdebug_log(\"%s: rq->cmd[0]: 0x%x\\n\", __func__, rq->cmd[0]); -\tpc->flags |= PC_FLAG_TIMEDOUT;+\t/*+\t * Some commands are *slow* and normally take a long time to complete.+\t * Usually we can use the ATAPI \"disconnect\" to bypass this, but not all+\t * commands/drives support that. Let ide_timer_expiry keep polling us+\t * for these.+\t */+\tswitch (rq->cmd[0]) {+\tcase GPCMD_BLANK:+\tcase GPCMD_FORMAT_UNIT:+\tcase GPCMD_RESERVE_RZONE_TRACK:+\tcase GPCMD_CLOSE_TRACK:+\tcase GPCMD_FLUSH_CACHE:+\t\twait = ATAPI_WAIT_PC;+\t\tbreak;+\tdefault:+\t\tif (!(rq->cmd_flags & REQ_QUIET))+\t\t\tprintk(KERN_INFO \"cmd 0x%x timed out\\n\",+\t\t\t\t\t rq->cmd[0]);+\t\twait = 0;+\t\tbreak;+\t}+\treturn wait;+}+EXPORT_SYMBOL_GPL(ide_cd_expiry); -\treturn 0; /* we do not want the IDE subsystem to retry */+int ide_cd_get_xferlen(struct request *rq)+{+\tif (blk_fs_request(rq))+\t\treturn 32768;+\telse if (blk_sense_request(rq) || blk_pc_request(rq) ||+\t\t\t rq->cmd_type == REQ_TYPE_ATA_PC)+\t\treturn rq->data_len;+\telse+\t\treturn 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) \tstruct request *rq = hwif->hwgroup->rq; \tconst struct ide_tp_ops *tp_ops = hwif->tp_ops; \txfer_func_t *xferfunc;-\tide_expiry_t *expiry; \tunsigned int timeout, temp; \tu16 bcount;-\tu8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;+\tu8 stat, ireason, dsc = 0; \tdebug_log(\"Enter %s - interrupt handler\\n\", __func__); -\tif (scsi) {-\t\ttimeout = ide_scsi_get_timeout(pc);-\t\texpiry = ide_scsi_expiry;-\t} else {-\t\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD-\t\t\t\t\t\t : WAIT_TAPE_CMD;-\t\texpiry = NULL;-\t}+\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD+\t\t\t\t\t : WAIT_TAPE_CMD; \tif (pc->flags & PC_FLAG_TIMEDOUT) { \t\tdrive->pc_callback(drive, 0);@@ -284,8 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) \tif (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { \t\tif (hwif->dma_ops->dma_end(drive) ||-\t\t (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) {-\t\t\tif (drive->media == ide_floppy && !scsi)+\t\t (drive->media == ide_tape && (stat & ATA_ERR))) {+\t\t\tif (drive->media == ide_floppy) \t\t\t\tprintk(KERN_ERR \"%s: DMA %s error\\n\", \t\t\t\t\tdrive->name, rq_data_dir(pc->rq) \t\t\t\t\t\t ? \"write\" : \"read\");@@ -307,7 +339,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) \t\tlocal_irq_enable_in_hardirq(); -\t\tif (drive->media == ide_tape && !scsi &&+\t\tif (drive->media == ide_tape && \t\t (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) \t\t\tstat &= ~ATA_ERR; @@ -315,11 +347,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) \t\t\t/* Error detected */ \t\t\tdebug_log(\"%s: I/O error\\n\", drive->name); -\t\t\tif (drive->media != ide_tape || scsi) {+\t\t\tif (drive->media != ide_tape) \t\t\t\tpc->rq->errors++;-\t\t\t\tif (scsi)-\t\t\t\t\tgoto cmd_finished;-\t\t\t} \t\t\tif (rq->cmd[0] == REQUEST_SENSE) { \t\t\t\tprintk(KERN_ERR \"%s: I/O error in request sense\"@@ -335,7 +364,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) \t\t\t/* queued, but not started */ \t\t\treturn ide_stopped; \t\t}-cmd_finished: \t\tpc->error = 0; \t\tif ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)@@ -382,25 +410,8 @@ cmd_finished: \t\t\t\t\t\t\"us more data than expected - \" \t\t\t\t\t\t\"discarding data\\n\", \t\t\t\t\t\tdrive->name);-\t\t\t\tif (scsi)-\t\t\t\t\ttemp = pc->buf_size - pc->xferred;-\t\t\t\telse-\t\t\t\t\ttemp = 0;-\t\t\t\tif (temp) {-\t\t\t\t\tif (pc->sg)-\t\t\t\t\t\tdrive->pc_io_buffers(drive, pc,-\t\t\t\t\t\t\t\t temp, 0);-\t\t\t\t\telse-\t\t\t\t\t\ttp_ops->input_data(drive, NULL,-\t\t\t\t\t\t\tpc->cur_pos, temp);-\t\t\t\t\tprintk(KERN_ERR \"%s: transferred %d of \"-\t\t\t\t\t\t\t\"%d bytes\\n\",-\t\t\t\t\t\t\tdrive->name,-\t\t\t\t\t\t\ttemp, bcount);-\t\t\t\t}-\t\t\t\tpc->xferred += temp;-\t\t\t\tpc->cur_pos += temp;-\t\t\t\tide_pad_transfer(drive, 0, bcount - temp);++\t\t\t\tide_pad_transfer(drive, 0, bcount); \t\t\t\tgoto next_irq; \t\t\t} \t\t\tdebug_log(\"The device wants to send us more data than \"@@ -410,14 +421,13 @@ cmd_finished: \t} else \t\txferfunc = tp_ops->output_data; -\tif ((drive->media == ide_floppy && !scsi && !pc->buf) ||-\t (drive->media == ide_tape && !scsi && pc->bh) ||-\t (scsi && pc->sg)) {+\tif ((drive->media == ide_floppy && !pc->buf) ||+\t (drive->media == ide_tape && pc->bh)) { \t\tint done = drive->pc_io_buffers(drive, pc, bcount, \t\t\t\t !!(pc->flags & PC_FLAG_WRITING)); \t\t/* FIXME: don't do partial completions */-\t\tif (drive->media == ide_floppy && !scsi)+\t\tif (drive->media == ide_floppy) \t\t\tide_end_request(drive, 1, done >> 9); \t} else \t\txferfunc(drive, NULL, pc->cur_pos, bcount);@@ -430,7 +440,7 @@ cmd_finished: \t\t rq->cmd[0], bcount); next_irq: \t/* And set the interrupt handler again */-\tide_set_handler(drive, ide_pc_intr, timeout, expiry);+\tide_set_handler(drive, ide_pc_intr, timeout, NULL); \treturn 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) {-\tstruct ide_atapi_pc *pc = drive->pc;+\tstruct ide_atapi_pc *uninitialized_var(pc); \tide_hwif_t *hwif = drive->hwif; \tstruct request *rq = hwif->hwgroup->rq; \tide_expiry_t *expiry; \tunsigned int timeout;+\tint cmd_len; \tide_startstop_t startstop; \tu8 ireason; @@ -493,101 +504,124 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) \t\treturn startstop; \t} -\tireason = ide_read_ireason(drive);-\tif (drive->media == ide_tape &&-\t (drive->dev_flags & IDE_DFLAG_SCSI) == 0)-\t\tireason = ide_wait_ireason(drive, ireason);--\tif ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {-\t\tprintk(KERN_ERR \"%s: (IO,CoD) != (0,1) while issuing \"-\t\t\t\t\"a packet command\\n\", drive->name);-\t\treturn ide_do_reset(drive);+\tif (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {+\t\tif (drive->dma)+\t\t\tdrive->waiting_for_dma = 1; \t} -\t/*-\t * If necessary schedule the packet transfer to occur 'timeout'-\t * miliseconds later in ide_delayed_transfer_pc() after the device-\t * says it's ready for a packet.-\t */-\tif (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {-\t\ttimeout = drive->pc_delay;-\t\texpiry = &ide_delayed_transfer_pc;+\tif (dev_is_idecd(drive)) {+\t\t/* ATAPI commands get padded out to 12 bytes minimum */+\t\tcmd_len = COMMAND_SIZE(rq->cmd[0]);+\t\tif (cmd_len < ATAPI_MIN_CDB_BYTES)+\t\t\tcmd_len = ATAPI_MIN_CDB_BYTES;++\t\ttimeout = rq->timeout;+\t\texpiry = ide_cd_expiry; \t} else {-\t\tif (drive->dev_flags & IDE_DFLAG_SCSI) {-\t\t\ttimeout = ide_scsi_get_timeout(pc);-\t\t\texpiry = ide_scsi_expiry;+\t\tpc = drive->pc;++\t\tcmd_len = ATAPI_MIN_CDB_BYTES;++\t\t/*+\t\t * If necessary schedule the packet transfer to occur 'timeout'+\t\t * miliseconds later in ide_delayed_transfer_pc() after the+\t\t * device says it's ready for a packet.+\t\t */+\t\tif (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {+\t\t\ttimeout = drive->pc_delay;+\t\t\texpiry = &ide_delayed_transfer_pc; \t\t} else { \t\t\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD \t\t\t\t\t\t\t : WAIT_TAPE_CMD; \t\t\texpiry = NULL; \t\t}++\t\tireason = ide_read_ireason(drive);+\t\tif (drive->media == ide_tape)+\t\t\tireason = ide_wait_ireason(drive, ireason);++\t\tif ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {+\t\t\tprintk(KERN_ERR \"%s: (IO,CoD) != (0,1) while issuing \"+\t\t\t\t\t\"a packet command\\n\", drive->name);++\t\t\treturn ide_do_reset(drive);+\t\t} \t} \t/* Set the interrupt routine */ \tide_set_handler(drive, ide_pc_intr, timeout, expiry); \t/* Begin DMA, if necessary */-\tif (pc->flags & PC_FLAG_DMA_OK) {-\t\tpc->flags |= PC_FLAG_DMA_IN_PROGRESS;-\t\thwif->dma_ops->dma_start(drive);+\tif (dev_is_idecd(drive)) {+\t\tif (drive->dma)+\t\t\thwif->dma_ops->dma_start(drive);+\t} else {+\t\tif (pc->flags & PC_FLAG_DMA_OK) {+\t\t\tpc->flags |= PC_FLAG_DMA_IN_PROGRESS;+\t\t\thwif->dma_ops->dma_start(drive);+\t\t} \t} \t/* Send the actual packet */ \tif ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)-\t\thwif->tp_ops->output_data(drive, NULL, rq->cmd, 12);+\t\thwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); \treturn ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,-\t\t\t ide_expiry_t *expiry)+ide_startstop_t ide_issue_pc(ide_drive_t *drive) {-\tstruct ide_atapi_pc *pc = drive->pc;+\tstruct ide_atapi_pc *pc; \tide_hwif_t *hwif = drive->hwif;+\tide_expiry_t *expiry = NULL;+\tunsigned int timeout; \tu32 tf_flags; \tu16 bcount;-\tu8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); -\t/* We haven't transferred any data yet */-\tpc->xferred = 0;-\tpc->cur_pos = pc->buf;+\tif (dev_is_idecd(drive)) {+\t\ttf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;+\t\tbcount = ide_cd_get_xferlen(hwif->hwgroup->rq);+\t\texpiry = ide_cd_expiry;+\t\ttimeout = ATAPI_WAIT_PC; -\t/* Request to transfer the entire buffer at once */-\tif (drive->media == ide_tape && scsi == 0)-\t\tbcount = pc->req_xfer;-\telse-\t\tbcount = min(pc->req_xfer, 63 * 1024);+\t\tif (drive->dma)+\t\t\tdrive->dma = !hwif->dma_ops->dma_setup(drive);+\t} else {+\t\tpc = drive->pc; -\tif (pc->flags & PC_FLAG_DMA_ERROR) {-\t\tpc->flags &= ~PC_FLAG_DMA_ERROR;-\t\tide_dma_off(drive);-\t}+\t\t/* We haven't transferred any data yet */+\t\tpc->xferred = 0;+\t\tpc->cur_pos = pc->buf; -\tif ((pc->flags & PC_FLAG_DMA_OK) &&-\t (drive->dev_flags & IDE_DFLAG_USING_DMA)) {-\t\tif (scsi)-\t\t\thwif->sg_mapped = 1;-\t\tdrive->dma = !hwif->dma_ops->dma_setup(drive);-\t\tif (scsi)-\t\t\thwif->sg_mapped = 0;-\t}+\t\ttf_flags = IDE_TFLAG_OUT_DEVICE;+\t\tbcount = ((drive->media == ide_tape) ?+\t\t\t\tpc->req_xfer :+\t\t\t\tmin(pc->req_xfer, 63 * 1024)); -\tif (!drive->dma)-\t\tpc->flags &= ~PC_FLAG_DMA_OK;+\t\tif (pc->flags & PC_FLAG_DMA_ERROR) {+\t\t\tpc->flags &= ~PC_FLAG_DMA_ERROR;+\t\t\tide_dma_off(drive);+\t\t} -\tif (scsi)-\t\ttf_flags = 0;-\telse if (drive->media == ide_cdrom || drive->media == ide_optical)-\t\ttf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;-\telse-\t\ttf_flags = IDE_TFLAG_OUT_DEVICE;+\t\tif ((pc->flags & PC_FLAG_DMA_OK) &&+\t\t (drive->dev_flags & IDE_DFLAG_USING_DMA))+\t\t\tdrive->dma = !hwif->dma_ops->dma_setup(drive);++\t\tif (!drive->dma)+\t\t\tpc->flags &= ~PC_FLAG_DMA_OK;++\t\ttimeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD+\t\t\t\t\t\t : WAIT_TAPE_CMD;+\t} \tide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); \t/* Issue the packet command */ \tif (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {+\t\tif (drive->dma)+\t\t\tdrive->waiting_for_dma = 0; \t\tide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,-\t\t\t\t timeout, NULL);+\t\t\t\t timeout, expiry); \t\treturn ide_started; \t} else { \t\tide_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\t\t1--#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: \treturn 1; } -static int cdrom_timer_expiry(ide_drive_t *drive)-{-\tstruct request *rq = HWGROUP(drive)->rq;-\tunsigned long wait = 0;--\tide_debug_log(IDE_DBG_RQ, \"Call %s: rq->cmd[0]: 0x%x\\n\", __func__,-\t\t rq->cmd[0]);--\t/*-\t * Some commands are *slow* and normally take a long time to complete.-\t * Usually we can use the ATAPI \"disconnect\" to bypass this, but not all-\t * commands/drives support that. Let ide_timer_expiry keep polling us-\t * for these.-\t */-\tswitch (rq->cmd[0]) {-\tcase GPCMD_BLANK:-\tcase GPCMD_FORMAT_UNIT:-\tcase GPCMD_RESERVE_RZONE_TRACK:-\tcase GPCMD_CLOSE_TRACK:-\tcase GPCMD_FLUSH_CACHE:-\t\twait = ATAPI_WAIT_PC;-\t\tbreak;-\tdefault:-\t\tif (!(rq->cmd_flags & REQ_QUIET))-\t\t\tprintk(KERN_INFO PFX \"cmd 0x%x timed out\\n\",-\t\t\t\t\t rq->cmd[0]);-\t\twait = 0;-\t\tbreak;-\t}-\treturn 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,-\t\t\t\t\t\t int xferlen,-\t\t\t\t\t\t ide_handler_t *handler)+static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive) { \tide_hwif_t *hwif = drive->hwif;+\tstruct request *rq = hwif->hwgroup->rq;+\tint xferlen;++\txferlen = ide_cd_get_xferlen(rq); \tide_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, \t\t\tdrive->waiting_for_dma = 0; \t\t/* packet command */-\t\tide_execute_command(drive, ATA_CMD_PACKET, handler,-\t\t\t\t ATAPI_WAIT_PC, cdrom_timer_expiry);+\t\tide_execute_command(drive, ATA_CMD_PACKET,+\t\t\t\t cdrom_transfer_packet_command,+\t\t\t\t ATAPI_WAIT_PC, ide_cd_expiry); \t\treturn ide_started; \t} else { \t\tide_execute_pkt_cmd(drive); -\t\treturn (*handler) (drive);+\t\treturn cdrom_transfer_packet_command(drive); \t} } @@ -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,-\t\t\t\t\t struct request *rq,-\t\t\t\t\t ide_handler_t *handler)+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive) { \tide_hwif_t *hwif = drive->hwif;+\tstruct request *rq = hwif->hwgroup->rq; \tint cmd_len; \tide_startstop_t startstop; @@ -629,7 +594,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, \t} \t/* arm the interrupt handler */-\tide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);+\tide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry); \t/* ATAPI commands get padded out to 12 bytes minimum */ \tcmd_len = COMMAND_SIZE(rq->cmd[0]);@@ -717,8 +682,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) \treturn 1; } -static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);- static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, \t\t\t\t\t\t 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)-{-\tstruct request *rq = drive->hwif->hwgroup->rq;--\t/* send the command to the drive and return */-\treturn 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) \t} else { \t\ttimeout = ATAPI_WAIT_PC; \t\tif (!blk_fs_request(rq))-\t\t\texpiry = cdrom_timer_expiry;+\t\t\texpiry = ide_cd_expiry; \t} \tide_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) \treturn ide_started; } -static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)-{-\tstruct request *rq = HWGROUP(drive)->rq;--\treturn 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, \t\t\t\t\tsector_t block) {-\tide_handler_t *fn;-\tint xferlen;- \tide_debug_log(IDE_DBG_RQ, \"Call %s, rq->cmd[0]: 0x%x, \" \t\t \"rq->cmd_type: 0x%x, block: %llu\\n\", \t\t __func__, rq->cmd[0], rq->cmd_type, \t\t (unsigned long long)block); \tif (blk_fs_request(rq)) {-\t\txferlen = 32768;-\t\tfn = cdrom_start_rw_cont;- \t\tif (cdrom_start_rw(drive, rq) == ide_stopped) \t\t\treturn ide_stopped; @@ -1233,9 +1169,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, \t\t\treturn ide_stopped; \t} else if (blk_sense_request(rq) || blk_pc_request(rq) || \t\t rq->cmd_type == REQ_TYPE_ATA_PC) {-\t\txferlen = rq->data_len;-\t\tfn = cdrom_do_newpc_cont;- \t\tif (!rq->timeout) \t\t\trq->timeout = ATAPI_WAIT_PC; @@ -1250,7 +1183,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, \t\treturn ide_stopped; \t} -\treturn cdrom_start_packet_command(drive, xferlen, fn);+\treturn 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\t\t(60 * HZ)+#define IDECD_DEBUG_LOG\t\t0++#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\t(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, \tpc->retries++; -\treturn ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);+\treturn 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,+\t\t\t\t\t struct ide_atapi_pc *pc) { \tstruct ide_disk_obj *floppy = drive->driver_data; \tstruct gendisk *disk = floppy->disk;-\tstruct ide_atapi_pc pc; \tu8 *page; \tint capacity, lba_capacity; \tu16 transfer_rate, sector_size, cyls, rpm; \tu8 heads, sectors; -\tide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);+\tide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); -\tif (ide_queue_pc_tail(drive, disk, &pc)) {+\tif (ide_queue_pc_tail(drive, disk, pc)) { \t\tprintk(KERN_ERR PFX \"Can't get flexible disk page params\\n\"); \t\treturn 1; \t} -\tif (pc.buf[3] & 0x80)+\tif (pc->buf[3] & 0x80) \t\tdrive->dev_flags |= IDE_DFLAG_WP; \telse \t\tdrive->dev_flags &= ~IDE_DFLAG_WP; \tset_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); -\tpage = &pc.buf[8];+\tpage = &pc->buf[8]; -\ttransfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);-\tsector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);-\tcyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);-\trpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);-\theads = pc.buf[8 + 4];-\tsectors = pc.buf[8 + 5];+\ttransfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]);+\tsector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]);+\tcyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]);+\trpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]);+\theads = pc->buf[8 + 4];+\tsectors = pc->buf[8 + 5]; \tcapacity = cyls * heads * sectors * sector_size; @@ -499,7 +499,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) \t/* Clik! disk does not support get_flexible_disk_page */ \tif (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))-\t\t(void) ide_floppy_get_flexible_disk_page(drive);+\t\t(void) ide_floppy_get_flexible_disk_page(drive, &pc); \treturn 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,+\t\t\t\t\t struct ide_atapi_pc *pc,+\t\t\t\t\t int __user *arg) { \tstruct ide_disk_obj *floppy = drive->driver_data;-\tstruct ide_atapi_pc pc; \tu8 header_len, desc_cnt; \tint i, blocks, length, u_array_size, u_index; \tint __user *argp;@@ -45,13 +46,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) \tif (u_array_size <= 0) \t\treturn -EINVAL; -\tide_floppy_create_read_capacity_cmd(&pc);-\tif (ide_queue_pc_tail(drive, floppy->disk, &pc)) {+\tide_floppy_create_read_capacity_cmd(pc);+\tif (ide_queue_pc_tail(drive, floppy->disk, pc)) { \t\tprintk(KERN_ERR \"ide-floppy: Can't get floppy parameters\\n\"); \t\treturn -EIO; \t} -\theader_len = pc.buf[3];+\theader_len = pc->buf[3]; \tdesc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ \tu_index = 0;@@ -68,8 +69,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) \t\tif (u_index >= u_array_size) \t\t\tbreak;\t/* User-supplied buffer too small */ -\t\tblocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);-\t\tlength = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);+\t\tblocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]);+\t\tlength = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]); \t\tif (put_user(blocks, argp)) \t\t\treturn -EFAULT;@@ -111,29 +112,28 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, \tpc->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) { \tstruct ide_disk_obj *floppy = drive->driver_data;-\tstruct ide_atapi_pc pc; \tdrive->atapi_flags &= ~IDE_AFLAG_SRFP; -\tide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);-\tpc.flags |= PC_FLAG_SUPPRESS_ERROR;+\tide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE);+\tpc->flags |= PC_FLAG_SUPPRESS_ERROR; -\tif (ide_queue_pc_tail(drive, floppy->disk, &pc))+\tif (ide_queue_pc_tail(drive, floppy->disk, pc)) \t\treturn 1; -\tif (pc.buf[8 + 2] & 0x40)+\tif (pc->buf[8 + 2] & 0x40) \t\tdrive->atapi_flags |= IDE_AFLAG_SRFP; \treturn 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,+\t\t\t\t int __user *arg) { \tstruct ide_disk_obj *floppy = drive->driver_data;-\tstruct ide_atapi_pc pc; \tint blocks, length, flags, err = 0; \tif (floppy->openers > 1) {@@ -166,10 +166,10 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) \t\tgoto out; \t} -\t(void)ide_floppy_get_sfrp_bit(drive);-\tide_floppy_create_format_unit_cmd(&pc, blocks, length, flags);+\tide_floppy_get_sfrp_bit(drive, pc);+\tide_floppy_create_format_unit_cmd(pc, blocks, length, flags); -\tif (ide_queue_pc_tail(drive, floppy->disk, &pc))+\tif (ide_queue_pc_tail(drive, floppy->disk, pc)) \t\terr = -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,+\t\t\t\t\t struct ide_atapi_pc *pc,+\t\t\t\t\t int __user *arg) { \tstruct ide_disk_obj *floppy = drive->driver_data;-\tstruct ide_atapi_pc pc; \tint progress_indication = 0x10000; \tif (drive->atapi_flags & IDE_AFLAG_SRFP) {-\t\tide_create_request_sense_cmd(drive, &pc);-\t\tif (ide_queue_pc_tail(drive, floppy->disk, &pc))+\t\tide_create_request_sense_cmd(drive, pc);+\t\tif (ide_queue_pc_tail(drive, floppy->disk, pc)) \t\t\treturn -EIO; \t\tif (floppy->sense_key == 2 &&@@ -241,20 +242,21 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, \treturn 0; } -static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode,-\t\t\t\t unsigned int cmd, void __user *argp)+static int ide_floppy_format_ioctl(ide_drive_t *drive, struct ide_atapi_pc *pc,+\t\t\t\t fmode_t mode, unsigned int cmd,+\t\t\t\t void __user *argp) { \tswitch (cmd) { \tcase IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: \t\treturn 0; \tcase IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:-\t\treturn ide_floppy_get_format_capacities(drive, argp);+\t\treturn ide_floppy_get_format_capacities(drive, pc, argp); \tcase IDEFLOPPY_IOCTL_FORMAT_START: \t\tif (!(mode & FMODE_WRITE)) \t\t\treturn -EPERM;-\t\treturn ide_floppy_format_unit(drive, (int __user *)argp);+\t\treturn ide_floppy_format_unit(drive, pc, (int __user *)argp); \tcase IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:-\t\treturn ide_floppy_get_format_progress(drive, argp);+\t\treturn ide_floppy_get_format_progress(drive, pc, argp); \tdefault: \t\treturn -ENOTTY; \t}@@ -270,7 +272,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, \tif (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) \t\treturn ide_floppy_lockdoor(drive, &pc, arg, cmd); -\terr = ide_floppy_format_ioctl(drive, mode, cmd, argp);+\terr = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp); \tif (err != -ENOTTY) \t\treturn 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) \tide_hwif_t *hwif = drive->hwif; \tstruct scatterlist *sg = hwif->sg_table; -\tif (hwif->sg_mapped)\t/* needed by ide-scsi */-\t\treturn;- \tif (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { \t\thwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); \t} else {@@ -667,85 +664,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) \tdrive->sleep = timeout + jiffies; \tdrive->dev_flags |= IDE_DFLAG_SLEEPING; }- EXPORT_SYMBOL(ide_stall_queue); -#define WAKEUP(drive)\t((drive)->service_start + 2 * (drive)->service_time)--/**- *\tchoose_drive\t\t-\tselect a drive to service- *\t@hwgroup: hardware group to select on- *- *\tchoose_drive() selects the next drive which will be serviced.- *\tThis is necessary because the IDE layer can't issue commands- *\tto both drives on the same cable, unlike SCSI.- */- -static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)-{-\tide_drive_t *drive, *best;--repeat:\t-\tbest = NULL;-\tdrive = hwgroup->drive;--\t/*-\t * drive is doing pre-flush, ordered write, post-flush sequence. even-\t * though that is 3 requests, it must be seen as a single transaction.-\t * we must not preempt this drive until that is complete-\t */-\tif (blk_queue_flushing(drive->queue)) {-\t\t/*-\t\t * small race where queue could get replugged during-\t\t * the 3-request flush cycle, just yank the plug since-\t\t * we want it to finish asap-\t\t */-\t\tblk_remove_plug(drive->queue);-\t\treturn drive;-\t}--\tdo {-\t\tu8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING);-\t\tu8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING));--\t\tif ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) &&-\t\t !elv_queue_empty(drive->queue)) {-\t\t\tif (best == NULL ||-\t\t\t (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) ||-\t\t\t (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) {-\t\t\t\tif (!blk_queue_plugged(drive->queue))-\t\t\t\t\tbest = drive;-\t\t\t}-\t\t}-\t} while ((drive = drive->next) != hwgroup->drive);--\tif (best && (best->dev_flags & IDE_DFLAG_NICE1) &&-\t (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 &&-\t best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {-\t\tlong t = (signed long)(WAKEUP(best) - jiffies);-\t\tif (t >= WAIT_MIN_SLEEP) {-\t\t/*-\t\t * We *may* have some time to spare, but first let's see if-\t\t * someone can potentially benefit from our nice mood today..-\t\t */-\t\t\tdrive = best->next;-\t\t\tdo {-\t\t\t\tif ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0-\t\t\t\t && time_before(jiffies - best->service_time, WAKEUP(drive))-\t\t\t\t && time_before(WAKEUP(drive), jiffies + t))-\t\t\t\t{-\t\t\t\t\tide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP));-\t\t\t\t\tgoto repeat;-\t\t\t\t}-\t\t\t} while ((drive = drive->next) != best);-\t\t}-\t}-\treturn 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) {-\tide_drive_t\t*drive;-\tide_hwif_t\t*hwif;+\tide_drive_t\t*drive = q->queuedata;+\tide_hwif_t\t*hwif = drive->hwif;+\tide_hwgroup_t\t*hwgroup = hwif->hwgroup; \tstruct request\t*rq; \tide_startstop_t\tstartstop;-\tint loops = 0;--\t/* caller must own hwgroup->lock */-\tBUG_ON(!irqs_disabled());--\twhile (!hwgroup->busy) {-\t\thwgroup->busy = 1;-\t\t/* for atari only */-\t\tide_get_lock(ide_intr, hwgroup);-\t\tdrive = choose_drive(hwgroup);-\t\tif (drive == NULL) {-\t\t\tint sleeping = 0;-\t\t\tunsigned long sleep = 0; /* shut up, gcc */-\t\t\thwgroup->rq = NULL;-\t\t\tdrive = hwgroup->drive;-\t\t\tdo {-\t\t\t\tif ((drive->dev_flags & IDE_DFLAG_SLEEPING) &&-\t\t\t\t (sleeping == 0 ||-\t\t\t\t time_before(drive->sleep, sleep))) {-\t\t\t\t\tsleeping = 1;-\t\t\t\t\tsleep = drive->sleep;-\t\t\t\t}-\t\t\t} while ((drive = drive->next) != hwgroup->drive);-\t\t\tif (sleeping) {++\t/*+\t * drive is doing pre-flush, ordered write, post-flush sequence. even+\t * though that is 3 requests, it must be seen as a single transaction.+\t * we must not preempt this drive until that is complete+\t */+\tif (blk_queue_flushing(q)) \t\t/*-\t\t * Take a short snooze, and then wake up this hwgroup again.-\t\t * This gives other hwgroups on the same a chance to-\t\t * play fairly with us, just in case there are big differences-\t\t * in relative throughputs.. don't want to hog the cpu too much.+\t\t * small race where queue could get replugged during+\t\t * the 3-request flush cycle, just yank the plug since+\t\t * we want it to finish asap \t\t */-\t\t\t\tif (time_before(sleep, jiffies + WAIT_MIN_SLEEP))-\t\t\t\t\tsleep = jiffies + WAIT_MIN_SLEEP;-#if 1-\t\t\t\tif (timer_pending(&hwgroup->timer))-\t\t\t\t\tprintk(KERN_CRIT \"ide_set_handler: timer already active\\n\");-#endif-\t\t\t\t/* so that ide_timer_expiry knows what to do */-\t\t\t\thwgroup->sleeping = 1;-\t\t\t\thwgroup->req_gen_timer = hwgroup->req_gen;-\t\t\t\tmod_timer(&hwgroup->timer, sleep);-\t\t\t\t/* we purposely leave hwgroup->busy==1-\t\t\t\t * while sleeping */-\t\t\t} else {-\t\t\t\t/* Ugly, but how can we sleep for the lock-\t\t\t\t * otherwise? perhaps from tq_disk?-\t\t\t\t */+\t\tblk_remove_plug(q); -\t\t\t\t/* for atari only */-\t\t\t\tide_release_lock();-\t\t\t\thwgroup->busy = 0;-\t\t\t}+\tspin_unlock_irq(q->queue_lock);+\tspin_lock_irq(&hwgroup->lock);++\tif (!ide_lock_hwgroup(hwgroup)) {+repeat:+\t\thwgroup->rq = NULL; -\t\t\t/* no more work for this hwgroup (for now) */-\t\t\treturn;+\t\tif (drive->dev_flags & IDE_DFLAG_SLEEPING) {+\t\t\tif (time_before(drive->sleep, jiffies)) {+\t\t\t\tide_unlock_hwgroup(hwgroup);+\t\t\t\tgoto plug_device;+\t\t\t} \t\t}-\tagain:-\t\thwif = HWIF(drive);+ \t\tif (hwif != hwgroup->hwif) { \t\t\t/* \t\t\t * set nIEN for previous hwif, drives in the@@ -852,16 +745,20 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) \t\thwgroup->hwif = hwif; \t\thwgroup->drive = drive; \t\tdrive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);-\t\tdrive->service_start = jiffies; +\t\tspin_unlock_irq(&hwgroup->lock);+\t\tspin_lock_irq(q->queue_lock); \t\t/* \t\t * we know that the queue isn't empty, but this can happen \t\t * if the q->prep_rq_fn() decides to kill a request \t\t */ \t\trq = elv_next_request(drive->queue);+\t\tspin_unlock_irq(q->queue_lock);+\t\tspin_lock_irq(&hwgroup->lock);+ \t\tif (!rq) {-\t\t\thwgroup->busy = 0;-\t\t\tbreak;+\t\t\tide_unlock_hwgroup(hwgroup);+\t\t\tgoto out; \t\t} \t\t/*@@ -876,53 +773,36 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) \t\t * though. I hope that doesn't happen too much, hopefully not \t\t * unless the subdriver triggers such a thing in its own PM \t\t * state machine.-\t\t *-\t\t * We count how many times we loop here to make sure we service-\t\t * all drives in the hwgroup without looping for ever \t\t */ \t\tif ((drive->dev_flags & IDE_DFLAG_BLOCKED) && \t\t blk_pm_request(rq) == 0 && \t\t (rq->cmd_flags & REQ_PREEMPT) == 0) {-\t\t\tdrive = drive->next ? drive->next : hwgroup->drive;-\t\t\tif (loops++ < 4 && !blk_queue_plugged(drive->queue))-\t\t\t\tgoto again;-\t\t\t/* We clear busy, there should be no pending ATA command at this point. */-\t\t\thwgroup->busy = 0;-\t\t\tbreak;+\t\t\t/* there should be no pending command at this point */+\t\t\tide_unlock_hwgroup(hwgroup);+\t\t\tgoto plug_device; \t\t} \t\thwgroup->rq = rq; -\t\t/*-\t\t * Some systems have trouble with IDE IRQs arriving while-\t\t * the driver is still setting things up. So, here we disable-\t\t * the IRQ used by this interface while the request is being started.-\t\t * This may look bad at first, but pretty much the same thing-\t\t * happens anyway when any interrupt comes in, IDE or otherwise-\t\t * -- the kernel masks the IRQ while it is being handled.-\t\t */-\t\tif (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)-\t\t\tdisable_irq_nosync(hwif->irq);-\t\tspin_unlock(&hwgroup->lock);-\t\tlocal_irq_enable_in_hardirq();-\t\t\t/* allow other IRQs while we start this request */+\t\tspin_unlock_irq(&hwgroup->lock); \t\tstartstop = start_request(drive, rq); \t\tspin_lock_irq(&hwgroup->lock);-\t\tif (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)-\t\t\tenable_irq(hwif->irq);+ \t\tif (startstop == ide_stopped)-\t\t\thwgroup->busy = 0;-\t}-}+\t\t\tgoto repeat;+\t} else+\t\tgoto plug_device;+out:+\tspin_unlock_irq(&hwgroup->lock);+\tspin_lock_irq(q->queue_lock);+\treturn; -/*- * Passes the stuff to ide_do_request- */-void do_ide_request(struct request_queue *q)-{-\tide_drive_t *drive = q->queuedata;+plug_device:+\tspin_unlock_irq(&hwgroup->lock);+\tspin_lock_irq(q->queue_lock); -\tide_do_request(HWGROUP(drive), IDE_NO_IRQ);+\tif (!elv_queue_empty(q))+\t\tblk_plug_device(q); } /*@@ -983,6 +863,17 @@ out: \treturn ret; } +static void ide_plug_device(ide_drive_t *drive)+{+\tstruct request_queue *q = drive->queue;+\tunsigned long flags;++\tspin_lock_irqsave(q->queue_lock, flags);+\tif (!elv_queue_empty(q))+\t\tblk_plug_device(q);+\tspin_unlock_irqrestore(q->queue_lock, flags);+}+ /** *\tide_timer_expiry\t-\thandle lack of an IDE interrupt *\t@data: timer callback magic (hwgroup)@@ -1000,10 +891,12 @@ out: void ide_timer_expiry (unsigned long data) { \tide_hwgroup_t\t*hwgroup = (ide_hwgroup_t *) data;+\tide_drive_t\t*uninitialized_var(drive); \tide_handler_t\t*handler; \tide_expiry_t\t*expiry; \tunsigned long\tflags; \tunsigned long\twait = -1;+\tint\t\tplug_device = 0; \tspin_lock_irqsave(&hwgroup->lock, flags); @@ -1015,22 +908,15 @@ void ide_timer_expiry (unsigned long data) \t\t * or we were \"sleeping\" to give other devices a chance. \t\t * Either way, we don't really want to complain about anything. \t\t */-\t\tif (hwgroup->sleeping) {-\t\t\thwgroup->sleeping = 0;-\t\t\thwgroup->busy = 0;-\t\t} \t} else {-\t\tide_drive_t *drive = hwgroup->drive;+\t\tdrive = hwgroup->drive; \t\tif (!drive) { \t\t\tprintk(KERN_ERR \"ide_timer_expiry: hwgroup->drive was NULL\\n\"); \t\t\thwgroup->handler = NULL; \t\t} else { \t\t\tide_hwif_t *hwif; \t\t\tide_startstop_t startstop = ide_stopped;-\t\t\tif (!hwgroup->busy) {-\t\t\t\thwgroup->busy = 1;\t/* paranoia */-\t\t\t\tprintk(KERN_ERR \"%s: ide_timer_expiry: hwgroup->busy was 0 ??\\n\", drive->name);-\t\t\t}+ \t\t\tif ((expiry = hwgroup->expiry) != NULL) { \t\t\t\t/* continue */ \t\t\t\tif ((wait = expiry(drive)) > 0) {@@ -1071,15 +957,18 @@ void ide_timer_expiry (unsigned long data) \t\t\t\t\tide_error(drive, \"irq timeout\", \t\t\t\t\t\t hwif->tp_ops->read_status(hwif)); \t\t\t}-\t\t\tdrive->service_time = jiffies - drive->service_start; \t\t\tspin_lock_irq(&hwgroup->lock); \t\t\tenable_irq(hwif->irq);-\t\t\tif (startstop == ide_stopped)-\t\t\t\thwgroup->busy = 0;+\t\t\tif (startstop == ide_stopped) {+\t\t\t\tide_unlock_hwgroup(hwgroup);+\t\t\t\tplug_device = 1;+\t\t\t} \t\t} \t}-\tide_do_request(hwgroup, IDE_NO_IRQ); \tspin_unlock_irqrestore(&hwgroup->lock, flags);++\tif (plug_device)+\t\tide_plug_device(drive); } /**@@ -1173,10 +1062,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) \tunsigned long flags; \tide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; \tide_hwif_t *hwif = hwgroup->hwif;-\tide_drive_t *drive;+\tide_drive_t *uninitialized_var(drive); \tide_handler_t *handler; \tide_startstop_t startstop; \tirqreturn_t irq_ret = IRQ_NONE;+\tint plug_device = 0; \tspin_lock_irqsave(&hwgroup->lock, flags); @@ -1241,10 +1131,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) \t\t */ \t\tgoto out; -\tif (!hwgroup->busy) {-\t\thwgroup->busy = 1;\t/* paranoia */-\t\tprintk(KERN_ERR \"%s: ide_intr: hwgroup->busy was 0 ??\\n\", drive->name);-\t} \thwgroup->handler = NULL; \thwgroup->req_gen++; \tdel_timer(&hwgroup->timer);@@ -1267,20 +1153,22 @@ irqreturn_t ide_intr (int irq, void *dev_id) \t * same irq as is currently being serviced here, and Linux \t * won't allow another of the same (on any CPU) until we return. \t */-\tdrive->service_time = jiffies - drive->service_start; \tif (startstop == ide_stopped) { \t\tif (hwgroup->handler == NULL) {\t/* paranoia */-\t\t\thwgroup->busy = 0;-\t\t\tide_do_request(hwgroup, hwif->irq);-\t\t} else {-\t\t\tprintk(KERN_ERR \"%s: ide_intr: huh? expected NULL handler \"-\t\t\t\t\"on exit\\n\", drive->name);-\t\t}+\t\t\tide_unlock_hwgroup(hwgroup);+\t\t\tplug_device = 1;+\t\t} else+\t\t\tprintk(KERN_ERR \"%s: %s: huh? expected NULL handler \"+\t\t\t\t\t\"on exit\\n\", __func__, drive->name); \t} out_handled: \tirq_ret = IRQ_HANDLED; out: \tspin_unlock_irqrestore(&hwgroup->lock, flags);++\tif (plug_device)+\t\tide_plug_device(drive);+ \treturn 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) \t\treturn -EPERM; \tif (((arg >> IDE_NICE_DSC_OVERLAP) & 1) &&-\t (drive->media != ide_tape ||-\t (drive->dev_flags & IDE_DFLAG_SCSI)))+\t (drive->media != ide_tape)) \t\treturn -EPERM; \tif ((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) \tspin_lock_irq(&hwgroup->lock); \tif (drive->dev_flags & IDE_DFLAG_PARKED) { \t\tint reset_timer = time_before(timeout, drive->sleep);+\t\tint start_queue = 0; \t\tdrive->sleep = timeout; \t\twake_up_all(&ide_park_wq);-\t\tif (reset_timer && hwgroup->sleeping &&-\t\t del_timer(&hwgroup->timer)) {-\t\t\thwgroup->sleeping = 0;-\t\t\thwgroup->busy = 0;+\t\tif (reset_timer && del_timer(&hwgroup->timer))+\t\t\tstart_queue = 1;+\t\tspin_unlock_irq(&hwgroup->lock);++\t\tif (start_queue) {+\t\t\tspin_lock_irq(q->queue_lock); \t\t\tblk_start_queueing(q);+\t\t\tspin_unlock_irq(q->queue_lock); \t\t}-\t\tspin_unlock_irq(&hwgroup->lock); \t\treturn; \t} \tspin_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) \t} } +static void ide_classify_ata_dev(ide_drive_t *drive)+{+\tu16 *id = drive->id;+\tchar *m = (char *)&id[ATA_ID_PROD];+\tint is_cfa = ata_id_is_cfa(id);++\t/* CF devices are *not* removable in Linux definition of the term */+\tif (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))+\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;++\tdrive->media = ide_disk;++\tif (!ata_id_has_unload(drive->id))+\t\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;++\tprintk(KERN_INFO \"%s: %s, %s DISK drive\\n\", drive->name, m,+\t\tis_cfa ? \"CFA\" : \"ATA\");+}++static void ide_classify_atapi_dev(ide_drive_t *drive)+{+\tu16 *id = drive->id;+\tchar *m = (char *)&id[ATA_ID_PROD];+\tu8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;++\tprintk(KERN_INFO \"%s: %s, ATAPI \", drive->name, m);+\tswitch (type) {+\tcase ide_floppy:+\t\tif (!strstr(m, \"CD-ROM\")) {+\t\t\tif (!strstr(m, \"oppy\") &&+\t\t\t !strstr(m, \"poyp\") &&+\t\t\t !strstr(m, \"ZIP\"))+\t\t\t\tprintk(KERN_CONT \"cdrom or floppy?, assuming \");+\t\t\tif (drive->media != ide_cdrom) {+\t\t\t\tprintk(KERN_CONT \"FLOPPY\");+\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;+\t\t\t\tbreak;+\t\t\t}+\t\t}+\t\t/* Early cdrom models used zero */+\t\ttype = ide_cdrom;+\tcase ide_cdrom:+\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;+#ifdef CONFIG_PPC+\t\t/* kludge for Apple PowerBook internal zip */+\t\tif (!strstr(m, \"CD-ROM\") && strstr(m, \"ZIP\")) {+\t\t\tprintk(KERN_CONT \"FLOPPY\");+\t\t\ttype = ide_floppy;+\t\t\tbreak;+\t\t}+#endif+\t\tprintk(KERN_CONT \"CD/DVD-ROM\");+\t\tbreak;+\tcase ide_tape:+\t\tprintk(KERN_CONT \"TAPE\");+\t\tbreak;+\tcase ide_optical:+\t\tprintk(KERN_CONT \"OPTICAL\");+\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;+\t\tbreak;+\tdefault:+\t\tprintk(KERN_CONT \"UNKNOWN (type %d)\", type);+\t\tbreak;+\t}++\tprintk(KERN_CONT \" drive\\n\");+\tdrive->media = type;+\t/* an ATAPI device ignores DRDY */+\tdrive->ready_stat = 0;+\tif (ata_id_cdb_intr(id))+\t\tdrive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;+\tdrive->dev_flags |= IDE_DFLAG_DOORLOCKING;+\t/* we don't do head unloading on ATAPI devices */+\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;+}+ /** *\tdo_identify\t-\tidentify a drive *\t@drive: drive to identify @@ -117,7 +193,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd) \tu16 *id = drive->id; \tchar *m = (char *)&id[ATA_ID_PROD]; \tunsigned long flags;-\tint bswap = 1, is_cfa;+\tint bswap = 1; \t/* local CPU only; some systems need this */ \tlocal_irq_save(flags);@@ -154,91 +230,23 @@ static void do_identify(ide_drive_t *drive, u8 cmd) \tif (strstr(m, \"E X A B Y T E N E S T\")) \t\tgoto err_misc; -\tprintk(KERN_INFO \"%s: %s, \", drive->name, m);- \tdrive->dev_flags |= IDE_DFLAG_PRESENT; \tdrive->dev_flags &= ~IDE_DFLAG_DEAD; \t/* \t * Check for an ATAPI device \t */-\tif (cmd == ATA_CMD_ID_ATAPI) {-\t\tu8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;--\t\tprintk(KERN_CONT \"ATAPI \");-\t\tswitch (type) {-\t\t\tcase ide_floppy:-\t\t\t\tif (!strstr(m, \"CD-ROM\")) {-\t\t\t\t\tif (!strstr(m, \"oppy\") &&-\t\t\t\t\t !strstr(m, \"poyp\") &&-\t\t\t\t\t !strstr(m, \"ZIP\"))-\t\t\t\t\t\tprintk(KERN_CONT \"cdrom or floppy?, assuming \");-\t\t\t\t\tif (drive->media != ide_cdrom) {-\t\t\t\t\t\tprintk(KERN_CONT \"FLOPPY\");-\t\t\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;-\t\t\t\t\t\tbreak;-\t\t\t\t\t}-\t\t\t\t}-\t\t\t\t/* Early cdrom models used zero */-\t\t\t\ttype = ide_cdrom;-\t\t\tcase ide_cdrom:-\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;-#ifdef CONFIG_PPC-\t\t\t\t/* kludge for Apple PowerBook internal zip */-\t\t\t\tif (!strstr(m, \"CD-ROM\") && strstr(m, \"ZIP\")) {-\t\t\t\t\tprintk(KERN_CONT \"FLOPPY\");-\t\t\t\t\ttype = ide_floppy;-\t\t\t\t\tbreak;-\t\t\t\t}-#endif-\t\t\t\tprintk(KERN_CONT \"CD/DVD-ROM\");-\t\t\t\tbreak;-\t\t\tcase ide_tape:-\t\t\t\tprintk(KERN_CONT \"TAPE\");-\t\t\t\tbreak;-\t\t\tcase ide_optical:-\t\t\t\tprintk(KERN_CONT \"OPTICAL\");-\t\t\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;-\t\t\t\tbreak;-\t\t\tdefault:-\t\t\t\tprintk(KERN_CONT \"UNKNOWN (type %d)\", type);-\t\t\t\tbreak;-\t\t}-\t\tprintk(KERN_CONT \" drive\\n\");-\t\tdrive->media = type;-\t\t/* an ATAPI device ignores DRDY */-\t\tdrive->ready_stat = 0;-\t\tif (ata_id_cdb_intr(id))-\t\t\tdrive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;-\t\tdrive->dev_flags |= IDE_DFLAG_DOORLOCKING;-\t\t/* we don't do head unloading on ATAPI devices */-\t\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;-\t\treturn;-\t}-+\tif (cmd == ATA_CMD_ID_ATAPI)+\t\tide_classify_atapi_dev(drive);+\telse \t/* \t * Not an ATAPI device: looks like a \"regular\" hard disk \t */--\tis_cfa = ata_id_is_cfa(id);--\t/* CF devices are *not* removable in Linux definition of the term */-\tif (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))-\t\tdrive->dev_flags |= IDE_DFLAG_REMOVABLE;--\tdrive->media = ide_disk;--\tif (!ata_id_has_unload(drive->id))-\t\tdrive->dev_flags |= IDE_DFLAG_NO_UNLOAD;--\tprintk(KERN_CONT \"%s DISK drive\\n\", is_cfa ? \"CFA\" : \"ATA\");-+\t\tide_classify_ata_dev(drive); \treturn;- err_misc: \tkfree(id); \tdrive->dev_flags &= ~IDE_DFLAG_PRESENT;-\treturn; } /**@@ -641,14 +649,9 @@ static int ide_register_port(ide_hwif_t *hwif) \t/* register with global device tree */ \tdev_set_name(&hwif->gendev, hwif->name); \thwif->gendev.driver_data = hwif;-\tif (hwif->gendev.parent == NULL) {-\t\tif (hwif->dev)-\t\t\thwif->gendev.parent = hwif->dev;-\t\telse-\t\t\t/* Would like to do = &device_legacy */-\t\t\thwif->gendev.parent = NULL;-\t}+\thwif->gendev.parent = hwif->dev; \thwif->gendev.release = hwif_release_dev;+ \tret = device_register(&hwif->gendev); \tif (ret < 0) { \t\tprintk(KERN_WARNING \"IDE: %s: device_register error: %d\\n\",@@ -878,8 +881,7 @@ static int ide_init_queue(ide_drive_t *drive) \t *\tdo not. \t */ -\tq = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock,-\t\t\t\thwif_to_node(hwif));+\tq = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif)); \tif (!q) \t\treturn 1; @@ -1139,8 +1141,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) \tif (drive->media == ide_disk) \t\trequest_module(\"ide-disk\");-\tif (drive->dev_flags & IDE_DFLAG_SCSI)-\t\trequest_module(\"ide-scsi\"); \tif (drive->media == ide_cdrom || drive->media == ide_optical) \t\trequest_module(\"ide-cd\"); \tif (drive->media == ide_tape)@@ -1417,58 +1417,6 @@ static void ide_port_cable_detect(ide_hwif_t *hwif) \t} } -static ssize_t store_delete_devices(struct device *portdev,-\t\t\t\t struct device_attribute *attr,-\t\t\t\t const char *buf, size_t n)-{-\tide_hwif_t *hwif = dev_get_drvdata(portdev);--\tif (strncmp(buf, \"1\", n))-\t\treturn -EINVAL;--\tide_port_unregister_devices(hwif);--\treturn n;-};--static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);--static ssize_t store_scan(struct device *portdev,-\t\t\t struct device_attribute *attr,-\t\t\t const char *buf, size_t n)-{-\tide_hwif_t *hwif = dev_get_drvdata(portdev);--\tif (strncmp(buf, \"1\", n))-\t\treturn -EINVAL;--\tide_port_unregister_devices(hwif);-\tide_port_scan(hwif);--\treturn n;-};--static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);--static struct device_attribute *ide_port_attrs[] = {-\t&dev_attr_delete_devices,-\t&dev_attr_scan,-\tNULL-};--static int ide_sysfs_register_port(ide_hwif_t *hwif)-{-\tint i, uninitialized_var(rc);--\tfor (i = 0; ide_port_attrs[i]; i++) {-\t\trc = device_create_file(hwif->portdev, ide_port_attrs[i]);-\t\tif (rc)-\t\t\tbreak;-\t}--\treturn rc;-}- static unsigned int ide_indexes; /**@@ -1655,9 +1603,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, \t\tif (hwif == NULL) \t\t\tcontinue; -\t\tif (hwif->chipset == ide_unknown)-\t\t\thwif->chipset = ide_generic;- \t\tif (hwif->present) \t\t\thwif_register_devices(hwif); \t}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)+{+\tswitch (drive->media) {+\tcase ide_disk:+\t\treturn \"disk\";+\tcase ide_cdrom:+\t\treturn \"cdrom\";+\tcase ide_tape:+\t\treturn \"tape\";+\tcase ide_floppy:+\t\treturn \"floppy\";+\tcase ide_optical:+\t\treturn \"optical\";+\tdefault:+\t\treturn \"UNKNOWN\";+\t}+}++static ssize_t media_show(struct device *dev, struct device_attribute *attr,+\t\t\t char *buf)+{+\tide_drive_t *drive = to_ide_device(dev);+\treturn sprintf(buf, \"%s\\n\", ide_media_string(drive));+}++static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,+\t\t\t char *buf)+{+\tide_drive_t *drive = to_ide_device(dev);+\treturn sprintf(buf, \"%s\\n\", drive->name);+}++static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,+\t\t\t char *buf)+{+\tide_drive_t *drive = to_ide_device(dev);+\treturn sprintf(buf, \"ide:m-%s\\n\", ide_media_string(drive));+}++static ssize_t model_show(struct device *dev, struct device_attribute *attr,+\t\t\t char *buf)+{+\tide_drive_t *drive = to_ide_device(dev);+\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_PROD]);+}++static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,+\t\t\t char *buf)+{+\tide_drive_t *drive = to_ide_device(dev);+\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_FW_REV]);+}++static ssize_t serial_show(struct device *dev, struct device_attribute *attr,+\t\t\t char *buf)+{+\tide_drive_t *drive = to_ide_device(dev);+\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_SERNO]);+}++struct device_attribute ide_dev_attrs[] = {+\t__ATTR_RO(media),+\t__ATTR_RO(drivename),+\t__ATTR_RO(modalias),+\t__ATTR_RO(model),+\t__ATTR_RO(firmware),+\t__ATTR(serial, 0400, serial_show, NULL),+\t__ATTR(unload_heads, 0644, ide_park_show, ide_park_store),+\t__ATTR_NULL+};++static ssize_t store_delete_devices(struct device *portdev,+\t\t\t\t struct device_attribute *attr,+\t\t\t\t const char *buf, size_t n)+{+\tide_hwif_t *hwif = dev_get_drvdata(portdev);++\tif (strncmp(buf, \"1\", n))+\t\treturn -EINVAL;++\tide_port_unregister_devices(hwif);++\treturn n;+};++static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices);++static ssize_t store_scan(struct device *portdev,+\t\t\t struct device_attribute *attr,+\t\t\t const char *buf, size_t n)+{+\tide_hwif_t *hwif = dev_get_drvdata(portdev);++\tif (strncmp(buf, \"1\", n))+\t\treturn -EINVAL;++\tide_port_unregister_devices(hwif);+\tide_port_scan(hwif);++\treturn n;+};++static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);++static struct device_attribute *ide_port_attrs[] = {+\t&dev_attr_delete_devices,+\t&dev_attr_scan,+\tNULL+};++int ide_sysfs_register_port(ide_hwif_t *hwif)+{+\tint i, uninitialized_var(rc);++\tfor (i = 0; ide_port_attrs[i]; i++) {+\t\trc = device_create_file(hwif->portdev, ide_port_attrs[i]);+\t\tif (rc)+\t\t\tbreak;+\t}++\treturn 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, \tpc->retries++; -\treturn ide_issue_pc(drive, WAIT_TAPE_CMD, NULL);+\treturn 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) \treturn 1; } -static char *media_string(ide_drive_t *drive)-{-\tswitch (drive->media) {-\tcase ide_disk:-\t\treturn \"disk\";-\tcase ide_cdrom:-\t\treturn \"cdrom\";-\tcase ide_tape:-\t\treturn \"tape\";-\tcase ide_floppy:-\t\treturn \"floppy\";-\tcase ide_optical:-\t\treturn \"optical\";-\tdefault:-\t\treturn \"UNKNOWN\";-\t}-}--static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)-{-\tide_drive_t *drive = to_ide_device(dev);-\treturn sprintf(buf, \"%s\\n\", media_string(drive));-}--static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)-{-\tide_drive_t *drive = to_ide_device(dev);-\treturn sprintf(buf, \"%s\\n\", drive->name);-}--static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)-{-\tide_drive_t *drive = to_ide_device(dev);-\treturn sprintf(buf, \"ide:m-%s\\n\", media_string(drive));-}--static ssize_t model_show(struct device *dev, struct device_attribute *attr,-\t\t\t char *buf)-{-\tide_drive_t *drive = to_ide_device(dev);-\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_PROD]);-}--static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,-\t\t\t char *buf)-{-\tide_drive_t *drive = to_ide_device(dev);-\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_FW_REV]);-}--static ssize_t serial_show(struct device *dev, struct device_attribute *attr,-\t\t\t char *buf)-{-\tide_drive_t *drive = to_ide_device(dev);-\treturn sprintf(buf, \"%s\\n\", (char *)&drive->id[ATA_ID_SERNO]);-}--static struct device_attribute ide_dev_attrs[] = {-\t__ATTR_RO(media),-\t__ATTR_RO(drivename),-\t__ATTR_RO(modalias),-\t__ATTR_RO(model),-\t__ATTR_RO(firmware),-\t__ATTR(serial, 0400, serial_show, NULL),-\t__ATTR(unload_heads, 0644, ide_park_show, ide_park_store),-\t__ATTR_NULL-};- static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) { \tide_drive_t *drive = to_ide_device(dev); -\tadd_uevent_var(env, \"MEDIA=%s\", media_string(drive));+\tadd_uevent_var(env, \"MEDIA=%s\", ide_media_string(drive)); \tadd_uevent_var(env, \"DRIVENAME=%s\", drive->name);-\tadd_uevent_var(env, \"MODALIAS=ide:m-%s\", media_string(drive));+\tadd_uevent_var(env, \"MODALIAS=ide:m-%s\", ide_media_string(drive)); \treturn 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\t/* __BIG_ENDIAN */ static const struct ide_port_ops tx4938ide_port_ops = {-\t.set_pio_mode = tx4938ide_set_pio_mode,+\t.set_pio_mode\t\t= tx4938ide_set_pio_mode, }; static const struct ide_port_info tx4938ide_port_info __initdata = {-\t.port_ops = &tx4938ide_port_ops,+\t.port_ops\t\t= &tx4938ide_port_ops, #ifdef __BIG_ENDIAN-\t.tp_ops = &tx4938ide_tp_ops,+\t.tp_ops\t\t\t= &tx4938ide_tp_ops, #endif-\t.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,-\t.pio_mask = ATA_PIO5,+\t.host_flags\t\t= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,+\t.pio_mask\t\t= ATA_PIO5,+\t.chipset\t\t= 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\t/* __LITTLE_ENDIAN */ static const struct ide_port_ops tx4939ide_port_ops = {-\t.set_pio_mode = tx4939ide_set_pio_mode,-\t.set_dma_mode = tx4939ide_set_dma_mode,-\t.clear_irq = tx4939ide_clear_irq,-\t.cable_detect = tx4939ide_cable_detect,+\t.set_pio_mode\t\t= tx4939ide_set_pio_mode,+\t.set_dma_mode\t\t= tx4939ide_set_dma_mode,+\t.clear_irq\t\t= tx4939ide_clear_irq,+\t.cable_detect\t\t= tx4939ide_cable_detect, }; static const struct ide_dma_ops tx4939ide_dma_ops = {-\t.dma_host_set = tx4939ide_dma_host_set,-\t.dma_setup = tx4939ide_dma_setup,-\t.dma_exec_cmd = ide_dma_exec_cmd,-\t.dma_start = ide_dma_start,-\t.dma_end = tx4939ide_dma_end,-\t.dma_test_irq = tx4939ide_dma_test_irq,-\t.dma_lost_irq = ide_dma_lost_irq,-\t.dma_timeout = ide_dma_timeout,+\t.dma_host_set\t\t= tx4939ide_dma_host_set,+\t.dma_setup\t\t= tx4939ide_dma_setup,+\t.dma_exec_cmd\t\t= ide_dma_exec_cmd,+\t.dma_start\t\t= ide_dma_start,+\t.dma_end\t\t= tx4939ide_dma_end,+\t.dma_test_irq\t\t= tx4939ide_dma_test_irq,+\t.dma_lost_irq\t\t= ide_dma_lost_irq,+\t.dma_timeout\t\t= ide_dma_timeout, }; static const struct ide_port_info tx4939ide_port_info __initdata = {-\t.init_hwif = tx4939ide_init_hwif,-\t.init_dma = tx4939ide_init_dma,-\t.port_ops = &tx4939ide_port_ops,-\t.dma_ops = &tx4939ide_dma_ops,-\t.tp_ops = &tx4939ide_tp_ops,-\t.host_flags = IDE_HFLAG_MMIO,-\t.pio_mask = ATA_PIO4,-\t.mwdma_mask = ATA_MWDMA2,-\t.udma_mask = ATA_UDMA5,+\t.init_hwif\t\t= tx4939ide_init_hwif,+\t.init_dma\t\t= tx4939ide_init_dma,+\t.port_ops\t\t= &tx4939ide_port_ops,+\t.dma_ops\t\t= &tx4939ide_dma_ops,+\t.tp_ops\t\t\t= &tx4939ide_tp_ops,+\t.host_flags\t\t= IDE_HFLAG_MMIO,+\t.pio_mask\t\t= ATA_PIO4,+\t.mwdma_mask\t\t= ATA_MWDMA2,+\t.udma_mask\t\t= ATA_UDMA5,+\t.chipset\t\t= 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 \t You also need to say Y here if you have a device which speaks \t the SCSI protocol. Examples of this include the parallel port \t version of the IOMEGA ZIP drive, USB storage devices, Fibre-\t Channel, FireWire storage and the IDE-SCSI emulation driver.+\t Channel, and FireWire storage. \t To compile this driver as a module, choose M here and read \t <file:Documentation/scsi/scsi.txt>.@@ -101,9 +101,9 @@ config CHR_DEV_OSST \t---help--- \t The OnStream SC-x0 SCSI tape drives cannot be driven by the \t standard st driver, but instead need this special osst driver and-\t use the /dev/osstX char device nodes (major 206). Via usb-storage-\t and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives-\t as well. Note that there is also a second generation of OnStream+\t use the /dev/osstX char device nodes (major 206). Via usb-storage,+\t you may be able to drive the USB-x0 and DI-x0 drives as well.+\t Note that there is also a second generation of OnStream \t tape drives (ADR-x0) that supports the standard SCSI-2 commands for \t tapes (QIC-157) and can be driven by the standard driver st. \t 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)\t\t+= gdth.o obj-$(CONFIG_SCSI_INITIO)\t+= initio.o obj-$(CONFIG_SCSI_INIA100)\t+= a100u2w.o obj-$(CONFIG_SCSI_QLOGICPTI)\t+= qlogicpti.o-obj-$(CONFIG_BLK_DEV_IDESCSI)\t+= ide-scsi.o obj-$(CONFIG_SCSI_MESH)\t\t+= mesh.o obj-$(CONFIG_SCSI_MAC53C94)\t+= 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@netvision.net.il>- * 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\t\t0--#if IDESCSI_DEBUG_LOG-#define debug_log(fmt, args...) \\-\tprintk(KERN_INFO \"ide-scsi: \" fmt, ## args)-#else-#define debug_log(fmt, args...) do {} while (0)-#endif--/*- *\tSCSI command transformation layer- */-#define IDESCSI_SG_TRANSFORM\t\t1\t/* /dev/sg transformation */--/*- *\tLog flags- */-#define IDESCSI_LOG_CMD\t\t\t0\t/* Log SCSI commands */--typedef struct ide_scsi_obj {-\tide_drive_t\t\t*drive;-\tide_driver_t\t\t*driver;-\tstruct gendisk\t\t*disk;-\tstruct Scsi_Host\t*host;--\tunsigned long transform;\t\t/* SCSI cmd translation layer */-\tunsigned long log;\t\t\t/* 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) \\-\tcontainer_of((disk)->private_data, struct ide_scsi_obj, driver)--static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)-{-\tstruct ide_scsi_obj *scsi = NULL;--\tmutex_lock(&idescsi_ref_mutex);-\tscsi = ide_scsi_g(disk);-\tif (scsi) {-\t\tif (ide_device_get(scsi->drive))-\t\t\tscsi = NULL;-\t\telse-\t\t\tscsi_host_get(scsi->host);-\t}-\tmutex_unlock(&idescsi_ref_mutex);-\treturn scsi;-}--static void ide_scsi_put(struct ide_scsi_obj *scsi)-{-\tide_drive_t *drive = scsi->drive;--\tmutex_lock(&idescsi_ref_mutex);-\tscsi_host_put(scsi->host);-\tide_device_put(drive);-\tmutex_unlock(&idescsi_ref_mutex);-}--static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)-{-\treturn (idescsi_scsi_t*) (&host[1]);-}--static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)-{-\treturn scsihost_to_idescsi(ide_drive->driver_data);-}--static void ide_scsi_hex_dump(u8 *data, int len)-{-\tprint_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)-{-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive);-\tstruct ide_atapi_pc *pc = drive->pc;--\tif (pc->flags & PC_FLAG_TIMEDOUT)-\t\tdebug_log(\"%s: got timed out packet %lu at %lu\\n\", __func__,-\t\t\t pc->scsi_cmd->serial_number, jiffies);-\t\t/* end this request now - scsi should retry it*/-\telse if (test_bit(IDESCSI_LOG_CMD, &scsi->log))-\t\tprintk(KERN_INFO \"Packet command completed, %d bytes\"-\t\t\t\t \" transferred\\n\", pc->xferred);--\tidescsi_end_request(drive, 1, 0);-}--static int idescsi_check_condition(ide_drive_t *drive,-\t\tstruct request *failed_cmd)-{-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive);-\tstruct ide_atapi_pc *pc;-\tstruct request *rq;-\tu8 *buf;--\t/* stuff a sense request in front of our current request */-\tpc = kzalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);-\trq = blk_get_request(drive->queue, READ, GFP_ATOMIC);-\tbuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);-\tif (!pc || !rq || !buf) {-\t\tkfree(buf);-\t\tif (rq)-\t\t\tblk_put_request(rq);-\t\tkfree(pc);-\t\treturn -ENOMEM;-\t}-\trq->special = (char *) pc;-\tpc->rq = rq;-\tpc->buf = buf;-\tpc->c[0] = REQUEST_SENSE;-\tpc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE;-\trq->cmd_type = REQ_TYPE_SENSE;-\trq->cmd_flags |= REQ_PREEMPT;-\tpc->timeout = jiffies + WAIT_READY;-\t/* NOTE! Save the failed packet command in \"rq->buffer\" */-\trq->buffer = (void *) failed_cmd->special;-\tpc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {-\t\tprintk (\"ide-scsi: %s: queue cmd = \", drive->name);-\t\tide_scsi_hex_dump(pc->c, 6);-\t}-\trq->rq_disk = scsi->disk;-\trq->ref_count++;-\tmemcpy(rq->cmd, pc->c, 12);-\tide_do_drive_cmd(drive, rq);-\treturn 0;-}--static ide_startstop_t-idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)-{-\tide_hwif_t *hwif = drive->hwif;--\tif (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))-\t\t/* force an abort */-\t\thwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);--\trq->errors++;--\tidescsi_end_request(drive, 0, 0);--\treturn ide_stopped;-}--static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)-{-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive);-\tstruct request *rq = HWGROUP(drive)->rq;-\tstruct ide_atapi_pc *pc = (struct ide_atapi_pc *) rq->special;-\tint log = test_bit(IDESCSI_LOG_CMD, &scsi->log);-\tstruct Scsi_Host *host;-\tint errors = rq->errors;-\tunsigned long flags;--\tif (!blk_special_request(rq) && !blk_sense_request(rq)) {-\t\tide_end_request(drive, uptodate, nrsecs);-\t\treturn 0;-\t}-\tide_end_drive_cmd (drive, 0, 0);-\tif (blk_sense_request(rq)) {-\t\tstruct ide_atapi_pc *opc = (struct ide_atapi_pc *) rq->buffer;-\t\tif (log) {-\t\t\tprintk (\"ide-scsi: %s: wrap up check %lu, rst = \", drive->name, opc->scsi_cmd->serial_number);-\t\t\tide_scsi_hex_dump(pc->buf, 16);-\t\t}-\t\tmemcpy((void *) opc->scsi_cmd->sense_buffer, pc->buf,-\t\t\tSCSI_SENSE_BUFFERSIZE);-\t\tkfree(pc->buf);-\t\tkfree(pc);-\t\tblk_put_request(rq);-\t\tpc = opc;-\t\trq = pc->rq;-\t\tpc->scsi_cmd->result = (CHECK_CONDITION << 1) |-\t\t\t\t(((pc->flags & PC_FLAG_TIMEDOUT) ?-\t\t\t\t DID_TIME_OUT :-\t\t\t\t DID_OK) << 16);-\t} else if (pc->flags & PC_FLAG_TIMEDOUT) {-\t\tif (log)-\t\t\tprintk (KERN_WARNING \"ide-scsi: %s: timed out for %lu\\n\",-\t\t\t\t\tdrive->name, pc->scsi_cmd->serial_number);-\t\tpc->scsi_cmd->result = DID_TIME_OUT << 16;-\t} else if (errors >= ERROR_MAX) {-\t\tpc->scsi_cmd->result = DID_ERROR << 16;-\t\tif (log)-\t\t\tprintk (\"ide-scsi: %s: I/O error for %lu\\n\", drive->name, pc->scsi_cmd->serial_number);-\t} else if (errors) {-\t\tif (log)-\t\t\tprintk (\"ide-scsi: %s: check condition for %lu\\n\", drive->name, pc->scsi_cmd->serial_number);-\t\tif (!idescsi_check_condition(drive, rq))-\t\t\t/* we started a request sense, so we'll be back, exit for now */-\t\t\treturn 0;-\t\tpc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);-\t} else {-\t\tpc->scsi_cmd->result = DID_OK << 16;-\t}-\thost = pc->scsi_cmd->device->host;-\tspin_lock_irqsave(host->host_lock, flags);-\tpc->done(pc->scsi_cmd);-\tspin_unlock_irqrestore(host->host_lock, flags);-\tkfree(pc);-\tblk_put_request(rq);-\tdrive->pc = NULL;-\treturn 0;-}--static inline int idescsi_set_direction(struct ide_atapi_pc *pc)-{-\tswitch (pc->c[0]) {-\t\tcase READ_6: case READ_10: case READ_12:-\t\t\tpc->flags &= ~PC_FLAG_WRITING;-\t\t\treturn 0;-\t\tcase WRITE_6: case WRITE_10: case WRITE_12:-\t\t\tpc->flags |= PC_FLAG_WRITING;-\t\t\treturn 0;-\t\tdefault:-\t\t\treturn 1;-\t}-}--static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc)-{-\tide_hwif_t *hwif = drive->hwif;-\tstruct scatterlist *sg, *scsi_sg;-\tint segments;--\tif (!pc->req_xfer || pc->req_xfer % 1024)-\t\treturn 1;--\tif (idescsi_set_direction(pc))-\t\treturn 1;--\tsg = hwif->sg_table;-\tscsi_sg = scsi_sglist(pc->scsi_cmd);-\tsegments = scsi_sg_count(pc->scsi_cmd);--\tif (segments > hwif->sg_max_nents)-\t\treturn 1;--\thwif->sg_nents = segments;-\tmemcpy(sg, scsi_sg, sizeof(*sg) * segments);--\treturn 0;-}--static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,-\t\tstruct ide_atapi_pc *pc)-{-\t/* Set the current packet command */-\tdrive->pc = pc;--\treturn ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry);-}--/*- *\tidescsi_do_request is our request handling function.- */-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)-{-\tdebug_log(\"dev: %s, cmd: %x, errors: %d\\n\", rq->rq_disk->disk_name,-\t\t rq->cmd[0], rq->errors);-\tdebug_log(\"sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\\n\",-\t\t rq->sector, rq->nr_sectors, rq->current_nr_sectors);--\tif (blk_sense_request(rq) || blk_special_request(rq)) {-\t\tstruct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;--\t\tif ((drive->dev_flags & IDE_DFLAG_USING_DMA) &&-\t\t idescsi_map_sg(drive, pc) == 0)-\t\t\tpc->flags |= PC_FLAG_DMA_OK;--\t\treturn idescsi_issue_pc(drive, pc);-\t}-\tblk_dump_rq_flags(rq, \"ide-scsi: unsup command\");-\tidescsi_end_request (drive, 0, 0);-\treturn ide_stopped;-}--#ifdef CONFIG_IDE_PROC_FS-static ide_proc_entry_t idescsi_proc[] = {-\t{ \"capacity\", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },-\t{ NULL, 0, NULL, NULL }-};--#define ide_scsi_devset_get(name, field) \\-static int get_##name(ide_drive_t *drive) \\-{ \\-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive); \\-\treturn scsi->field; \\-}--#define ide_scsi_devset_set(name, field) \\-static int set_##name(ide_drive_t *drive, int arg) \\-{ \\-\tidescsi_scsi_t *scsi = drive_to_idescsi(drive); \\-\tscsi->field = arg; \\-\treturn 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[] = {-\tIDE_PROC_DEVSET(bios_cyl, 0, 1023),-\tIDE_PROC_DEVSET(bios_head, 0, 255),-\tIDE_PROC_DEVSET(bios_sect, 0,\t63),-\tIDE_PROC_DEVSET(log,\t 0,\t 1),-\tIDE_PROC_DEVSET(transform, 0,\t 3),-\t{ 0 },-};--static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive)-{-\treturn idescsi_proc;-}--static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive)-{-\treturn idescsi_settings;-}-#endif--/*- *\tDriver initialization.- */-static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)-{-\tclear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);-#if IDESCSI_DEBUG_LOG-\tset_bit(IDESCSI_LOG_CMD, &scsi->log);-#endif /* IDESCSI_DEBUG_LOG */--\tdrive->pc_callback\t = ide_scsi_callback;-\tdrive->pc_update_buffers = NULL;-\tdrive->pc_io_buffers\t = ide_io_buffers;--\tide_proc_register_driver(drive, scsi->driver);-}--static void ide_scsi_remove(ide_drive_t *drive)-{-\tstruct Scsi_Host *scsihost = drive->driver_data;-\tstruct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);-\tstruct gendisk *g = scsi->disk;--\tscsi_remove_host(scsihost);-\tide_proc_unregister_driver(drive, scsi->driver);--\tide_unregister_region(g);--\tdrive->driver_data = NULL;-\tg->private_data = NULL;-\tput_disk(g);--\tide_scsi_put(scsi);--\tdrive->dev_flags &= ~IDE_DFLAG_SCSI;-}--static int ide_scsi_probe(ide_drive_t *);--static ide_driver_t idescsi_driver = {-\t.gen_driver = {-\t\t.owner\t\t= THIS_MODULE,-\t\t.name\t\t= \"ide-scsi\",-\t\t.bus\t\t= &ide_bus_type,-\t},-\t.probe\t\t\t= ide_scsi_probe,-\t.remove\t\t\t= ide_scsi_remove,-\t.version\t\t= IDESCSI_VERSION,-\t.do_request\t\t= idescsi_do_request,-\t.end_request\t\t= idescsi_end_request,-\t.error = idescsi_atapi_error,-#ifdef CONFIG_IDE_PROC_FS-\t.proc_entries\t\t= ide_scsi_proc_entries,-\t.proc_devsets\t\t= ide_scsi_proc_devsets,-#endif-};--static int idescsi_ide_open(struct block_device *bdev, fmode_t mode)-{-\tstruct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk);--\tif (!scsi)-\t\treturn -ENXIO;--\treturn 0;-}--static int idescsi_ide_release(struct gendisk *disk, fmode_t mode)-{-\tide_scsi_put(ide_scsi_g(disk));-\treturn 0;-}--static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode,-\t\t\tunsigned int cmd, unsigned long arg)-{-\tstruct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk);-\treturn generic_ide_ioctl(scsi->drive, bdev, cmd, arg);-}--static struct block_device_operations idescsi_ops = {-\t.owner\t\t= THIS_MODULE,-\t.open\t\t= idescsi_ide_open,-\t.release\t= idescsi_ide_release,-\t.locked_ioctl\t= idescsi_ide_ioctl,-};--static int idescsi_slave_configure(struct scsi_device * sdp)-{-\t/* Configure detected device */-\tsdp->use_10_for_rw = 1;-\tsdp->use_10_for_ms = 1;-\tscsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);-\treturn 0;-}--static const char *idescsi_info (struct Scsi_Host *host)-{-\treturn \"SCSI host adapter emulation for IDE ATAPI devices\";-}--static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)-{-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host);--\tif (cmd == SG_SET_TRANSFORM) {-\t\tif (arg)-\t\t\tset_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);-\t\telse-\t\t\tclear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);-\t\treturn 0;-\t} else if (cmd == SG_GET_TRANSFORM)-\t\treturn put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg);-\treturn -EINVAL;-}--static int idescsi_queue (struct scsi_cmnd *cmd,-\t\tvoid (*done)(struct scsi_cmnd *))-{-\tstruct Scsi_Host *host = cmd->device->host;-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(host);-\tide_drive_t *drive = scsi->drive;-\tstruct request *rq = NULL;-\tstruct ide_atapi_pc *pc = NULL;-\tint write = cmd->sc_data_direction == DMA_TO_DEVICE;--\tif (!drive) {-\t\tscmd_printk (KERN_ERR, cmd, \"drive not present\\n\");-\t\tgoto abort;-\t}-\tscsi = drive_to_idescsi(drive);-\tpc = kmalloc(sizeof(struct ide_atapi_pc), GFP_ATOMIC);-\trq = blk_get_request(drive->queue, write, GFP_ATOMIC);-\tif (rq == NULL || pc == NULL) {-\t\tprintk (KERN_ERR \"ide-scsi: %s: out of memory\\n\", drive->name);-\t\tgoto abort;-\t}--\tmemset (pc->c, 0, 12);-\tpc->flags = 0;-\tif (cmd->sc_data_direction == DMA_TO_DEVICE)-\t\tpc->flags |= PC_FLAG_WRITING;-\tpc->rq = rq;-\tmemcpy (pc->c, cmd->cmnd, cmd->cmd_len);-\tpc->buf = NULL;-\tpc->sg = scsi_sglist(cmd);-\tpc->sg_cnt = scsi_sg_count(cmd);-\tpc->b_count = 0;-\tpc->req_xfer = pc->buf_size = scsi_bufflen(cmd);-\tpc->scsi_cmd = cmd;-\tpc->done = done;-\tpc->timeout = jiffies + cmd->request->timeout;--\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {-\t\tprintk (\"ide-scsi: %s: que %lu, cmd = \", drive->name, cmd->serial_number);-\t\tide_scsi_hex_dump(cmd->cmnd, cmd->cmd_len);-\t\tif (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) {-\t\t\tprintk (\"ide-scsi: %s: que %lu, tsl = \", drive->name, cmd->serial_number);-\t\t\tide_scsi_hex_dump(pc->c, 12);-\t\t}-\t}--\trq->special = (char *) pc;-\trq->cmd_type = REQ_TYPE_SPECIAL;-\tspin_unlock_irq(host->host_lock);-\trq->ref_count++;-\tmemcpy(rq->cmd, pc->c, 12);-\tblk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);-\tspin_lock_irq(host->host_lock);-\treturn 0;-abort:-\tkfree (pc);-\tif (rq)-\t\tblk_put_request(rq);-\tcmd->result = DID_ERROR << 16;-\tdone(cmd);-\treturn 0;-}--static int idescsi_eh_abort (struct scsi_cmnd *cmd)-{-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host);-\tide_drive_t *drive = scsi->drive;-\tide_hwif_t *hwif;-\tide_hwgroup_t *hwgroup;-\tint\t\tbusy;-\tint ret = FAILED;--\tstruct ide_atapi_pc *pc;--\t/* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */--\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))-\t\tprintk (KERN_WARNING \"ide-scsi: abort called for %lu\\n\", cmd->serial_number);--\tif (!drive) {-\t\tprintk (KERN_WARNING \"ide-scsi: Drive not set in idescsi_eh_abort\\n\");-\t\tWARN_ON(1);-\t\tgoto no_drive;-\t}--\thwif = drive->hwif;-\thwgroup = hwif->hwgroup;--\t/* First give it some more time, how much is \"right\" is hard to say :-(-\t FIXME - uses mdelay which causes latency? */-\tbusy = ide_wait_not_busy(hwif, 100);-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))-\t\tprintk (KERN_WARNING \"ide-scsi: drive did%s become ready\\n\", busy?\" not\":\"\");--\tspin_lock_irq(&hwgroup->lock);--\t/* If there is no pc running we're done (our interrupt took care of it) */-\tpc = drive->pc;-\tif (pc == NULL) {-\t\tret = SUCCESS;-\t\tgoto ide_unlock;-\t}--\t/* It's somewhere in flight. Does ide subsystem agree? */-\tif (pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&-\t elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) {-\t\t/*-\t\t * FIXME - not sure this condition can ever occur-\t\t */-\t\tprintk (KERN_ERR \"ide-scsi: cmd aborted!\\n\");--\t\tif (blk_sense_request(pc->rq))-\t\t\tkfree(pc->buf);-\t\t/* we need to call blk_put_request twice. */-\t\tblk_put_request(pc->rq);-\t\tblk_put_request(pc->rq);-\t\tkfree(pc);-\t\tdrive->pc = NULL;--\t\tret = SUCCESS;-\t}--ide_unlock:-\tspin_unlock_irq(&hwgroup->lock);-no_drive:-\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))-\t\tprintk (KERN_WARNING \"ide-scsi: abort returns %s\\n\", ret == SUCCESS?\"success\":\"failed\");--\treturn ret;-}--static int idescsi_eh_reset (struct scsi_cmnd *cmd)-{-\tstruct request *req;-\tidescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host);-\tide_drive_t *drive = scsi->drive;-\tide_hwgroup_t *hwgroup;-\tint ready = 0;-\tint ret = SUCCESS;--\tstruct ide_atapi_pc *pc;--\t/* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */--\tif (test_bit(IDESCSI_LOG_CMD, &scsi->log))-\t\tprintk (KERN_WARNING \"ide-scsi: reset called for %lu\\n\", cmd->serial_number);--\tif (!drive) {-\t\tprintk (KERN_WARNING \"ide-scsi: Drive not set in idescsi_eh_reset\\n\");-\t\tWARN_ON(1);-\t\treturn FAILED;-\t}--\thwgroup = drive->hwif->hwgroup;--\tspin_lock_irq(cmd->device->host->host_lock);-\tspin_lock(&hwgroup->lock);--\tpc = drive->pc;-\tif (pc)-\t\treq = pc->rq;--\tif (pc == NULL || req != hwgroup->rq || hwgroup->handler == NULL) {-\t\tprintk (KERN_WARNING \"ide-scsi: No active request in idescsi_eh_reset\\n\");-\t\tspin_unlock(&hwgroup->lock);-\t\tspin_unlock_irq(cmd->device->host->host_lock);-\t\treturn FAILED;-\t}--\t/* kill current request */-\tif (__blk_end_request(req, -EIO, 0))-\t\tBUG();-\tif (blk_sense_request(req))-\t\tkfree(pc->buf);-\tkfree(pc);-\tdrive->pc = NULL;-\tblk_put_request(req);--\t/* now nuke the drive queue */-\twhile ((req = elv_next_request(drive->queue))) {-\t\tif (__blk_end_request(req, -EIO, 0))-\t\t\tBUG();-\t}--\thwgroup->rq = NULL;-\thwgroup->handler = NULL;-\thwgroup->busy = 1; /* will set this to zero when ide reset finished */-\tspin_unlock(&hwgroup->lock);--\tide_do_reset(drive);--\t/* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */--\tdo {-\t\tspin_unlock_irq(cmd->device->host->host_lock);-\t\tmsleep(50);-\t\tspin_lock_irq(cmd->device->host->host_lock);-\t} while ( HWGROUP(drive)->handler );--\tready = drive_is_ready(drive);-\tHWGROUP(drive)->busy--;-\tif (!ready) {-\t\tprintk (KERN_ERR \"ide-scsi: reset failed!\\n\");-\t\tret = FAILED;-\t}--\tspin_unlock_irq(cmd->device->host->host_lock);-\treturn ret;-}--static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,-\t\tsector_t capacity, int *parm)-{-\tidescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host);-\tide_drive_t *drive = idescsi->drive;--\tif (drive->bios_cyl && drive->bios_head && drive->bios_sect) {-\t\tparm[0] = drive->bios_head;-\t\tparm[1] = drive->bios_sect;-\t\tparm[2] = drive->bios_cyl;-\t}-\treturn 0;-}--static struct scsi_host_template idescsi_template = {-\t.module\t\t\t= THIS_MODULE,-\t.name\t\t\t= \"idescsi\",-\t.info\t\t\t= idescsi_info,-\t.slave_configure = idescsi_slave_configure,-\t.ioctl\t\t\t= idescsi_ioctl,-\t.queuecommand\t\t= idescsi_queue,-\t.eh_abort_handler\t= idescsi_eh_abort,-\t.eh_host_reset_handler = idescsi_eh_reset,-\t.bios_param\t\t= idescsi_bios,-\t.can_queue\t\t= 40,-\t.this_id\t\t= -1,-\t.sg_tablesize\t\t= 256,-\t.cmd_per_lun\t\t= 5,-\t.max_sectors\t\t= 128,-\t.use_clustering\t\t= DISABLE_CLUSTERING,-\t.emulated\t\t= 1,-\t.proc_name\t\t= \"ide-scsi\",-};--static int ide_scsi_probe(ide_drive_t *drive)-{-\tidescsi_scsi_t *idescsi;-\tstruct Scsi_Host *host;-\tstruct gendisk *g;-\tstatic int warned;-\tint err = -ENOMEM;-\tu16 last_lun;--\tif (!warned && drive->media == ide_cdrom) {-\t\tprintk(KERN_WARNING \"ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\\n\");-\t\twarned = 1;-\t}--\tif (idescsi_nocd && drive->media == ide_cdrom)-\t\treturn -ENODEV;--\tif (!strstr(\"ide-scsi\", drive->driver_req) ||-\t drive->media == ide_disk ||-\t !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))-\t\treturn -ENODEV;--\tdrive->dev_flags |= IDE_DFLAG_SCSI;--\tg = alloc_disk(1 << PARTN_BITS);-\tif (!g)-\t\tgoto out_host_put;--\tide_init_disk(g, drive);--\thost->max_id = 1;--\tlast_lun = drive->id[ATA_ID_LAST_LUN];-\tif (last_lun)-\t\tdebug_log(\"%s: last_lun=%u\\n\", drive->name, last_lun);--\tif ((last_lun & 7) != 7)-\t\thost->max_lun = (last_lun & 7) + 1;-\telse-\t\thost->max_lun = 1;--\tdrive->driver_data = host;-\tidescsi = scsihost_to_idescsi(host);-\tidescsi->drive = drive;-\tidescsi->driver = &idescsi_driver;-\tidescsi->host = host;-\tidescsi->disk = g;-\tg->private_data = &idescsi->driver;-\terr = 0;-\tidescsi_setup(drive, idescsi);-\tg->fops = &idescsi_ops;-\tide_register_region(g);-\terr = scsi_add_host(host, &drive->gendev);-\tif (!err) {-\t\tscsi_scan_host(host);-\t\treturn 0;-\t}-\t/* fall through on error */-\tide_unregister_region(g);-\tide_proc_unregister_driver(drive, &idescsi_driver);--\tput_disk(g);-out_host_put:-\tdrive->dev_flags &= ~IDE_DFLAG_SCSI;-\tscsi_host_put(host);-\treturn err;-}--static int __init init_idescsi_module(void)-{-\treturn driver_register(&idescsi_driver.gen_driver);-}--static void __exit exit_idescsi_module(void)-{-\tdriver_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\t\t(-1)- typedef unsigned char\tbyte;\t/* used everywhere */ /*@@ -403,6 +396,7 @@ enum { * This is used for several packet commands (not for READ/WRITE commands). */ #define IDE_PC_BUFFER_SIZE\t256+#define ATAPI_WAIT_PC\t\t(60 * HZ) struct ide_atapi_pc { \t/* actual packet bytes */@@ -480,53 +474,53 @@ enum { \t/* ide-cd */ \t/* Drive cannot eject the disc. */-\tIDE_AFLAG_NO_EJECT\t\t= (1 << 3),+\tIDE_AFLAG_NO_EJECT\t\t= (1 << 1), \t/* Drive is a pre ATAPI 1.2 drive. */-\tIDE_AFLAG_PRE_ATAPI12\t\t= (1 << 4),+\tIDE_AFLAG_PRE_ATAPI12\t\t= (1 << 2), \t/* TOC addresses are in BCD. */-\tIDE_AFLAG_TOCADDR_AS_BCD\t= (1 << 5),+\tIDE_AFLAG_TOCADDR_AS_BCD\t= (1 << 3), \t/* TOC track numbers are in BCD. */-\tIDE_AFLAG_TOCTRACKS_AS_BCD\t= (1 << 6),+\tIDE_AFLAG_TOCTRACKS_AS_BCD\t= (1 << 4), \t/* \t * Drive does not provide data in multiples of SECTOR_SIZE \t * when more than one interrupt is needed. \t */-\tIDE_AFLAG_LIMIT_NFRAMES\t\t= (1 << 7),+\tIDE_AFLAG_LIMIT_NFRAMES\t\t= (1 << 5), \t/* Saved TOC information is current. */-\tIDE_AFLAG_TOC_VALID\t\t= (1 << 9),+\tIDE_AFLAG_TOC_VALID\t\t= (1 << 6), \t/* We think that the drive door is locked. */-\tIDE_AFLAG_DOOR_LOCKED\t\t= (1 << 10),+\tIDE_AFLAG_DOOR_LOCKED\t\t= (1 << 7), \t/* SET_CD_SPEED command is unsupported. */-\tIDE_AFLAG_NO_SPEED_SELECT\t= (1 << 11),-\tIDE_AFLAG_VERTOS_300_SSD\t= (1 << 12),-\tIDE_AFLAG_VERTOS_600_ESD\t= (1 << 13),-\tIDE_AFLAG_SANYO_3CD\t\t= (1 << 14),-\tIDE_AFLAG_FULL_CAPS_PAGE\t= (1 << 15),-\tIDE_AFLAG_PLAY_AUDIO_OK\t\t= (1 << 16),-\tIDE_AFLAG_LE_SPEED_FIELDS\t= (1 << 17),+\tIDE_AFLAG_NO_SPEED_SELECT\t= (1 << 8),+\tIDE_AFLAG_VERTOS_300_SSD\t= (1 << 9),+\tIDE_AFLAG_VERTOS_600_ESD\t= (1 << 10),+\tIDE_AFLAG_SANYO_3CD\t\t= (1 << 11),+\tIDE_AFLAG_FULL_CAPS_PAGE\t= (1 << 12),+\tIDE_AFLAG_PLAY_AUDIO_OK\t\t= (1 << 13),+\tIDE_AFLAG_LE_SPEED_FIELDS\t= (1 << 14), \t/* ide-floppy */ \t/* Avoid commands not supported in Clik drive */-\tIDE_AFLAG_CLIK_DRIVE\t\t= (1 << 19),+\tIDE_AFLAG_CLIK_DRIVE\t\t= (1 << 15), \t/* Requires BH algorithm for packets */-\tIDE_AFLAG_ZIP_DRIVE\t\t= (1 << 20),+\tIDE_AFLAG_ZIP_DRIVE\t\t= (1 << 16), \t/* Supports format progress report */-\tIDE_AFLAG_SRFP\t\t\t= (1 << 22),+\tIDE_AFLAG_SRFP\t\t\t= (1 << 17), \t/* ide-tape */-\tIDE_AFLAG_IGNORE_DSC\t\t= (1 << 23),+\tIDE_AFLAG_IGNORE_DSC\t\t= (1 << 18), \t/* 0 When the tape position is unknown */-\tIDE_AFLAG_ADDRESS_VALID\t\t= (1 <<\t24),+\tIDE_AFLAG_ADDRESS_VALID\t\t= (1 <<\t19), \t/* Device already opened */-\tIDE_AFLAG_BUSY\t\t\t= (1 << 25),+\tIDE_AFLAG_BUSY\t\t\t= (1 << 20), \t/* Attempt to auto-detect the current user block size */-\tIDE_AFLAG_DETECT_BS\t\t= (1 << 26),+\tIDE_AFLAG_DETECT_BS\t\t= (1 << 21), \t/* Currently on a filemark */-\tIDE_AFLAG_FILEMARK\t\t= (1 << 27),+\tIDE_AFLAG_FILEMARK\t\t= (1 << 22), \t/* 0 = no tape is loaded, so we don't rewind after ejecting */-\tIDE_AFLAG_MEDIUM_PRESENT\t= (1 << 28),+\tIDE_AFLAG_MEDIUM_PRESENT\t= (1 << 23), -\tIDE_AFLAG_NO_AUTOCLOSE\t\t= (1 << 29),+\tIDE_AFLAG_NO_AUTOCLOSE\t\t= (1 << 24), }; /* device flags */@@ -565,28 +559,26 @@ enum { \tIDE_DFLAG_NODMA\t\t\t= (1 << 16), \t/* powermanagment told us not to do anything, so sleep nicely */ \tIDE_DFLAG_BLOCKED\t\t= (1 << 17),-\t/* ide-scsi emulation */-\tIDE_DFLAG_SCSI\t\t\t= (1 << 18), \t/* sleeping & sleep field valid */-\tIDE_DFLAG_SLEEPING\t\t= (1 << 19),-\tIDE_DFLAG_POST_RESET\t\t= (1 << 20),-\tIDE_DFLAG_UDMA33_WARNED\t\t= (1 << 21),-\tIDE_DFLAG_LBA48\t\t\t= (1 << 22),+\tIDE_DFLAG_SLEEPING\t\t= (1 << 18),+\tIDE_DFLAG_POST_RESET\t\t= (1 << 19),+\tIDE_DFLAG_UDMA33_WARNED\t\t= (1 << 20),+\tIDE_DFLAG_LBA48\t\t\t= (1 << 21), \t/* status of write cache */-\tIDE_DFLAG_WCACHE\t\t= (1 << 23),+\tIDE_DFLAG_WCACHE\t\t= (1 << 22), \t/* used for ignoring ATA_DF */-\tIDE_DFLAG_NOWERR\t\t= (1 << 24),+\tIDE_DFLAG_NOWERR\t\t= (1 << 23), \t/* retrying in PIO */-\tIDE_DFLAG_DMA_PIO_RETRY\t\t= (1 << 25),-\tIDE_DFLAG_LBA\t\t\t= (1 << 26),+\tIDE_DFLAG_DMA_PIO_RETRY\t\t= (1 << 24),+\tIDE_DFLAG_LBA\t\t\t= (1 << 25), \t/* don't unload heads */-\tIDE_DFLAG_NO_UNLOAD\t\t= (1 << 27),+\tIDE_DFLAG_NO_UNLOAD\t\t= (1 << 26), \t/* heads unloaded, please don't reset port */-\tIDE_DFLAG_PARKED\t\t= (1 << 28),-\tIDE_DFLAG_MEDIA_CHANGED\t\t= (1 << 29),+\tIDE_DFLAG_PARKED\t\t= (1 << 27),+\tIDE_DFLAG_MEDIA_CHANGED\t\t= (1 << 28), \t/* write protect */-\tIDE_DFLAG_WP\t\t\t= (1 << 30),-\tIDE_DFLAG_FORMAT_IN_PROGRESS\t= (1 << 31),+\tIDE_DFLAG_WP\t\t\t= (1 << 29),+\tIDE_DFLAG_FORMAT_IN_PROGRESS\t= (1 << 30), }; struct ide_drive_s {@@ -610,8 +602,6 @@ struct ide_drive_s { \tunsigned long dev_flags; \tunsigned long sleep;\t\t/* sleep until this time */-\tunsigned long service_start;\t/* time we started last request */-\tunsigned long service_time;\t/* service time of last request */ \tunsigned long timeout;\t\t/* max time to wait for irq */ \tspecial_t\tspecial;\t/* special action flags */@@ -879,8 +869,6 @@ typedef struct hwgroup_s { \t\t/* BOOL: protects all fields below */ \tvolatile int busy;-\t\t/* BOOL: wake us up on timer expiry */-\tunsigned int sleeping\t: 1; \t\t/* BOOL: polling active & poll_timeout field valid */ \tunsigned int polling\t: 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)-{-\treturn 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)+{+\tif (hwgroup->busy)+\t\treturn 1;++\thwgroup->busy = 1;+\t/* for atari only */+\tide_get_lock(ide_intr, hwgroup);++\treturn 0;+}++static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)+{+\t/* for atari only */+\tide_release_lock();+\thwgroup->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)\tdo { 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; \0\303\277\303\264\303\250\302\272{.n\303\207+\302\211\302\267\302\237\302\256\302\211\302\255\302\206+%\302\212\303\213\303\277\302\261\303\251\303\235\302\266\027\302\245\302\212w\303\277\302\272{.n\303\207+\302\211\302\267\302\245\302\212{\302\261\303\276G\302\253\302\235\303\251\303\277\302\212{ay\302\272\035\303\212\302\207\303\232\302\231\303\253,j\a\302\255\302\242f\302\243\302\242\302\267h\302\232\302\217\303\257\302\201\303\252\303\277\302\221\303\252\303\247z_\303\250\302\256\003(\302\255\303\251\302\232\302\216\302\212\303\235\302\242j\"\302\235\303\272\032\302\266\033m\302\247\303\277\303\277\302\276\a\302\253\303\276G\302\253\302\235\303\251\303\277\302\242\302\270?\302\231\302\250\303\250\302\255\303\232&\302\243\303\270\302\247~\302\217\303\241\302\266iO\302\225\303\246\302\254z\302\267\302\232v\303\230^\024\004\032\302\266\033m\302\247\303\277\303\277\303\203\f\303\277\302\266\303\254\303\277\302\242\302\270?\302\226I\302\245" -654e17b9cfae547080b2d99d18bc71f7d15b4d7b0b783289f190667cef38e157 +656c52b145847038c1c759a205542dbd48acbc608791b3b53a567ea1faa0cb44
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.