Commit 27951daa authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6

* 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (28 commits)
  ide-tape: fix debug call
  alim15x3: Remove historical hacks, re-enable init_hwif for PowerPC
  ide-dma: don't reset request fields on dma_timeout_retry()
  ide: drop rq->data handling from ide_map_sg()
  ide-atapi: kill unused fields and callbacks
  ide-tape: simplify read/write functions
  ide-tape: use byte size instead of sectors on rw issue functions
  ide-tape: unify r/w init paths
  ide-tape: kill idetape_bh
  ide-tape: use standard data transfer mechanism
  ide-tape: use single continuous buffer
  ide-atapi,tape,floppy: allow ->pc_callback() to change rq->data_len
  ide-tape,floppy: fix failed command completion after request sense
  ide-pm: don't abuse rq->data
  ide-cd,atapi: use bio for internal commands
  ide-atapi: convert ide-{floppy,tape} to using preallocated sense buffer
  ide-cd: convert to using generic sense request
  ide: add helpers for preparing sense requests
  ide-cd: don't abuse rq->buffer
  ide-atapi: don't abuse rq->buffer
  ...
parents 59c288ff e8e7526c
...@@ -1732,10 +1732,14 @@ static int __end_that_request_first(struct request *req, int error, ...@@ -1732,10 +1732,14 @@ static int __end_that_request_first(struct request *req, int error,
trace_block_rq_complete(req->q, req); trace_block_rq_complete(req->q, req);
/* /*
* for a REQ_TYPE_BLOCK_PC request, we want to carry any eventual * For fs requests, rq is just carrier of independent bio's
* sense key with us all the way through * and each partial completion should be handled separately.
* Reset per-request error on each partial completion.
*
* TODO: tj: This is too subtle. It would be better to let
* low level drivers do what they see fit.
*/ */
if (!blk_pc_request(req)) if (blk_fs_request(req))
req->errors = 0; req->errors = 0;
if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) { if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) {
......
...@@ -402,27 +402,23 @@ static u8 ali_cable_detect(ide_hwif_t *hwif) ...@@ -402,27 +402,23 @@ static u8 ali_cable_detect(ide_hwif_t *hwif)
return cbl; return cbl;
} }
#if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) #ifndef CONFIG_SPARC64
/** /**
* init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
* @hwif: interface to configure * @hwif: interface to configure
* *
* Obtain the IRQ tables for an ALi based IDE solution on the PC * Obtain the IRQ tables for an ALi based IDE solution on the PC
* class platforms. This part of the code isn't applicable to the * class platforms. This part of the code isn't applicable to the
* Sparc and PowerPC systems. * Sparc systems.
*/ */
static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
{ {
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 ideic, inmir; u8 ideic, inmir;
s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
1, 11, 0, 12, 0, 14, 0, 15 }; 1, 11, 0, 12, 0, 14, 0, 15 };
int irq = -1; int irq = -1;
if (dev->device == PCI_DEVICE_ID_AL_M5229)
hwif->irq = hwif->channel ? 15 : 14;
if (isa_dev) { if (isa_dev) {
/* /*
* read IDE interface control * read IDE interface control
...@@ -455,7 +451,7 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) ...@@ -455,7 +451,7 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
} }
#else #else
#define init_hwif_ali15x3 NULL #define init_hwif_ali15x3 NULL
#endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */ #endif /* CONFIG_SPARC64 */
/** /**
* init_dma_ali15x3 - set up DMA on ALi15x3 * init_dma_ali15x3 - set up DMA on ALi15x3
......
...@@ -79,34 +79,6 @@ void ide_init_pc(struct ide_atapi_pc *pc) ...@@ -79,34 +79,6 @@ void ide_init_pc(struct ide_atapi_pc *pc)
} }
EXPORT_SYMBOL_GPL(ide_init_pc); EXPORT_SYMBOL_GPL(ide_init_pc);
/*
* Generate a new packet command request in front of the request queue, before
* the current request, so that it will be processed immediately, on the next
* pass through the driver.
*/
static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
struct ide_atapi_pc *pc, struct request *rq)
{
blk_rq_init(NULL, rq);
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd_flags |= REQ_PREEMPT;
rq->buffer = (char *)pc;
rq->rq_disk = disk;
if (pc->req_xfer) {
rq->data = pc->buf;
rq->data_len = pc->req_xfer;
}
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
drive->hwif->rq = NULL;
elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
/* /*
* Add a special packet command request to the tail of the request queue, * Add a special packet command request to the tail of the request queue,
* and wait for it to be serviced. * and wait for it to be serviced.
...@@ -119,19 +91,21 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, ...@@ -119,19 +91,21 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_type = REQ_TYPE_SPECIAL;
rq->buffer = (char *)pc; rq->special = (char *)pc;
if (pc->req_xfer) { if (pc->req_xfer) {
rq->data = pc->buf; error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer,
rq->data_len = pc->req_xfer; GFP_NOIO);
if (error)
goto put_req;
} }
memcpy(rq->cmd, pc->c, 12); memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape) if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1; rq->cmd[13] = REQ_IDETAPE_PC1;
error = blk_execute_rq(drive->queue, disk, rq, 0); error = blk_execute_rq(drive->queue, disk, rq, 0);
put_req:
blk_put_request(rq); blk_put_request(rq);
return error; return error;
} }
EXPORT_SYMBOL_GPL(ide_queue_pc_tail); EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
...@@ -191,20 +165,103 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) ...@@ -191,20 +165,103 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
} }
EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
void ide_prep_sense(ide_drive_t *drive, struct request *rq)
{
struct request_sense *sense = &drive->sense_data;
struct request *sense_rq = &drive->sense_rq;
unsigned int cmd_len, sense_len;
int err;
debug_log("%s: enter\n", __func__);
switch (drive->media) {
case ide_floppy:
cmd_len = 255;
sense_len = 18;
break;
case ide_tape:
cmd_len = 20;
sense_len = 20;
break;
default:
cmd_len = 18;
sense_len = 18;
}
BUG_ON(sense_len > sizeof(*sense));
if (blk_sense_request(rq) || drive->sense_rq_armed)
return;
memset(sense, 0, sizeof(*sense));
blk_rq_init(rq->q, sense_rq);
err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
GFP_NOIO);
if (unlikely(err)) {
if (printk_ratelimit())
printk(KERN_WARNING "%s: failed to map sense buffer\n",
drive->name);
return;
}
sense_rq->rq_disk = rq->rq_disk;
sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
sense_rq->cmd[4] = cmd_len;
sense_rq->cmd_type = REQ_TYPE_SENSE;
sense_rq->cmd_flags |= REQ_PREEMPT;
if (drive->media == ide_tape)
sense_rq->cmd[13] = REQ_IDETAPE_PC1;
drive->sense_rq_armed = true;
}
EXPORT_SYMBOL_GPL(ide_prep_sense);
int ide_queue_sense_rq(ide_drive_t *drive, void *special)
{
/* deferred failure from ide_prep_sense() */
if (!drive->sense_rq_armed) {
printk(KERN_WARNING "%s: failed queue sense request\n",
drive->name);
return -ENOMEM;
}
drive->sense_rq.special = special;
drive->sense_rq_armed = false;
drive->hwif->rq = NULL;
elv_add_request(drive->queue, &drive->sense_rq,
ELEVATOR_INSERT_FRONT, 0);
return 0;
}
EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
/* /*
* Called when an error was detected during the last packet command. * Called when an error was detected during the last packet command.
* We queue a request sense packet command in the head of the request list. * We queue a request sense packet command at the head of the request
* queue.
*/ */
void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) void ide_retry_pc(ide_drive_t *drive)
{ {
struct request *rq = &drive->request_sense_rq; struct request *sense_rq = &drive->sense_rq;
struct ide_atapi_pc *pc = &drive->request_sense_pc; struct ide_atapi_pc *pc = &drive->request_sense_pc;
(void)ide_read_error(drive); (void)ide_read_error(drive);
ide_create_request_sense_cmd(drive, pc);
/* init pc from sense_rq */
ide_init_pc(pc);
memcpy(pc->c, sense_rq->cmd, 12);
pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */
pc->req_xfer = sense_rq->data_len;
if (drive->media == ide_tape) if (drive->media == ide_tape)
set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
ide_queue_pc_head(drive, disk, pc, rq);
if (ide_queue_sense_rq(drive, pc))
ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq));
} }
EXPORT_SYMBOL_GPL(ide_retry_pc); EXPORT_SYMBOL_GPL(ide_retry_pc);
...@@ -276,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -276,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
struct ide_cmd *cmd = &hwif->cmd; struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq; struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops; const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
unsigned int timeout, done; unsigned int timeout, done;
u16 bcount; u16 bcount;
u8 stat, ireason, dsc = 0; u8 stat, ireason, dsc = 0;
...@@ -303,11 +359,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -303,11 +359,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
drive->name, rq_data_dir(pc->rq) drive->name, rq_data_dir(pc->rq)
? "write" : "read"); ? "write" : "read");
pc->flags |= PC_FLAG_DMA_ERROR; pc->flags |= PC_FLAG_DMA_ERROR;
} else { } else
pc->xferred = pc->req_xfer; pc->xferred = pc->req_xfer;
if (drive->pc_update_buffers)
drive->pc_update_buffers(drive, pc);
}
debug_log("%s: DMA finished\n", drive->name); debug_log("%s: DMA finished\n", drive->name);
} }
...@@ -343,7 +396,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -343,7 +396,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
debug_log("[cmd %x]: check condition\n", rq->cmd[0]); debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
/* Retry operation */ /* Retry operation */
ide_retry_pc(drive, rq->rq_disk); ide_retry_pc(drive);
/* queued, but not started */ /* queued, but not started */
return ide_stopped; return ide_stopped;
...@@ -353,6 +406,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -353,6 +406,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
dsc = 1; dsc = 1;
/*
* ->pc_callback() might change rq->data_len for
* residual count, cache total length.
*/
done = blk_rq_bytes(rq);
/* Command finished - Call the callback function */ /* Command finished - Call the callback function */
uptodate = drive->pc_callback(drive, dsc); uptodate = drive->pc_callback(drive, dsc);
...@@ -361,7 +420,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -361,7 +420,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if (blk_special_request(rq)) { if (blk_special_request(rq)) {
rq->errors = 0; rq->errors = 0;
done = blk_rq_bytes(rq);
error = 0; error = 0;
} else { } else {
...@@ -370,11 +428,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -370,11 +428,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
rq->errors = -EIO; rq->errors = -EIO;
} }
if (drive->media == ide_tape)
done = ide_rq_bytes(rq); /* FIXME */
else
done = blk_rq_bytes(rq);
error = uptodate ? 0 : -EIO; error = uptodate ? 0 : -EIO;
} }
...@@ -407,21 +460,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) ...@@ -407,21 +460,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive); return ide_do_reset(drive);
} }
xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
if (drive->media == ide_floppy && pc->buf == NULL) {
done = min_t(unsigned int, bcount, cmd->nleft); done = min_t(unsigned int, bcount, cmd->nleft);
ide_pio_bytes(drive, cmd, write, done); ide_pio_bytes(drive, cmd, write, done);
} else if (drive->media == ide_tape && pc->bh) {
done = drive->pc_io_buffers(drive, pc, bcount, write);
} else {
done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
xferfunc(drive, NULL, pc->cur_pos, done);
}
/* Update the current position */ /* Update transferred byte count */
pc->xferred += done; pc->xferred += done;
pc->cur_pos += done;
bcount -= done; bcount -= done;
...@@ -599,7 +642,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) ...@@ -599,7 +642,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
/* We haven't transferred any data yet */ /* We haven't transferred any data yet */
pc->xferred = 0; pc->xferred = 0;
pc->cur_pos = pc->buf;
valid_tf = IDE_VALID_DEVICE; valid_tf = IDE_VALID_DEVICE;
bcount = ((drive->media == ide_tape) ? bcount = ((drive->media == ide_tape) ?
......
...@@ -206,54 +206,25 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, ...@@ -206,54 +206,25 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_cd_log_error(drive->name, failed_command, sense); ide_cd_log_error(drive->name, failed_command, sense);
} }
static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
struct cdrom_info *info = drive->driver_data;
struct request *rq = &drive->request_sense_rq;
ide_debug_log(IDE_DBG_SENSE, "enter");
if (sense == NULL)
sense = &info->sense_data;
/* stuff the sense request in front of our current request */
blk_rq_init(NULL, rq);
rq->cmd_type = REQ_TYPE_ATA_PC;
rq->rq_disk = info->disk;
rq->data = sense;
rq->cmd[0] = GPCMD_REQUEST_SENSE;
rq->cmd[4] = 18;
rq->data_len = 18;
rq->cmd_type = REQ_TYPE_SENSE;
rq->cmd_flags |= REQ_PREEMPT;
/* NOTE! Save the failed command in "rq->buffer" */
rq->buffer = (void *) failed_command;
if (failed_command)
ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
failed_command->cmd[0]);
drive->hwif->rq = NULL;
elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{ {
/* /*
* For REQ_TYPE_SENSE, "rq->buffer" points to the original * For REQ_TYPE_SENSE, "rq->special" points to the original
* failed request * failed request. Also, the sense data should be read
* directly from rq which might be different from the original
* sense buffer if it got copied during mapping.
*/ */
struct request *failed = (struct request *)rq->buffer; struct request *failed = (struct request *)rq->special;
struct cdrom_info *info = drive->driver_data; void *sense = bio_data(rq->bio);
void *sense = &info->sense_data;
if (failed) { if (failed) {
if (failed->sense) { if (failed->sense) {
/*
* Sense is always read into drive->sense_data.
* Copy back if the failed request has its
* sense pointer set.
*/
memcpy(failed->sense, sense, 18);
sense = failed->sense; sense = failed->sense;
failed->sense_len = rq->sense_len; failed->sense_len = rq->sense_len;
} }
...@@ -428,7 +399,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) ...@@ -428,7 +399,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
/* if we got a CHECK_CONDITION status, queue a request sense command */ /* if we got a CHECK_CONDITION status, queue a request sense command */
if (stat & ATA_ERR) if (stat & ATA_ERR)
cdrom_queue_request_sense(drive, NULL, NULL); return ide_queue_sense_rq(drive, NULL) ? 2 : 1;
return 1; return 1;
end_request: end_request:
...@@ -442,8 +413,7 @@ end_request: ...@@ -442,8 +413,7 @@ end_request:
hwif->rq = NULL; hwif->rq = NULL;
cdrom_queue_request_sense(drive, rq->sense, rq); return ide_queue_sense_rq(drive, rq) ? 2 : 1;
return 1;
} else } else
return 2; return 2;
} }
...@@ -503,14 +473,8 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) ...@@ -503,14 +473,8 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
* and some drives don't send them. Sigh. * and some drives don't send them. Sigh.
*/ */
if (rq->cmd[0] == GPCMD_REQUEST_SENSE && if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
cmd->nleft > 0 && cmd->nleft <= 5) { cmd->nleft > 0 && cmd->nleft <= 5)
unsigned int ofs = cmd->nbytes - cmd->nleft; cmd->nleft = 0;
while (cmd->nleft > 0) {
*((u8 *)rq->data + ofs++) = 0;
cmd->nleft--;
}
}
} }
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
...@@ -543,8 +507,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, ...@@ -543,8 +507,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
rq->cmd_flags |= cmd_flags; rq->cmd_flags |= cmd_flags;
rq->timeout = timeout; rq->timeout = timeout;
if (buffer) { if (buffer) {
rq->data = buffer; error = blk_rq_map_kern(drive->queue, rq, buffer,
rq->data_len = *bufflen; *bufflen, GFP_NOIO);
if (error) {
blk_put_request(rq);
return error;
}
} }
error = blk_execute_rq(drive->queue, info->disk, rq, 0); error = blk_execute_rq(drive->queue, info->disk, rq, 0);
...@@ -838,15 +806,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) ...@@ -838,15 +806,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
drive->dma = 0; drive->dma = 0;
/* sg request */ /* sg request */
if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { if (rq->bio) {
struct request_queue *q = drive->queue; struct request_queue *q = drive->queue;
char *buf = bio_data(rq->bio);
unsigned int alignment; unsigned int alignment;
char *buf;
if (rq->bio)
buf = bio_data(rq->bio);
else
buf = rq->data;
drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
...@@ -896,6 +859,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, ...@@ -896,6 +859,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
goto out_end; goto out_end;
} }
/* prepare sense request for this command */
ide_prep_sense(drive, rq);
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq)) if (rq_data_dir(rq))
......
...@@ -87,10 +87,6 @@ struct cdrom_info { ...@@ -87,10 +87,6 @@ struct cdrom_info {
struct atapi_toc *toc; struct atapi_toc *toc;
/* The result of the last successful request sense command
on this device. */
struct request_sense sense_data;
u8 max_speed; /* Max speed of the drive. */ u8 max_speed; /* Max speed of the drive. */
u8 current_speed; /* Current speed of the drive. */ u8 current_speed; /* Current speed of the drive. */
......
...@@ -411,7 +411,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) ...@@ -411,7 +411,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
cmd->protocol = ATA_PROT_NODATA; cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
rq->cmd_flags |= REQ_SOFTBARRIER;
rq->special = cmd; rq->special = cmd;
} }
......
...@@ -510,23 +510,11 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) ...@@ -510,23 +510,11 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
/* /*
* un-busy drive etc and make sure request is sane * un-busy drive etc and make sure request is sane
*/ */
rq = hwif->rq; rq = hwif->rq;
if (!rq) if (rq) {
goto out;
hwif->rq = NULL; hwif->rq = NULL;
rq->errors = 0; rq->errors = 0;
}
if (!rq->bio)
goto out;
rq->sector = rq->bio->bi_sector;
rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
rq->hard_cur_sectors = rq->current_nr_sectors;
rq->buffer = bio_data(rq->bio);
out:
return ret; return ret;
} }
......
...@@ -134,13 +134,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, ...@@ -134,13 +134,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
drive->pc = pc; drive->pc = pc;
if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) {
unsigned int done = blk_rq_bytes(drive->hwif->rq);
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc); ide_floppy_report_error(floppy, pc);
/* Giving up */ /* Giving up */
pc->error = IDE_DRV_ERROR_GENERAL; pc->error = IDE_DRV_ERROR_GENERAL;
drive->failed_pc = NULL; drive->failed_pc = NULL;
drive->pc_callback(drive, 0); drive->pc_callback(drive, 0);
ide_complete_rq(drive, -EIO, done);
return ide_stopped; return ide_stopped;
} }
...@@ -216,15 +220,13 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, ...@@ -216,15 +220,13 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
ide_init_pc(pc); ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c)); memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq; pc->rq = rq;
if (rq->data_len && rq_data_dir(rq) == WRITE) if (rq->data_len) {
pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data;
if (rq->bio)
pc->flags |= PC_FLAG_DMA_OK; pc->flags |= PC_FLAG_DMA_OK;
/* if (rq_data_dir(rq) == WRITE)
* possibly problematic, doesn't look like ide-floppy correctly pc->flags |= PC_FLAG_WRITING;
* handled scattered requests if dma fails... }
*/ /* pio will be performed by ide_pio_bytes() which handles sg fine */
pc->buf = NULL;
pc->req_xfer = pc->buf_size = rq->data_len; pc->req_xfer = pc->buf_size = rq->data_len;
} }
...@@ -265,8 +267,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, ...@@ -265,8 +267,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
} }
pc = &floppy->queued_pc; pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
} else if (blk_special_request(rq)) { } else if (blk_special_request(rq) || blk_sense_request(rq)) {
pc = (struct ide_atapi_pc *) rq->buffer; pc = (struct ide_atapi_pc *)rq->special;
} else if (blk_pc_request(rq)) { } else if (blk_pc_request(rq)) {
pc = &floppy->queued_pc; pc = &floppy->queued_pc;
idefloppy_blockpc_cmd(floppy, pc, rq); idefloppy_blockpc_cmd(floppy, pc, rq);
...@@ -275,6 +277,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, ...@@ -275,6 +277,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
goto out_end; goto out_end;
} }
ide_prep_sense(drive, rq);
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq)) if (rq_data_dir(rq))
......
...@@ -248,13 +248,6 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) ...@@ -248,13 +248,6 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
struct scatterlist *sg = hwif->sg_table; struct scatterlist *sg = hwif->sg_table;
struct request *rq = cmd->rq; struct request *rq = cmd->rq;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
cmd->sg_nents = 1;
} else if (!rq->bio) {
sg_init_one(sg, rq->data, rq->data_len);
cmd->sg_nents = 1;
} else
cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
} }
EXPORT_SYMBOL_GPL(ide_map_sg); EXPORT_SYMBOL_GPL(ide_map_sg);
...@@ -371,7 +364,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ...@@ -371,7 +364,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
return execute_drive_cmd(drive, rq); return execute_drive_cmd(drive, rq);
else if (blk_pm_request(rq)) { else if (blk_pm_request(rq)) {
struct request_pm_state *pm = rq->data; struct request_pm_state *pm = rq->special;
#ifdef DEBUG_PM #ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n", printk("%s: start_power_step(step: %d)\n",
drive->name, pm->pm_step); drive->name, pm->pm_step);
...@@ -484,6 +477,9 @@ void do_ide_request(struct request_queue *q) ...@@ -484,6 +477,9 @@ void do_ide_request(struct request_queue *q)
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
/* HLD do_request() callback might sleep, make sure it's okay */
might_sleep();
if (ide_lock_host(host, hwif)) if (ide_lock_host(host, hwif))
goto plug_device_2; goto plug_device_2;
......
...@@ -231,7 +231,6 @@ static int generic_drive_reset(ide_drive_t *drive) ...@@ -231,7 +231,6 @@ static int generic_drive_reset(ide_drive_t *drive)
rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd_len = 1; rq->cmd_len = 1;
rq->cmd[0] = REQ_DRIVE_RESET; rq->cmd[0] = REQ_DRIVE_RESET;
rq->cmd_flags |= REQ_SOFTBARRIER;
if (blk_execute_rq(drive->queue, NULL, rq, 1)) if (blk_execute_rq(drive->queue, NULL, rq, 1))
ret = rq->errors; ret = rq->errors;
blk_put_request(rq); blk_put_request(rq);
......
...@@ -24,11 +24,8 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) ...@@ -24,11 +24,8 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
start_queue = 1; start_queue = 1;
spin_unlock_irq(&hwif->lock); spin_unlock_irq(&hwif->lock);
if (start_queue) { if (start_queue)
spin_lock_irq(q->queue_lock); blk_run_queue(q);
blk_start_queueing(q);
spin_unlock_irq(q->queue_lock);
}
return; return;
} }
spin_unlock_irq(&hwif->lock); spin_unlock_irq(&hwif->lock);
......
...@@ -7,7 +7,6 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ...@@ -7,7 +7,6 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
struct request *rq; struct request *rq;
struct request_pm_state rqpm; struct request_pm_state rqpm;
struct ide_cmd cmd;
int ret; int ret;
/* call ACPI _GTM only once */ /* call ACPI _GTM only once */
...@@ -15,11 +14,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ...@@ -15,11 +14,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_acpi_get_timing(hwif); ide_acpi_get_timing(hwif);
memset(&rqpm, 0, sizeof(rqpm)); memset(&rqpm, 0, sizeof(rqpm));
memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_SUSPEND; rq->cmd_type = REQ_TYPE_PM_SUSPEND;
rq->special = &cmd; rq->special = &rqpm;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND; rqpm.pm_step = IDE_PM_START_SUSPEND;
if (mesg.event == PM_EVENT_PRETHAW) if (mesg.event == PM_EVENT_PRETHAW)
mesg.event = PM_EVENT_FREEZE; mesg.event = PM_EVENT_FREEZE;
...@@ -41,7 +38,6 @@ int generic_ide_resume(struct device *dev) ...@@ -41,7 +38,6 @@ int generic_ide_resume(struct device *dev)
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
struct request *rq; struct request *rq;
struct request_pm_state rqpm; struct request_pm_state rqpm;
struct ide_cmd cmd;
int err; int err;
/* call ACPI _PS0 / _STM only once */ /* call ACPI _PS0 / _STM only once */
...@@ -53,12 +49,10 @@ int generic_ide_resume(struct device *dev) ...@@ -53,12 +49,10 @@ int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive); ide_acpi_exec_tfs(drive);
memset(&rqpm, 0, sizeof(rqpm)); memset(&rqpm, 0, sizeof(rqpm));
memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_type = REQ_TYPE_PM_RESUME;
rq->cmd_flags |= REQ_PREEMPT; rq->cmd_flags |= REQ_PREEMPT;
rq->special = &cmd; rq->special = &rqpm;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_step = IDE_PM_START_RESUME;
rqpm.pm_state = PM_EVENT_ON; rqpm.pm_state = PM_EVENT_ON;
...@@ -77,7 +71,7 @@ int generic_ide_resume(struct device *dev) ...@@ -77,7 +71,7 @@ int generic_ide_resume(struct device *dev)
void ide_complete_power_step(ide_drive_t *drive, struct request *rq) void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
{ {
struct request_pm_state *pm = rq->data; struct request_pm_state *pm = rq->special;
#ifdef DEBUG_PM #ifdef DEBUG_PM
printk(KERN_INFO "%s: complete_power_step(step: %d)\n", printk(KERN_INFO "%s: complete_power_step(step: %d)\n",
...@@ -107,10 +101,8 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq) ...@@ -107,10 +101,8 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{ {
struct request_pm_state *pm = rq->data; struct request_pm_state *pm = rq->special;
struct ide_cmd *cmd = rq->special; struct ide_cmd cmd = { };
memset(cmd, 0, sizeof(*cmd));
switch (pm->pm_step) { switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
...@@ -123,12 +115,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ...@@ -123,12 +115,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped; return ide_stopped;
} }
if (ata_id_flush_ext_enabled(drive->id)) if (ata_id_flush_ext_enabled(drive->id))
cmd->tf.command = ATA_CMD_FLUSH_EXT; cmd.tf.command = ATA_CMD_FLUSH_EXT;
else else
cmd->tf.command = ATA_CMD_FLUSH; cmd.tf.command = ATA_CMD_FLUSH;
goto out_do_tf; goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
cmd->tf.command = ATA_CMD_STANDBYNOW1; cmd.tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf; goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive); ide_set_max_pio(drive);
...@@ -141,7 +133,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ...@@ -141,7 +133,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
ide_complete_power_step(drive, rq); ide_complete_power_step(drive, rq);
return ide_stopped; return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */ case IDE_PM_IDLE: /* Resume step 2 (idle) */
cmd->tf.command = ATA_CMD_IDLEIMMEDIATE; cmd.tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf; goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/* /*
...@@ -163,11 +155,11 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ...@@ -163,11 +155,11 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped; return ide_stopped;
out_do_tf: out_do_tf:
cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
cmd->protocol = ATA_PROT_NODATA; cmd.protocol = ATA_PROT_NODATA;
return do_rw_taskfile(drive, cmd); return do_rw_taskfile(drive, &cmd);
} }
/** /**
...@@ -181,7 +173,7 @@ out_do_tf: ...@@ -181,7 +173,7 @@ out_do_tf:
void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
{ {
struct request_queue *q = drive->queue; struct request_queue *q = drive->queue;
struct request_pm_state *pm = rq->data; struct request_pm_state *pm = rq->special;
unsigned long flags; unsigned long flags;
ide_complete_power_step(drive, rq); ide_complete_power_step(drive, rq);
...@@ -207,7 +199,7 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) ...@@ -207,7 +199,7 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
void ide_check_pm_state(ide_drive_t *drive, struct request *rq) void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{ {
struct request_pm_state *pm = rq->data; struct request_pm_state *pm = rq->special;
if (blk_pm_suspend_request(rq) && if (blk_pm_suspend_request(rq) &&
pm->pm_step == IDE_PM_START_SUSPEND) pm->pm_step == IDE_PM_START_SUSPEND)
......
This diff is collapsed.
...@@ -424,7 +424,9 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, ...@@ -424,7 +424,9 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
rq->buffer = buf;
if (cmd->tf_flags & IDE_TFLAG_WRITE)
rq->cmd_flags |= REQ_RW;
/* /*
* (ks) We transfer currently only whole sectors. * (ks) We transfer currently only whole sectors.
...@@ -432,18 +434,20 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, ...@@ -432,18 +434,20 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
* if we would find a solution to transfer any size. * if we would find a solution to transfer any size.
* To support special commands like READ LONG. * To support special commands like READ LONG.
*/ */
rq->hard_nr_sectors = rq->nr_sectors = nsect; if (nsect) {
rq->hard_cur_sectors = rq->current_nr_sectors = nsect; error = blk_rq_map_kern(drive->queue, rq, buf,
nsect * SECTOR_SIZE, __GFP_WAIT);
if (cmd->tf_flags & IDE_TFLAG_WRITE) if (error)
rq->cmd_flags |= REQ_RW; goto put_req;
}
rq->special = cmd; rq->special = cmd;
cmd->rq = rq; cmd->rq = rq;
error = blk_execute_rq(drive->queue, NULL, rq, 0); error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
put_req:
blk_put_request(rq);
return error; return error;
} }
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/mutex.h> #include <asm/mutex.h>
/* for request_sense */
#include <linux/cdrom.h>
#if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) #if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300)
# define SUPPORT_VLB_SYNC 0 # define SUPPORT_VLB_SYNC 0
#else #else
...@@ -324,7 +327,6 @@ struct ide_cmd { ...@@ -324,7 +327,6 @@ struct ide_cmd {
unsigned int cursg_ofs; unsigned int cursg_ofs;
struct request *rq; /* copy of request */ struct request *rq; /* copy of request */
void *special; /* valid_t generally */
}; };
/* ATAPI packet command flags */ /* ATAPI packet command flags */
...@@ -360,11 +362,7 @@ struct ide_atapi_pc { ...@@ -360,11 +362,7 @@ struct ide_atapi_pc {
/* data buffer */ /* data buffer */
u8 *buf; u8 *buf;
/* current buffer position */
u8 *cur_pos;
int buf_size; int buf_size;
/* missing/available data on the current buffer */
int b_count;
/* the corresponding request */ /* the corresponding request */
struct request *rq; struct request *rq;
...@@ -377,10 +375,6 @@ struct ide_atapi_pc { ...@@ -377,10 +375,6 @@ struct ide_atapi_pc {
*/ */
u8 pc_buf[IDE_PC_BUFFER_SIZE]; u8 pc_buf[IDE_PC_BUFFER_SIZE];
/* idetape only */
struct idetape_bh *bh;
char *b_data;
unsigned long timeout; unsigned long timeout;
}; };
...@@ -593,16 +587,16 @@ struct ide_drive_s { ...@@ -593,16 +587,16 @@ struct ide_drive_s {
/* callback for packet commands */ /* callback for packet commands */
int (*pc_callback)(struct ide_drive_s *, int); int (*pc_callback)(struct ide_drive_s *, int);
void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *);
int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *,
unsigned int, int);
ide_startstop_t (*irq_handler)(struct ide_drive_s *); ide_startstop_t (*irq_handler)(struct ide_drive_s *);
unsigned long atapi_flags; unsigned long atapi_flags;
struct ide_atapi_pc request_sense_pc; struct ide_atapi_pc request_sense_pc;
struct request request_sense_rq;
/* current sense rq and buffer */
bool sense_rq_armed;
struct request sense_rq;
struct request_sense sense_data;
}; };
typedef struct ide_drive_s ide_drive_t; typedef struct ide_drive_s ide_drive_t;
...@@ -1174,7 +1168,10 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); ...@@ -1174,7 +1168,10 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); 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_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);
void ide_retry_pc(ide_drive_t *, struct gendisk *); void ide_retry_pc(ide_drive_t *drive);
void ide_prep_sense(ide_drive_t *drive, struct request *rq);
int ide_queue_sense_rq(ide_drive_t *drive, void *special);
int ide_cd_expiry(ide_drive_t *); int ide_cd_expiry(ide_drive_t *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment