aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2008-11-16 13:06:37 -0500
committerJens Axboe <jens.axboe@oracle.com>2008-12-29 02:28:43 -0500
commitd194139c18edb7dae45e159a24f2aa72091033b8 (patch)
tree98dab9ca446fceca1f519924fd392fbeb5e2eb14 /drivers
parent3147c531b6b53fbbf8942689c4aa113c519f5e4e (diff)
cdrom: reduce stack usage of mmc_ioctl_dvd_read_struct
1. kmalloc 192 bytes in dvd_read_bca (which is inlined into dvd_read_struct) 2. Pass struct packet_command to all dvd_read_* functions. Checkstack output: Before: mmc_ioctl_dvd_read_struct: 280 After: mmc_ioctl_dvd_read_struct: 56 Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cdrom/cdrom.c139
1 files changed, 77 insertions, 62 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index b927aa244247..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",
@@ -3027,7 +3041,8 @@ static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi,
3027} 3041}
3028 3042
3029static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi, 3043static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
3030 void __user *arg) 3044 void __user *arg,
3045 struct packet_command *cgc)
3031{ 3046{
3032 int ret; 3047 int ret;
3033 dvd_struct *s; 3048 dvd_struct *s;
@@ -3046,7 +3061,7 @@ static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
3046 return -EFAULT; 3061 return -EFAULT;
3047 } 3062 }
3048 3063
3049 ret = dvd_read_struct(cdi, s); 3064 ret = dvd_read_struct(cdi, s, cgc);
3050 if (ret) 3065 if (ret)
3051 goto out; 3066 goto out;
3052 3067
@@ -3132,7 +3147,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
3132 case CDROMRESUME: 3147 case CDROMRESUME:
3133 return mmc_ioctl_cdrom_pause_resume(cdi, &cgc, cmd); 3148 return mmc_ioctl_cdrom_pause_resume(cdi, &cgc, cmd);
3134 case DVD_READ_STRUCT: 3149 case DVD_READ_STRUCT:
3135 return mmc_ioctl_dvd_read_struct(cdi, userptr); 3150 return mmc_ioctl_dvd_read_struct(cdi, userptr, &cgc);
3136 case DVD_AUTH: 3151 case DVD_AUTH:
3137 return mmc_ioctl_dvd_auth(cdi, userptr); 3152 return mmc_ioctl_dvd_auth(cdi, userptr);
3138 case CDROM_NEXT_WRITABLE: 3153 case CDROM_NEXT_WRITABLE: