提交 2640c9a9 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (32 commits)
  ide-atapi: start dma in a drive-specific way
  ide-atapi: put the rest of non-ide-cd code into the else-clause of ide_transfer_pc
  ide-atapi: remove timeout arg to ide_issue_pc
  ide-cd: remove handler wrappers
  ide-cd: remove xferlen arg to cdrom_start_packet_command
  ide-atapi: split drive-specific functionality in ide_issue_pc
  ide-atapi: assign expiry and timeout based on device type
  ide-atapi: compute cmd_len based on device type in ide_transfer_pc
  ide: remove the last ide-scsi remnants
  ide-atapi: remove ide-scsi remnants from ide_pc_intr()
  ide-atapi: remove ide-scsi remnants from ide_transfer_pc()
  ide-atapi: remove ide-scsi remnants from ide_issue_pc
  ide-cd: move cdrom_timer_expiry to ide-atapi.c
  ide-atapi: teach ide atapi about drive->waiting_for_dma
  ide-atapi: accomodate transfer length calculation for ide-cd
  ide-atapi: setup dma for ide-cd
  ide-atapi: combine drive-specific assignments
  ide-atapi: add a dev_is_idecd-inline
  remove ide-scsi
  ide-floppy: allocate only toplevel packet commands
  ...
......@@ -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
......
......@@ -2152,11 +2152,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
......
......@@ -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
......
......@@ -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
......
......@@ -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 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
"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 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
} 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 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
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);
......
......@@ -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 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
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)
{
......@@ -760,20 +723,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
return ide_started;
}
/*
* 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);
}
/*
......
......@@ -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)
/************************************************************************/
......
......@@ -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;
}
......
......@@ -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 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
* 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;
......
......@@ -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 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
* 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 @@ static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
* 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 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
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 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
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;
}
......
......@@ -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)
......
......@@ -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);
......
......@@ -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);
}
......
#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;
}
......@@ -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. */
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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)
......
......@@ -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
......
......@@ -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
......
此差异已折叠。
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册