aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-03-31 14:15:26 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-03-31 14:15:26 -0400
commitd93bc4521c80e9d87767779814e88f6d725453d7 (patch)
tree6c373208132f687e4ffb31db6c60e2a8638f6080 /drivers/ide
parent9f5af4d667a6d4ebd66019b4b26b445ddbae6d6c (diff)
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 <petkovbb@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-atapi.c57
-rw-r--r--drivers/ide/ide-tape.c32
2 files changed, 35 insertions, 54 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 3f3fc7c7b2fe..40f413b20bd8 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -110,13 +110,6 @@ int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
110 } 110 }
111 } 111 }
112 112
113 if (bcount) {
114 printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
115 bcount, write ? "padding with zeros"
116 : "discarding data");
117 ide_pad_transfer(drive, write, bcount);
118 }
119
120 return done; 113 return done;
121} 114}
122EXPORT_SYMBOL_GPL(ide_io_buffers); 115EXPORT_SYMBOL_GPL(ide_io_buffers);
@@ -330,9 +323,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
330 struct request *rq = hwif->rq; 323 struct request *rq = hwif->rq;
331 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 324 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
332 xfer_func_t *xferfunc; 325 xfer_func_t *xferfunc;
333 unsigned int timeout, temp; 326 unsigned int timeout, done;
334 u16 bcount; 327 u16 bcount;
335 u8 stat, ireason, dsc = 0; 328 u8 stat, ireason, dsc = 0;
329 u8 write = !!(pc->flags & PC_FLAG_WRITING);
336 330
337 debug_log("Enter %s - interrupt handler\n", __func__); 331 debug_log("Enter %s - interrupt handler\n", __func__);
338 332
@@ -441,8 +435,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
441 return ide_do_reset(drive); 435 return ide_do_reset(drive);
442 } 436 }
443 437
444 if (((ireason & ATAPI_IO) == ATAPI_IO) == 438 if (((ireason & ATAPI_IO) == ATAPI_IO) == write) {
445 !!(pc->flags & PC_FLAG_WRITING)) {
446 /* Hopefully, we will never get here */ 439 /* Hopefully, we will never get here */
447 printk(KERN_ERR "%s: We wanted to %s, but the device wants us " 440 printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
448 "to %s!\n", drive->name, 441 "to %s!\n", drive->name,
@@ -451,45 +444,33 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
451 return ide_do_reset(drive); 444 return ide_do_reset(drive);
452 } 445 }
453 446
454 if (!(pc->flags & PC_FLAG_WRITING)) { 447 xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
455 /* Reading - Check that we have enough space */
456 temp = pc->xferred + bcount;
457 if (temp > pc->req_xfer) {
458 if (temp > pc->buf_size) {
459 printk(KERN_ERR "%s: The device wants to send "
460 "us more data than expected - "
461 "discarding data\n",
462 drive->name);
463
464 ide_pad_transfer(drive, 0, bcount);
465 goto next_irq;
466 }
467 debug_log("The device wants to send us more data than "
468 "expected - allowing transfer\n");
469 }
470 xferfunc = tp_ops->input_data;
471 } else
472 xferfunc = tp_ops->output_data;
473 448
474 if ((drive->media == ide_floppy && !pc->buf) || 449 if ((drive->media == ide_floppy && !pc->buf) ||
475 (drive->media == ide_tape && pc->bh)) { 450 (drive->media == ide_tape && pc->bh)) {
476 int done = drive->pc_io_buffers(drive, pc, bcount, 451 done = drive->pc_io_buffers(drive, pc, bcount, write);
477 !!(pc->flags & PC_FLAG_WRITING));
478 452
479 /* FIXME: don't do partial completions */ 453 /* FIXME: don't do partial completions */
480 if (drive->media == ide_floppy) 454 if (drive->media == ide_floppy)
481 ide_complete_rq(drive, 0, 455 ide_complete_rq(drive, 0,
482 done ? done : ide_rq_bytes(rq)); 456 done ? done : ide_rq_bytes(rq));
483 } else 457 } else {
484 xferfunc(drive, NULL, pc->cur_pos, bcount); 458 done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
459 xferfunc(drive, NULL, pc->cur_pos, done);
460 }
485 461
486 /* Update the current position */ 462 /* Update the current position */
487 pc->xferred += bcount; 463 pc->xferred += done;
488 pc->cur_pos += bcount; 464 pc->cur_pos += done;
465
466 bcount -= done;
467
468 if (bcount)
469 ide_pad_transfer(drive, write, bcount);
470
471 debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n",
472 rq->cmd[0], done, bcount);
489 473
490 debug_log("[cmd %x] transferred %d bytes on that intr.\n",
491 rq->cmd[0], bcount);
492next_irq:
493 /* And set the interrupt handler again */ 474 /* And set the interrupt handler again */
494 ide_set_handler(drive, ide_pc_intr, timeout); 475 ide_set_handler(drive, ide_pc_intr, timeout);
495 return ide_started; 476 return ide_started;
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index cafc67d9e2e8..cb942a9b580f 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -297,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
297 return tape; 297 return tape;
298} 298}
299 299
300static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 300static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
301 unsigned int bcount) 301 unsigned int bcount)
302{ 302{
303 struct idetape_bh *bh = pc->bh; 303 struct idetape_bh *bh = pc->bh;
304 int count; 304 int count;
305 305
306 while (bcount) { 306 while (bcount) {
307 if (bh == NULL) { 307 if (bh == NULL)
308 printk(KERN_ERR "ide-tape: bh == NULL in " 308 break;
309 "idetape_input_buffers\n");
310 ide_pad_transfer(drive, 0, bcount);
311 return;
312 }
313 count = min( 309 count = min(
314 (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), 310 (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
315 bcount); 311 bcount);
@@ -323,21 +319,21 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
323 atomic_set(&bh->b_count, 0); 319 atomic_set(&bh->b_count, 0);
324 } 320 }
325 } 321 }
322
326 pc->bh = bh; 323 pc->bh = bh;
324
325 return bcount;
327} 326}
328 327
329static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 328static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
330 unsigned int bcount) 329 unsigned int bcount)
331{ 330{
332 struct idetape_bh *bh = pc->bh; 331 struct idetape_bh *bh = pc->bh;
333 int count; 332 int count;
334 333
335 while (bcount) { 334 while (bcount) {
336 if (bh == NULL) { 335 if (bh == NULL)
337 printk(KERN_ERR "ide-tape: bh == NULL in %s\n", 336 break;
338 __func__);
339 return;
340 }
341 count = min((unsigned int)pc->b_count, (unsigned int)bcount); 337 count = min((unsigned int)pc->b_count, (unsigned int)bcount);
342 drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); 338 drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
343 bcount -= count; 339 bcount -= count;
@@ -352,6 +348,8 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
352 } 348 }
353 } 349 }
354 } 350 }
351
352 return bcount;
355} 353}
356 354
357static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) 355static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
@@ -563,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
563static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 561static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
564 unsigned int bcount, int write) 562 unsigned int bcount, int write)
565{ 563{
564 unsigned int bleft;
565
566 if (write) 566 if (write)
567 idetape_output_buffers(drive, pc, bcount); 567 bleft = idetape_output_buffers(drive, pc, bcount);
568 else 568 else
569 idetape_input_buffers(drive, pc, bcount); 569 bleft = idetape_input_buffers(drive, pc, bcount);
570 570
571 return bcount; 571 return bcount - bleft;
572} 572}
573 573
574/* 574/*