aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cdrom/cdrom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cdrom/cdrom.c')
-rw-r--r--drivers/cdrom/cdrom.c703
1 files changed, 403 insertions, 300 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 7d2e91cccb13..cceace61ef28 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1712,29 +1712,30 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
1712 return 0; 1712 return 0;
1713} 1713}
1714 1714
1715static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s) 1715static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s,
1716 struct packet_command *cgc)
1716{ 1717{
1717 unsigned char buf[21], *base; 1718 unsigned char buf[21], *base;
1718 struct dvd_layer *layer; 1719 struct dvd_layer *layer;
1719 struct packet_command cgc;
1720 struct cdrom_device_ops *cdo = cdi->ops; 1720 struct cdrom_device_ops *cdo = cdi->ops;
1721 int ret, layer_num = s->physical.layer_num; 1721 int ret, layer_num = s->physical.layer_num;
1722 1722
1723 if (layer_num >= DVD_LAYERS) 1723 if (layer_num >= DVD_LAYERS)
1724 return -EINVAL; 1724 return -EINVAL;
1725 1725
1726 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); 1726 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1727 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 1727 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1728 cgc.cmd[6] = layer_num; 1728 cgc->cmd[6] = layer_num;
1729 cgc.cmd[7] = s->type; 1729 cgc->cmd[7] = s->type;
1730 cgc.cmd[9] = cgc.buflen & 0xff; 1730 cgc->cmd[9] = cgc->buflen & 0xff;
1731 1731
1732 /* 1732 /*
1733 * refrain from reporting errors on non-existing layers (mainly) 1733 * refrain from reporting errors on non-existing layers (mainly)
1734 */ 1734 */
1735 cgc.quiet = 1; 1735 cgc->quiet = 1;
1736 1736
1737 if ((ret = cdo->generic_packet(cdi, &cgc))) 1737 ret = cdo->generic_packet(cdi, cgc);
1738 if (ret)
1738 return ret; 1739 return ret;
1739 1740
1740 base = &buf[4]; 1741 base = &buf[4];
@@ -1762,21 +1763,22 @@ static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
1762 return 0; 1763 return 0;
1763} 1764}
1764 1765
1765static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s) 1766static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s,
1767 struct packet_command *cgc)
1766{ 1768{
1767 int ret; 1769 int ret;
1768 u_char buf[8]; 1770 u_char buf[8];
1769 struct packet_command cgc;
1770 struct cdrom_device_ops *cdo = cdi->ops; 1771 struct cdrom_device_ops *cdo = cdi->ops;
1771 1772
1772 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); 1773 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1773 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 1774 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1774 cgc.cmd[6] = s->copyright.layer_num; 1775 cgc->cmd[6] = s->copyright.layer_num;
1775 cgc.cmd[7] = s->type; 1776 cgc->cmd[7] = s->type;
1776 cgc.cmd[8] = cgc.buflen >> 8; 1777 cgc->cmd[8] = cgc->buflen >> 8;
1777 cgc.cmd[9] = cgc.buflen & 0xff; 1778 cgc->cmd[9] = cgc->buflen & 0xff;
1778 1779
1779 if ((ret = cdo->generic_packet(cdi, &cgc))) 1780 ret = cdo->generic_packet(cdi, cgc);
1781 if (ret)
1780 return ret; 1782 return ret;
1781 1783
1782 s->copyright.cpst = buf[4]; 1784 s->copyright.cpst = buf[4];
@@ -1785,79 +1787,89 @@ static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
1785 return 0; 1787 return 0;
1786} 1788}
1787 1789
1788static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s) 1790static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s,
1791 struct packet_command *cgc)
1789{ 1792{
1790 int ret, size; 1793 int ret, size;
1791 u_char *buf; 1794 u_char *buf;
1792 struct packet_command cgc;
1793 struct cdrom_device_ops *cdo = cdi->ops; 1795 struct cdrom_device_ops *cdo = cdi->ops;
1794 1796
1795 size = sizeof(s->disckey.value) + 4; 1797 size = sizeof(s->disckey.value) + 4;
1796 1798
1797 if ((buf = kmalloc(size, GFP_KERNEL)) == NULL) 1799 buf = kmalloc(size, GFP_KERNEL);
1800 if (!buf)
1798 return -ENOMEM; 1801 return -ENOMEM;
1799 1802
1800 init_cdrom_command(&cgc, buf, size, CGC_DATA_READ); 1803 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1801 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 1804 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1802 cgc.cmd[7] = s->type; 1805 cgc->cmd[7] = s->type;
1803 cgc.cmd[8] = size >> 8; 1806 cgc->cmd[8] = size >> 8;
1804 cgc.cmd[9] = size & 0xff; 1807 cgc->cmd[9] = size & 0xff;
1805 cgc.cmd[10] = s->disckey.agid << 6; 1808 cgc->cmd[10] = s->disckey.agid << 6;
1806 1809
1807 if (!(ret = cdo->generic_packet(cdi, &cgc))) 1810 ret = cdo->generic_packet(cdi, cgc);
1811 if (!ret)
1808 memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value)); 1812 memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
1809 1813
1810 kfree(buf); 1814 kfree(buf);
1811 return ret; 1815 return ret;
1812} 1816}
1813 1817
1814static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) 1818static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s,
1819 struct packet_command *cgc)
1815{ 1820{
1816 int ret; 1821 int ret, size = 4 + 188;
1817 u_char buf[4 + 188]; 1822 u_char *buf;
1818 struct packet_command cgc;
1819 struct cdrom_device_ops *cdo = cdi->ops; 1823 struct cdrom_device_ops *cdo = cdi->ops;
1820 1824
1821 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); 1825 buf = kmalloc(size, GFP_KERNEL);
1822 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 1826 if (!buf)
1823 cgc.cmd[7] = s->type; 1827 return -ENOMEM;
1824 cgc.cmd[9] = cgc.buflen & 0xff;
1825 1828
1826 if ((ret = cdo->generic_packet(cdi, &cgc))) 1829 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1827 return ret; 1830 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1831 cgc->cmd[7] = s->type;
1832 cgc->cmd[9] = cgc->buflen & 0xff;
1833
1834 ret = cdo->generic_packet(cdi, cgc);
1835 if (ret)
1836 goto out;
1828 1837
1829 s->bca.len = buf[0] << 8 | buf[1]; 1838 s->bca.len = buf[0] << 8 | buf[1];
1830 if (s->bca.len < 12 || s->bca.len > 188) { 1839 if (s->bca.len < 12 || s->bca.len > 188) {
1831 cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len); 1840 cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len);
1832 return -EIO; 1841 ret = -EIO;
1842 goto out;
1833 } 1843 }
1834 memcpy(s->bca.value, &buf[4], s->bca.len); 1844 memcpy(s->bca.value, &buf[4], s->bca.len);
1835 1845 ret = 0;
1836 return 0; 1846out:
1847 kfree(buf);
1848 return ret;
1837} 1849}
1838 1850
1839static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s) 1851static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s,
1852 struct packet_command *cgc)
1840{ 1853{
1841 int ret = 0, size; 1854 int ret = 0, size;
1842 u_char *buf; 1855 u_char *buf;
1843 struct packet_command cgc;
1844 struct cdrom_device_ops *cdo = cdi->ops; 1856 struct cdrom_device_ops *cdo = cdi->ops;
1845 1857
1846 size = sizeof(s->manufact.value) + 4; 1858 size = sizeof(s->manufact.value) + 4;
1847 1859
1848 if ((buf = kmalloc(size, GFP_KERNEL)) == NULL) 1860 buf = kmalloc(size, GFP_KERNEL);
1861 if (!buf)
1849 return -ENOMEM; 1862 return -ENOMEM;
1850 1863
1851 init_cdrom_command(&cgc, buf, size, CGC_DATA_READ); 1864 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1852 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; 1865 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1853 cgc.cmd[7] = s->type; 1866 cgc->cmd[7] = s->type;
1854 cgc.cmd[8] = size >> 8; 1867 cgc->cmd[8] = size >> 8;
1855 cgc.cmd[9] = size & 0xff; 1868 cgc->cmd[9] = size & 0xff;
1856 1869
1857 if ((ret = cdo->generic_packet(cdi, &cgc))) { 1870 ret = cdo->generic_packet(cdi, cgc);
1858 kfree(buf); 1871 if (ret)
1859 return ret; 1872 goto out;
1860 }
1861 1873
1862 s->manufact.len = buf[0] << 8 | buf[1]; 1874 s->manufact.len = buf[0] << 8 | buf[1];
1863 if (s->manufact.len < 0 || s->manufact.len > 2048) { 1875 if (s->manufact.len < 0 || s->manufact.len > 2048) {
@@ -1868,27 +1880,29 @@ static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
1868 memcpy(s->manufact.value, &buf[4], s->manufact.len); 1880 memcpy(s->manufact.value, &buf[4], s->manufact.len);
1869 } 1881 }
1870 1882
1883out:
1871 kfree(buf); 1884 kfree(buf);
1872 return ret; 1885 return ret;
1873} 1886}
1874 1887
1875static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s) 1888static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s,
1889 struct packet_command *cgc)
1876{ 1890{
1877 switch (s->type) { 1891 switch (s->type) {
1878 case DVD_STRUCT_PHYSICAL: 1892 case DVD_STRUCT_PHYSICAL:
1879 return dvd_read_physical(cdi, s); 1893 return dvd_read_physical(cdi, s, cgc);
1880 1894
1881 case DVD_STRUCT_COPYRIGHT: 1895 case DVD_STRUCT_COPYRIGHT:
1882 return dvd_read_copyright(cdi, s); 1896 return dvd_read_copyright(cdi, s, cgc);
1883 1897
1884 case DVD_STRUCT_DISCKEY: 1898 case DVD_STRUCT_DISCKEY:
1885 return dvd_read_disckey(cdi, s); 1899 return dvd_read_disckey(cdi, s, cgc);
1886 1900
1887 case DVD_STRUCT_BCA: 1901 case DVD_STRUCT_BCA:
1888 return dvd_read_bca(cdi, s); 1902 return dvd_read_bca(cdi, s, cgc);
1889 1903
1890 case DVD_STRUCT_MANUFACT: 1904 case DVD_STRUCT_MANUFACT:
1891 return dvd_read_manufact(cdi, s); 1905 return dvd_read_manufact(cdi, s, cgc);
1892 1906
1893 default: 1907 default:
1894 cdinfo(CD_WARNING, ": Invalid DVD structure read requested (%d)\n", 1908 cdinfo(CD_WARNING, ": Invalid DVD structure read requested (%d)\n",
@@ -2787,271 +2801,360 @@ static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
2787 return cdo->generic_packet(cdi, &cgc); 2801 return cdo->generic_packet(cdi, &cgc);
2788} 2802}
2789 2803
2790static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, 2804static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi,
2791 unsigned long arg) 2805 void __user *arg,
2792{ 2806 struct packet_command *cgc,
2793 struct cdrom_device_ops *cdo = cdi->ops; 2807 int cmd)
2794 struct packet_command cgc; 2808{
2795 struct request_sense sense; 2809 struct request_sense sense;
2796 unsigned char buffer[32]; 2810 struct cdrom_msf msf;
2797 int ret = 0; 2811 int blocksize = 0, format = 0, lba;
2798 2812 int ret;
2799 memset(&cgc, 0, sizeof(cgc));
2800 2813
2801 /* build a unified command and queue it through
2802 cdo->generic_packet() */
2803 switch (cmd) { 2814 switch (cmd) {
2804 case CDROMREADRAW: 2815 case CDROMREADRAW:
2816 blocksize = CD_FRAMESIZE_RAW;
2817 break;
2805 case CDROMREADMODE1: 2818 case CDROMREADMODE1:
2806 case CDROMREADMODE2: { 2819 blocksize = CD_FRAMESIZE;
2807 struct cdrom_msf msf; 2820 format = 2;
2808 int blocksize = 0, format = 0, lba; 2821 break;
2809 2822 case CDROMREADMODE2:
2810 switch (cmd) { 2823 blocksize = CD_FRAMESIZE_RAW0;
2811 case CDROMREADRAW: 2824 break;
2812 blocksize = CD_FRAMESIZE_RAW; 2825 }
2813 break; 2826 IOCTL_IN(arg, struct cdrom_msf, msf);
2814 case CDROMREADMODE1: 2827 lba = msf_to_lba(msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0);
2815 blocksize = CD_FRAMESIZE; 2828 /* FIXME: we need upper bound checking, too!! */
2816 format = 2; 2829 if (lba < 0)
2817 break; 2830 return -EINVAL;
2818 case CDROMREADMODE2: 2831
2819 blocksize = CD_FRAMESIZE_RAW0; 2832 cgc->buffer = kmalloc(blocksize, GFP_KERNEL);
2820 break; 2833 if (cgc->buffer == NULL)
2821 } 2834 return -ENOMEM;
2822 IOCTL_IN(arg, struct cdrom_msf, msf); 2835
2823 lba = msf_to_lba(msf.cdmsf_min0,msf.cdmsf_sec0,msf.cdmsf_frame0); 2836 memset(&sense, 0, sizeof(sense));
2824 /* FIXME: we need upper bound checking, too!! */ 2837 cgc->sense = &sense;
2825 if (lba < 0) 2838 cgc->data_direction = CGC_DATA_READ;
2826 return -EINVAL; 2839 ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize);
2827 cgc.buffer = kmalloc(blocksize, GFP_KERNEL); 2840 if (ret && sense.sense_key == 0x05 &&
2828 if (cgc.buffer == NULL) 2841 sense.asc == 0x20 &&
2829 return -ENOMEM; 2842 sense.ascq == 0x00) {
2830 memset(&sense, 0, sizeof(sense)); 2843 /*
2831 cgc.sense = &sense; 2844 * SCSI-II devices are not required to support
2832 cgc.data_direction = CGC_DATA_READ; 2845 * READ_CD, so let's try switching block size
2833 ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize); 2846 */
2834 if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) { 2847 /* FIXME: switch back again... */
2835 /* 2848 ret = cdrom_switch_blocksize(cdi, blocksize);
2836 * SCSI-II devices are not required to support 2849 if (ret)
2837 * READ_CD, so let's try switching block size 2850 goto out;
2838 */ 2851 cgc->sense = NULL;
2839 /* FIXME: switch back again... */ 2852 ret = cdrom_read_cd(cdi, cgc, lba, blocksize, 1);
2840 if ((ret = cdrom_switch_blocksize(cdi, blocksize))) { 2853 ret |= cdrom_switch_blocksize(cdi, blocksize);
2841 kfree(cgc.buffer); 2854 }
2842 return ret; 2855 if (!ret && copy_to_user(arg, cgc->buffer, blocksize))
2843 } 2856 ret = -EFAULT;
2844 cgc.sense = NULL; 2857out:
2845 ret = cdrom_read_cd(cdi, &cgc, lba, blocksize, 1); 2858 kfree(cgc->buffer);
2846 ret |= cdrom_switch_blocksize(cdi, blocksize); 2859 return ret;
2847 } 2860}
2848 if (!ret && copy_to_user((char __user *)arg, cgc.buffer, blocksize)) 2861
2849 ret = -EFAULT; 2862static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi,
2850 kfree(cgc.buffer); 2863 void __user *arg)
2864{
2865 struct cdrom_read_audio ra;
2866 int lba;
2867
2868 IOCTL_IN(arg, struct cdrom_read_audio, ra);
2869
2870 if (ra.addr_format == CDROM_MSF)
2871 lba = msf_to_lba(ra.addr.msf.minute,
2872 ra.addr.msf.second,
2873 ra.addr.msf.frame);
2874 else if (ra.addr_format == CDROM_LBA)
2875 lba = ra.addr.lba;
2876 else
2877 return -EINVAL;
2878
2879 /* FIXME: we need upper bound checking, too!! */
2880 if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES)
2881 return -EINVAL;
2882
2883 return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes);
2884}
2885
2886static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi,
2887 void __user *arg)
2888{
2889 int ret;
2890 struct cdrom_subchnl q;
2891 u_char requested, back;
2892 IOCTL_IN(arg, struct cdrom_subchnl, q);
2893 requested = q.cdsc_format;
2894 if (!((requested == CDROM_MSF) ||
2895 (requested == CDROM_LBA)))
2896 return -EINVAL;
2897 q.cdsc_format = CDROM_MSF;
2898 ret = cdrom_read_subchannel(cdi, &q, 0);
2899 if (ret)
2851 return ret; 2900 return ret;
2852 } 2901 back = q.cdsc_format; /* local copy */
2853 case CDROMREADAUDIO: { 2902 sanitize_format(&q.cdsc_absaddr, &back, requested);
2854 struct cdrom_read_audio ra; 2903 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2855 int lba; 2904 IOCTL_OUT(arg, struct cdrom_subchnl, q);
2856 2905 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2857 IOCTL_IN(arg, struct cdrom_read_audio, ra); 2906 return 0;
2858 2907}
2859 if (ra.addr_format == CDROM_MSF)
2860 lba = msf_to_lba(ra.addr.msf.minute,
2861 ra.addr.msf.second,
2862 ra.addr.msf.frame);
2863 else if (ra.addr_format == CDROM_LBA)
2864 lba = ra.addr.lba;
2865 else
2866 return -EINVAL;
2867 2908
2868 /* FIXME: we need upper bound checking, too!! */ 2909static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi,
2869 if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES) 2910 void __user *arg,
2870 return -EINVAL; 2911 struct packet_command *cgc)
2912{
2913 struct cdrom_device_ops *cdo = cdi->ops;
2914 struct cdrom_msf msf;
2915 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2916 IOCTL_IN(arg, struct cdrom_msf, msf);
2917 cgc->cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2918 cgc->cmd[3] = msf.cdmsf_min0;
2919 cgc->cmd[4] = msf.cdmsf_sec0;
2920 cgc->cmd[5] = msf.cdmsf_frame0;
2921 cgc->cmd[6] = msf.cdmsf_min1;
2922 cgc->cmd[7] = msf.cdmsf_sec1;
2923 cgc->cmd[8] = msf.cdmsf_frame1;
2924 cgc->data_direction = CGC_DATA_NONE;
2925 return cdo->generic_packet(cdi, cgc);
2926}
2871 2927
2872 return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes); 2928static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi,
2873 } 2929 void __user *arg,
2874 case CDROMSUBCHNL: { 2930 struct packet_command *cgc)
2875 struct cdrom_subchnl q; 2931{
2876 u_char requested, back; 2932 struct cdrom_device_ops *cdo = cdi->ops;
2877 IOCTL_IN(arg, struct cdrom_subchnl, q); 2933 struct cdrom_blk blk;
2878 requested = q.cdsc_format; 2934 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
2879 if (!((requested == CDROM_MSF) || 2935 IOCTL_IN(arg, struct cdrom_blk, blk);
2880 (requested == CDROM_LBA))) 2936 cgc->cmd[0] = GPCMD_PLAY_AUDIO_10;
2881 return -EINVAL; 2937 cgc->cmd[2] = (blk.from >> 24) & 0xff;
2882 q.cdsc_format = CDROM_MSF; 2938 cgc->cmd[3] = (blk.from >> 16) & 0xff;
2883 if ((ret = cdrom_read_subchannel(cdi, &q, 0))) 2939 cgc->cmd[4] = (blk.from >> 8) & 0xff;
2884 return ret; 2940 cgc->cmd[5] = blk.from & 0xff;
2885 back = q.cdsc_format; /* local copy */ 2941 cgc->cmd[7] = (blk.len >> 8) & 0xff;
2886 sanitize_format(&q.cdsc_absaddr, &back, requested); 2942 cgc->cmd[8] = blk.len & 0xff;
2887 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested); 2943 cgc->data_direction = CGC_DATA_NONE;
2888 IOCTL_OUT(arg, struct cdrom_subchnl, q); 2944 return cdo->generic_packet(cdi, cgc);
2889 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ 2945}
2890 return 0; 2946
2891 } 2947static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi,
2892 case CDROMPLAYMSF: { 2948 void __user *arg,
2893 struct cdrom_msf msf; 2949 struct packet_command *cgc,
2894 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); 2950 unsigned int cmd)
2895 IOCTL_IN(arg, struct cdrom_msf, msf); 2951{
2896 cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF; 2952 struct cdrom_volctrl volctrl;
2897 cgc.cmd[3] = msf.cdmsf_min0; 2953 unsigned char buffer[32];
2898 cgc.cmd[4] = msf.cdmsf_sec0; 2954 char mask[sizeof(buffer)];
2899 cgc.cmd[5] = msf.cdmsf_frame0; 2955 unsigned short offset;
2900 cgc.cmd[6] = msf.cdmsf_min1; 2956 int ret;
2901 cgc.cmd[7] = msf.cdmsf_sec1;
2902 cgc.cmd[8] = msf.cdmsf_frame1;
2903 cgc.data_direction = CGC_DATA_NONE;
2904 return cdo->generic_packet(cdi, &cgc);
2905 }
2906 case CDROMPLAYBLK: {
2907 struct cdrom_blk blk;
2908 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
2909 IOCTL_IN(arg, struct cdrom_blk, blk);
2910 cgc.cmd[0] = GPCMD_PLAY_AUDIO_10;
2911 cgc.cmd[2] = (blk.from >> 24) & 0xff;
2912 cgc.cmd[3] = (blk.from >> 16) & 0xff;
2913 cgc.cmd[4] = (blk.from >> 8) & 0xff;
2914 cgc.cmd[5] = blk.from & 0xff;
2915 cgc.cmd[7] = (blk.len >> 8) & 0xff;
2916 cgc.cmd[8] = blk.len & 0xff;
2917 cgc.data_direction = CGC_DATA_NONE;
2918 return cdo->generic_packet(cdi, &cgc);
2919 }
2920 case CDROMVOLCTRL:
2921 case CDROMVOLREAD: {
2922 struct cdrom_volctrl volctrl;
2923 char mask[sizeof(buffer)];
2924 unsigned short offset;
2925 2957
2926 cdinfo(CD_DO_IOCTL, "entering CDROMVOLUME\n"); 2958 cdinfo(CD_DO_IOCTL, "entering CDROMVOLUME\n");
2927 2959
2928 IOCTL_IN(arg, struct cdrom_volctrl, volctrl); 2960 IOCTL_IN(arg, struct cdrom_volctrl, volctrl);
2929 2961
2930 cgc.buffer = buffer; 2962 cgc->buffer = buffer;
2931 cgc.buflen = 24; 2963 cgc->buflen = 24;
2932 if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 0))) 2964 ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 0);
2933 return ret; 2965 if (ret)
2966 return ret;
2934 2967
2935 /* originally the code depended on buffer[1] to determine 2968 /* originally the code depended on buffer[1] to determine
2936 how much data is available for transfer. buffer[1] is 2969 how much data is available for transfer. buffer[1] is
2937 unfortunately ambigious and the only reliable way seem 2970 unfortunately ambigious and the only reliable way seem
2938 to be to simply skip over the block descriptor... */ 2971 to be to simply skip over the block descriptor... */
2939 offset = 8 + be16_to_cpu(*(__be16 *)(buffer+6)); 2972 offset = 8 + be16_to_cpu(*(__be16 *)(buffer + 6));
2940 2973
2941 if (offset + 16 > sizeof(buffer)) 2974 if (offset + 16 > sizeof(buffer))
2942 return -E2BIG; 2975 return -E2BIG;
2943 2976
2944 if (offset + 16 > cgc.buflen) { 2977 if (offset + 16 > cgc->buflen) {
2945 cgc.buflen = offset+16; 2978 cgc->buflen = offset + 16;
2946 ret = cdrom_mode_sense(cdi, &cgc, 2979 ret = cdrom_mode_sense(cdi, cgc,
2947 GPMODE_AUDIO_CTL_PAGE, 0); 2980 GPMODE_AUDIO_CTL_PAGE, 0);
2948 if (ret) 2981 if (ret)
2949 return ret; 2982 return ret;
2950 } 2983 }
2951 2984
2952 /* sanity check */ 2985 /* sanity check */
2953 if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE || 2986 if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE ||
2954 buffer[offset+1] < 14) 2987 buffer[offset + 1] < 14)
2955 return -EINVAL; 2988 return -EINVAL;
2956 2989
2957 /* now we have the current volume settings. if it was only 2990 /* now we have the current volume settings. if it was only
2958 a CDROMVOLREAD, return these values */ 2991 a CDROMVOLREAD, return these values */
2959 if (cmd == CDROMVOLREAD) { 2992 if (cmd == CDROMVOLREAD) {
2960 volctrl.channel0 = buffer[offset+9]; 2993 volctrl.channel0 = buffer[offset+9];
2961 volctrl.channel1 = buffer[offset+11]; 2994 volctrl.channel1 = buffer[offset+11];
2962 volctrl.channel2 = buffer[offset+13]; 2995 volctrl.channel2 = buffer[offset+13];
2963 volctrl.channel3 = buffer[offset+15]; 2996 volctrl.channel3 = buffer[offset+15];
2964 IOCTL_OUT(arg, struct cdrom_volctrl, volctrl); 2997 IOCTL_OUT(arg, struct cdrom_volctrl, volctrl);
2965 return 0; 2998 return 0;
2966 } 2999 }
2967 3000
2968 /* get the volume mask */ 3001 /* get the volume mask */
2969 cgc.buffer = mask; 3002 cgc->buffer = mask;
2970 if ((ret = cdrom_mode_sense(cdi, &cgc, 3003 ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 1);
2971 GPMODE_AUDIO_CTL_PAGE, 1))) 3004 if (ret)
2972 return ret; 3005 return ret;
2973 3006
2974 buffer[offset+9] = volctrl.channel0 & mask[offset+9]; 3007 buffer[offset + 9] = volctrl.channel0 & mask[offset + 9];
2975 buffer[offset+11] = volctrl.channel1 & mask[offset+11]; 3008 buffer[offset + 11] = volctrl.channel1 & mask[offset + 11];
2976 buffer[offset+13] = volctrl.channel2 & mask[offset+13]; 3009 buffer[offset + 13] = volctrl.channel2 & mask[offset + 13];
2977 buffer[offset+15] = volctrl.channel3 & mask[offset+15]; 3010 buffer[offset + 15] = volctrl.channel3 & mask[offset + 15];
2978 3011
2979 /* set volume */ 3012 /* set volume */
2980 cgc.buffer = buffer + offset - 8; 3013 cgc->buffer = buffer + offset - 8;
2981 memset(cgc.buffer, 0, 8); 3014 memset(cgc->buffer, 0, 8);
2982 return cdrom_mode_select(cdi, &cgc); 3015 return cdrom_mode_select(cdi, cgc);
2983 } 3016}
2984 3017
2985 case CDROMSTART: 3018static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi,
2986 case CDROMSTOP: { 3019 struct packet_command *cgc,
2987 cdinfo(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n"); 3020 int cmd)
2988 cgc.cmd[0] = GPCMD_START_STOP_UNIT; 3021{
2989 cgc.cmd[1] = 1; 3022 struct cdrom_device_ops *cdo = cdi->ops;
2990 cgc.cmd[4] = (cmd == CDROMSTART) ? 1 : 0; 3023 cdinfo(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n");
2991 cgc.data_direction = CGC_DATA_NONE; 3024 cgc->cmd[0] = GPCMD_START_STOP_UNIT;
2992 return cdo->generic_packet(cdi, &cgc); 3025 cgc->cmd[1] = 1;
2993 } 3026 cgc->cmd[4] = (cmd == CDROMSTART) ? 1 : 0;
3027 cgc->data_direction = CGC_DATA_NONE;
3028 return cdo->generic_packet(cdi, cgc);
3029}
2994 3030
2995 case CDROMPAUSE: 3031static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi,
2996 case CDROMRESUME: { 3032 struct packet_command *cgc,
2997 cdinfo(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n"); 3033 int cmd)
2998 cgc.cmd[0] = GPCMD_PAUSE_RESUME; 3034{
2999 cgc.cmd[8] = (cmd == CDROMRESUME) ? 1 : 0; 3035 struct cdrom_device_ops *cdo = cdi->ops;
3000 cgc.data_direction = CGC_DATA_NONE; 3036 cdinfo(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n");
3001 return cdo->generic_packet(cdi, &cgc); 3037 cgc->cmd[0] = GPCMD_PAUSE_RESUME;
3002 } 3038 cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
3039 cgc->data_direction = CGC_DATA_NONE;
3040 return cdo->generic_packet(cdi, cgc);
3041}
3003 3042
3004 case DVD_READ_STRUCT: { 3043static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
3005 dvd_struct *s; 3044 void __user *arg,
3006 int size = sizeof(dvd_struct); 3045 struct packet_command *cgc)
3007 if (!CDROM_CAN(CDC_DVD)) 3046{
3008 return -ENOSYS; 3047 int ret;
3009 if ((s = kmalloc(size, GFP_KERNEL)) == NULL) 3048 dvd_struct *s;
3010 return -ENOMEM; 3049 int size = sizeof(dvd_struct);
3011 cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n"); 3050
3012 if (copy_from_user(s, (dvd_struct __user *)arg, size)) { 3051 if (!CDROM_CAN(CDC_DVD))
3013 kfree(s); 3052 return -ENOSYS;
3014 return -EFAULT; 3053
3015 } 3054 s = kmalloc(size, GFP_KERNEL);
3016 if ((ret = dvd_read_struct(cdi, s))) { 3055 if (!s)
3017 kfree(s); 3056 return -ENOMEM;
3018 return ret; 3057
3019 } 3058 cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
3020 if (copy_to_user((dvd_struct __user *)arg, s, size)) 3059 if (copy_from_user(s, arg, size)) {
3021 ret = -EFAULT;
3022 kfree(s); 3060 kfree(s);
3061 return -EFAULT;
3062 }
3063
3064 ret = dvd_read_struct(cdi, s, cgc);
3065 if (ret)
3066 goto out;
3067
3068 if (copy_to_user(arg, s, size))
3069 ret = -EFAULT;
3070out:
3071 kfree(s);
3072 return ret;
3073}
3074
3075static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi,
3076 void __user *arg)
3077{
3078 int ret;
3079 dvd_authinfo ai;
3080 if (!CDROM_CAN(CDC_DVD))
3081 return -ENOSYS;
3082 cdinfo(CD_DO_IOCTL, "entering DVD_AUTH\n");
3083 IOCTL_IN(arg, dvd_authinfo, ai);
3084 ret = dvd_do_auth(cdi, &ai);
3085 if (ret)
3023 return ret; 3086 return ret;
3024 } 3087 IOCTL_OUT(arg, dvd_authinfo, ai);
3088 return 0;
3089}
3025 3090
3026 case DVD_AUTH: { 3091static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi,
3027 dvd_authinfo ai; 3092 void __user *arg)
3028 if (!CDROM_CAN(CDC_DVD)) 3093{
3029 return -ENOSYS; 3094 int ret;
3030 cdinfo(CD_DO_IOCTL, "entering DVD_AUTH\n"); 3095 long next = 0;
3031 IOCTL_IN(arg, dvd_authinfo, ai); 3096 cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n");
3032 if ((ret = dvd_do_auth (cdi, &ai))) 3097 ret = cdrom_get_next_writable(cdi, &next);
3033 return ret; 3098 if (ret)
3034 IOCTL_OUT(arg, dvd_authinfo, ai); 3099 return ret;
3035 return 0; 3100 IOCTL_OUT(arg, long, next);
3036 } 3101 return 0;
3102}
3037 3103
3038 case CDROM_NEXT_WRITABLE: { 3104static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi,
3039 long next = 0; 3105 void __user *arg)
3040 cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n"); 3106{
3041 if ((ret = cdrom_get_next_writable(cdi, &next))) 3107 int ret;
3042 return ret; 3108 long last = 0;
3043 IOCTL_OUT(arg, long, next); 3109 cdinfo(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n");
3044 return 0; 3110 ret = cdrom_get_last_written(cdi, &last);
3045 } 3111 if (ret)
3046 case CDROM_LAST_WRITTEN: { 3112 return ret;
3047 long last = 0; 3113 IOCTL_OUT(arg, long, last);
3048 cdinfo(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n"); 3114 return 0;
3049 if ((ret = cdrom_get_last_written(cdi, &last))) 3115}
3050 return ret; 3116
3051 IOCTL_OUT(arg, long, last); 3117static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
3052 return 0; 3118 unsigned long arg)
3053 } 3119{
3054 } /* switch */ 3120 struct packet_command cgc;
3121 void __user *userptr = (void __user *)arg;
3122
3123 memset(&cgc, 0, sizeof(cgc));
3124
3125 /* build a unified command and queue it through
3126 cdo->generic_packet() */
3127 switch (cmd) {
3128 case CDROMREADRAW:
3129 case CDROMREADMODE1:
3130 case CDROMREADMODE2:
3131 return mmc_ioctl_cdrom_read_data(cdi, userptr, &cgc, cmd);
3132 case CDROMREADAUDIO:
3133 return mmc_ioctl_cdrom_read_audio(cdi, userptr);
3134 case CDROMSUBCHNL:
3135 return mmc_ioctl_cdrom_subchannel(cdi, userptr);
3136 case CDROMPLAYMSF:
3137 return mmc_ioctl_cdrom_play_msf(cdi, userptr, &cgc);
3138 case CDROMPLAYBLK:
3139 return mmc_ioctl_cdrom_play_blk(cdi, userptr, &cgc);
3140 case CDROMVOLCTRL:
3141 case CDROMVOLREAD:
3142 return mmc_ioctl_cdrom_volume(cdi, userptr, &cgc, cmd);
3143 case CDROMSTART:
3144 case CDROMSTOP:
3145 return mmc_ioctl_cdrom_start_stop(cdi, &cgc, cmd);
3146 case CDROMPAUSE:
3147 case CDROMRESUME:
3148 return mmc_ioctl_cdrom_pause_resume(cdi, &cgc, cmd);
3149 case DVD_READ_STRUCT:
3150 return mmc_ioctl_dvd_read_struct(cdi, userptr, &cgc);
3151 case DVD_AUTH:
3152 return mmc_ioctl_dvd_auth(cdi, userptr);
3153 case CDROM_NEXT_WRITABLE:
3154 return mmc_ioctl_cdrom_next_writable(cdi, userptr);
3155 case CDROM_LAST_WRITTEN:
3156 return mmc_ioctl_cdrom_last_written(cdi, userptr);
3157 }
3055 3158
3056 return -ENOTTY; 3159 return -ENOTTY;
3057} 3160}