Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 139415
b: refs/heads/master
c: a08915b
h: refs/heads/master
i:
  139413: e95e814
  139411: ed5c3f4
  139407: 0463946
v: v3
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Mar 31, 2009
1 parent cc4df75 commit ad11483
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 106 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: 5ed57ad705d6b58386ac43d2ca1c8fc66aee1101
refs/heads/master: a08915ba594da66145f33a972db578a58b9135f1
146 changes: 43 additions & 103 deletions trunk/drivers/ide/ide-cd.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,64 +539,12 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
{
ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags);

if (rq_data_dir(rq) == READ) {
unsigned short sectors_per_frame =
queue_hardsect_size(drive->queue) >> SECTOR_BITS;
int nskip = rq->sector & (sectors_per_frame - 1);

/*
* If the requested sector doesn't start on a frame boundary,
* we must adjust the start of the transfer so that it does,
* and remember to skip the first few sectors.
*
* If the rq->current_nr_sectors field is larger than the size
* of the buffer, it will mean that we're to skip a number of
* sectors equal to the amount by which rq->current_nr_sectors
* is larger than the buffer size.
*/
if (nskip > 0) {
/* sanity check... */
if (rq->current_nr_sectors !=
bio_cur_sectors(rq->bio)) {
printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n",
drive->name, __func__,
rq->current_nr_sectors);
return ide_stopped;
}
rq->current_nr_sectors += nskip;
}
}

/* set up the command */
rq->timeout = ATAPI_WAIT_PC;

return ide_started;
}

/*
* Fix up a possibly partially-processed request so that we can start it over
* entirely, or even put it back on the request queue.
*/
static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
{

ide_debug_log(IDE_DBG_FUNC, "enter");

if (rq->buffer != bio_data(rq->bio)) {
sector_t n =
(rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;

rq->buffer = bio_data(rq->bio);
rq->nr_sectors += n;
rq->sector -= n;
}
rq->current_nr_sectors = bio_cur_sectors(rq->bio);
rq->hard_cur_sectors = rq->current_nr_sectors;
rq->hard_nr_sectors = rq->nr_sectors;
rq->hard_sector = rq->sector;
rq->q->prep_rq_fn(rq->q, rq);
}

static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
{
ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
Expand Down Expand Up @@ -690,6 +638,17 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}

static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
unsigned int nr_bytes = cmd->nbytes - cmd->nleft;

if (cmd->tf_flags & IDE_TFLAG_WRITE)
nr_bytes -= cmd->last_xfer_len;

if (nr_bytes > 0)
ide_complete_rq(drive, 0, nr_bytes);
}

/*
* Called from blk_end_request_callback() after the data of the request is
* completed and before the request itself is completed. By returning value '1',
Expand All @@ -703,6 +662,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq)
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
xfer_func_t *xferfunc;
ide_expiry_t *expiry = NULL;
Expand Down Expand Up @@ -769,11 +729,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
* Otherwise, complete the command normally.
*/
uptodate = 1;
if (rq->current_nr_sectors > 0) {
if (cmd->nleft > 0) {
printk(KERN_ERR PFX "%s: %s: data underrun "
"(%d blocks)\n",
drive->name, __func__,
rq->current_nr_sectors);
"(%u bytes)\n", drive->name, __func__,
cmd->nleft);
if (!write)
rq->cmd_flags |= REQ_FAILED;
uptodate = 0;
Expand All @@ -795,24 +754,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)

if (blk_fs_request(rq)) {
if (write == 0) {
int nskip;

if (ide_cd_check_transfer_size(drive, len))
goto out_end;

/*
* First, figure out if we need to bit-bucket
* any of the leading sectors.
*/
nskip = min_t(int, rq->current_nr_sectors
- bio_cur_sectors(rq->bio),
thislen >> 9);
if (nskip > 0) {
ide_pad_transfer(drive, write, nskip << 9);
rq->current_nr_sectors -= nskip;
thislen -= (nskip << 9);
}
}
cmd->last_xfer_len = 0;
}

