diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 101 |
1 files changed, 35 insertions, 66 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 57a5f63d6ae3..c7d77f0ad892 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -1068,8 +1068,8 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason) | |||
1068 | return 0; | 1068 | return 0; |
1069 | else if (ireason == 0) { | 1069 | else if (ireason == 0) { |
1070 | /* Whoops... The drive is expecting to receive data from us! */ | 1070 | /* Whoops... The drive is expecting to receive data from us! */ |
1071 | printk(KERN_ERR "%s: read_intr: Drive wants to transfer data the " | 1071 | printk(KERN_ERR "%s: %s: wrong transfer direction!\n", |
1072 | "wrong way!\n", drive->name); | 1072 | drive->name, __FUNCTION__); |
1073 | 1073 | ||
1074 | /* Throw some data at the drive so it doesn't hang | 1074 | /* Throw some data at the drive so it doesn't hang |
1075 | and quit this request. */ | 1075 | and quit this request. */ |
@@ -1086,8 +1086,8 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason) | |||
1086 | return 0; | 1086 | return 0; |
1087 | } else { | 1087 | } else { |
1088 | /* Drive wants a command packet, or invalid ireason... */ | 1088 | /* Drive wants a command packet, or invalid ireason... */ |
1089 | printk(KERN_ERR "%s: read_intr: bad interrupt reason %x\n", drive->name, | 1089 | printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", |
1090 | ireason); | 1090 | drive->name, __FUNCTION__, ireason); |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | cdrom_end_request(drive, 0); | 1093 | cdrom_end_request(drive, 0); |
@@ -1112,8 +1112,11 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) | |||
1112 | */ | 1112 | */ |
1113 | if (dma) { | 1113 | if (dma) { |
1114 | info->dma = 0; | 1114 | info->dma = 0; |
1115 | if ((dma_error = HWIF(drive)->ide_dma_end(drive))) | 1115 | dma_error = HWIF(drive)->ide_dma_end(drive); |
1116 | if (dma_error) { | ||
1117 | printk(KERN_ERR "%s: DMA read error\n", drive->name); | ||
1116 | ide_dma_off(drive); | 1118 | ide_dma_off(drive); |
1119 | } | ||
1117 | } | 1120 | } |
1118 | 1121 | ||
1119 | if (cdrom_decode_status(drive, 0, &stat)) | 1122 | if (cdrom_decode_status(drive, 0, &stat)) |
@@ -1443,7 +1446,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) | |||
1443 | return ide_stopped; | 1446 | return ide_stopped; |
1444 | 1447 | ||
1445 | /* Read the interrupt reason and the transfer length. */ | 1448 | /* Read the interrupt reason and the transfer length. */ |
1446 | ireason = HWIF(drive)->INB(IDE_IREASON_REG); | 1449 | ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; |
1447 | lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); | 1450 | lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); |
1448 | highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); | 1451 | highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); |
1449 | 1452 | ||
@@ -1484,7 +1487,7 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) | |||
1484 | if (thislen > len) thislen = len; | 1487 | if (thislen > len) thislen = len; |
1485 | 1488 | ||
1486 | /* The drive wants to be written to. */ | 1489 | /* The drive wants to be written to. */ |
1487 | if ((ireason & 3) == 0) { | 1490 | if (ireason == 0) { |
1488 | if (!rq->data) { | 1491 | if (!rq->data) { |
1489 | blk_dump_rq_flags(rq, "cdrom_pc_intr, write"); | 1492 | blk_dump_rq_flags(rq, "cdrom_pc_intr, write"); |
1490 | goto confused; | 1493 | goto confused; |
@@ -1506,9 +1509,9 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) | |||
1506 | } | 1509 | } |
1507 | 1510 | ||
1508 | /* Same drill for reading. */ | 1511 | /* Same drill for reading. */ |
1509 | else if ((ireason & 3) == 2) { | 1512 | else if (ireason == 2) { |
1510 | if (!rq->data) { | 1513 | if (!rq->data) { |
1511 | blk_dump_rq_flags(rq, "cdrom_pc_intr, write"); | 1514 | blk_dump_rq_flags(rq, "cdrom_pc_intr, read"); |
1512 | goto confused; | 1515 | goto confused; |
1513 | } | 1516 | } |
1514 | /* Transfer the data. */ | 1517 | /* Transfer the data. */ |
@@ -1632,8 +1635,8 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) | |||
1632 | return 0; | 1635 | return 0; |
1633 | else if (ireason == 2) { | 1636 | else if (ireason == 2) { |
1634 | /* Whoops... The drive wants to send data. */ | 1637 | /* Whoops... The drive wants to send data. */ |
1635 | printk(KERN_ERR "%s: write_intr: wrong transfer direction!\n", | 1638 | printk(KERN_ERR "%s: %s: wrong transfer direction!\n", |
1636 | drive->name); | 1639 | drive->name, __FUNCTION__); |
1637 | 1640 | ||
1638 | while (len > 0) { | 1641 | while (len > 0) { |
1639 | int dum = 0; | 1642 | int dum = 0; |
@@ -1642,39 +1645,14 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) | |||
1642 | } | 1645 | } |
1643 | } else { | 1646 | } else { |
1644 | /* Drive wants a command packet, or invalid ireason... */ | 1647 | /* Drive wants a command packet, or invalid ireason... */ |
1645 | printk(KERN_ERR "%s: write_intr: bad interrupt reason %x\n", | 1648 | printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", |
1646 | drive->name, ireason); | 1649 | drive->name, __FUNCTION__, ireason); |
1647 | } | 1650 | } |
1648 | 1651 | ||
1649 | cdrom_end_request(drive, 0); | 1652 | cdrom_end_request(drive, 0); |
1650 | return 1; | 1653 | return 1; |
1651 | } | 1654 | } |
1652 | 1655 | ||
1653 | static void post_transform_command(struct request *req) | ||
1654 | { | ||
1655 | u8 *c = req->cmd; | ||
1656 | char *ibuf; | ||
1657 | |||
1658 | if (!blk_pc_request(req)) | ||
1659 | return; | ||
1660 | |||
1661 | if (req->bio) | ||
1662 | ibuf = bio_data(req->bio); | ||
1663 | else | ||
1664 | ibuf = req->data; | ||
1665 | |||
1666 | if (!ibuf) | ||
1667 | return; | ||
1668 | |||
1669 | /* | ||
1670 | * set ansi-revision and response data as atapi | ||
1671 | */ | ||
1672 | if (c[0] == GPCMD_INQUIRY) { | ||
1673 | ibuf[2] |= 2; | ||
1674 | ibuf[3] = (ibuf[3] & 0xf0) | 2; | ||
1675 | } | ||
1676 | } | ||
1677 | |||
1678 | typedef void (xfer_func_t)(ide_drive_t *, void *, u32); | 1656 | typedef void (xfer_func_t)(ide_drive_t *, void *, u32); |
1679 | 1657 | ||
1680 | /* | 1658 | /* |
@@ -1810,9 +1788,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1810 | return ide_started; | 1788 | return ide_started; |
1811 | 1789 | ||
1812 | end_request: | 1790 | end_request: |
1813 | if (!rq->data_len) | ||
1814 | post_transform_command(rq); | ||
1815 | |||
1816 | spin_lock_irqsave(&ide_lock, flags); | 1791 | spin_lock_irqsave(&ide_lock, flags); |
1817 | blkdev_dequeue_request(rq); | 1792 | blkdev_dequeue_request(rq); |
1818 | end_that_request_last(rq, 1); | 1793 | end_that_request_last(rq, 1); |
@@ -1833,8 +1808,9 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) | |||
1833 | /* Check for errors. */ | 1808 | /* Check for errors. */ |
1834 | if (dma) { | 1809 | if (dma) { |
1835 | info->dma = 0; | 1810 | info->dma = 0; |
1836 | if ((dma_error = HWIF(drive)->ide_dma_end(drive))) { | 1811 | dma_error = HWIF(drive)->ide_dma_end(drive); |
1837 | printk(KERN_ERR "ide-cd: write dma error\n"); | 1812 | if (dma_error) { |
1813 | printk(KERN_ERR "%s: DMA write error\n", drive->name); | ||
1838 | ide_dma_off(drive); | 1814 | ide_dma_off(drive); |
1839 | } | 1815 | } |
1840 | } | 1816 | } |
@@ -1854,7 +1830,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) | |||
1854 | } | 1830 | } |
1855 | 1831 | ||
1856 | /* Read the interrupt reason and the transfer length. */ | 1832 | /* Read the interrupt reason and the transfer length. */ |
1857 | ireason = HWIF(drive)->INB(IDE_IREASON_REG); | 1833 | ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; |
1858 | lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); | 1834 | lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); |
1859 | highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); | 1835 | highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); |
1860 | 1836 | ||
@@ -1867,8 +1843,9 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) | |||
1867 | */ | 1843 | */ |
1868 | uptodate = 1; | 1844 | uptodate = 1; |
1869 | if (rq->current_nr_sectors > 0) { | 1845 | if (rq->current_nr_sectors > 0) { |
1870 | printk(KERN_ERR "%s: write_intr: data underrun (%d blocks)\n", | 1846 | printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n", |
1871 | drive->name, rq->current_nr_sectors); | 1847 | drive->name, __FUNCTION__, |
1848 | rq->current_nr_sectors); | ||
1872 | uptodate = 0; | 1849 | uptodate = 0; |
1873 | } | 1850 | } |
1874 | cdrom_end_request(drive, uptodate); | 1851 | cdrom_end_request(drive, uptodate); |
@@ -1888,7 +1865,8 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) | |||
1888 | int this_transfer; | 1865 | int this_transfer; |
1889 | 1866 | ||
1890 | if (!rq->current_nr_sectors) { | 1867 | if (!rq->current_nr_sectors) { |
1891 | printk(KERN_ERR "ide-cd: write_intr: oops\n"); | 1868 | printk(KERN_ERR "%s: %s: confused, missing data\n", |
1869 | drive->name, __FUNCTION__); | ||
1892 | break; | 1870 | break; |
1893 | } | 1871 | } |
1894 | 1872 | ||
@@ -2716,14 +2694,14 @@ void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page | |||
2716 | if (!drive->id->model[0] && | 2694 | if (!drive->id->model[0] && |
2717 | !strncmp(drive->id->fw_rev, "241N", 4)) { | 2695 | !strncmp(drive->id->fw_rev, "241N", 4)) { |
2718 | CDROM_STATE_FLAGS(drive)->current_speed = | 2696 | CDROM_STATE_FLAGS(drive)->current_speed = |
2719 | (((unsigned int)cap->curspeed) + (176/2)) / 176; | 2697 | (le16_to_cpu(cap->curspeed) + (176/2)) / 176; |
2720 | CDROM_CONFIG_FLAGS(drive)->max_speed = | 2698 | CDROM_CONFIG_FLAGS(drive)->max_speed = |
2721 | (((unsigned int)cap->maxspeed) + (176/2)) / 176; | 2699 | (le16_to_cpu(cap->maxspeed) + (176/2)) / 176; |
2722 | } else { | 2700 | } else { |
2723 | CDROM_STATE_FLAGS(drive)->current_speed = | 2701 | CDROM_STATE_FLAGS(drive)->current_speed = |
2724 | (ntohs(cap->curspeed) + (176/2)) / 176; | 2702 | (be16_to_cpu(cap->curspeed) + (176/2)) / 176; |
2725 | CDROM_CONFIG_FLAGS(drive)->max_speed = | 2703 | CDROM_CONFIG_FLAGS(drive)->max_speed = |
2726 | (ntohs(cap->maxspeed) + (176/2)) / 176; | 2704 | (be16_to_cpu(cap->maxspeed) + (176/2)) / 176; |
2727 | } | 2705 | } |
2728 | } | 2706 | } |
2729 | 2707 | ||
@@ -2937,6 +2915,9 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) | |||
2937 | if (!CDROM_CONFIG_FLAGS(drive)->ram) | 2915 | if (!CDROM_CONFIG_FLAGS(drive)->ram) |
2938 | devinfo->mask |= CDC_RAM; | 2916 | devinfo->mask |= CDC_RAM; |
2939 | 2917 | ||
2918 | if (CDROM_CONFIG_FLAGS(drive)->no_speed_select) | ||
2919 | devinfo->mask |= CDC_SELECT_SPEED; | ||
2920 | |||
2940 | devinfo->disk = info->disk; | 2921 | devinfo->disk = info->disk; |
2941 | return register_cdrom(devinfo); | 2922 | return register_cdrom(devinfo); |
2942 | } | 2923 | } |
@@ -3049,12 +3030,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) | |||
3049 | else | 3030 | else |
3050 | printk(" drive"); | 3031 | printk(" drive"); |
3051 | 3032 | ||
3052 | printk(", %dkB Cache", be16_to_cpu(cap.buffer_size)); | 3033 | printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(cap.buffer_size)); |
3053 | |||
3054 | if (drive->using_dma) | ||
3055 | ide_dma_verbose(drive); | ||
3056 | |||
3057 | printk("\n"); | ||
3058 | 3034 | ||
3059 | return nslots; | 3035 | return nslots; |
3060 | } | 3036 | } |
@@ -3194,7 +3170,7 @@ int ide_cdrom_setup (ide_drive_t *drive) | |||
3194 | CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; | 3170 | CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1; |
3195 | /* the 3231 model does not support the SET_CD_SPEED command */ | 3171 | /* the 3231 model does not support the SET_CD_SPEED command */ |
3196 | else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231")) | 3172 | else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231")) |
3197 | cdi->mask |= CDC_SELECT_SPEED; | 3173 | CDROM_CONFIG_FLAGS(drive)->no_speed_select = 1; |
3198 | 3174 | ||
3199 | #if ! STANDARD_ATAPI | 3175 | #if ! STANDARD_ATAPI |
3200 | /* by default Sanyo 3 CD changer support is turned off and | 3176 | /* by default Sanyo 3 CD changer support is turned off and |
@@ -3537,15 +3513,8 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
3537 | g->driverfs_dev = &drive->gendev; | 3513 | g->driverfs_dev = &drive->gendev; |
3538 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; | 3514 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; |
3539 | if (ide_cdrom_setup(drive)) { | 3515 | if (ide_cdrom_setup(drive)) { |
3540 | struct cdrom_device_info *devinfo = &info->devinfo; | ||
3541 | ide_proc_unregister_driver(drive, &ide_cdrom_driver); | 3516 | ide_proc_unregister_driver(drive, &ide_cdrom_driver); |
3542 | kfree(info->buffer); | 3517 | ide_cd_release(&info->kref); |
3543 | kfree(info->toc); | ||
3544 | kfree(info->changer_info); | ||
3545 | if (devinfo->handle == drive && unregister_cdrom(devinfo)) | ||
3546 | printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name); | ||
3547 | kfree(info); | ||
3548 | drive->driver_data = NULL; | ||
3549 | goto failed; | 3518 | goto failed; |
3550 | } | 3519 | } |
3551 | 3520 | ||