aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c123
1 files changed, 92 insertions, 31 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 6de3cd3d6e8e..654d4cd09847 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -301,7 +301,6 @@
301 301
302#define IDECD_VERSION "4.61" 302#define IDECD_VERSION "4.61"
303 303
304#include <linux/config.h>
305#include <linux/module.h> 304#include <linux/module.h>
306#include <linux/types.h> 305#include <linux/types.h>
307#include <linux/kernel.h> 306#include <linux/kernel.h>
@@ -395,7 +394,8 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
395 * we cannot reliably check if drive can auto-close 394 * we cannot reliably check if drive can auto-close
396 */ 395 */
397 if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) 396 if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
398 log = 0; 397 break;
398 log = 1;
399 break; 399 break;
400 case UNIT_ATTENTION: 400 case UNIT_ATTENTION:
401 /* 401 /*
@@ -417,6 +417,11 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
417 struct request *failed_command, 417 struct request *failed_command,
418 struct request_sense *sense) 418 struct request_sense *sense)
419{ 419{
420 unsigned long sector;
421 unsigned long bio_sectors;
422 unsigned long valid;
423 struct cdrom_info *info = drive->driver_data;
424
420 if (!cdrom_log_sense(drive, failed_command, sense)) 425 if (!cdrom_log_sense(drive, failed_command, sense))
421 return; 426 return;
422 427
@@ -429,6 +434,37 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
429 if (sense->sense_key == 0x05 && sense->asc == 0x24) 434 if (sense->sense_key == 0x05 && sense->asc == 0x24)
430 return; 435 return;
431 436
437 if (sense->error_code == 0x70) { /* Current Error */
438 switch(sense->sense_key) {
439 case MEDIUM_ERROR:
440 case VOLUME_OVERFLOW:
441 case ILLEGAL_REQUEST:
442 if (!sense->valid)
443 break;
444 if (failed_command == NULL ||
445 !blk_fs_request(failed_command))
446 break;
447 sector = (sense->information[0] << 24) |
448 (sense->information[1] << 16) |
449 (sense->information[2] << 8) |
450 (sense->information[3]);
451
452 bio_sectors = bio_sectors(failed_command->bio);
453 if (bio_sectors < 4)
454 bio_sectors = 4;
455 if (drive->queue->hardsect_size == 2048)
456 sector <<= 2; /* Device sector size is 2K */
457 sector &= ~(bio_sectors -1);
458 valid = (sector - failed_command->sector) << 9;
459
460 if (valid < 0)
461 valid = 0;
462 if (sector < get_capacity(info->disk) &&
463 drive->probed_capacity - sector < 4 * 75) {
464 set_capacity(info->disk, sector);
465 }
466 }
467 }
432#if VERBOSE_IDE_CD_ERRORS 468#if VERBOSE_IDE_CD_ERRORS
433 { 469 {
434 int i; 470 int i;
@@ -609,17 +645,23 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
609 sense = failed->sense; 645 sense = failed->sense;
610 failed->sense_len = rq->sense_len; 646 failed->sense_len = rq->sense_len;
611 } 647 }
612 648 cdrom_analyze_sense_data(drive, failed, sense);
613 /* 649 /*
614 * now end failed request 650 * now end failed request
615 */ 651 */
616 spin_lock_irqsave(&ide_lock, flags); 652 if (blk_fs_request(failed)) {
617 end_that_request_chunk(failed, 0, failed->data_len); 653 if (ide_end_dequeued_request(drive, failed, 0,
618 end_that_request_last(failed, 0); 654 failed->hard_nr_sectors))
619 spin_unlock_irqrestore(&ide_lock, flags); 655 BUG();
620 } 656 } else {
621 657 spin_lock_irqsave(&ide_lock, flags);
622 cdrom_analyze_sense_data(drive, failed, sense); 658 end_that_request_chunk(failed, 0,
659 failed->data_len);
660 end_that_request_last(failed, 0);
661 spin_unlock_irqrestore(&ide_lock, flags);
662 }
663 } else
664 cdrom_analyze_sense_data(drive, NULL, sense);
623 } 665 }
624 666
625 if (!rq->current_nr_sectors && blk_fs_request(rq)) 667 if (!rq->current_nr_sectors && blk_fs_request(rq))
@@ -633,6 +675,13 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate)
633 ide_end_request(drive, uptodate, nsectors); 675 ide_end_request(drive, uptodate, nsectors);
634} 676}
635 677
678static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
679{
680 if (stat & 0x80)
681 return;
682 ide_dump_status(drive, msg, stat);
683}
684
636/* Returns 0 if the request should be continued. 685/* Returns 0 if the request should be continued.
637 Returns 1 if the request was ended. */ 686 Returns 1 if the request was ended. */
638static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) 687static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
@@ -761,16 +810,16 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
761 sense_key == DATA_PROTECT) { 810 sense_key == DATA_PROTECT) {
762 /* No point in retrying after an illegal 811 /* No point in retrying after an illegal
763 request or data protect error.*/ 812 request or data protect error.*/
764 ide_dump_status (drive, "command error", stat); 813 ide_dump_status_no_sense (drive, "command error", stat);
765 do_end_request = 1; 814 do_end_request = 1;
766 } else if (sense_key == MEDIUM_ERROR) { 815 } else if (sense_key == MEDIUM_ERROR) {
767 /* No point in re-trying a zillion times on a bad 816 /* No point in re-trying a zillion times on a bad
768 * sector... If we got here the error is not correctable */ 817 * sector... If we got here the error is not correctable */
769 ide_dump_status (drive, "media error (bad sector)", stat); 818 ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
770 do_end_request = 1; 819 do_end_request = 1;
771 } else if (sense_key == BLANK_CHECK) { 820 } else if (sense_key == BLANK_CHECK) {
772 /* Disk appears blank ?? */ 821 /* Disk appears blank ?? */
773 ide_dump_status (drive, "media error (blank)", stat); 822 ide_dump_status_no_sense (drive, "media error (blank)", stat);
774 do_end_request = 1; 823 do_end_request = 1;
775 } else if ((err & ~ABRT_ERR) != 0) { 824 } else if ((err & ~ABRT_ERR) != 0) {
776 /* Go to the default handler 825 /* Go to the default handler
@@ -782,13 +831,27 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
782 do_end_request = 1; 831 do_end_request = 1;
783 } 832 }
784 833
785 if (do_end_request) 834 /* End a request through request sense analysis when we have
786 cdrom_end_request(drive, 0); 835 sense data. We need this in order to perform end of media
787 836 processing */
788 /* If we got a CHECK_CONDITION status, 837
789 queue a request sense command. */ 838 if (do_end_request) {
790 if ((stat & ERR_STAT) != 0) 839 if (stat & ERR_STAT) {
791 cdrom_queue_request_sense(drive, NULL, NULL); 840 unsigned long flags;
841 spin_lock_irqsave(&ide_lock, flags);
842 blkdev_dequeue_request(rq);
843 HWGROUP(drive)->rq = NULL;
844 spin_unlock_irqrestore(&ide_lock, flags);
845
846 cdrom_queue_request_sense(drive, rq->sense, rq);
847 } else
848 cdrom_end_request(drive, 0);
849 } else {
850 /* If we got a CHECK_CONDITION status,
851 queue a request sense command. */
852 if (stat & ERR_STAT)
853 cdrom_queue_request_sense(drive, NULL, NULL);
854 }
792 } else { 855 } else {
793 blk_dump_rq_flags(rq, "ide-cd: bad rq"); 856 blk_dump_rq_flags(rq, "ide-cd: bad rq");
794 cdrom_end_request(drive, 0); 857 cdrom_end_request(drive, 0);
@@ -1491,8 +1554,7 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
1491} 1554}
1492 1555
1493 1556
1494static 1557static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
1495int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
1496{ 1558{
1497 struct request_sense sense; 1559 struct request_sense sense;
1498 int retries = 10; 1560 int retries = 10;
@@ -2220,6 +2282,9 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
2220 toc->capacity = 0x1fffff; 2282 toc->capacity = 0x1fffff;
2221 2283
2222 set_capacity(info->disk, toc->capacity * sectors_per_frame); 2284 set_capacity(info->disk, toc->capacity * sectors_per_frame);
2285 /* Save a private copy of te TOC capacity for error handling */
2286 drive->probed_capacity = toc->capacity * sectors_per_frame;
2287
2223 blk_queue_hardsect_size(drive->queue, 2288 blk_queue_hardsect_size(drive->queue,
2224 sectors_per_frame << SECTOR_BITS); 2289 sectors_per_frame << SECTOR_BITS);
2225 2290
@@ -2342,6 +2407,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
2342 if (!stat && (last_written > toc->capacity)) { 2407 if (!stat && (last_written > toc->capacity)) {
2343 toc->capacity = last_written; 2408 toc->capacity = last_written;
2344 set_capacity(info->disk, toc->capacity * sectors_per_frame); 2409 set_capacity(info->disk, toc->capacity * sectors_per_frame);
2410 drive->probed_capacity = toc->capacity * sectors_per_frame;
2345 } 2411 }
2346 2412
2347 /* Remember that we've read this stuff. */ 2413 /* Remember that we've read this stuff. */
@@ -2698,14 +2764,11 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2698 * any other way to detect this... 2764 * any other way to detect this...
2699 */ 2765 */
2700 if (sense.sense_key == NOT_READY) { 2766 if (sense.sense_key == NOT_READY) {
2701 if (sense.asc == 0x3a) { 2767 if (sense.asc == 0x3a && sense.ascq == 1)
2702 if (sense.ascq == 1) 2768 return CDS_NO_DISC;
2703 return CDS_NO_DISC; 2769 else
2704 else if (sense.ascq == 0 || sense.ascq == 2) 2770 return CDS_TRAY_OPEN;
2705 return CDS_TRAY_OPEN;
2706 }
2707 } 2771 }
2708
2709 return CDS_DRIVE_NOT_READY; 2772 return CDS_DRIVE_NOT_READY;
2710} 2773}
2711 2774
@@ -3463,8 +3526,6 @@ static int ide_cd_probe(ide_drive_t *drive)
3463 drive->driver_data = info; 3526 drive->driver_data = info;
3464 3527
3465 g->minors = 1; 3528 g->minors = 1;
3466 snprintf(g->devfs_name, sizeof(g->devfs_name),
3467 "%s/cd", drive->devfs_name);
3468 g->driverfs_dev = &drive->gendev; 3529 g->driverfs_dev = &drive->gendev;
3469 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; 3530 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3470 if (ide_cdrom_setup(drive)) { 3531 if (ide_cdrom_setup(drive)) {