diff options
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1dc4a9ec36fc..8b6af1e0ed2d 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -1104,19 +1104,22 @@ static void idetape_postpone_request (ide_drive_t *drive) | |||
1104 | ide_stall_queue(drive, tape->dsc_polling_frequency); | 1104 | ide_stall_queue(drive, tape->dsc_polling_frequency); |
1105 | } | 1105 | } |
1106 | 1106 | ||
1107 | typedef void idetape_io_buf(ide_drive_t *, idetape_pc_t *, unsigned int); | ||
1108 | |||
1107 | /* | 1109 | /* |
1108 | * idetape_pc_intr is the usual interrupt handler which will be called | 1110 | * This is the usual interrupt handler which will be called during a packet |
1109 | * during a packet command. We will transfer some of the data (as | 1111 | * command. We will transfer some of the data (as requested by the drive) and |
1110 | * requested by the drive) and will re-point interrupt handler to us. | 1112 | * will re-point interrupt handler to us. When data transfer is finished, we |
1111 | * When data transfer is finished, we will act according to the | 1113 | * will act according to the algorithm described before |
1112 | * algorithm described before idetape_issue_packet_command. | 1114 | * idetape_issue_packet_command. |
1113 | * | ||
1114 | */ | 1115 | */ |
1115 | static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | 1116 | static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) |
1116 | { | 1117 | { |
1117 | ide_hwif_t *hwif = drive->hwif; | 1118 | ide_hwif_t *hwif = drive->hwif; |
1118 | idetape_tape_t *tape = drive->driver_data; | 1119 | idetape_tape_t *tape = drive->driver_data; |
1119 | idetape_pc_t *pc = tape->pc; | 1120 | idetape_pc_t *pc = tape->pc; |
1121 | xfer_func_t *xferfunc; | ||
1122 | idetape_io_buf *iobuf; | ||
1120 | unsigned int temp; | 1123 | unsigned int temp; |
1121 | #if SIMULATE_ERRORS | 1124 | #if SIMULATE_ERRORS |
1122 | static int error_sim_count = 0; | 1125 | static int error_sim_count = 0; |
@@ -1184,7 +1187,8 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1184 | debug_log(DBG_ERR, "%s: I/O error\n", tape->name); | 1187 | debug_log(DBG_ERR, "%s: I/O error\n", tape->name); |
1185 | 1188 | ||
1186 | if (pc->c[0] == REQUEST_SENSE) { | 1189 | if (pc->c[0] == REQUEST_SENSE) { |
1187 | printk(KERN_ERR "ide-tape: I/O error in request sense command\n"); | 1190 | printk(KERN_ERR "ide-tape: I/O error in request" |
1191 | " sense command\n"); | ||
1188 | return ide_do_reset(drive); | 1192 | return ide_do_reset(drive); |
1189 | } | 1193 | } |
1190 | debug_log(DBG_ERR, "[cmd %x]: check condition\n", | 1194 | debug_log(DBG_ERR, "[cmd %x]: check condition\n", |
@@ -1223,7 +1227,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1223 | ireason = hwif->INB(IDE_IREASON_REG); | 1227 | ireason = hwif->INB(IDE_IREASON_REG); |
1224 | 1228 | ||
1225 | if (ireason & CD) { | 1229 | if (ireason & CD) { |
1226 | printk(KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); | 1230 | printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__); |
1227 | return ide_do_reset(drive); | 1231 | return ide_do_reset(drive); |
1228 | } | 1232 | } |
1229 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { | 1233 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { |
@@ -1239,31 +1243,29 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1239 | temp = pc->actually_transferred + bcount; | 1243 | temp = pc->actually_transferred + bcount; |
1240 | if (temp > pc->request_transfer) { | 1244 | if (temp > pc->request_transfer) { |
1241 | if (temp > pc->buffer_size) { | 1245 | if (temp > pc->buffer_size) { |
1242 | printk(KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); | 1246 | printk(KERN_ERR "ide-tape: The tape wants to " |
1247 | "send us more data than expected " | ||
1248 | "- discarding data\n"); | ||
1243 | idetape_discard_data(drive, bcount); | 1249 | idetape_discard_data(drive, bcount); |
1244 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | 1250 | ide_set_handler(drive, &idetape_pc_intr, |
1251 | IDETAPE_WAIT_CMD, NULL); | ||
1245 | return ide_started; | 1252 | return ide_started; |
1246 | } | 1253 | } |
1247 | debug_log(DBG_SENSE, "The tape wants to send us more " | 1254 | debug_log(DBG_SENSE, "The tape wants to send us more " |
1248 | "data than expected - allowing transfer\n"); | 1255 | "data than expected - allowing transfer\n"); |
1249 | |||
1250 | } | 1256 | } |
1251 | } | 1257 | iobuf = &idetape_input_buffers; |
1252 | if (test_bit(PC_WRITING, &pc->flags)) { | 1258 | xferfunc = hwif->atapi_input_bytes; |
1253 | if (pc->bh != NULL) | ||
1254 | idetape_output_buffers(drive, pc, bcount); | ||
1255 | else | ||
1256 | /* Write the current buffer */ | ||
1257 | hwif->atapi_output_bytes(drive, pc->current_position, | ||
1258 | bcount); | ||
1259 | } else { | 1259 | } else { |
1260 | if (pc->bh != NULL) | 1260 | iobuf = &idetape_output_buffers; |
1261 | idetape_input_buffers(drive, pc, bcount); | 1261 | xferfunc = hwif->atapi_output_bytes; |
1262 | else | ||
1263 | /* Read the current buffer */ | ||
1264 | hwif->atapi_input_bytes(drive, pc->current_position, | ||
1265 | bcount); | ||
1266 | } | 1262 | } |
1263 | |||
1264 | if (pc->bh) | ||
1265 | iobuf(drive, pc, bcount); | ||
1266 | else | ||
1267 | xferfunc(drive, pc->current_position, bcount); | ||
1268 | |||
1267 | /* Update the current position */ | 1269 | /* Update the current position */ |
1268 | pc->actually_transferred += bcount; | 1270 | pc->actually_transferred += bcount; |
1269 | pc->current_position += bcount; | 1271 | pc->current_position += bcount; |