aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2008-12-04 01:16:36 -0500
committerJames Morris <jmorris@namei.org>2008-12-04 01:16:36 -0500
commitec98ce480ada787f2cfbd696980ff3564415505b (patch)
tree1a4d644b38f9f1e4b4e086fde0b195df4a92cf84 /fs/ubifs
parent3496f92beb9aa99ef21fccc154a36c7698e9c538 (diff)
parentfeaf3848a813a106f163013af6fcf6c4bfec92d9 (diff)
Merge branch 'master' into next
Conflicts: fs/nfsd/nfs4recover.c Manually fixed above to use new creds API functions, e.g. nfs4_save_creds(). Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/commit.c4
-rw-r--r--fs/ubifs/debug.c66
-rw-r--r--fs/ubifs/dir.c5
-rw-r--r--fs/ubifs/file.c91
-rw-r--r--fs/ubifs/journal.c8
-rw-r--r--fs/ubifs/key.h4
-rw-r--r--fs/ubifs/lpt_commit.c2
-rw-r--r--fs/ubifs/orphan.c28
-rw-r--r--fs/ubifs/recovery.c17
-rw-r--r--fs/ubifs/replay.c2
-rw-r--r--fs/ubifs/sb.c9
-rw-r--r--fs/ubifs/super.c70
-rw-r--r--fs/ubifs/tnc.c12
-rw-r--r--fs/ubifs/ubifs.h12
14 files changed, 221 insertions, 109 deletions
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 0a6aa2cc78f0..b49884c8c10e 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -234,8 +234,8 @@ int ubifs_bg_thread(void *info)
234 int err; 234 int err;
235 struct ubifs_info *c = info; 235 struct ubifs_info *c = info;
236 236
237 ubifs_msg("background thread \"%s\" started, PID %d", 237 dbg_msg("background thread \"%s\" started, PID %d",
238 c->bgt_name, current->pid); 238 c->bgt_name, current->pid);
239 set_freezable(); 239 set_freezable();
240 240
241 while (1) { 241 while (1) {
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 7186400750e7..510ffa0bbda4 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -101,21 +101,24 @@ static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key,
101 if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) { 101 if (c->key_fmt == UBIFS_SIMPLE_KEY_FMT) {
102 switch (type) { 102 switch (type) {
103 case UBIFS_INO_KEY: 103 case UBIFS_INO_KEY:
104 sprintf(p, "(%lu, %s)", key_inum(c, key), 104 sprintf(p, "(%lu, %s)", (unsigned long)key_inum(c, key),
105 get_key_type(type)); 105 get_key_type(type));
106 break; 106 break;
107 case UBIFS_DENT_KEY: 107 case UBIFS_DENT_KEY:
108 case UBIFS_XENT_KEY: 108 case UBIFS_XENT_KEY:
109 sprintf(p, "(%lu, %s, %#08x)", key_inum(c, key), 109 sprintf(p, "(%lu, %s, %#08x)",
110 (unsigned long)key_inum(c, key),
110 get_key_type(type), key_hash(c, key)); 111 get_key_type(type), key_hash(c, key));
111 break; 112 break;
112 case UBIFS_DATA_KEY: 113 case UBIFS_DATA_KEY:
113 sprintf(p, "(%lu, %s, %u)", key_inum(c, key), 114 sprintf(p, "(%lu, %s, %u)",
115 (unsigned long)key_inum(c, key),
114 get_key_type(type), key_block(c, key)); 116 get_key_type(type), key_block(c, key));
115 break; 117 break;
116 case UBIFS_TRUN_KEY: 118 case UBIFS_TRUN_KEY:
117 sprintf(p, "(%lu, %s)", 119 sprintf(p, "(%lu, %s)",
118 key_inum(c, key), get_key_type(type)); 120 (unsigned long)key_inum(c, key),
121 get_key_type(type));
119 break; 122 break;
120 default: 123 default:
121 sprintf(p, "(bad key type: %#08x, %#08x)", 124 sprintf(p, "(bad key type: %#08x, %#08x)",
@@ -364,8 +367,8 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
364 le32_to_cpu(mst->ihead_lnum)); 367 le32_to_cpu(mst->ihead_lnum));
365 printk(KERN_DEBUG "\tihead_offs %u\n", 368 printk(KERN_DEBUG "\tihead_offs %u\n",
366 le32_to_cpu(mst->ihead_offs)); 369 le32_to_cpu(mst->ihead_offs));
367 printk(KERN_DEBUG "\tindex_size %u\n", 370 printk(KERN_DEBUG "\tindex_size %llu\n",
368 le32_to_cpu(mst->index_size)); 371 (unsigned long long)le64_to_cpu(mst->index_size));
369 printk(KERN_DEBUG "\tlpt_lnum %u\n", 372 printk(KERN_DEBUG "\tlpt_lnum %u\n",
370 le32_to_cpu(mst->lpt_lnum)); 373 le32_to_cpu(mst->lpt_lnum));
371 printk(KERN_DEBUG "\tlpt_offs %u\n", 374 printk(KERN_DEBUG "\tlpt_offs %u\n",
@@ -1589,7 +1592,7 @@ static struct fsck_inode *add_inode(struct ubifs_info *c,
1589 1592
1590 if (inum > c->highest_inum) { 1593 if (inum > c->highest_inum) {
1591 ubifs_err("too high inode number, max. is %lu", 1594 ubifs_err("too high inode number, max. is %lu",
1592 c->highest_inum); 1595 (unsigned long)c->highest_inum);
1593 return ERR_PTR(-EINVAL); 1596 return ERR_PTR(-EINVAL);
1594 } 1597 }
1595 1598
@@ -1668,16 +1671,18 @@ static struct fsck_inode *read_add_inode(struct ubifs_info *c,
1668 ino_key_init(c, &key, inum); 1671 ino_key_init(c, &key, inum);
1669 err = ubifs_lookup_level0(c, &key, &znode, &n); 1672 err = ubifs_lookup_level0(c, &key, &znode, &n);
1670 if (!err) { 1673 if (!err) {
1671 ubifs_err("inode %lu not found in index", inum); 1674 ubifs_err("inode %lu not found in index", (unsigned long)inum);
1672 return ERR_PTR(-ENOENT); 1675 return ERR_PTR(-ENOENT);
1673 } else if (err < 0) { 1676 } else if (err < 0) {
1674 ubifs_err("error %d while looking up inode %lu", err, inum); 1677 ubifs_err("error %d while looking up inode %lu",
1678 err, (unsigned long)inum);
1675 return ERR_PTR(err); 1679 return ERR_PTR(err);
1676 } 1680 }
1677 1681
1678 zbr = &znode->zbranch[n]; 1682 zbr = &znode->zbranch[n];
1679 if (zbr->len < UBIFS_INO_NODE_SZ) { 1683 if (zbr->len < UBIFS_INO_NODE_SZ) {
1680 ubifs_err("bad node %lu node length %d", inum, zbr->len); 1684 ubifs_err("bad node %lu node length %d",
1685 (unsigned long)inum, zbr->len);
1681 return ERR_PTR(-EINVAL); 1686 return ERR_PTR(-EINVAL);
1682 } 1687 }
1683 1688
@@ -1697,7 +1702,7 @@ static struct fsck_inode *read_add_inode(struct ubifs_info *c,
1697 kfree(ino); 1702 kfree(ino);
1698 if (IS_ERR(fscki)) { 1703 if (IS_ERR(fscki)) {
1699 ubifs_err("error %ld while adding inode %lu node", 1704 ubifs_err("error %ld while adding inode %lu node",
1700 PTR_ERR(fscki), inum); 1705 PTR_ERR(fscki), (unsigned long)inum);
1701 return fscki; 1706 return fscki;
1702 } 1707 }
1703 1708
@@ -1786,7 +1791,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
1786 if (IS_ERR(fscki)) { 1791 if (IS_ERR(fscki)) {
1787 err = PTR_ERR(fscki); 1792 err = PTR_ERR(fscki);
1788 ubifs_err("error %d while processing data node and " 1793 ubifs_err("error %d while processing data node and "
1789 "trying to find inode node %lu", err, inum); 1794 "trying to find inode node %lu",
1795 err, (unsigned long)inum);
1790 goto out_dump; 1796 goto out_dump;
1791 } 1797 }
1792 1798
@@ -1819,7 +1825,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
1819 if (IS_ERR(fscki)) { 1825 if (IS_ERR(fscki)) {
1820 err = PTR_ERR(fscki); 1826 err = PTR_ERR(fscki);
1821 ubifs_err("error %d while processing entry node and " 1827 ubifs_err("error %d while processing entry node and "
1822 "trying to find inode node %lu", err, inum); 1828 "trying to find inode node %lu",
1829 err, (unsigned long)inum);
1823 goto out_dump; 1830 goto out_dump;
1824 } 1831 }
1825 1832
@@ -1832,7 +1839,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
1832 err = PTR_ERR(fscki); 1839 err = PTR_ERR(fscki);
1833 ubifs_err("error %d while processing entry node and " 1840 ubifs_err("error %d while processing entry node and "
1834 "trying to find parent inode node %lu", 1841 "trying to find parent inode node %lu",
1835 err, inum); 1842 err, (unsigned long)inum);
1836 goto out_dump; 1843 goto out_dump;
1837 } 1844 }
1838 1845
@@ -1923,7 +1930,8 @@ static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd)
1923 fscki->references != 1) { 1930 fscki->references != 1) {
1924 ubifs_err("directory inode %lu has %d " 1931 ubifs_err("directory inode %lu has %d "
1925 "direntries which refer it, but " 1932 "direntries which refer it, but "
1926 "should be 1", fscki->inum, 1933 "should be 1",
1934 (unsigned long)fscki->inum,
1927 fscki->references); 1935 fscki->references);
1928 goto out_dump; 1936 goto out_dump;
1929 } 1937 }
@@ -1931,27 +1939,29 @@ static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd)
1931 fscki->references != 0) { 1939 fscki->references != 0) {
1932 ubifs_err("root inode %lu has non-zero (%d) " 1940 ubifs_err("root inode %lu has non-zero (%d) "
1933 "direntries which refer it", 1941 "direntries which refer it",
1934 fscki->inum, fscki->references); 1942 (unsigned long)fscki->inum,
1943 fscki->references);
1935 goto out_dump; 1944 goto out_dump;
1936 } 1945 }
1937 if (fscki->calc_sz != fscki->size) { 1946 if (fscki->calc_sz != fscki->size) {
1938 ubifs_err("directory inode %lu size is %lld, " 1947 ubifs_err("directory inode %lu size is %lld, "
1939 "but calculated size is %lld", 1948 "but calculated size is %lld",
1940 fscki->inum, fscki->size, 1949 (unsigned long)fscki->inum,
1941 fscki->calc_sz); 1950 fscki->size, fscki->calc_sz);
1942 goto out_dump; 1951 goto out_dump;
1943 } 1952 }
1944 if (fscki->calc_cnt != fscki->nlink) { 1953 if (fscki->calc_cnt != fscki->nlink) {
1945 ubifs_err("directory inode %lu nlink is %d, " 1954 ubifs_err("directory inode %lu nlink is %d, "
1946 "but calculated nlink is %d", 1955 "but calculated nlink is %d",
1947 fscki->inum, fscki->nlink, 1956 (unsigned long)fscki->inum,
1948 fscki->calc_cnt); 1957 fscki->nlink, fscki->calc_cnt);
1949 goto out_dump; 1958 goto out_dump;
1950 } 1959 }
1951 } else { 1960 } else {
1952 if (fscki->references != fscki->nlink) { 1961 if (fscki->references != fscki->nlink) {
1953 ubifs_err("inode %lu nlink is %d, but " 1962 ubifs_err("inode %lu nlink is %d, but "
1954 "calculated nlink is %d", fscki->inum, 1963 "calculated nlink is %d",
1964 (unsigned long)fscki->inum,
1955 fscki->nlink, fscki->references); 1965 fscki->nlink, fscki->references);
1956 goto out_dump; 1966 goto out_dump;
1957 } 1967 }
@@ -1959,20 +1969,21 @@ static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd)
1959 if (fscki->xattr_sz != fscki->calc_xsz) { 1969 if (fscki->xattr_sz != fscki->calc_xsz) {
1960 ubifs_err("inode %lu has xattr size %u, but " 1970 ubifs_err("inode %lu has xattr size %u, but "
1961 "calculated size is %lld", 1971 "calculated size is %lld",
1962 fscki->inum, fscki->xattr_sz, 1972 (unsigned long)fscki->inum, fscki->xattr_sz,
1963 fscki->calc_xsz); 1973 fscki->calc_xsz);
1964 goto out_dump; 1974 goto out_dump;
1965 } 1975 }
1966 if (fscki->xattr_cnt != fscki->calc_xcnt) { 1976 if (fscki->xattr_cnt != fscki->calc_xcnt) {
1967 ubifs_err("inode %lu has %u xattrs, but " 1977 ubifs_err("inode %lu has %u xattrs, but "
1968 "calculated count is %lld", fscki->inum, 1978 "calculated count is %lld",
1979 (unsigned long)fscki->inum,
1969 fscki->xattr_cnt, fscki->calc_xcnt); 1980 fscki->xattr_cnt, fscki->calc_xcnt);
1970 goto out_dump; 1981 goto out_dump;
1971 } 1982 }
1972 if (fscki->xattr_nms != fscki->calc_xnms) { 1983 if (fscki->xattr_nms != fscki->calc_xnms) {
1973 ubifs_err("inode %lu has xattr names' size %u, but " 1984 ubifs_err("inode %lu has xattr names' size %u, but "
1974 "calculated names' size is %lld", 1985 "calculated names' size is %lld",
1975 fscki->inum, fscki->xattr_nms, 1986 (unsigned long)fscki->inum, fscki->xattr_nms,
1976 fscki->calc_xnms); 1987 fscki->calc_xnms);
1977 goto out_dump; 1988 goto out_dump;
1978 } 1989 }
@@ -1985,11 +1996,12 @@ out_dump:
1985 ino_key_init(c, &key, fscki->inum); 1996 ino_key_init(c, &key, fscki->inum);
1986 err = ubifs_lookup_level0(c, &key, &znode, &n); 1997 err = ubifs_lookup_level0(c, &key, &znode, &n);
1987 if (!err) { 1998 if (!err) {
1988 ubifs_err("inode %lu not found in index", fscki->inum); 1999 ubifs_err("inode %lu not found in index",
2000 (unsigned long)fscki->inum);
1989 return -ENOENT; 2001 return -ENOENT;
1990 } else if (err < 0) { 2002 } else if (err < 0) {
1991 ubifs_err("error %d while looking up inode %lu", 2003 ubifs_err("error %d while looking up inode %lu",
1992 err, fscki->inum); 2004 err, (unsigned long)fscki->inum);
1993 return err; 2005 return err;
1994 } 2006 }
1995 2007
@@ -2007,7 +2019,7 @@ out_dump:
2007 } 2019 }
2008 2020
2009 ubifs_msg("dump of the inode %lu sitting in LEB %d:%d", 2021 ubifs_msg("dump of the inode %lu sitting in LEB %d:%d",
2010 fscki->inum, zbr->lnum, zbr->offs); 2022 (unsigned long)fscki->inum, zbr->lnum, zbr->offs);
2011 dbg_dump_node(c, ino); 2023 dbg_dump_node(c, ino);
2012 kfree(ino); 2024 kfree(ino);
2013 return -EINVAL; 2025 return -EINVAL;
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 856189014a3a..f448ab1f9c38 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -161,7 +161,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
161 return ERR_PTR(-EINVAL); 161 return ERR_PTR(-EINVAL);
162 } 162 }
163 ubifs_warn("running out of inode numbers (current %lu, max %d)", 163 ubifs_warn("running out of inode numbers (current %lu, max %d)",
164 c->highest_inum, INUM_WATERMARK); 164 (unsigned long)c->highest_inum, INUM_WATERMARK);
165 } 165 }
166 166
167 inode->i_ino = ++c->highest_inum; 167 inode->i_ino = ++c->highest_inum;
@@ -428,7 +428,8 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
428 dbg_gen("feed '%s', ino %llu, new f_pos %#x", 428 dbg_gen("feed '%s', ino %llu, new f_pos %#x",
429 dent->name, (unsigned long long)le64_to_cpu(dent->inum), 429 dent->name, (unsigned long long)le64_to_cpu(dent->inum),
430 key_hash_flash(c, &dent->key)); 430 key_hash_flash(c, &dent->key));
431 ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum); 431 ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
432 ubifs_inode(dir)->creat_sqnum);
432 433
433 nm.len = le16_to_cpu(dent->nlen); 434 nm.len = le16_to_cpu(dent->nlen);
434 over = filldir(dirent, dent->name, nm.len, file->f_pos, 435 over = filldir(dirent, dent->name, nm.len, file->f_pos,
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 51cf511d44d9..2624411d9758 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -72,7 +72,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
72 return err; 72 return err;
73 } 73 }
74 74
75 ubifs_assert(dn->ch.sqnum > ubifs_inode(inode)->creat_sqnum); 75 ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum);
76 76
77 len = le32_to_cpu(dn->size); 77 len = le32_to_cpu(dn->size);
78 if (len <= 0 || len > UBIFS_BLOCK_SIZE) 78 if (len <= 0 || len > UBIFS_BLOCK_SIZE)
@@ -626,7 +626,7 @@ static int populate_page(struct ubifs_info *c, struct page *page,
626 626
627 dn = bu->buf + (bu->zbranch[nn].offs - offs); 627 dn = bu->buf + (bu->zbranch[nn].offs - offs);
628 628
629 ubifs_assert(dn->ch.sqnum > 629 ubifs_assert(le64_to_cpu(dn->ch.sqnum) >
630 ubifs_inode(inode)->creat_sqnum); 630 ubifs_inode(inode)->creat_sqnum);
631 631
632 len = le32_to_cpu(dn->size); 632 len = le32_to_cpu(dn->size);
@@ -691,32 +691,22 @@ out_err:
691/** 691/**
692 * ubifs_do_bulk_read - do bulk-read. 692 * ubifs_do_bulk_read - do bulk-read.
693 * @c: UBIFS file-system description object 693 * @c: UBIFS file-system description object
694 * @page1: first page 694 * @bu: bulk-read information
695 * @page1: first page to read
695 * 696 *
696 * This function returns %1 if the bulk-read is done, otherwise %0 is returned. 697 * This function returns %1 if the bulk-read is done, otherwise %0 is returned.
697 */ 698 */
698static int ubifs_do_bulk_read(struct ubifs_info *c, struct page *page1) 699static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
700 struct page *page1)
699{ 701{
700 pgoff_t offset = page1->index, end_index; 702 pgoff_t offset = page1->index, end_index;
701 struct address_space *mapping = page1->mapping; 703 struct address_space *mapping = page1->mapping;
702 struct inode *inode = mapping->host; 704 struct inode *inode = mapping->host;
703 struct ubifs_inode *ui = ubifs_inode(inode); 705 struct ubifs_inode *ui = ubifs_inode(inode);
704 struct bu_info *bu;
705 int err, page_idx, page_cnt, ret = 0, n = 0; 706 int err, page_idx, page_cnt, ret = 0, n = 0;
707 int allocate = bu->buf ? 0 : 1;
706 loff_t isize; 708 loff_t isize;
707 709
708 bu = kmalloc(sizeof(struct bu_info), GFP_NOFS);
709 if (!bu)
710 return 0;
711
712 bu->buf_len = c->bulk_read_buf_size;
713 bu->buf = kmalloc(bu->buf_len, GFP_NOFS);
714 if (!bu->buf)
715 goto out_free;
716
717 data_key_init(c, &bu->key, inode->i_ino,
718 offset << UBIFS_BLOCKS_PER_PAGE_SHIFT);
719
720 err = ubifs_tnc_get_bu_keys(c, bu); 710 err = ubifs_tnc_get_bu_keys(c, bu);
721 if (err) 711 if (err)
722 goto out_warn; 712 goto out_warn;
@@ -735,12 +725,25 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct page *page1)
735 * together. If all the pages were like this, bulk-read would 725 * together. If all the pages were like this, bulk-read would
736 * reduce performance, so we turn it off for a while. 726 * reduce performance, so we turn it off for a while.
737 */ 727 */
738 ui->read_in_a_row = 0; 728 goto out_bu_off;
739 ui->bulk_read = 0;
740 goto out_free;
741 } 729 }
742 730
743 if (bu->cnt) { 731 if (bu->cnt) {
732 if (allocate) {
733 /*
734 * Allocate bulk-read buffer depending on how many data
735 * nodes we are going to read.
736 */
737 bu->buf_len = bu->zbranch[bu->cnt - 1].offs +
738 bu->zbranch[bu->cnt - 1].len -
739 bu->zbranch[0].offs;
740 ubifs_assert(bu->buf_len > 0);
741 ubifs_assert(bu->buf_len <= c->leb_size);
742 bu->buf = kmalloc(bu->buf_len, GFP_NOFS | __GFP_NOWARN);
743 if (!bu->buf)
744 goto out_bu_off;
745 }
746
744 err = ubifs_tnc_bulk_read(c, bu); 747 err = ubifs_tnc_bulk_read(c, bu);
745 if (err) 748 if (err)
746 goto out_warn; 749 goto out_warn;
@@ -779,13 +782,17 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct page *page1)
779 ui->last_page_read = offset + page_idx - 1; 782 ui->last_page_read = offset + page_idx - 1;
780 783
781out_free: 784out_free:
782 kfree(bu->buf); 785 if (allocate)
783 kfree(bu); 786 kfree(bu->buf);
784 return ret; 787 return ret;
785 788
786out_warn: 789out_warn:
787 ubifs_warn("ignoring error %d and skipping bulk-read", err); 790 ubifs_warn("ignoring error %d and skipping bulk-read", err);
788 goto out_free; 791 goto out_free;
792
793out_bu_off:
794 ui->read_in_a_row = ui->bulk_read = 0;
795 goto out_free;
789} 796}
790 797
791/** 798/**
@@ -803,18 +810,20 @@ static int ubifs_bulk_read(struct page *page)
803 struct ubifs_info *c = inode->i_sb->s_fs_info; 810 struct ubifs_info *c = inode->i_sb->s_fs_info;
804 struct ubifs_inode *ui = ubifs_inode(inode); 811 struct ubifs_inode *ui = ubifs_inode(inode);
805 pgoff_t index = page->index, last_page_read = ui->last_page_read; 812 pgoff_t index = page->index, last_page_read = ui->last_page_read;
806 int ret = 0; 813 struct bu_info *bu;
814 int err = 0, allocated = 0;
807 815
808 ui->last_page_read = index; 816 ui->last_page_read = index;
809
810 if (!c->bulk_read) 817 if (!c->bulk_read)
811 return 0; 818 return 0;
819
812 /* 820 /*
813 * Bulk-read is protected by ui_mutex, but it is an optimization, so 821 * Bulk-read is protected by @ui->ui_mutex, but it is an optimization,
814 * don't bother if we cannot lock the mutex. 822 * so don't bother if we cannot lock the mutex.
815 */ 823 */
816 if (!mutex_trylock(&ui->ui_mutex)) 824 if (!mutex_trylock(&ui->ui_mutex))
817 return 0; 825 return 0;
826
818 if (index != last_page_read + 1) { 827 if (index != last_page_read + 1) {
819 /* Turn off bulk-read if we stop reading sequentially */ 828 /* Turn off bulk-read if we stop reading sequentially */
820 ui->read_in_a_row = 1; 829 ui->read_in_a_row = 1;
@@ -822,6 +831,7 @@ static int ubifs_bulk_read(struct page *page)
822 ui->bulk_read = 0; 831 ui->bulk_read = 0;
823 goto out_unlock; 832 goto out_unlock;
824 } 833 }
834
825 if (!ui->bulk_read) { 835 if (!ui->bulk_read) {
826 ui->read_in_a_row += 1; 836 ui->read_in_a_row += 1;
827 if (ui->read_in_a_row < 3) 837 if (ui->read_in_a_row < 3)
@@ -829,10 +839,35 @@ static int ubifs_bulk_read(struct page *page)
829 /* Three reads in a row, so switch on bulk-read */ 839 /* Three reads in a row, so switch on bulk-read */
830 ui->bulk_read = 1; 840 ui->bulk_read = 1;
831 } 841 }
832 ret = ubifs_do_bulk_read(c, page); 842
843 /*
844 * If possible, try to use pre-allocated bulk-read information, which
845 * is protected by @c->bu_mutex.
846 */
847 if (mutex_trylock(&c->bu_mutex))
848 bu = &c->bu;
849 else {
850 bu = kmalloc(sizeof(struct bu_info), GFP_NOFS | __GFP_NOWARN);
851 if (!bu)
852 goto out_unlock;
853
854 bu->buf = NULL;
855 allocated = 1;
856 }
857
858 bu->buf_len = c->max_bu_buf_len;
859 data_key_init(c, &bu->key, inode->i_ino,
860 page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT);
861 err = ubifs_do_bulk_read(c, bu, page);
862
863 if (!allocated)
864 mutex_unlock(&c->bu_mutex);
865 else
866 kfree(bu);
867
833out_unlock: 868out_unlock:
834 mutex_unlock(&ui->ui_mutex); 869 mutex_unlock(&ui->ui_mutex);
835 return ret; 870 return err;
836} 871}
837 872
838static int ubifs_readpage(struct file *file, struct page *page) 873static int ubifs_readpage(struct file *file, struct page *page)
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 22993f867d19..f91b745908ea 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -690,8 +690,9 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
690 int dlen = UBIFS_DATA_NODE_SZ + UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR; 690 int dlen = UBIFS_DATA_NODE_SZ + UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR;
691 struct ubifs_inode *ui = ubifs_inode(inode); 691 struct ubifs_inode *ui = ubifs_inode(inode);
692 692
693 dbg_jnl("ino %lu, blk %u, len %d, key %s", key_inum(c, key), 693 dbg_jnl("ino %lu, blk %u, len %d, key %s",
694 key_block(c, key), len, DBGKEY(key)); 694 (unsigned long)key_inum(c, key), key_block(c, key), len,
695 DBGKEY(key));
695 ubifs_assert(len <= UBIFS_BLOCK_SIZE); 696 ubifs_assert(len <= UBIFS_BLOCK_SIZE);
696 697
697 data = kmalloc(dlen, GFP_NOFS); 698 data = kmalloc(dlen, GFP_NOFS);
@@ -1128,7 +1129,8 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
1128 ino_t inum = inode->i_ino; 1129 ino_t inum = inode->i_ino;
1129 unsigned int blk; 1130 unsigned int blk;
1130 1131
1131 dbg_jnl("ino %lu, size %lld -> %lld", inum, old_size, new_size); 1132 dbg_jnl("ino %lu, size %lld -> %lld",
1133 (unsigned long)inum, old_size, new_size);
1132 ubifs_assert(!ui->data_len); 1134 ubifs_assert(!ui->data_len);
1133 ubifs_assert(S_ISREG(inode->i_mode)); 1135 ubifs_assert(S_ISREG(inode->i_mode));
1134 ubifs_assert(mutex_is_locked(&ui->ui_mutex)); 1136 ubifs_assert(mutex_is_locked(&ui->ui_mutex));
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h
index 9ee65086f627..3f1f16bc25c9 100644
--- a/fs/ubifs/key.h
+++ b/fs/ubifs/key.h
@@ -345,7 +345,7 @@ static inline int key_type_flash(const struct ubifs_info *c, const void *k)
345{ 345{
346 const union ubifs_key *key = k; 346 const union ubifs_key *key = k;
347 347
348 return le32_to_cpu(key->u32[1]) >> UBIFS_S_KEY_BLOCK_BITS; 348 return le32_to_cpu(key->j32[1]) >> UBIFS_S_KEY_BLOCK_BITS;
349} 349}
350 350
351/** 351/**
@@ -416,7 +416,7 @@ static inline unsigned int key_block_flash(const struct ubifs_info *c,
416{ 416{
417 const union ubifs_key *key = k; 417 const union ubifs_key *key = k;
418 418
419 return le32_to_cpu(key->u32[1]) & UBIFS_S_KEY_BLOCK_MASK; 419 return le32_to_cpu(key->j32[1]) & UBIFS_S_KEY_BLOCK_MASK;
420} 420}
421 421
422/** 422/**
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index eed5a0025d63..a41434b42785 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -571,8 +571,6 @@ static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
571 /* We assume here that LEB zero is never an LPT LEB */ 571 /* We assume here that LEB zero is never an LPT LEB */
572 if (nnode->nbranch[iip].lnum) 572 if (nnode->nbranch[iip].lnum)
573 return ubifs_get_pnode(c, nnode, iip); 573 return ubifs_get_pnode(c, nnode, iip);
574 else
575 return NULL;
576 } 574 }
577 575
578 /* Go up while can't go right */ 576 /* Go up while can't go right */
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index 02d3462f4d3e..9bd5a43d4526 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -105,7 +105,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
105 list_add_tail(&orphan->list, &c->orph_list); 105 list_add_tail(&orphan->list, &c->orph_list);
106 list_add_tail(&orphan->new_list, &c->orph_new); 106 list_add_tail(&orphan->new_list, &c->orph_new);
107 spin_unlock(&c->orphan_lock); 107 spin_unlock(&c->orphan_lock);
108 dbg_gen("ino %lu", inum); 108 dbg_gen("ino %lu", (unsigned long)inum);
109 return 0; 109 return 0;
110} 110}
111 111
@@ -132,14 +132,16 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
132 else { 132 else {
133 if (o->dnext) { 133 if (o->dnext) {
134 spin_unlock(&c->orphan_lock); 134 spin_unlock(&c->orphan_lock);
135 dbg_gen("deleted twice ino %lu", inum); 135 dbg_gen("deleted twice ino %lu",
136 (unsigned long)inum);
136 return; 137 return;
137 } 138 }
138 if (o->cnext) { 139 if (o->cnext) {
139 o->dnext = c->orph_dnext; 140 o->dnext = c->orph_dnext;
140 c->orph_dnext = o; 141 c->orph_dnext = o;
141 spin_unlock(&c->orphan_lock); 142 spin_unlock(&c->orphan_lock);
142 dbg_gen("delete later ino %lu", inum); 143 dbg_gen("delete later ino %lu",
144 (unsigned long)inum);
143 return; 145 return;
144 } 146 }
145 rb_erase(p, &c->orph_tree); 147 rb_erase(p, &c->orph_tree);
@@ -151,12 +153,12 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
151 } 153 }
152 spin_unlock(&c->orphan_lock); 154 spin_unlock(&c->orphan_lock);
153 kfree(o); 155 kfree(o);
154 dbg_gen("inum %lu", inum); 156 dbg_gen("inum %lu", (unsigned long)inum);
155 return; 157 return;
156 } 158 }
157 } 159 }
158 spin_unlock(&c->orphan_lock); 160 spin_unlock(&c->orphan_lock);
159 dbg_err("missing orphan ino %lu", inum); 161 dbg_err("missing orphan ino %lu", (unsigned long)inum);
160 dbg_dump_stack(); 162 dbg_dump_stack();
161} 163}
162 164
@@ -448,7 +450,7 @@ static void erase_deleted(struct ubifs_info *c)
448 rb_erase(&orphan->rb, &c->orph_tree); 450 rb_erase(&orphan->rb, &c->orph_tree);
449 list_del(&orphan->list); 451 list_del(&orphan->list);
450 c->tot_orphans -= 1; 452 c->tot_orphans -= 1;
451 dbg_gen("deleting orphan ino %lu", orphan->inum); 453 dbg_gen("deleting orphan ino %lu", (unsigned long)orphan->inum);
452 kfree(orphan); 454 kfree(orphan);
453 } 455 }
454 c->orph_dnext = NULL; 456 c->orph_dnext = NULL;
@@ -536,8 +538,8 @@ static int insert_dead_orphan(struct ubifs_info *c, ino_t inum)
536 list_add_tail(&orphan->list, &c->orph_list); 538 list_add_tail(&orphan->list, &c->orph_list);
537 orphan->dnext = c->orph_dnext; 539 orphan->dnext = c->orph_dnext;
538 c->orph_dnext = orphan; 540 c->orph_dnext = orphan;
539 dbg_mnt("ino %lu, new %d, tot %d", 541 dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum,
540 inum, c->new_orphans, c->tot_orphans); 542 c->new_orphans, c->tot_orphans);
541 return 0; 543 return 0;
542} 544}
543 545
@@ -609,7 +611,8 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
609 n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; 611 n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3;
610 for (i = 0; i < n; i++) { 612 for (i = 0; i < n; i++) {
611 inum = le64_to_cpu(orph->inos[i]); 613 inum = le64_to_cpu(orph->inos[i]);
612 dbg_rcvry("deleting orphaned inode %lu", inum); 614 dbg_rcvry("deleting orphaned inode %lu",
615 (unsigned long)inum);
613 err = ubifs_tnc_remove_ino(c, inum); 616 err = ubifs_tnc_remove_ino(c, inum);
614 if (err) 617 if (err)
615 return err; 618 return err;
@@ -840,8 +843,8 @@ static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr,
840 if (inum != ci->last_ino) { 843 if (inum != ci->last_ino) {
841 /* Lowest node type is the inode node, so it comes first */ 844 /* Lowest node type is the inode node, so it comes first */
842 if (key_type(c, &zbr->key) != UBIFS_INO_KEY) 845 if (key_type(c, &zbr->key) != UBIFS_INO_KEY)
843 ubifs_err("found orphan node ino %lu, type %d", inum, 846 ubifs_err("found orphan node ino %lu, type %d",
844 key_type(c, &zbr->key)); 847 (unsigned long)inum, key_type(c, &zbr->key));
845 ci->last_ino = inum; 848 ci->last_ino = inum;
846 ci->tot_inos += 1; 849 ci->tot_inos += 1;
847 err = ubifs_tnc_read_node(c, zbr, ci->node); 850 err = ubifs_tnc_read_node(c, zbr, ci->node);
@@ -853,7 +856,8 @@ static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr,
853 /* Must be recorded as an orphan */ 856 /* Must be recorded as an orphan */
854 if (!dbg_find_check_orphan(&ci->root, inum) && 857 if (!dbg_find_check_orphan(&ci->root, inum) &&
855 !dbg_find_orphan(c, inum)) { 858 !dbg_find_orphan(c, inum)) {
856 ubifs_err("missing orphan, ino %lu", inum); 859 ubifs_err("missing orphan, ino %lu",
860 (unsigned long)inum);
857 ci->missing += 1; 861 ci->missing += 1;
858 } 862 }
859 } 863 }
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 77d26c141cf6..90acac603e63 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -168,12 +168,12 @@ static int write_rcvrd_mst_node(struct ubifs_info *c,
168 struct ubifs_mst_node *mst) 168 struct ubifs_mst_node *mst)
169{ 169{
170 int err = 0, lnum = UBIFS_MST_LNUM, sz = c->mst_node_alsz; 170 int err = 0, lnum = UBIFS_MST_LNUM, sz = c->mst_node_alsz;
171 uint32_t save_flags; 171 __le32 save_flags;
172 172
173 dbg_rcvry("recovery"); 173 dbg_rcvry("recovery");
174 174
175 save_flags = mst->flags; 175 save_flags = mst->flags;
176 mst->flags = cpu_to_le32(le32_to_cpu(mst->flags) | UBIFS_MST_RCVRY); 176 mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
177 177
178 ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1); 178 ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
179 err = ubi_leb_change(c->ubi, lnum, mst, sz, UBI_SHORTTERM); 179 err = ubi_leb_change(c->ubi, lnum, mst, sz, UBI_SHORTTERM);
@@ -1435,13 +1435,13 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
1435 err = ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN); 1435 err = ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN);
1436 if (err) 1436 if (err)
1437 goto out; 1437 goto out;
1438 dbg_rcvry("inode %lu at %d:%d size %lld -> %lld ", e->inum, lnum, offs, 1438 dbg_rcvry("inode %lu at %d:%d size %lld -> %lld ",
1439 i_size, e->d_size); 1439 (unsigned long)e->inum, lnum, offs, i_size, e->d_size);
1440 return 0; 1440 return 0;
1441 1441
1442out: 1442out:
1443 ubifs_warn("inode %lu failed to fix size %lld -> %lld error %d", 1443 ubifs_warn("inode %lu failed to fix size %lld -> %lld error %d",
1444 e->inum, e->i_size, e->d_size, err); 1444 (unsigned long)e->inum, e->i_size, e->d_size, err);
1445 return err; 1445 return err;
1446} 1446}
1447 1447
@@ -1472,7 +1472,8 @@ int ubifs_recover_size(struct ubifs_info *c)
1472 return err; 1472 return err;
1473 if (err == -ENOENT) { 1473 if (err == -ENOENT) {
1474 /* Remove data nodes that have no inode */ 1474 /* Remove data nodes that have no inode */
1475 dbg_rcvry("removing ino %lu", e->inum); 1475 dbg_rcvry("removing ino %lu",
1476 (unsigned long)e->inum);
1476 err = ubifs_tnc_remove_ino(c, e->inum); 1477 err = ubifs_tnc_remove_ino(c, e->inum);
1477 if (err) 1478 if (err)
1478 return err; 1479 return err;
@@ -1493,8 +1494,8 @@ int ubifs_recover_size(struct ubifs_info *c)
1493 return PTR_ERR(inode); 1494 return PTR_ERR(inode);
1494 if (inode->i_size < e->d_size) { 1495 if (inode->i_size < e->d_size) {
1495 dbg_rcvry("ino %lu size %lld -> %lld", 1496 dbg_rcvry("ino %lu size %lld -> %lld",
1496 e->inum, e->d_size, 1497 (unsigned long)e->inum,
1497 inode->i_size); 1498 e->d_size, inode->i_size);
1498 inode->i_size = e->d_size; 1499 inode->i_size = e->d_size;
1499 ubifs_inode(inode)->ui_size = e->d_size; 1500 ubifs_inode(inode)->ui_size = e->d_size;
1500 e->inode = inode; 1501 e->inode = inode;
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 7399692af859..21f7d047c306 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -1065,7 +1065,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
1065 ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); 1065 ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
1066 dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, " 1066 dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, "
1067 "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum, 1067 "highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum,
1068 c->highest_inum); 1068 (unsigned long)c->highest_inum);
1069out: 1069out:
1070 destroy_replay_tree(c); 1070 destroy_replay_tree(c);
1071 destroy_bud_list(c); 1071 destroy_bud_list(c);
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index 2bf753b38889..0f392351dc5a 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -81,6 +81,7 @@ static int create_default_filesystem(struct ubifs_info *c)
81 int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; 81 int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0;
82 int min_leb_cnt = UBIFS_MIN_LEB_CNT; 82 int min_leb_cnt = UBIFS_MIN_LEB_CNT;
83 uint64_t tmp64, main_bytes; 83 uint64_t tmp64, main_bytes;
84 __le64 tmp_le64;
84 85
85 /* Some functions called from here depend on the @c->key_len filed */ 86 /* Some functions called from here depend on the @c->key_len filed */
86 c->key_len = UBIFS_SK_LEN; 87 c->key_len = UBIFS_SK_LEN;
@@ -295,10 +296,10 @@ static int create_default_filesystem(struct ubifs_info *c)
295 ino->ch.node_type = UBIFS_INO_NODE; 296 ino->ch.node_type = UBIFS_INO_NODE;
296 ino->creat_sqnum = cpu_to_le64(++c->max_sqnum); 297 ino->creat_sqnum = cpu_to_le64(++c->max_sqnum);
297 ino->nlink = cpu_to_le32(2); 298 ino->nlink = cpu_to_le32(2);
298 tmp = cpu_to_le64(CURRENT_TIME_SEC.tv_sec); 299 tmp_le64 = cpu_to_le64(CURRENT_TIME_SEC.tv_sec);
299 ino->atime_sec = tmp; 300 ino->atime_sec = tmp_le64;
300 ino->ctime_sec = tmp; 301 ino->ctime_sec = tmp_le64;
301 ino->mtime_sec = tmp; 302 ino->mtime_sec = tmp_le64;
302 ino->atime_nsec = 0; 303 ino->atime_nsec = 0;
303 ino->ctime_nsec = 0; 304 ino->ctime_nsec = 0;
304 ino->mtime_nsec = 0; 305 ino->mtime_nsec = 0;
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 8780efbf40ac..d80b2aef42b6 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,6 +36,12 @@
36#include <linux/mount.h> 36#include <linux/mount.h>
37#include "ubifs.h" 37#include "ubifs.h"
38 38
39/*
40 * Maximum amount of memory we may 'kmalloc()' without worrying that we are
41 * allocating too much.
42 */
43#define UBIFS_KMALLOC_OK (128*1024)
44
39/* Slab cache for UBIFS inodes */ 45/* Slab cache for UBIFS inodes */
40struct kmem_cache *ubifs_inode_slab; 46struct kmem_cache *ubifs_inode_slab;
41 47
@@ -561,18 +567,11 @@ static int init_constants_early(struct ubifs_info *c)
561 * calculations when reporting free space. 567 * calculations when reporting free space.
562 */ 568 */
563 c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ; 569 c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ;
564 /* Buffer size for bulk-reads */
565 c->bulk_read_buf_size = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ;
566 if (c->bulk_read_buf_size > c->leb_size)
567 c->bulk_read_buf_size = c->leb_size;
568 if (c->bulk_read_buf_size > 128 * 1024) {
569 /* Check if we can kmalloc more than 128KiB */
570 void *try = kmalloc(c->bulk_read_buf_size, GFP_KERNEL);
571 570
572 kfree(try); 571 /* Buffer size for bulk-reads */
573 if (!try) 572 c->max_bu_buf_len = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ;
574 c->bulk_read_buf_size = 128 * 1024; 573 if (c->max_bu_buf_len > c->leb_size)
575 } 574 c->max_bu_buf_len = c->leb_size;
576 return 0; 575 return 0;
577} 576}
578 577
@@ -992,6 +991,34 @@ static void destroy_journal(struct ubifs_info *c)
992} 991}
993 992
994/** 993/**
994 * bu_init - initialize bulk-read information.
995 * @c: UBIFS file-system description object
996 */
997static void bu_init(struct ubifs_info *c)
998{
999 ubifs_assert(c->bulk_read == 1);
1000
1001 if (c->bu.buf)
1002 return; /* Already initialized */
1003
1004again:
1005 c->bu.buf = kmalloc(c->max_bu_buf_len, GFP_KERNEL | __GFP_NOWARN);
1006 if (!c->bu.buf) {
1007 if (c->max_bu_buf_len > UBIFS_KMALLOC_OK) {
1008 c->max_bu_buf_len = UBIFS_KMALLOC_OK;
1009 goto again;
1010 }
1011
1012 /* Just disable bulk-read */
1013 ubifs_warn("Cannot allocate %d bytes of memory for bulk-read, "
1014 "disabling it", c->max_bu_buf_len);
1015 c->mount_opts.bulk_read = 1;
1016 c->bulk_read = 0;
1017 return;
1018 }
1019}
1020
1021/**
995 * mount_ubifs - mount UBIFS file-system. 1022 * mount_ubifs - mount UBIFS file-system.
996 * @c: UBIFS file-system description object 1023 * @c: UBIFS file-system description object
997 * 1024 *
@@ -1059,6 +1086,13 @@ static int mount_ubifs(struct ubifs_info *c)
1059 goto out_free; 1086 goto out_free;
1060 } 1087 }
1061 1088
1089 if (c->bulk_read == 1)
1090 bu_init(c);
1091
1092 /*
1093 * We have to check all CRCs, even for data nodes, when we mount the FS
1094 * (specifically, when we are replaying).
1095 */
1062 c->always_chk_crc = 1; 1096 c->always_chk_crc = 1;
1063 1097
1064 err = ubifs_read_superblock(c); 1098 err = ubifs_read_superblock(c);
@@ -1289,6 +1323,7 @@ out_cbuf:
1289out_dereg: 1323out_dereg:
1290 dbg_failure_mode_deregistration(c); 1324 dbg_failure_mode_deregistration(c);
1291out_free: 1325out_free:
1326 kfree(c->bu.buf);
1292 vfree(c->ileb_buf); 1327 vfree(c->ileb_buf);
1293 vfree(c->sbuf); 1328 vfree(c->sbuf);
1294 kfree(c->bottom_up_buf); 1329 kfree(c->bottom_up_buf);
@@ -1325,10 +1360,11 @@ static void ubifs_umount(struct ubifs_info *c)
1325 kfree(c->cbuf); 1360 kfree(c->cbuf);
1326 kfree(c->rcvrd_mst_node); 1361 kfree(c->rcvrd_mst_node);
1327 kfree(c->mst_node); 1362 kfree(c->mst_node);
1363 kfree(c->bu.buf);
1364 vfree(c->ileb_buf);
1328 vfree(c->sbuf); 1365 vfree(c->sbuf);
1329 kfree(c->bottom_up_buf); 1366 kfree(c->bottom_up_buf);
1330 UBIFS_DBG(vfree(c->dbg_buf)); 1367 UBIFS_DBG(vfree(c->dbg_buf));
1331 vfree(c->ileb_buf);
1332 dbg_failure_mode_deregistration(c); 1368 dbg_failure_mode_deregistration(c);
1333} 1369}
1334 1370
@@ -1626,6 +1662,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
1626 ubifs_err("invalid or unknown remount parameter"); 1662 ubifs_err("invalid or unknown remount parameter");
1627 return err; 1663 return err;
1628 } 1664 }
1665
1629 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { 1666 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
1630 err = ubifs_remount_rw(c); 1667 err = ubifs_remount_rw(c);
1631 if (err) 1668 if (err)
@@ -1633,6 +1670,14 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
1633 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) 1670 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
1634 ubifs_remount_ro(c); 1671 ubifs_remount_ro(c);
1635 1672
1673 if (c->bulk_read == 1)
1674 bu_init(c);
1675 else {
1676 dbg_gen("disable bulk-read");
1677 kfree(c->bu.buf);
1678 c->bu.buf = NULL;
1679 }
1680
1636 return 0; 1681 return 0;
1637} 1682}
1638 1683
@@ -1723,6 +1768,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
1723 mutex_init(&c->log_mutex); 1768 mutex_init(&c->log_mutex);
1724 mutex_init(&c->mst_mutex); 1769 mutex_init(&c->mst_mutex);
1725 mutex_init(&c->umount_mutex); 1770 mutex_init(&c->umount_mutex);
1771 mutex_init(&c->bu_mutex);
1726 init_waitqueue_head(&c->cmt_wq); 1772 init_waitqueue_head(&c->cmt_wq);
1727 c->buds = RB_ROOT; 1773 c->buds = RB_ROOT;
1728 c->old_idx = RB_ROOT; 1774 c->old_idx = RB_ROOT;
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index d27fd918b9c9..6eef5344a145 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -1501,7 +1501,12 @@ out:
1501 * @bu: bulk-read parameters and results 1501 * @bu: bulk-read parameters and results
1502 * 1502 *
1503 * Lookup consecutive data node keys for the same inode that reside 1503 * Lookup consecutive data node keys for the same inode that reside
1504 * consecutively in the same LEB. 1504 * consecutively in the same LEB. This function returns zero in case of success
1505 * and a negative error code in case of failure.
1506 *
1507 * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function
1508 * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares
1509 * maxumum possible amount of nodes for bulk-read.
1505 */ 1510 */
1506int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) 1511int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu)
1507{ 1512{
@@ -2677,7 +2682,7 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum)
2677 struct ubifs_dent_node *xent, *pxent = NULL; 2682 struct ubifs_dent_node *xent, *pxent = NULL;
2678 struct qstr nm = { .name = NULL }; 2683 struct qstr nm = { .name = NULL };
2679 2684
2680 dbg_tnc("ino %lu", inum); 2685 dbg_tnc("ino %lu", (unsigned long)inum);
2681 2686
2682 /* 2687 /*
2683 * Walk all extended attribute entries and remove them together with 2688 * Walk all extended attribute entries and remove them together with
@@ -2697,7 +2702,8 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum)
2697 } 2702 }
2698 2703
2699 xattr_inum = le64_to_cpu(xent->inum); 2704 xattr_inum = le64_to_cpu(xent->inum);
2700 dbg_tnc("xent '%s', ino %lu", xent->name, xattr_inum); 2705 dbg_tnc("xent '%s', ino %lu", xent->name,
2706 (unsigned long)xattr_inum);
2701 2707
2702 nm.name = xent->name; 2708 nm.name = xent->name;
2703 nm.len = le16_to_cpu(xent->nlen); 2709 nm.len = le16_to_cpu(xent->nlen);
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index a7bd32fa15b9..46b172560a06 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -753,7 +753,7 @@ struct ubifs_znode {
753}; 753};
754 754
755/** 755/**
756 * struct bu_info - bulk-read information 756 * struct bu_info - bulk-read information.
757 * @key: first data node key 757 * @key: first data node key
758 * @zbranch: zbranches of data nodes to bulk read 758 * @zbranch: zbranches of data nodes to bulk read
759 * @buf: buffer to read into 759 * @buf: buffer to read into
@@ -969,7 +969,10 @@ struct ubifs_mount_opts {
969 * @mst_node: master node 969 * @mst_node: master node
970 * @mst_offs: offset of valid master node 970 * @mst_offs: offset of valid master node
971 * @mst_mutex: protects the master node area, @mst_node, and @mst_offs 971 * @mst_mutex: protects the master node area, @mst_node, and @mst_offs
972 * @bulk_read_buf_size: buffer size for bulk-reads 972 *
973 * @max_bu_buf_len: maximum bulk-read buffer length
974 * @bu_mutex: protects the pre-allocated bulk-read buffer and @c->bu
975 * @bu: pre-allocated bulk-read information
973 * 976 *
974 * @log_lebs: number of logical eraseblocks in the log 977 * @log_lebs: number of logical eraseblocks in the log
975 * @log_bytes: log size in bytes 978 * @log_bytes: log size in bytes
@@ -1217,7 +1220,10 @@ struct ubifs_info {
1217 struct ubifs_mst_node *mst_node; 1220 struct ubifs_mst_node *mst_node;
1218 int mst_offs; 1221 int mst_offs;
1219 struct mutex mst_mutex; 1222 struct mutex mst_mutex;
1220 int bulk_read_buf_size; 1223
1224 int max_bu_buf_len;
1225 struct mutex bu_mutex;
1226 struct bu_info bu;
1221 1227
1222 int log_lebs; 1228 int log_lebs;
1223 long long log_bytes; 1229 long long log_bytes;
otg->dev, "trying to write more for ep%d\n", hs_ep->index); return s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req); } return 0; } /** * s3c_hsotg_complete_in - complete IN transfer * @hsotg: The device state. * @hs_ep: The endpoint that has just completed. * * An IN transfer has been completed, update the transfer's state and then * call the relevant completion routines. */ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep) { struct s3c_hsotg_req *hs_req = hs_ep->req; u32 epsize = readl(hsotg->regs + S3C_DIEPTSIZ(hs_ep->index)); int size_left, size_done; if (!hs_req) { dev_dbg(hsotg->dev, "XferCompl but no req\n"); return; } /* Calculate the size of the transfer by checking how much is left * in the endpoint size register and then working it out from * the amount we loaded for the transfer. * * We do this even for DMA, as the transfer may have incremented * past the end of the buffer (DMA transfers are always 32bit * aligned). */ size_left = S3C_DxEPTSIZ_XferSize_GET(epsize); size_done = hs_ep->size_loaded - size_left; size_done += hs_ep->last_load; if (hs_req->req.actual != size_done) dev_dbg(hsotg->dev, "%s: adjusting size done %d => %d\n", __func__, hs_req->req.actual, size_done); hs_req->req.actual = size_done; /* if we did all of the transfer, and there is more data left * around, then try restarting the rest of the request */ if (!size_left && hs_req->req.actual < hs_req->req.length) { dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); } else s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); } /** * s3c_hsotg_epint - handle an in/out endpoint interrupt * @hsotg: The driver state * @idx: The index for the endpoint (0..15) * @dir_in: Set if this is an IN endpoint * * Process and clear any interrupt pending for an individual endpoint */ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, int dir_in) { struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx]; u32 epint_reg = dir_in ? S3C_DIEPINT(idx) : S3C_DOEPINT(idx); u32 epctl_reg = dir_in ? S3C_DIEPCTL(idx) : S3C_DOEPCTL(idx); u32 epsiz_reg = dir_in ? S3C_DIEPTSIZ(idx) : S3C_DOEPTSIZ(idx); u32 ints; ints = readl(hsotg->regs + epint_reg); /* Clear endpoint interrupts */ writel(ints, hsotg->regs + epint_reg); dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n", __func__, idx, dir_in ? "in" : "out", ints); if (ints & S3C_DxEPINT_XferCompl) { dev_dbg(hsotg->dev, "%s: XferCompl: DxEPCTL=0x%08x, DxEPTSIZ=%08x\n", __func__, readl(hsotg->regs + epctl_reg), readl(hsotg->regs + epsiz_reg)); /* we get OutDone from the FIFO, so we only need to look * at completing IN requests here */ if (dir_in) { s3c_hsotg_complete_in(hsotg, hs_ep); if (idx == 0 && !hs_ep->req) s3c_hsotg_enqueue_setup(hsotg); } else if (using_dma(hsotg)) { /* We're using DMA, we need to fire an OutDone here * as we ignore the RXFIFO. */ s3c_hsotg_handle_outdone(hsotg, idx, false); } } if (ints & S3C_DxEPINT_EPDisbld) { dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__); if (dir_in) { int epctl = readl(hsotg->regs + epctl_reg); s3c_hsotg_txfifo_flush(hsotg, idx); if ((epctl & S3C_DxEPCTL_Stall) && (epctl & S3C_DxEPCTL_EPType_Bulk)) { int dctl = readl(hsotg->regs + S3C_DCTL); dctl |= S3C_DCTL_CGNPInNAK; writel(dctl, hsotg->regs + S3C_DCTL); } } } if (ints & S3C_DxEPINT_AHBErr) dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__); if (ints & S3C_DxEPINT_Setup) { /* Setup or Timeout */ dev_dbg(hsotg->dev, "%s: Setup/Timeout\n", __func__); if (using_dma(hsotg) && idx == 0) { /* this is the notification we've received a * setup packet. In non-DMA mode we'd get this * from the RXFIFO, instead we need to process * the setup here. */ if (dir_in) WARN_ON_ONCE(1); else s3c_hsotg_handle_outdone(hsotg, 0, true); } } if (ints & S3C_DxEPINT_Back2BackSetup) dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__); if (dir_in) { /* not sure if this is important, but we'll clear it anyway */ if (ints & S3C_DIEPMSK_INTknTXFEmpMsk) { dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n", __func__, idx); } /* this probably means something bad is happening */ if (ints & S3C_DIEPMSK_INTknEPMisMsk) { dev_warn(hsotg->dev, "%s: ep%d: INTknEP\n", __func__, idx); } /* FIFO has space or is empty (see GAHBCFG) */ if (hsotg->dedicated_fifos && ints & S3C_DIEPMSK_TxFIFOEmpty) { dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); s3c_hsotg_trytx(hsotg, hs_ep); } } } /** * s3c_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done) * @hsotg: The device state. * * Handle updating the device settings after the enumeration phase has * been completed. */ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) { u32 dsts = readl(hsotg->regs + S3C_DSTS); int ep0_mps = 0, ep_mps; /* This should signal the finish of the enumeration phase * of the USB handshaking, so we should now know what rate * we connected at. */ dev_dbg(hsotg->dev, "EnumDone (DSTS=0x%08x)\n", dsts); /* note, since we're limited by the size of transfer on EP0, and * it seems IN transfers must be a even number of packets we do * not advertise a 64byte MPS on EP0. */ /* catch both EnumSpd_FS and EnumSpd_FS48 */ switch (dsts & S3C_DSTS_EnumSpd_MASK) { case S3C_DSTS_EnumSpd_FS: case S3C_DSTS_EnumSpd_FS48: hsotg->gadget.speed = USB_SPEED_FULL; ep0_mps = EP0_MPS_LIMIT; ep_mps = 64; break; case S3C_DSTS_EnumSpd_HS: hsotg->gadget.speed = USB_SPEED_HIGH; ep0_mps = EP0_MPS_LIMIT; ep_mps = 512; break; case S3C_DSTS_EnumSpd_LS: hsotg->gadget.speed = USB_SPEED_LOW; /* note, we don't actually support LS in this driver at the * moment, and the documentation seems to imply that it isn't * supported by the PHYs on some of the devices. */ break; } dev_info(hsotg->dev, "new device is %s\n", usb_speed_string(hsotg->gadget.speed)); /* we should now know the maximum packet size for an * endpoint, so set the endpoints to a default value. */ if (ep0_mps) { int i; s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps); for (i = 1; i < S3C_HSOTG_EPS; i++) s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps); } /* ensure after enumeration our EP0 is active */ s3c_hsotg_enqueue_setup(hsotg); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", readl(hsotg->regs + S3C_DIEPCTL0), readl(hsotg->regs + S3C_DOEPCTL0)); } /** * kill_all_requests - remove all requests from the endpoint's queue * @hsotg: The device state. * @ep: The endpoint the requests may be on. * @result: The result code to use. * @force: Force removal of any current requests * * Go through the requests on the given endpoint and mark them * completed with the given result code. */ static void kill_all_requests(struct s3c_hsotg *hsotg, struct s3c_hsotg_ep *ep, int result, bool force) { struct s3c_hsotg_req *req, *treq; unsigned long flags; spin_lock_irqsave(&ep->lock, flags); list_for_each_entry_safe(req, treq, &ep->queue, queue) { /* currently, we can't do much about an already * running request on an in endpoint */ if (ep->req == req && ep->dir_in && !force) continue; s3c_hsotg_complete_request(hsotg, ep, req, result); } spin_unlock_irqrestore(&ep->lock, flags); } #define call_gadget(_hs, _entry) \ if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ (_hs)->driver && (_hs)->driver->_entry) \ (_hs)->driver->_entry(&(_hs)->gadget); /** * s3c_hsotg_disconnect_irq - disconnect irq service * @hsotg: The device state. * * A disconnect IRQ has been received, meaning that the host has * lost contact with the bus. Remove all current transactions * and signal the gadget driver that this has happened. */ static void s3c_hsotg_disconnect_irq(struct s3c_hsotg *hsotg) { unsigned ep; for (ep = 0; ep < S3C_HSOTG_EPS; ep++) kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); call_gadget(hsotg, disconnect); } /** * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler * @hsotg: The device state: * @periodic: True if this is a periodic FIFO interrupt */ static void s3c_hsotg_irq_fifoempty(struct s3c_hsotg *hsotg, bool periodic) { struct s3c_hsotg_ep *ep; int epno, ret; /* look through for any more data to transmit */ for (epno = 0; epno < S3C_HSOTG_EPS; epno++) { ep = &hsotg->eps[epno]; if (!ep->dir_in) continue; if ((periodic && !ep->periodic) || (!periodic && ep->periodic)) continue; ret = s3c_hsotg_trytx(hsotg, ep); if (ret < 0) break; } } static struct s3c_hsotg *our_hsotg; /* IRQ flags which will trigger a retry around the IRQ loop */ #define IRQ_RETRY_MASK (S3C_GINTSTS_NPTxFEmp | \ S3C_GINTSTS_PTxFEmp | \ S3C_GINTSTS_RxFLvl) /** * s3c_hsotg_irq - handle device interrupt * @irq: The IRQ number triggered * @pw: The pw value when registered the handler. */ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) { struct s3c_hsotg *hsotg = pw; int retry_count = 8; u32 gintsts; u32 gintmsk; irq_retry: gintsts = readl(hsotg->regs + S3C_GINTSTS); gintmsk = readl(hsotg->regs + S3C_GINTMSK); dev_dbg(hsotg->dev, "%s: %08x %08x (%08x) retry %d\n", __func__, gintsts, gintsts & gintmsk, gintmsk, retry_count); gintsts &= gintmsk; if (gintsts & S3C_GINTSTS_OTGInt) { u32 otgint = readl(hsotg->regs + S3C_GOTGINT); dev_info(hsotg->dev, "OTGInt: %08x\n", otgint); writel(otgint, hsotg->regs + S3C_GOTGINT); } if (gintsts & S3C_GINTSTS_DisconnInt) { dev_dbg(hsotg->dev, "%s: DisconnInt\n", __func__); writel(S3C_GINTSTS_DisconnInt, hsotg->regs + S3C_GINTSTS); s3c_hsotg_disconnect_irq(hsotg); } if (gintsts & S3C_GINTSTS_SessReqInt) { dev_dbg(hsotg->dev, "%s: SessReqInt\n", __func__); writel(S3C_GINTSTS_SessReqInt, hsotg->regs + S3C_GINTSTS); } if (gintsts & S3C_GINTSTS_EnumDone) { writel(S3C_GINTSTS_EnumDone, hsotg->regs + S3C_GINTSTS); s3c_hsotg_irq_enumdone(hsotg); } if (gintsts & S3C_GINTSTS_ConIDStsChng) { dev_dbg(hsotg->dev, "ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n", readl(hsotg->regs + S3C_DSTS), readl(hsotg->regs + S3C_GOTGCTL)); writel(S3C_GINTSTS_ConIDStsChng, hsotg->regs + S3C_GINTSTS); } if (gintsts & (S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt)) { u32 daint = readl(hsotg->regs + S3C_DAINT); u32 daint_out = daint >> S3C_DAINT_OutEP_SHIFT; u32 daint_in = daint & ~(daint_out << S3C_DAINT_OutEP_SHIFT); int ep; dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint); for (ep = 0; ep < 15 && daint_out; ep++, daint_out >>= 1) { if (daint_out & 1) s3c_hsotg_epint(hsotg, ep, 0); } for (ep = 0; ep < 15 && daint_in; ep++, daint_in >>= 1) { if (daint_in & 1) s3c_hsotg_epint(hsotg, ep, 1); } } if (gintsts & S3C_GINTSTS_USBRst) { dev_info(hsotg->dev, "%s: USBRst\n", __func__); dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", readl(hsotg->regs + S3C_GNPTXSTS)); writel(S3C_GINTSTS_USBRst, hsotg->regs + S3C_GINTSTS); kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true); /* it seems after a reset we can end up with a situation * where the TXFIFO still has data in it... the docs * suggest resetting all the fifos, so use the init_fifo * code to relayout and flush the fifos. */ s3c_hsotg_init_fifo(hsotg); s3c_hsotg_enqueue_setup(hsotg); } /* check both FIFOs */ if (gintsts & S3C_GINTSTS_NPTxFEmp) { dev_dbg(hsotg->dev, "NPTxFEmp\n"); /* Disable the interrupt to stop it happening again * unless one of these endpoint routines decides that * it needs re-enabling */ s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_NPTxFEmp); s3c_hsotg_irq_fifoempty(hsotg, false); } if (gintsts & S3C_GINTSTS_PTxFEmp) { dev_dbg(hsotg->dev, "PTxFEmp\n"); /* See note in S3C_GINTSTS_NPTxFEmp */ s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_PTxFEmp); s3c_hsotg_irq_fifoempty(hsotg, true); } if (gintsts & S3C_GINTSTS_RxFLvl) { /* note, since GINTSTS_RxFLvl doubles as FIFO-not-empty, * we need to retry s3c_hsotg_handle_rx if this is still * set. */ s3c_hsotg_handle_rx(hsotg); } if (gintsts & S3C_GINTSTS_ModeMis) { dev_warn(hsotg->dev, "warning, mode mismatch triggered\n"); writel(S3C_GINTSTS_ModeMis, hsotg->regs + S3C_GINTSTS); } if (gintsts & S3C_GINTSTS_USBSusp) { dev_info(hsotg->dev, "S3C_GINTSTS_USBSusp\n"); writel(S3C_GINTSTS_USBSusp, hsotg->regs + S3C_GINTSTS); call_gadget(hsotg, suspend); } if (gintsts & S3C_GINTSTS_WkUpInt) { dev_info(hsotg->dev, "S3C_GINTSTS_WkUpIn\n"); writel(S3C_GINTSTS_WkUpInt, hsotg->regs + S3C_GINTSTS); call_gadget(hsotg, resume); } if (gintsts & S3C_GINTSTS_ErlySusp) { dev_dbg(hsotg->dev, "S3C_GINTSTS_ErlySusp\n"); writel(S3C_GINTSTS_ErlySusp, hsotg->regs + S3C_GINTSTS); } /* these next two seem to crop-up occasionally causing the core * to shutdown the USB transfer, so try clearing them and logging * the occurrence. */ if (gintsts & S3C_GINTSTS_GOUTNakEff) { dev_info(hsotg->dev, "GOUTNakEff triggered\n"); writel(S3C_DCTL_CGOUTNak, hsotg->regs + S3C_DCTL); s3c_hsotg_dump(hsotg); } if (gintsts & S3C_GINTSTS_GINNakEff) { dev_info(hsotg->dev, "GINNakEff triggered\n"); writel(S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); s3c_hsotg_dump(hsotg); } /* if we've had fifo events, we should try and go around the * loop again to see if there's any point in returning yet. */ if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) goto irq_retry; return IRQ_HANDLED; } /** * s3c_hsotg_ep_enable - enable the given endpoint * @ep: The USB endpint to configure * @desc: The USB endpoint descriptor to configure with. * * This is called from the USB gadget code's usb_ep_enable(). */ static int s3c_hsotg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct s3c_hsotg *hsotg = hs_ep->parent; unsigned long flags; int index = hs_ep->index; u32 epctrl_reg; u32 epctrl; u32 mps; int dir_in; int ret = 0; dev_dbg(hsotg->dev, "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n", __func__, ep->name, desc->bEndpointAddress, desc->bmAttributes, desc->wMaxPacketSize, desc->bInterval); /* not to be called for EP0 */ WARN_ON(index == 0); dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; if (dir_in != hs_ep->dir_in) { dev_err(hsotg->dev, "%s: direction mismatch!\n", __func__); return -EINVAL; } mps = usb_endpoint_maxp(desc); /* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */ epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index); epctrl = readl(hsotg->regs + epctrl_reg); dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", __func__, epctrl, epctrl_reg); spin_lock_irqsave(&hs_ep->lock, flags); epctrl &= ~(S3C_DxEPCTL_EPType_MASK | S3C_DxEPCTL_MPS_MASK); epctrl |= S3C_DxEPCTL_MPS(mps); /* mark the endpoint as active, otherwise the core may ignore * transactions entirely for this endpoint */ epctrl |= S3C_DxEPCTL_USBActEp; /* set the NAK status on the endpoint, otherwise we might try and * do something with data that we've yet got a request to process * since the RXFIFO will take data for an endpoint even if the * size register hasn't been set. */ epctrl |= S3C_DxEPCTL_SNAK; /* update the endpoint state */ hs_ep->ep.maxpacket = mps; /* default, set to non-periodic */ hs_ep->periodic = 0; switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_ISOC: dev_err(hsotg->dev, "no current ISOC support\n"); ret = -EINVAL; goto out; case USB_ENDPOINT_XFER_BULK: epctrl |= S3C_DxEPCTL_EPType_Bulk; break; case USB_ENDPOINT_XFER_INT: if (dir_in) { /* Allocate our TxFNum by simply using the index * of the endpoint for the moment. We could do * something better if the host indicates how * many FIFOs we are expecting to use. */ hs_ep->periodic = 1; epctrl |= S3C_DxEPCTL_TxFNum(index); } epctrl |= S3C_DxEPCTL_EPType_Intterupt; break; case USB_ENDPOINT_XFER_CONTROL: epctrl |= S3C_DxEPCTL_EPType_Control; break; } /* if the hardware has dedicated fifos, we must give each IN EP * a unique tx-fifo even if it is non-periodic. */ if (dir_in && hsotg->dedicated_fifos) epctrl |= S3C_DxEPCTL_TxFNum(index); /* for non control endpoints, set PID to D0 */ if (index) epctrl |= S3C_DxEPCTL_SetD0PID; dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n", __func__, epctrl); writel(epctrl, hsotg->regs + epctrl_reg); dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x\n", __func__, readl(hsotg->regs + epctrl_reg)); /* enable the endpoint interrupt */ s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); out: spin_unlock_irqrestore(&hs_ep->lock, flags); return ret; } static int s3c_hsotg_ep_disable(struct usb_ep *ep) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct s3c_hsotg *hsotg = hs_ep->parent; int dir_in = hs_ep->dir_in; int index = hs_ep->index; unsigned long flags; u32 epctrl_reg; u32 ctrl; dev_info(hsotg->dev, "%s(ep %p)\n", __func__, ep); if (ep == &hsotg->eps[0].ep) { dev_err(hsotg->dev, "%s: called for ep0\n", __func__); return -EINVAL; } epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index); /* terminate all requests with shutdown */ kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); spin_lock_irqsave(&hs_ep->lock, flags); ctrl = readl(hsotg->regs + epctrl_reg); ctrl &= ~S3C_DxEPCTL_EPEna; ctrl &= ~S3C_DxEPCTL_USBActEp; ctrl |= S3C_DxEPCTL_SNAK; dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); writel(ctrl, hsotg->regs + epctrl_reg); /* disable endpoint interrupts */ s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); spin_unlock_irqrestore(&hs_ep->lock, flags); return 0; } /** * on_list - check request is on the given endpoint * @ep: The endpoint to check. * @test: The request to test if it is on the endpoint. */ static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test) { struct s3c_hsotg_req *req, *treq; list_for_each_entry_safe(req, treq, &ep->queue, queue) { if (req == test) return true; } return false; } static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { struct s3c_hsotg_req *hs_req = our_req(req); struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct s3c_hsotg *hs = hs_ep->parent; unsigned long flags; dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); spin_lock_irqsave(&hs_ep->lock, flags); if (!on_list(hs_ep, hs_req)) { spin_unlock_irqrestore(&hs_ep->lock, flags); return -EINVAL; } s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); spin_unlock_irqrestore(&hs_ep->lock, flags); return 0; } static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) { struct s3c_hsotg_ep *hs_ep = our_ep(ep); struct s3c_hsotg *hs = hs_ep->parent; int index = hs_ep->index; unsigned long irqflags; u32 epreg; u32 epctl; u32 xfertype; dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); spin_lock_irqsave(&hs_ep->lock, irqflags); /* write both IN and OUT control registers */ epreg = S3C_DIEPCTL(index); epctl = readl(hs->regs + epreg); if (value) { epctl |= S3C_DxEPCTL_Stall + S3C_DxEPCTL_SNAK; if (epctl & S3C_DxEPCTL_EPEna) epctl |= S3C_DxEPCTL_EPDis; } else { epctl &= ~S3C_DxEPCTL_Stall; xfertype = epctl & S3C_DxEPCTL_EPType_MASK; if (xfertype == S3C_DxEPCTL_EPType_Bulk || xfertype == S3C_DxEPCTL_EPType_Intterupt) epctl |= S3C_DxEPCTL_SetD0PID; } writel(epctl, hs->regs + epreg); epreg = S3C_DOEPCTL(index); epctl = readl(hs->regs + epreg); if (value) epctl |= S3C_DxEPCTL_Stall; else { epctl &= ~S3C_DxEPCTL_Stall; xfertype = epctl & S3C_DxEPCTL_EPType_MASK; if (xfertype == S3C_DxEPCTL_EPType_Bulk || xfertype == S3C_DxEPCTL_EPType_Intterupt) epctl |= S3C_DxEPCTL_SetD0PID; } writel(epctl, hs->regs + epreg); spin_unlock_irqrestore(&hs_ep->lock, irqflags); return 0; } static struct usb_ep_ops s3c_hsotg_ep_ops = { .enable = s3c_hsotg_ep_enable, .disable = s3c_hsotg_ep_disable, .alloc_request = s3c_hsotg_ep_alloc_request, .free_request = s3c_hsotg_ep_free_request, .queue = s3c_hsotg_ep_queue, .dequeue = s3c_hsotg_ep_dequeue, .set_halt = s3c_hsotg_ep_sethalt, /* note, don't believe we have any call for the fifo routines */ }; /** * s3c_hsotg_corereset - issue softreset to the core * @hsotg: The device state * * Issue a soft reset to the core, and await the core finishing it. */ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg) { int timeout; u32 grstctl; dev_dbg(hsotg->dev, "resetting core\n"); /* issue soft reset */ writel(S3C_GRSTCTL_CSftRst, hsotg->regs + S3C_GRSTCTL); timeout = 1000; do { grstctl = readl(hsotg->regs + S3C_GRSTCTL); } while ((grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0); if (grstctl & S3C_GRSTCTL_CSftRst) { dev_err(hsotg->dev, "Failed to get CSftRst asserted\n"); return -EINVAL; } timeout = 1000; while (1) { u32 grstctl = readl(hsotg->regs + S3C_GRSTCTL); if (timeout-- < 0) { dev_info(hsotg->dev, "%s: reset failed, GRSTCTL=%08x\n", __func__, grstctl); return -ETIMEDOUT; } if (!(grstctl & S3C_GRSTCTL_AHBIdle)) continue; break; /* reset done */ } dev_dbg(hsotg->dev, "reset successful\n"); return 0; } static int s3c_hsotg_start(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *)) { struct s3c_hsotg *hsotg = our_hsotg; int ret; if (!hsotg) { printk(KERN_ERR "%s: called with no device\n", __func__); return -ENODEV; } if (!driver) { dev_err(hsotg->dev, "%s: no driver\n", __func__); return -EINVAL; } if (driver->speed != USB_SPEED_HIGH && driver->speed != USB_SPEED_FULL) { dev_err(hsotg->dev, "%s: bad speed\n", __func__); } if (!bind || !driver->setup) { dev_err(hsotg->dev, "%s: missing entry points\n", __func__); return -EINVAL; } WARN_ON(hsotg->driver); driver->driver.bus = NULL; hsotg->driver = driver; hsotg->gadget.dev.driver = &driver->driver; hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; hsotg->gadget.speed = USB_SPEED_UNKNOWN; ret = device_add(&hsotg->gadget.dev); if (ret) { dev_err(hsotg->dev, "failed to register gadget device\n"); goto err; } ret = bind(&hsotg->gadget); if (ret) { dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name); hsotg->gadget.dev.driver = NULL; hsotg->driver = NULL; goto err; } /* we must now enable ep0 ready for host detection and then * set configuration. */ s3c_hsotg_corereset(hsotg); /* set the PLL on, remove the HNP/SRP and set the PHY */ writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | (0x5 << 10), hsotg->regs + S3C_GUSBCFG); /* looks like soft-reset changes state of FIFOs */ s3c_hsotg_init_fifo(hsotg); __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); writel(1 << 18 | S3C_DCFG_DevSpd_HS, hsotg->regs + S3C_DCFG); /* Clear any pending OTG interrupts */ writel(0xffffffff, hsotg->regs + S3C_GOTGINT); /* Clear any pending interrupts */ writel(0xffffffff, hsotg->regs + S3C_GINTSTS); writel(S3C_GINTSTS_DisconnInt | S3C_GINTSTS_SessReqInt | S3C_GINTSTS_ConIDStsChng | S3C_GINTSTS_USBRst | S3C_GINTSTS_EnumDone | S3C_GINTSTS_OTGInt | S3C_GINTSTS_USBSusp | S3C_GINTSTS_WkUpInt | S3C_GINTSTS_GOUTNakEff | S3C_GINTSTS_GINNakEff | S3C_GINTSTS_ErlySusp, hsotg->regs + S3C_GINTMSK); if (using_dma(hsotg)) writel(S3C_GAHBCFG_GlblIntrEn | S3C_GAHBCFG_DMAEn | S3C_GAHBCFG_HBstLen_Incr4, hsotg->regs + S3C_GAHBCFG); else writel(S3C_GAHBCFG_GlblIntrEn, hsotg->regs + S3C_GAHBCFG); /* Enabling INTknTXFEmpMsk here seems to be a big mistake, we end * up being flooded with interrupts if the host is polling the * endpoint to try and read data. */ writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk | S3C_DIEPMSK_INTknEPMisMsk | S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk | ((hsotg->dedicated_fifos) ? S3C_DIEPMSK_TxFIFOEmpty : 0), hsotg->regs + S3C_DIEPMSK); /* don't need XferCompl, we get that from RXFIFO in slave mode. In * DMA mode we may need this. */ writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | S3C_DOEPMSK_EPDisbldMsk | (using_dma(hsotg) ? (S3C_DIEPMSK_XferComplMsk | S3C_DIEPMSK_TimeOUTMsk) : 0), hsotg->regs + S3C_DOEPMSK); writel(0, hsotg->regs + S3C_DAINTMSK); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", readl(hsotg->regs + S3C_DIEPCTL0), readl(hsotg->regs + S3C_DOEPCTL0)); /* enable in and out endpoint interrupts */ s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt); /* Enable the RXFIFO when in slave mode, as this is how we collect * the data. In DMA mode, we get events from the FIFO but also * things we cannot process, so do not use it. */ if (!using_dma(hsotg)) s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_RxFLvl); /* Enable interrupts for EP0 in and out */ s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone); udelay(10); /* see openiboot */ __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone); dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + S3C_DCTL)); /* S3C_DxEPCTL_USBActEp says RO in manual, but seems to be set by writing to the EPCTL register.. */ /* set to read 1 8byte packet */ writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) | S3C_DxEPTSIZ_XferSize(8), hsotg->regs + DOEPTSIZ0); writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | S3C_DxEPCTL_CNAK | S3C_DxEPCTL_EPEna | S3C_DxEPCTL_USBActEp, hsotg->regs + S3C_DOEPCTL0); /* enable, but don't activate EP0in */ writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | S3C_DxEPCTL_USBActEp, hsotg->regs + S3C_DIEPCTL0); s3c_hsotg_enqueue_setup(hsotg); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", readl(hsotg->regs + S3C_DIEPCTL0), readl(hsotg->regs + S3C_DOEPCTL0)); /* clear global NAKs */ writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); /* must be at-least 3ms to allow bus to see disconnect */ msleep(3); /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); /* report to the user, and return */ dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); return 0; err: hsotg->driver = NULL; hsotg->gadget.dev.driver = NULL; return ret; } static int s3c_hsotg_stop(struct usb_gadget_driver *driver) { struct s3c_hsotg *hsotg = our_hsotg; int ep; if (!hsotg) return -ENODEV; if (!driver || driver != hsotg->driver || !driver->unbind) return -EINVAL; /* all endpoints should be shutdown */ for (ep = 0; ep < S3C_HSOTG_EPS; ep++) s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); call_gadget(hsotg, disconnect); driver->unbind(&hsotg->gadget); hsotg->driver = NULL; hsotg->gadget.speed = USB_SPEED_UNKNOWN; device_del(&hsotg->gadget.dev); dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", driver->driver.name); return 0; } static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) { return s3c_hsotg_read_frameno(to_hsotg(gadget)); } static struct usb_gadget_ops s3c_hsotg_gadget_ops = { .get_frame = s3c_hsotg_gadget_getframe, .start = s3c_hsotg_start, .stop = s3c_hsotg_stop, }; /** * s3c_hsotg_initep - initialise a single endpoint * @hsotg: The device state. * @hs_ep: The endpoint to be initialised. * @epnum: The endpoint number * * Initialise the given endpoint (as part of the probe and device state * creation) to give to the gadget driver. Setup the endpoint name, any * direction information and other state that may be required. */ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, int epnum) { u32 ptxfifo; char *dir; if (epnum == 0) dir = ""; else if ((epnum % 2) == 0) { dir = "out"; } else { dir = "in"; hs_ep->dir_in = 1; } hs_ep->index = epnum; snprintf(hs_ep->name, sizeof(hs_ep->name), "ep%d%s", epnum, dir); INIT_LIST_HEAD(&hs_ep->queue); INIT_LIST_HEAD(&hs_ep->ep.ep_list); spin_lock_init(&hs_ep->lock); /* add to the list of endpoints known by the gadget driver */ if (epnum) list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); hs_ep->parent = hsotg; hs_ep->ep.name = hs_ep->name; hs_ep->ep.maxpacket = epnum ? 512 : EP0_MPS_LIMIT; hs_ep->ep.ops = &s3c_hsotg_ep_ops; /* Read the FIFO size for the Periodic TX FIFO, even if we're * an OUT endpoint, we may as well do this if in future the * code is changed to make each endpoint's direction changeable. */ ptxfifo = readl(hsotg->regs + S3C_DPTXFSIZn(epnum)); hs_ep->fifo_size = S3C_DPTXFSIZn_DPTxFSize_GET(ptxfifo) * 4; /* if we're using dma, we need to set the next-endpoint pointer * to be something valid. */ if (using_dma(hsotg)) { u32 next = S3C_DxEPCTL_NextEp((epnum + 1) % 15); writel(next, hsotg->regs + S3C_DIEPCTL(epnum)); writel(next, hsotg->regs + S3C_DOEPCTL(epnum)); } } /** * s3c_hsotg_otgreset - reset the OtG phy block * @hsotg: The host state. * * Power up the phy, set the basic configuration and start the PHY. */ static void s3c_hsotg_otgreset(struct s3c_hsotg *hsotg) { struct clk *xusbxti; u32 pwr, osc; pwr = readl(S3C_PHYPWR); pwr &= ~0x19; writel(pwr, S3C_PHYPWR); mdelay(1); osc = hsotg->plat->is_osc ? S3C_PHYCLK_EXT_OSC : 0; xusbxti = clk_get(hsotg->dev, "xusbxti"); if (xusbxti && !IS_ERR(xusbxti)) { switch (clk_get_rate(xusbxti)) { case 12*MHZ: osc |= S3C_PHYCLK_CLKSEL_12M; break; case 24*MHZ: osc |= S3C_PHYCLK_CLKSEL_24M; break; default: case 48*MHZ: /* default reference clock */ break; } clk_put(xusbxti); } writel(osc | 0x10, S3C_PHYCLK); /* issue a full set of resets to the otg and core */ writel(S3C_RSTCON_PHY, S3C_RSTCON); udelay(20); /* at-least 10uS */ writel(0, S3C_RSTCON); } static void s3c_hsotg_init(struct s3c_hsotg *hsotg) { u32 cfg4; /* unmask subset of endpoint interrupts */ writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk | S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk, hsotg->regs + S3C_DIEPMSK); writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk | S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk, hsotg->regs + S3C_DOEPMSK); writel(0, hsotg->regs + S3C_DAINTMSK); /* Be in disconnected state until gadget is registered */ __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); if (0) { /* post global nak until we're ready */ writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak, hsotg->regs + S3C_DCTL); } /* setup fifos */ dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", readl(hsotg->regs + S3C_GRXFSIZ), readl(hsotg->regs + S3C_GNPTXFSIZ)); s3c_hsotg_init_fifo(hsotg); /* set the PLL on, remove the HNP/SRP and set the PHY */ writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | (0x5 << 10), hsotg->regs + S3C_GUSBCFG); writel(using_dma(hsotg) ? S3C_GAHBCFG_DMAEn : 0x0, hsotg->regs + S3C_GAHBCFG); /* check hardware configuration */ cfg4 = readl(hsotg->regs + 0x50); hsotg->dedicated_fifos = (cfg4 >> 25) & 1; dev_info(hsotg->dev, "%s fifos\n", hsotg->dedicated_fifos ? "dedicated" : "shared"); } static void s3c_hsotg_dump(struct s3c_hsotg *hsotg) { #ifdef DEBUG struct device *dev = hsotg->dev; void __iomem *regs = hsotg->regs; u32 val; int idx; dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n", readl(regs + S3C_DCFG), readl(regs + S3C_DCTL), readl(regs + S3C_DIEPMSK)); dev_info(dev, "GAHBCFG=0x%08x, 0x44=0x%08x\n", readl(regs + S3C_GAHBCFG), readl(regs + 0x44)); dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", readl(regs + S3C_GRXFSIZ), readl(regs + S3C_GNPTXFSIZ)); /* show periodic fifo settings */ for (idx = 1; idx <= 15; idx++) { val = readl(regs + S3C_DPTXFSIZn(idx)); dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx, val >> S3C_DPTXFSIZn_DPTxFSize_SHIFT, val & S3C_DPTXFSIZn_DPTxFStAddr_MASK); } for (idx = 0; idx < 15; idx++) { dev_info(dev, "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx, readl(regs + S3C_DIEPCTL(idx)), readl(regs + S3C_DIEPTSIZ(idx)), readl(regs + S3C_DIEPDMA(idx))); val = readl(regs + S3C_DOEPCTL(idx)); dev_info(dev, "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx, readl(regs + S3C_DOEPCTL(idx)), readl(regs + S3C_DOEPTSIZ(idx)), readl(regs + S3C_DOEPDMA(idx))); } dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n", readl(regs + S3C_DVBUSDIS), readl(regs + S3C_DVBUSPULSE)); #endif } /** * state_show - debugfs: show overall driver and device state. * @seq: The seq file to write to. * @v: Unused parameter. * * This debugfs entry shows the overall state of the hardware and * some general information about each of the endpoints available * to the system. */ static int state_show(struct seq_file *seq, void *v) { struct s3c_hsotg *hsotg = seq->private; void __iomem *regs = hsotg->regs; int idx; seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n", readl(regs + S3C_DCFG), readl(regs + S3C_DCTL), readl(regs + S3C_DSTS)); seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n", readl(regs + S3C_DIEPMSK), readl(regs + S3C_DOEPMSK)); seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n", readl(regs + S3C_GINTMSK), readl(regs + S3C_GINTSTS)); seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n", readl(regs + S3C_DAINTMSK), readl(regs + S3C_DAINT)); seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n", readl(regs + S3C_GNPTXSTS), readl(regs + S3C_GRXSTSR)); seq_printf(seq, "\nEndpoint status:\n"); for (idx = 0; idx < 15; idx++) { u32 in, out; in = readl(regs + S3C_DIEPCTL(idx)); out = readl(regs + S3C_DOEPCTL(idx)); seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x", idx, in, out); in = readl(regs + S3C_DIEPTSIZ(idx)); out = readl(regs + S3C_DOEPTSIZ(idx)); seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x", in, out); seq_printf(seq, "\n"); } return 0; } static int state_open(struct inode *inode, struct file *file) { return single_open(file, state_show, inode->i_private); } static const struct file_operations state_fops = { .owner = THIS_MODULE, .open = state_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; /** * fifo_show - debugfs: show the fifo information * @seq: The seq_file to write data to. * @v: Unused parameter. * * Show the FIFO information for the overall fifo and all the * periodic transmission FIFOs. */ static int fifo_show(struct seq_file *seq, void *v) { struct s3c_hsotg *hsotg = seq->private; void __iomem *regs = hsotg->regs; u32 val; int idx; seq_printf(seq, "Non-periodic FIFOs:\n"); seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + S3C_GRXFSIZ)); val = readl(regs + S3C_GNPTXFSIZ); seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n", val >> S3C_GNPTXFSIZ_NPTxFDep_SHIFT, val & S3C_GNPTXFSIZ_NPTxFStAddr_MASK); seq_printf(seq, "\nPeriodic TXFIFOs:\n"); for (idx = 1; idx <= 15; idx++) { val = readl(regs + S3C_DPTXFSIZn(idx)); seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, val >> S3C_DPTXFSIZn_DPTxFSize_SHIFT, val & S3C_DPTXFSIZn_DPTxFStAddr_MASK); } return 0; } static int fifo_open(struct inode *inode, struct file *file) { return single_open(file, fifo_show, inode->i_private); } static const struct file_operations fifo_fops = { .owner = THIS_MODULE, .open = fifo_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static const char *decode_direction(int is_in) { return is_in ? "in" : "out"; } /** * ep_show - debugfs: show the state of an endpoint. * @seq: The seq_file to write data to. * @v: Unused parameter. * * This debugfs entry shows the state of the given endpoint (one is * registered for each available). */ static int ep_show(struct seq_file *seq, void *v) { struct s3c_hsotg_ep *ep = seq->private; struct s3c_hsotg *hsotg = ep->parent; struct s3c_hsotg_req *req; void __iomem *regs = hsotg->regs; int index = ep->index; int show_limit = 15; unsigned long flags; seq_printf(seq, "Endpoint index %d, named %s, dir %s:\n", ep->index, ep->ep.name, decode_direction(ep->dir_in)); /* first show the register state */ seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n", readl(regs + S3C_DIEPCTL(index)), readl(regs + S3C_DOEPCTL(index))); seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n", readl(regs + S3C_DIEPDMA(index)), readl(regs + S3C_DOEPDMA(index))); seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n", readl(regs + S3C_DIEPINT(index)), readl(regs + S3C_DOEPINT(index))); seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n", readl(regs + S3C_DIEPTSIZ(index)), readl(regs + S3C_DOEPTSIZ(index))); seq_printf(seq, "\n"); seq_printf(seq, "mps %d\n", ep->ep.maxpacket); seq_printf(seq, "total_data=%ld\n", ep->total_data); seq_printf(seq, "request list (%p,%p):\n", ep->queue.next, ep->queue.prev); spin_lock_irqsave(&ep->lock, flags); list_for_each_entry(req, &ep->queue, queue) { if (--show_limit < 0) { seq_printf(seq, "not showing more requests...\n"); break; } seq_printf(seq, "%c req %p: %d bytes @%p, ", req == ep->req ? '*' : ' ', req, req->req.length, req->req.buf); seq_printf(seq, "%d done, res %d\n", req->req.actual, req->req.status); } spin_unlock_irqrestore(&ep->lock, flags); return 0; } static int ep_open(struct inode *inode, struct file *file) { return single_open(file, ep_show, inode->i_private); } static const struct file_operations ep_fops = { .owner = THIS_MODULE, .open = ep_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; /** * s3c_hsotg_create_debug - create debugfs directory and files * @hsotg: The driver state * * Create the debugfs files to allow the user to get information * about the state of the system. The directory name is created * with the same name as the device itself, in case we end up * with multiple blocks in future systems. */ static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) { struct dentry *root; unsigned epidx; root = debugfs_create_dir(dev_name(hsotg->dev), NULL); hsotg->debug_root = root; if (IS_ERR(root)) { dev_err(hsotg->dev, "cannot create debug root\n"); return; } /* create general state file */ hsotg->debug_file = debugfs_create_file("state", 0444, root, hsotg, &state_fops); if (IS_ERR(hsotg->debug_file)) dev_err(hsotg->dev, "%s: failed to create state\n", __func__); hsotg->debug_fifo = debugfs_create_file("fifo", 0444, root, hsotg, &fifo_fops); if (IS_ERR(hsotg->debug_fifo)) dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); /* create one file for each endpoint */ for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) { struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; ep->debugfs = debugfs_create_file(ep->name, 0444, root, ep, &ep_fops); if (IS_ERR(ep->debugfs)) dev_err(hsotg->dev, "failed to create %s debug file\n", ep->name); } } /** * s3c_hsotg_delete_debug - cleanup debugfs entries * @hsotg: The driver state * * Cleanup (remove) the debugfs files for use on module exit. */ static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) { unsigned epidx; for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) { struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; debugfs_remove(ep->debugfs); } debugfs_remove(hsotg->debug_file); debugfs_remove(hsotg->debug_fifo); debugfs_remove(hsotg->debug_root); } /** * s3c_hsotg_gate - set the hardware gate for the block * @pdev: The device we bound to * @on: On or off. * * Set the hardware gate setting into the block. If we end up on * something other than an S3C64XX, then we might need to change this * to using a platform data callback, or some other mechanism. */ static void s3c_hsotg_gate(struct platform_device *pdev, bool on) { unsigned long flags; u32 others; local_irq_save(flags); others = __raw_readl(S3C64XX_OTHERS); if (on) others |= S3C64XX_OTHERS_USBMASK; else others &= ~S3C64XX_OTHERS_USBMASK; __raw_writel(others, S3C64XX_OTHERS); local_irq_restore(flags); } static struct s3c_hsotg_plat s3c_hsotg_default_pdata; static int __devinit s3c_hsotg_probe(struct platform_device *pdev) { struct s3c_hsotg_plat *plat = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct s3c_hsotg *hsotg; struct resource *res; int epnum; int ret; if (!plat) plat = &s3c_hsotg_default_pdata; hsotg = kzalloc(sizeof(struct s3c_hsotg) + sizeof(struct s3c_hsotg_ep) * S3C_HSOTG_EPS, GFP_KERNEL); if (!hsotg) { dev_err(dev, "cannot get memory\n"); return -ENOMEM; } hsotg->dev = dev; hsotg->plat = plat; hsotg->clk = clk_get(&pdev->dev, "otg"); if (IS_ERR(hsotg->clk)) { dev_err(dev, "cannot get otg clock\n"); ret = PTR_ERR(hsotg->clk); goto err_mem; } platform_set_drvdata(pdev, hsotg); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "cannot find register resource 0\n"); ret = -EINVAL; goto err_clk; } hsotg->regs_res = request_mem_region(res->start, resource_size(res), dev_name(dev)); if (!hsotg->regs_res) { dev_err(dev, "cannot reserve registers\n"); ret = -ENOENT; goto err_clk; } hsotg->regs = ioremap(res->start, resource_size(res)); if (!hsotg->regs) { dev_err(dev, "cannot map registers\n"); ret = -ENXIO; goto err_regs_res; } ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(dev, "cannot find IRQ\n"); goto err_regs; } hsotg->irq = ret; ret = request_irq(ret, s3c_hsotg_irq, 0, dev_name(dev), hsotg); if (ret < 0) { dev_err(dev, "cannot claim IRQ\n"); goto err_regs; } dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); device_initialize(&hsotg->gadget.dev); dev_set_name(&hsotg->gadget.dev, "gadget"); hsotg->gadget.is_dualspeed = 1; hsotg->gadget.ops = &s3c_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); hsotg->gadget.dev.parent = dev; hsotg->gadget.dev.dma_mask = dev->dma_mask; /* setup endpoint information */ INIT_LIST_HEAD(&hsotg->gadget.ep_list); hsotg->gadget.ep0 = &hsotg->eps[0].ep; /* allocate EP0 request */ hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps[0].ep, GFP_KERNEL); if (!hsotg->ctrl_req) { dev_err(dev, "failed to allocate ctrl req\n"); goto err_regs; } /* reset the system */ clk_enable(hsotg->clk); s3c_hsotg_gate(pdev, true); s3c_hsotg_otgreset(hsotg); s3c_hsotg_corereset(hsotg); s3c_hsotg_init(hsotg); /* initialise the endpoints now the core has been initialised */ for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++) s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum); ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget); if (ret) goto err_add_udc; s3c_hsotg_create_debug(hsotg); s3c_hsotg_dump(hsotg); our_hsotg = hsotg; return 0; err_add_udc: s3c_hsotg_gate(pdev, false); clk_disable(hsotg->clk); clk_put(hsotg->clk); err_regs: iounmap(hsotg->regs); err_regs_res: release_resource(hsotg->regs_res); kfree(hsotg->regs_res); err_clk: clk_put(hsotg->clk); err_mem: kfree(hsotg); return ret; } static int __devexit s3c_hsotg_remove(struct platform_device *pdev) { struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); usb_del_gadget_udc(&hsotg->gadget); s3c_hsotg_delete_debug(hsotg); usb_gadget_unregister_driver(hsotg->driver); free_irq(hsotg->irq, hsotg); iounmap(hsotg->regs); release_resource(hsotg->regs_res); kfree(hsotg->regs_res); s3c_hsotg_gate(pdev, false); clk_disable(hsotg->clk); clk_put(hsotg->clk); kfree(hsotg); return 0; } #if 1 #define s3c_hsotg_suspend NULL #define s3c_hsotg_resume NULL #endif static struct platform_driver s3c_hsotg_driver = { .driver = { .name = "s3c-hsotg", .owner = THIS_MODULE, }, .probe = s3c_hsotg_probe, .remove = __devexit_p(s3c_hsotg_remove), .suspend = s3c_hsotg_suspend, .resume = s3c_hsotg_resume, }; static int __init s3c_hsotg_modinit(void) { return platform_driver_register(&s3c_hsotg_driver); } static void __exit s3c_hsotg_modexit(void) { platform_driver_unregister(&s3c_hsotg_driver); } module_init(s3c_hsotg_modinit); module_exit(s3c_hsotg_modexit); MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:s3c-hsotg");