ide-{floppy,tape}: fix padding for PIO transfers
PATCH 1/2 ide-{floppy,tape}: fix padding for PIO transfers
From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] ide-{floppy,tape}: fix padding for PIO transfers
* Return number of bytes left to transfer from idetape_{in,out}put_buffers() and number of bytes done from ide_tape_io_buffers().
* Fix padding for PIO transfers in ide_pc_intr() so read/write buffers are always completely processed and then the transfer is padded if necessary.
* Remove invalid error messages.
* Remove now superfluous padding from ide{_io_buffers,tape_input_buffers}().
While at it:
* Set pc->bh to NULL in idetape_input_buffers() after all bh-s are done.
* Cache !!(pc->flags & PC_FLAG_WRITING) in local variable in ide_pc_intr().
Cc Borislav Petkov <[email protected]>
Signed-off-by Bartlomiej Zolnierkiewicz <[email protected]>
---
against pata-2.6 tree
drivers/ide/ide-atapi.c | 57 ++++++++++++++++-------------------------------- drivers/ide/ide-tape.c | 32 +++++++++++++------------- 2 files changed, 35 insertions(+), 54 deletions(-)
drivers/ide/ide-atapi.c +19 -38
@@ -108,13 +108,6 @@ int ide_io_buffers(ide_drive_t *drive, s } } -if (bcount) { -printk (KERN_ERR "%s: %d leftover bytes, %s\n" , drive->name, - bcount, write ?"padding with zeros" - :"discarding data" ); -ide_pad_transfer (drive, write, bcount); - } -return done; }EXPORT_SYMBOL_GPL (ide_io_buffers);
@@ -315,9 +308,10 @@ static ide_startstop_t ide_pc_intr(ide_dstruct request *rq = hwif->rq;const struct ide_tp_ops *tp_ops = hwif->tp_ops;xfer_func_t *xferfunc; -unsigned int timeout, temp; +unsigned int timeout, done;u16 bcount;u8 stat, ireason, dsc =0 ; +u8 write = !!(pc->flags &PC_FLAG_WRITING );debug_log ("Enter %s - interrupt handler\n" , __func__);
@@ -421,8 +415,7 @@ static ide_startstop_t ide_pc_intr(ide_dreturn ide_do_reset (drive); } -if (((ireason &ATAPI_IO ) ==ATAPI_IO ) == - !!(pc->flags &PC_FLAG_WRITING )) { +if (((ireason &ATAPI_IO ) ==ATAPI_IO ) == write) {/* Hopefully, we will never get here */ printk(KERN_ERR "%s: We wanted to %s, but the device wants us " "to %s!\n", drive->name,
@@ -431,45 +424,33 @@ static ide_startstop_t ide_pc_intr(ide_dreturn ide_do_reset (drive); } -if (!(pc->flags &PC_FLAG_WRITING )) { -/* Reading - Check that we have enough space */ - temp = pc->xferred + bcount; -if (temp > pc->req_xfer) { -if (temp > pc->buf_size) { -printk (KERN_ERR "%s: The device wants to send " -"us more data than expected - " -"discarding data\n" , - drive->name); - -ide_pad_transfer (drive,0 , bcount); - goto next_irq; - } -debug_log ("The device wants to send us more data than " -"expected - allowing transfer\n" ); - } - xferfunc = tp_ops->input_data; - }else - xferfunc = tp_ops->output_data; + xferfunc = write ? tp_ops->output_data : tp_ops->input_data;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 )); + done = drive->pc_io_buffers (drive, pc, bcount, write);/* FIXME: don't do partial completions */ if (drive->media == ide_floppy)ide_complete_rq (drive,0 , done ? done :ide_rq_bytes (rq)); - }else -xferfunc (drive,NULL , pc->cur_pos, bcount); + }else { + done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); +xferfunc (drive,NULL , pc->cur_pos, done); + }/* Update the current position */ - pc->xferred += bcount; - pc->cur_pos += bcount; + pc->xferred += done; + pc->cur_pos += done; + + bcount -= done; + +if (bcount) +ide_pad_transfer (drive, write, bcount); + +debug_log ("[cmd %x] transferred %d bytes, padded %d bytes\n" , + rq->cmd[0 ], done, bcount); -debug_log ("[cmd %x] transferred %d bytes on that intr.\n" , - rq->cmd[0 ], bcount); -next_irq:/* And set the interrupt handler again */ ide_set_handler (drive, ide_pc_intr, timeout);return ide_started;
drivers/ide/ide-tape.c +16 -16
@@ -297,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrreturn tape; } -static void idetape_input_buffers (ide_drive_t *drive,struct ide_atapi_pc *pc, +static int idetape_input_buffers (ide_drive_t *drive,struct ide_atapi_pc *pc,unsigned int bcount) {struct idetape_bh *bh = pc->bh;int count;while (bcount) { -if (bh ==NULL ) { -printk (KERN_ERR "ide-tape: bh == NULL in " -"idetape_input_buffers\n" ); -ide_pad_transfer (drive,0 , bcount); -return ; - } +if (bh ==NULL ) +break ; count =min ( (unsigned int )(bh->b_size -atomic_read (&bh->b_count)), bcount);
@@ -323,21 +319,21 @@ static void idetape_input_buffers(ide_dratomic_set (&bh->b_count,0 ); } } + pc->bh = bh; + +return bcount; } -static void idetape_output_buffers (ide_drive_t *drive,struct ide_atapi_pc *pc, +static int idetape_output_buffers (ide_drive_t *drive,struct ide_atapi_pc *pc,unsigned int bcount) {struct idetape_bh *bh = pc->bh;int count;while (bcount) { -if (bh ==NULL ) { -printk (KERN_ERR "ide-tape: bh == NULL in %s\n" , - __func__); -return ; - } +if (bh ==NULL ) +break ; count =min ((unsigned int )pc->b_count, (unsigned int )bcount); drive->hwif->tp_ops->output_data (drive,NULL , pc->b_data, count); bcount -= count;
@@ -352,6 +348,8 @@ static void idetape_output_buffers(ide_d } } } + +return bcount; }static void idetape_update_buffers (ide_drive_t *drive,struct ide_atapi_pc *pc)
@@ -563,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drivstatic int ide_tape_io_buffers (ide_drive_t *drive,struct ide_atapi_pc *pc,unsigned int bcount,int write) { +unsigned int bleft; +if (write) -idetape_output_buffers (drive, pc, bcount); + bleft =idetape_output_buffers (drive, pc, bcount);else -idetape_input_buffers (drive, pc, bcount); + bleft =idetape_input_buffers (drive, pc, bcount); -return bcount; +return bcount - bleft; }/*