diff options
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r-- | drivers/ide/ide-floppy.c | 123 |
1 files changed, 41 insertions, 82 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 04a357808f2e..ff8232ef9659 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -369,27 +369,6 @@ typedef struct ide_floppy_obj { | |||
369 | #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 | 369 | #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 |
370 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 | 370 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 |
371 | 371 | ||
372 | #if 0 | ||
373 | /* | ||
374 | * Special requests for our block device strategy routine. | ||
375 | */ | ||
376 | #define IDEFLOPPY_FIRST_RQ 90 | ||
377 | |||
378 | /* | ||
379 | * IDEFLOPPY_PC_RQ is used to queue a packet command in the request queue. | ||
380 | */ | ||
381 | #define IDEFLOPPY_PC_RQ 90 | ||
382 | |||
383 | #define IDEFLOPPY_LAST_RQ 90 | ||
384 | |||
385 | /* | ||
386 | * A macro which can be used to check if a given request command | ||
387 | * originated in the driver or in the buffer cache layer. | ||
388 | */ | ||
389 | #define IDEFLOPPY_RQ_CMD(cmd) ((cmd >= IDEFLOPPY_FIRST_RQ) && (cmd <= IDEFLOPPY_LAST_RQ)) | ||
390 | |||
391 | #endif | ||
392 | |||
393 | /* | 372 | /* |
394 | * Error codes which are returned in rq->errors to the higher part | 373 | * Error codes which are returned in rq->errors to the higher part |
395 | * of the driver. | 374 | * of the driver. |
@@ -793,9 +772,8 @@ static void idefloppy_retry_pc (ide_drive_t *drive) | |||
793 | { | 772 | { |
794 | idefloppy_pc_t *pc; | 773 | idefloppy_pc_t *pc; |
795 | struct request *rq; | 774 | struct request *rq; |
796 | atapi_error_t error; | ||
797 | 775 | ||
798 | error.all = HWIF(drive)->INB(IDE_ERROR_REG); | 776 | (void)drive->hwif->INB(IDE_ERROR_REG); |
799 | pc = idefloppy_next_pc_storage(drive); | 777 | pc = idefloppy_next_pc_storage(drive); |
800 | rq = idefloppy_next_rq_storage(drive); | 778 | rq = idefloppy_next_rq_storage(drive); |
801 | idefloppy_create_request_sense_cmd(pc); | 779 | idefloppy_create_request_sense_cmd(pc); |
@@ -809,12 +787,12 @@ static void idefloppy_retry_pc (ide_drive_t *drive) | |||
809 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | 787 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) |
810 | { | 788 | { |
811 | idefloppy_floppy_t *floppy = drive->driver_data; | 789 | idefloppy_floppy_t *floppy = drive->driver_data; |
812 | atapi_status_t status; | 790 | ide_hwif_t *hwif = drive->hwif; |
813 | atapi_bcount_t bcount; | ||
814 | atapi_ireason_t ireason; | ||
815 | idefloppy_pc_t *pc = floppy->pc; | 791 | idefloppy_pc_t *pc = floppy->pc; |
816 | struct request *rq = pc->rq; | 792 | struct request *rq = pc->rq; |
817 | unsigned int temp; | 793 | unsigned int temp; |
794 | u16 bcount; | ||
795 | u8 stat, ireason; | ||
818 | 796 | ||
819 | debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n", | 797 | debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n", |
820 | __FUNCTION__); | 798 | __FUNCTION__); |
@@ -830,16 +808,16 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
830 | } | 808 | } |
831 | 809 | ||
832 | /* Clear the interrupt */ | 810 | /* Clear the interrupt */ |
833 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 811 | stat = drive->hwif->INB(IDE_STATUS_REG); |
834 | 812 | ||
835 | if (!status.b.drq) { /* No more interrupts */ | 813 | if ((stat & DRQ_STAT) == 0) { /* No more interrupts */ |
836 | debug_log(KERN_INFO "Packet command completed, %d bytes " | 814 | debug_log(KERN_INFO "Packet command completed, %d bytes " |
837 | "transferred\n", pc->actually_transferred); | 815 | "transferred\n", pc->actually_transferred); |
838 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); | 816 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); |
839 | 817 | ||
840 | local_irq_enable_in_hardirq(); | 818 | local_irq_enable_in_hardirq(); |
841 | 819 | ||
842 | if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { | 820 | if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) { |
843 | /* Error detected */ | 821 | /* Error detected */ |
844 | debug_log(KERN_INFO "ide-floppy: %s: I/O error\n", | 822 | debug_log(KERN_INFO "ide-floppy: %s: I/O error\n", |
845 | drive->name); | 823 | drive->name); |
@@ -870,32 +848,32 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
870 | } | 848 | } |
871 | 849 | ||
872 | /* Get the number of bytes to transfer */ | 850 | /* Get the number of bytes to transfer */ |
873 | bcount.b.high = HWIF(drive)->INB(IDE_BCOUNTH_REG); | 851 | bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) | |
874 | bcount.b.low = HWIF(drive)->INB(IDE_BCOUNTL_REG); | 852 | hwif->INB(IDE_BCOUNTL_REG); |
875 | /* on this interrupt */ | 853 | /* on this interrupt */ |
876 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 854 | ireason = hwif->INB(IDE_IREASON_REG); |
877 | 855 | ||
878 | if (ireason.b.cod) { | 856 | if (ireason & CD) { |
879 | printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); | 857 | printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); |
880 | return ide_do_reset(drive); | 858 | return ide_do_reset(drive); |
881 | } | 859 | } |
882 | if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { | 860 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { |
883 | /* Hopefully, we will never get here */ | 861 | /* Hopefully, we will never get here */ |
884 | printk(KERN_ERR "ide-floppy: We wanted to %s, ", | 862 | printk(KERN_ERR "ide-floppy: We wanted to %s, ", |
885 | ireason.b.io ? "Write":"Read"); | 863 | (ireason & IO) ? "Write" : "Read"); |
886 | printk(KERN_ERR "but the floppy wants us to %s !\n", | 864 | printk(KERN_ERR "but the floppy wants us to %s !\n", |
887 | ireason.b.io ? "Read":"Write"); | 865 | (ireason & IO) ? "Read" : "Write"); |
888 | return ide_do_reset(drive); | 866 | return ide_do_reset(drive); |
889 | } | 867 | } |
890 | if (!test_bit(PC_WRITING, &pc->flags)) { | 868 | if (!test_bit(PC_WRITING, &pc->flags)) { |
891 | /* Reading - Check that we have enough space */ | 869 | /* Reading - Check that we have enough space */ |
892 | temp = pc->actually_transferred + bcount.all; | 870 | temp = pc->actually_transferred + bcount; |
893 | if (temp > pc->request_transfer) { | 871 | if (temp > pc->request_transfer) { |
894 | if (temp > pc->buffer_size) { | 872 | if (temp > pc->buffer_size) { |
895 | printk(KERN_ERR "ide-floppy: The floppy wants " | 873 | printk(KERN_ERR "ide-floppy: The floppy wants " |
896 | "to send us more data than expected " | 874 | "to send us more data than expected " |
897 | "- discarding data\n"); | 875 | "- discarding data\n"); |
898 | idefloppy_discard_data(drive,bcount.all); | 876 | idefloppy_discard_data(drive, bcount); |
899 | BUG_ON(HWGROUP(drive)->handler != NULL); | 877 | BUG_ON(HWGROUP(drive)->handler != NULL); |
900 | ide_set_handler(drive, | 878 | ide_set_handler(drive, |
901 | &idefloppy_pc_intr, | 879 | &idefloppy_pc_intr, |
@@ -911,23 +889,21 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
911 | if (test_bit(PC_WRITING, &pc->flags)) { | 889 | if (test_bit(PC_WRITING, &pc->flags)) { |
912 | if (pc->buffer != NULL) | 890 | if (pc->buffer != NULL) |
913 | /* Write the current buffer */ | 891 | /* Write the current buffer */ |
914 | HWIF(drive)->atapi_output_bytes(drive, | 892 | hwif->atapi_output_bytes(drive, pc->current_position, |
915 | pc->current_position, | 893 | bcount); |
916 | bcount.all); | ||
917 | else | 894 | else |
918 | idefloppy_output_buffers(drive, pc, bcount.all); | 895 | idefloppy_output_buffers(drive, pc, bcount); |
919 | } else { | 896 | } else { |
920 | if (pc->buffer != NULL) | 897 | if (pc->buffer != NULL) |
921 | /* Read the current buffer */ | 898 | /* Read the current buffer */ |
922 | HWIF(drive)->atapi_input_bytes(drive, | 899 | hwif->atapi_input_bytes(drive, pc->current_position, |
923 | pc->current_position, | 900 | bcount); |
924 | bcount.all); | ||
925 | else | 901 | else |
926 | idefloppy_input_buffers(drive, pc, bcount.all); | 902 | idefloppy_input_buffers(drive, pc, bcount); |
927 | } | 903 | } |
928 | /* Update the current position */ | 904 | /* Update the current position */ |
929 | pc->actually_transferred += bcount.all; | 905 | pc->actually_transferred += bcount; |
930 | pc->current_position += bcount.all; | 906 | pc->current_position += bcount; |
931 | 907 | ||
932 | BUG_ON(HWGROUP(drive)->handler != NULL); | 908 | BUG_ON(HWGROUP(drive)->handler != NULL); |
933 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ | 909 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ |
@@ -943,15 +919,15 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) | |||
943 | { | 919 | { |
944 | ide_startstop_t startstop; | 920 | ide_startstop_t startstop; |
945 | idefloppy_floppy_t *floppy = drive->driver_data; | 921 | idefloppy_floppy_t *floppy = drive->driver_data; |
946 | atapi_ireason_t ireason; | 922 | u8 ireason; |
947 | 923 | ||
948 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | 924 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { |
949 | printk(KERN_ERR "ide-floppy: Strange, packet command " | 925 | printk(KERN_ERR "ide-floppy: Strange, packet command " |
950 | "initiated yet DRQ isn't asserted\n"); | 926 | "initiated yet DRQ isn't asserted\n"); |
951 | return startstop; | 927 | return startstop; |
952 | } | 928 | } |
953 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 929 | ireason = drive->hwif->INB(IDE_IREASON_REG); |
954 | if (!ireason.b.cod || ireason.b.io) { | 930 | if ((ireason & CD) == 0 || (ireason & IO)) { |
955 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " | 931 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " |
956 | "issuing a packet command\n"); | 932 | "issuing a packet command\n"); |
957 | return ide_do_reset(drive); | 933 | return ide_do_reset(drive); |
@@ -991,15 +967,15 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) | |||
991 | { | 967 | { |
992 | idefloppy_floppy_t *floppy = drive->driver_data; | 968 | idefloppy_floppy_t *floppy = drive->driver_data; |
993 | ide_startstop_t startstop; | 969 | ide_startstop_t startstop; |
994 | atapi_ireason_t ireason; | 970 | u8 ireason; |
995 | 971 | ||
996 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | 972 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { |
997 | printk(KERN_ERR "ide-floppy: Strange, packet command " | 973 | printk(KERN_ERR "ide-floppy: Strange, packet command " |
998 | "initiated yet DRQ isn't asserted\n"); | 974 | "initiated yet DRQ isn't asserted\n"); |
999 | return startstop; | 975 | return startstop; |
1000 | } | 976 | } |
1001 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 977 | ireason = drive->hwif->INB(IDE_IREASON_REG); |
1002 | if (!ireason.b.cod || ireason.b.io) { | 978 | if ((ireason & CD) == 0 || (ireason & IO)) { |
1003 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " | 979 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " |
1004 | "while issuing a packet command\n"); | 980 | "while issuing a packet command\n"); |
1005 | return ide_do_reset(drive); | 981 | return ide_do_reset(drive); |
@@ -1041,21 +1017,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p | |||
1041 | { | 1017 | { |
1042 | idefloppy_floppy_t *floppy = drive->driver_data; | 1018 | idefloppy_floppy_t *floppy = drive->driver_data; |
1043 | ide_hwif_t *hwif = drive->hwif; | 1019 | ide_hwif_t *hwif = drive->hwif; |
1044 | atapi_feature_t feature; | ||
1045 | atapi_bcount_t bcount; | ||
1046 | ide_handler_t *pkt_xfer_routine; | 1020 | ide_handler_t *pkt_xfer_routine; |
1047 | 1021 | u16 bcount; | |
1048 | #if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone | 1022 | u8 dma; |
1049 | and have lived on another thread's stack; that stack may have become | ||
1050 | unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */ | ||
1051 | #if IDEFLOPPY_DEBUG_BUGS | ||
1052 | if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && | ||
1053 | pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { | ||
1054 | printk(KERN_ERR "ide-floppy: possible ide-floppy.c bug - " | ||
1055 | "Two request sense in serial were issued\n"); | ||
1056 | } | ||
1057 | #endif /* IDEFLOPPY_DEBUG_BUGS */ | ||
1058 | #endif | ||
1059 | 1023 | ||
1060 | if (floppy->failed_pc == NULL && | 1024 | if (floppy->failed_pc == NULL && |
1061 | pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) | 1025 | pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) |
@@ -1093,25 +1057,20 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p | |||
1093 | /* We haven't transferred any data yet */ | 1057 | /* We haven't transferred any data yet */ |
1094 | pc->actually_transferred = 0; | 1058 | pc->actually_transferred = 0; |
1095 | pc->current_position = pc->buffer; | 1059 | pc->current_position = pc->buffer; |
1096 | bcount.all = min(pc->request_transfer, 63 * 1024); | 1060 | bcount = min(pc->request_transfer, 63 * 1024); |
1097 | 1061 | ||
1098 | if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) | 1062 | if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) |
1099 | ide_dma_off(drive); | 1063 | ide_dma_off(drive); |
1100 | 1064 | ||
1101 | feature.all = 0; | 1065 | dma = 0; |
1102 | 1066 | ||
1103 | if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) | 1067 | if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) |
1104 | feature.b.dma = !hwif->dma_setup(drive); | 1068 | dma = !hwif->dma_setup(drive); |
1105 | 1069 | ||
1106 | if (IDE_CONTROL_REG) | 1070 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | |
1107 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | 1071 | IDE_TFLAG_OUT_DEVICE, bcount, dma); |
1108 | /* Use PIO/DMA */ | ||
1109 | HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG); | ||
1110 | HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG); | ||
1111 | HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG); | ||
1112 | HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG); | ||
1113 | 1072 | ||
1114 | if (feature.b.dma) { /* Begin DMA, if necessary */ | 1073 | if (dma) { /* Begin DMA, if necessary */ |
1115 | set_bit(PC_DMA_IN_PROGRESS, &pc->flags); | 1074 | set_bit(PC_DMA_IN_PROGRESS, &pc->flags); |
1116 | hwif->dma_start(drive); | 1075 | hwif->dma_start(drive); |
1117 | } | 1076 | } |
@@ -1665,14 +1624,14 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) | |||
1665 | /* Else assume format_unit has finished, and we're | 1624 | /* Else assume format_unit has finished, and we're |
1666 | ** at 0x10000 */ | 1625 | ** at 0x10000 */ |
1667 | } else { | 1626 | } else { |
1668 | atapi_status_t status; | ||
1669 | unsigned long flags; | 1627 | unsigned long flags; |
1628 | u8 stat; | ||
1670 | 1629 | ||
1671 | local_irq_save(flags); | 1630 | local_irq_save(flags); |
1672 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 1631 | stat = drive->hwif->INB(IDE_STATUS_REG); |
1673 | local_irq_restore(flags); | 1632 | local_irq_restore(flags); |
1674 | 1633 | ||
1675 | progress_indication = !status.b.dsc ? 0 : 0x10000; | 1634 | progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; |
1676 | } | 1635 | } |
1677 | if (put_user(progress_indication, arg)) | 1636 | if (put_user(progress_indication, arg)) |
1678 | return (-EFAULT); | 1637 | return (-EFAULT); |