aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-floppy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r--drivers/ide/ide-floppy.c128
1 files changed, 3 insertions, 125 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 70aef97fb8bc..0f3602a5efb0 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -388,132 +388,10 @@ static void idefloppy_retry_pc(ide_drive_t *drive)
388static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) 388static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
389{ 389{
390 idefloppy_floppy_t *floppy = drive->driver_data; 390 idefloppy_floppy_t *floppy = drive->driver_data;
391 ide_hwif_t *hwif = drive->hwif;
392 struct ide_atapi_pc *pc = floppy->pc;
393 struct request *rq = pc->rq;
394 xfer_func_t *xferfunc;
395 unsigned int temp;
396 int dma_error = 0;
397 u16 bcount;
398 u8 stat, ireason;
399
400 debug_log("Enter %s - interrupt handler\n", __func__);
401
402 /* Clear the interrupt */
403 stat = ide_read_status(drive);
404
405 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
406 dma_error = hwif->dma_ops->dma_end(drive);
407 if (dma_error) {
408 printk(KERN_ERR "%s: DMA %s error\n", drive->name,
409 rq_data_dir(rq) ? "write" : "read");
410 pc->flags |= PC_FLAG_DMA_ERROR;
411 } else {
412 pc->xferred = pc->req_xfer;
413 idefloppy_update_buffers(drive, pc);
414 }
415 debug_log("%s: DMA finished\n", drive->name);
416 }
417
418 /* No more interrupts */
419 if ((stat & DRQ_STAT) == 0) {
420 debug_log("Packet command completed, %d bytes transferred\n",
421 pc->xferred);
422 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
423
424 local_irq_enable_in_hardirq();
425
426 if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
427 /* Error detected */
428 debug_log("%s: I/O error\n", drive->name);
429 rq->errors++;
430 if (pc->c[0] == GPCMD_REQUEST_SENSE) {
431 printk(KERN_ERR "%s: I/O error in request sense"
432 " command\n", drive->name);
433 return ide_do_reset(drive);
434 }
435
436 debug_log("[cmd %x]: check condition\n", pc->c[0]);
437
438 /* Retry operation */
439 idefloppy_retry_pc(drive);
440 /* queued, but not started */
441 return ide_stopped;
442 }
443 pc->error = 0;
444 /* Command finished - Call the callback function */
445 pc->callback(drive);
446 return ide_stopped;
447 }
448
449 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
450 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
451 printk(KERN_ERR "%s: The device wants to issue more interrupts "
452 "in DMA mode\n", drive->name);
453 ide_dma_off(drive);
454 return ide_do_reset(drive);
455 }
456
457 /* Get the number of bytes to transfer */
458 bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
459 hwif->INB(hwif->io_ports.lbam_addr);
460 /* on this interrupt */
461 ireason = hwif->INB(hwif->io_ports.nsect_addr);
462
463 if (ireason & CD) {
464 printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
465 return ide_do_reset(drive);
466 }
467 if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
468 /* Hopefully, we will never get here */
469 printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
470 "to %s!\n", drive->name,
471 (ireason & IO) ? "Write" : "Read",
472 (ireason & IO) ? "Read" : "Write");
473 return ide_do_reset(drive);
474 }
475 if (!(pc->flags & PC_FLAG_WRITING)) {
476 /* Reading - Check that we have enough space */
477 temp = pc->xferred + bcount;
478 if (temp > pc->req_xfer) {
479 if (temp > pc->buf_size) {
480 printk(KERN_ERR "%s: The device wants to send "
481 "us more data than expected - "
482 "discarding data\n",
483 drive->name);
484 ide_pad_transfer(drive, 0, bcount);
485
486 ide_set_handler(drive,
487 &idefloppy_pc_intr,
488 IDEFLOPPY_WAIT_CMD,
489 NULL);
490 return ide_started;
491 }
492 debug_log("The device wants to send us more data than "
493 "expected - allowing transfer\n");
494 }
495 }
496 if (pc->flags & PC_FLAG_WRITING)
497 xferfunc = hwif->output_data;
498 else
499 xferfunc = hwif->input_data;
500
501 if (pc->buf)
502 xferfunc(drive, NULL, pc->cur_pos, bcount);
503 else
504 ide_floppy_io_buffers(drive, pc, bcount,
505 !!(pc->flags & PC_FLAG_WRITING));
506
507 /* Update the current position */
508 pc->xferred += bcount;
509 pc->cur_pos += bcount;
510
511 debug_log("[cmd %x] transferred %d bytes on that intr.\n",
512 pc->c[0], bcount);
513 391
514 /* And set the interrupt handler again */ 392 return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
515 ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); 393 IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers,
516 return ide_started; 394 idefloppy_retry_pc, NULL, ide_floppy_io_buffers);
517} 395}
518 396
519/* 397/*