if (ireason == 0) {
Expand All @@ -835,15 +780,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/* bio backed? */
if (rq->bio) {
if (blk_fs_request(rq)) {
ptr = rq->buffer;
blen = rq->current_nr_sectors << 9;
blen = min_t(int, thislen, cmd->nleft);
} else {
ptr = bio_data(rq->bio);
blen = bio_iovec(rq->bio)->bv_len;
}
}

if (!ptr) {
if ((blk_fs_request(rq) && cmd->nleft == 0) ||
(blk_fs_request(rq) == 0 && ptr == NULL)) {
if (blk_fs_request(rq) && !write)
/*
* If the buffers are full, pipe the rest into
Expand All @@ -863,26 +808,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (blen > thislen)
blen = thislen;

xferfunc(drive, NULL, ptr, blen);
if (blk_fs_request(rq)) {
ide_pio_bytes(drive, cmd, write, blen);
cmd->last_xfer_len += blen;
} else
xferfunc(drive, NULL, ptr, blen);

thislen -= blen;
len -= blen;

if (blk_fs_request(rq)) {
rq->buffer += blen;
rq->nr_sectors -= (blen >> 9);
rq->current_nr_sectors -= (blen >> 9);
rq->sector += (blen >> 9);

if (rq->current_nr_sectors == 0 && rq->nr_sectors) {
nsectors = rq->hard_cur_sectors;

if (nsectors == 0)
nsectors = 1;

ide_complete_rq(drive, 0, nsectors << 9);
}
} else {
if (blk_fs_request(rq) == 0) {
rq->data_len -= blen;

/*
Expand Down Expand Up @@ -933,8 +868,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
ide_cd_complete_failed_rq(drive, rq);

if (blk_fs_request(rq)) {
if (rq->current_nr_sectors == 0)
if (cmd->nleft == 0)
uptodate = 1;
if (uptodate == 0)
ide_cd_error_cmd(drive, cmd);
} else {
if (uptodate <= 0 && rq->errors == 0)
rq->errors = -EIO;
Expand All @@ -944,7 +881,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
if (blk_pc_request(rq))
nsectors = (rq->data_len + 511) >> 9;
else
nsectors = rq->hard_cur_sectors;
nsectors = rq->hard_nr_sectors;

if (nsectors == 0)
nsectors = 1;
Expand All @@ -960,9 +897,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
queue_hardsect_size(drive->queue) >> SECTOR_BITS;
queue_hardsect_size(q) >> SECTOR_BITS;

ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, "
"secs_per_frame: %u",
Expand All @@ -977,17 +915,16 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
* We may be retrying this request after an error. Fix up any
* weirdness which might be present in the request packet.
*/
ide_cd_restore_request(drive, rq);
q->prep_rq_fn(q, rq);
}

/* use DMA, if possible / writes *must* be hardware frame aligned */
/* fs requests *must* be hardware frame aligned */
if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
(rq->sector & (sectors_per_frame - 1))) {
if (write)
return ide_stopped;
drive->dma = 0;
} else
drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
(rq->sector & (sectors_per_frame - 1)))
return ide_stopped;

/* use DMA, if possible */
drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);

if (write)
cd->devinfo.media_written = 1;
Expand Down Expand Up @@ -1050,8 +987,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
if (blk_fs_request(rq)) {
if (cdrom_start_rw(drive, rq) == ide_stopped ||
ide_cd_prepare_rw_request(drive, rq) == ide_stopped) {
if (rq->current_nr_sectors == 0)
uptodate = 1;
goto out_end;
}
} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
Expand All @@ -1078,6 +1013,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,

cmd.rq = rq;

if (blk_fs_request(rq)) {
ide_init_sg_cmd(&cmd, rq->nr_sectors << 9);
ide_map_sg(drive, &cmd);
}

return ide_issue_pc(drive, &cmd);
out_end:
nsectors = rq->hard_nr_sectors;
Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/ide/ide-taskfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}

static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write, unsigned int len)
void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
Expand Down Expand Up @@ -243,6 +243,7 @@ static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
len -= nr_bytes;
}
}
EXPORT_SYMBOL_GPL(ide_pio_bytes);

static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write)
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/linux/ide.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ struct ide_cmd {

unsigned int nbytes;
unsigned int nleft;
unsigned int last_xfer_len;

struct scatterlist *cursg;
unsigned int cursg_ofs;

Expand Down Expand Up @@ -1226,6 +1228,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_cmd *);

ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *);

void ide_pio_bytes(ide_drive_t *, struct ide_cmd *, unsigned int, unsigned int);

void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8);

int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16);
Expand Down

0 comments on commit ad11483

Please sign in to comment.