Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146337
b: refs/heads/master
c: 5c4be57
h: refs/heads/master
i:
  146335: 6544906
v: v3
  • Loading branch information
Tejun Heo committed Apr 18, 2009
1 parent 6b61168 commit 9966ce8
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6b544fcc8cd0a04eb42de9d1ecdd345e979d6ada
refs/heads/master: 5c4be57249e2e09136446597d2fe2a967c6ffef0
52 changes: 31 additions & 21 deletions trunk/drivers/ide/ide-atapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,18 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq->special = (char *)pc;

if (pc->req_xfer) {
rq->data = pc->buf;
rq->data_len = pc->req_xfer;
error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer,
GFP_NOIO);
if (error)
goto put_req;
}

memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
error = blk_execute_rq(drive->queue, disk, rq, 0);
put_req:
blk_put_request(rq);

return error;
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
Expand Down Expand Up @@ -168,6 +170,7 @@ 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__);

Expand All @@ -193,13 +196,19 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
memset(sense, 0, sizeof(*sense));

blk_rq_init(rq->q, sense_rq);
sense_rq->rq_disk = rq->rq_disk;

sense_rq->data = sense;
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->data_len = sense_len;

sense_rq->cmd_type = REQ_TYPE_SENSE;
sense_rq->cmd_flags |= REQ_PREEMPT;

Expand All @@ -210,9 +219,14 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
}
EXPORT_SYMBOL_GPL(ide_prep_sense);

void ide_queue_sense_rq(ide_drive_t *drive, void *special)
int ide_queue_sense_rq(ide_drive_t *drive, void *special)
{
BUG_ON(!drive->sense_rq_armed);
/* 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;
Expand All @@ -221,6 +235,7 @@ void ide_queue_sense_rq(ide_drive_t *drive, void *special)

elv_add_request(drive->queue, &drive->sense_rq,
ELEVATOR_INSERT_FRONT, 0);
return 0;
}
EXPORT_SYMBOL_GPL(ide_queue_sense_rq);

Expand All @@ -239,13 +254,14 @@ void ide_retry_pc(ide_drive_t *drive)
/* init pc from sense_rq */
ide_init_pc(pc);
memcpy(pc->c, sense_rq->cmd, 12);
pc->buf = sense_rq->data;
pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */
pc->req_xfer = sense_rq->data_len;

if (drive->media == ide_tape)
set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);

ide_queue_sense_rq(drive, pc);
if (ide_queue_sense_rq(drive, pc))
ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq));
}
EXPORT_SYMBOL_GPL(ide_retry_pc);

Expand Down Expand Up @@ -317,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
Expand Down Expand Up @@ -411,7 +426,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
rq->errors = -EIO;
}

if (drive->media == ide_tape)
if (drive->media == ide_tape && !rq->bio)
done = ide_rq_bytes(rq); /* FIXME */
else
done = blk_rq_bytes(rq);
Expand Down Expand Up @@ -448,16 +463,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}

xferfunc = write ? tp_ops->output_data : tp_ops->input_data;

if (drive->media == ide_floppy && pc->buf == NULL) {
if (drive->media == ide_tape && pc->bh)
done = drive->pc_io_buffers(drive, pc, bcount, write);
else {
done = min_t(unsigned int, bcount, cmd->nleft);
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 */
Expand Down
28 changes: 14 additions & 14 deletions trunk/drivers/ide/ide-cd.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,12 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
/*
* 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->special;
struct request_sense *sense = &drive->sense_data;
void *sense = bio_data(rq->bio);

if (failed) {
if (failed->sense) {
Expand Down Expand Up @@ -398,7 +400,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 (stat & ATA_ERR)
ide_queue_sense_rq(drive, NULL);
return ide_queue_sense_rq(drive, NULL) ? 2 : 1;
return 1;

end_request:
Expand All @@ -412,8 +414,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)

hwif->rq = NULL;

ide_queue_sense_rq(drive, rq);
return 1;
return ide_queue_sense_rq(drive, rq) ? 2 : 1;
} else
return 2;
}
Expand Down Expand Up @@ -507,8 +508,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
rq->cmd_flags |= cmd_flags;
rq->timeout = timeout;
if (buffer) {
rq->data = buffer;
rq->data_len = *bufflen;
error = blk_rq_map_kern(drive->queue, rq, buffer,
*bufflen, GFP_NOIO);
if (error) {
blk_put_request(rq);
return error;
}
}

error = blk_execute_rq(drive->queue, info->disk, rq, 0);
Expand Down Expand Up @@ -802,15 +807,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
drive->dma = 0;

/* sg request */
if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
if (rq->bio) {
struct request_queue *q = drive->queue;
char *buf = bio_data(rq->bio);
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);

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ void do_ide_request(struct request_queue *q)

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))
goto plug_device_2;

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/ide/ide-tape.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,

cmd.rq = rq;

ide_init_sg_cmd(&cmd, pc->req_xfer);
ide_map_sg(drive, &cmd);

return ide_tape_issue_pc(drive, &cmd, pc);
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/include/linux/ide.h
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);
void ide_retry_pc(ide_drive_t *drive);

void ide_prep_sense(ide_drive_t *drive, struct request *rq);
void ide_queue_sense_rq(ide_drive_t *drive, void *special);
int ide_queue_sense_rq(ide_drive_t *drive, void *special);

int ide_cd_expiry(ide_drive_t *);

Expand Down

0 comments on commit 9966ce8

Please sign in to comment.