diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 185 |
1 files changed, 88 insertions, 97 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ffbaa6d578ff..3ce1eafef5e4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -311,7 +311,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
311 | { | 311 | { |
312 | ide_hwif_t *hwif = drive->hwif; | 312 | ide_hwif_t *hwif = drive->hwif; |
313 | struct request *rq = hwif->rq; | 313 | struct request *rq = hwif->rq; |
314 | int err, sense_key; | 314 | int err, sense_key, do_end_request = 0; |
315 | u8 quiet = rq->cmd_flags & REQ_QUIET; | 315 | u8 quiet = rq->cmd_flags & REQ_QUIET; |
316 | 316 | ||
317 | /* get the IDE error register */ | 317 | /* get the IDE error register */ |
@@ -330,117 +330,108 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
330 | */ | 330 | */ |
331 | rq->cmd_flags |= REQ_FAILED; | 331 | rq->cmd_flags |= REQ_FAILED; |
332 | return 2; | 332 | return 2; |
333 | } else { | 333 | } |
334 | int do_end_request = 0; | ||
335 | |||
336 | /* | ||
337 | * if we have an error, pass back CHECK_CONDITION as the | ||
338 | * scsi status byte | ||
339 | */ | ||
340 | if (blk_pc_request(rq) && !rq->errors) | ||
341 | rq->errors = SAM_STAT_CHECK_CONDITION; | ||
342 | 334 | ||
343 | if (blk_noretry_request(rq)) | 335 | /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ |
344 | do_end_request = 1; | 336 | if (blk_pc_request(rq) && !rq->errors) |
337 | rq->errors = SAM_STAT_CHECK_CONDITION; | ||
345 | 338 | ||
346 | switch (sense_key) { | 339 | if (blk_noretry_request(rq)) |
347 | case NOT_READY: | 340 | do_end_request = 1; |
348 | if (blk_fs_request(rq) == 0 || | ||
349 | rq_data_dir(rq) == READ) { | ||
350 | cdrom_saw_media_change(drive); | ||
351 | 341 | ||
352 | if (blk_fs_request(rq) && !quiet) | 342 | switch (sense_key) { |
353 | printk(KERN_ERR PFX "%s: tray open\n", | 343 | case NOT_READY: |
354 | drive->name); | 344 | if (blk_fs_request(rq) == 0 || rq_data_dir(rq) == READ) { |
355 | } else { | ||
356 | if (ide_cd_breathe(drive, rq)) | ||
357 | return 1; | ||
358 | } | ||
359 | do_end_request = 1; | ||
360 | break; | ||
361 | case UNIT_ATTENTION: | ||
362 | cdrom_saw_media_change(drive); | 345 | cdrom_saw_media_change(drive); |
363 | 346 | ||
364 | if (blk_fs_request(rq) == 0) | 347 | if (blk_fs_request(rq) && !quiet) |
365 | return 0; | 348 | printk(KERN_ERR PFX "%s: tray open\n", |
366 | /* | 349 | drive->name); |
367 | * Arrange to retry the request but be sure to give up | 350 | } else { |
368 | * if we've retried too many times. | 351 | if (ide_cd_breathe(drive, rq)) |
369 | */ | ||
370 | if (++rq->errors > ERROR_MAX) | ||
371 | do_end_request = 1; | ||
372 | break; | ||
373 | case ILLEGAL_REQUEST: | ||
374 | /* | ||
375 | * Don't print error message for this condition-- | ||
376 | * SFF8090i indicates that 5/24/00 is the correct | ||
377 | * response to a request to close the tray if the | ||
378 | * drive doesn't have that capability. | ||
379 | * cdrom_log_sense() knows this! | ||
380 | */ | ||
381 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT) | ||
382 | break; | ||
383 | /* fall-through */ | ||
384 | case DATA_PROTECT: | ||
385 | /* | ||
386 | * No point in retrying after an illegal request or data | ||
387 | * protect error. | ||
388 | */ | ||
389 | if (!quiet) | ||
390 | ide_dump_status(drive, "command error", stat); | ||
391 | do_end_request = 1; | ||
392 | break; | ||
393 | case MEDIUM_ERROR: | ||
394 | /* | ||
395 | * No point in re-trying a zillion times on a bad | ||
396 | * sector. If we got here the error is not correctable. | ||
397 | */ | ||
398 | if (!quiet) | ||
399 | ide_dump_status(drive, "media error " | ||
400 | "(bad sector)", stat); | ||
401 | do_end_request = 1; | ||
402 | break; | ||
403 | case BLANK_CHECK: | ||
404 | /* disk appears blank ?? */ | ||
405 | if (!quiet) | ||
406 | ide_dump_status(drive, "media error (blank)", | ||
407 | stat); | ||
408 | do_end_request = 1; | ||
409 | break; | ||
410 | default: | ||
411 | if (blk_fs_request(rq) == 0) | ||
412 | break; | ||
413 | if (err & ~ATA_ABORTED) { | ||
414 | /* go to the default handler for other errors */ | ||
415 | ide_error(drive, "cdrom_decode_status", stat); | ||
416 | return 1; | 352 | return 1; |
417 | } else if (++rq->errors > ERROR_MAX) | ||
418 | /* we've racked up too many retries, abort */ | ||
419 | do_end_request = 1; | ||
420 | } | 353 | } |
354 | do_end_request = 1; | ||
355 | break; | ||
356 | case UNIT_ATTENTION: | ||
357 | cdrom_saw_media_change(drive); | ||
421 | 358 | ||
422 | if (blk_fs_request(rq) == 0) { | 359 | if (blk_fs_request(rq) == 0) |
423 | rq->cmd_flags |= REQ_FAILED; | 360 | return 0; |
424 | do_end_request = 1; | ||
425 | } | ||
426 | 361 | ||
427 | /* | 362 | /* |
428 | * End a request through request sense analysis when we have | 363 | * Arrange to retry the request but be sure to give up if we've |
429 | * sense data. We need this in order to perform end of media | 364 | * retried too many times. |
430 | * processing. | ||
431 | */ | 365 | */ |
432 | if (do_end_request) | 366 | if (++rq->errors > ERROR_MAX) |
433 | goto end_request; | 367 | do_end_request = 1; |
434 | 368 | break; | |
369 | case ILLEGAL_REQUEST: | ||
370 | /* | ||
371 | * Don't print error message for this condition -- SFF8090i | ||
372 | * indicates that 5/24/00 is the correct response to a request | ||
373 | * to close the tray if the drive doesn't have that capability. | ||
374 | * | ||
375 | * cdrom_log_sense() knows this! | ||
376 | */ | ||
377 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT) | ||
378 | break; | ||
379 | /* fall-through */ | ||
380 | case DATA_PROTECT: | ||
435 | /* | 381 | /* |
436 | * If we got a CHECK_CONDITION status, queue | 382 | * No point in retrying after an illegal request or data |
437 | * a request sense command. | 383 | * protect error. |
438 | */ | 384 | */ |
439 | if (stat & ATA_ERR) | 385 | if (!quiet) |
440 | cdrom_queue_request_sense(drive, NULL, NULL); | 386 | ide_dump_status(drive, "command error", stat); |
441 | return 1; | 387 | do_end_request = 1; |
388 | break; | ||
389 | case MEDIUM_ERROR: | ||
390 | /* | ||
391 | * No point in re-trying a zillion times on a bad sector. | ||
392 | * If we got here the error is not correctable. | ||
393 | */ | ||
394 | if (!quiet) | ||
395 | ide_dump_status(drive, "media error " | ||
396 | "(bad sector)", stat); | ||
397 | do_end_request = 1; | ||
398 | break; | ||
399 | case BLANK_CHECK: | ||
400 | /* disk appears blank? */ | ||
401 | if (!quiet) | ||
402 | ide_dump_status(drive, "media error (blank)", | ||
403 | stat); | ||
404 | do_end_request = 1; | ||
405 | break; | ||
406 | default: | ||
407 | if (blk_fs_request(rq) == 0) | ||
408 | break; | ||
409 | if (err & ~ATA_ABORTED) { | ||
410 | /* go to the default handler for other errors */ | ||
411 | ide_error(drive, "cdrom_decode_status", stat); | ||
412 | return 1; | ||
413 | } else if (++rq->errors > ERROR_MAX) | ||
414 | /* we've racked up too many retries, abort */ | ||
415 | do_end_request = 1; | ||
442 | } | 416 | } |
443 | 417 | ||
418 | if (blk_fs_request(rq) == 0) { | ||
419 | rq->cmd_flags |= REQ_FAILED; | ||
420 | do_end_request = 1; | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * End a request through request sense analysis when we have sense data. | ||
425 | * We need this in order to perform end of media processing. | ||
426 | */ | ||
427 | if (do_end_request) | ||
428 | goto end_request; | ||
429 | |||
430 | /* if we got a CHECK_CONDITION status, queue a request sense command */ | ||
431 | if (stat & ATA_ERR) | ||
432 | cdrom_queue_request_sense(drive, NULL, NULL); | ||
433 | return 1; | ||
434 | |||
444 | end_request: | 435 | end_request: |
445 | if (stat & ATA_ERR) { | 436 | if (stat & ATA_ERR) { |
446 | struct request_queue *q = drive->queue; | 437 | struct request_queue *q = drive->queue; |