diff options
| author | Alan Stern <stern@rowland.harvard.edu> | 2009-04-27 13:19:41 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:44 -0400 |
| commit | 604eb89ffed9fba268582dc44d5b462ea94cc0ca (patch) | |
| tree | ede974bfeb0f016122573317eac20b6519eb30ae | |
| parent | 5d44b36120d5b67081419d9307a526a0dfd949fc (diff) | |
USB: g_file_storage: use the "unaligned" accessors
This patch (as1233) makes g_file_storage use the "unaligned" accessors.
This is based on work originally done by Harvey Harrison.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Harvey Harrison <harvey.harrison@gmail.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/usb/gadget/file_storage.c | 93 |
1 files changed, 42 insertions, 51 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 381a53b3e11c..1e6aa504d58a 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
| @@ -248,6 +248,8 @@ | |||
| 248 | #include <linux/freezer.h> | 248 | #include <linux/freezer.h> |
| 249 | #include <linux/utsname.h> | 249 | #include <linux/utsname.h> |
| 250 | 250 | ||
| 251 | #include <asm/unaligned.h> | ||
| 252 | |||
| 251 | #include <linux/usb/ch9.h> | 253 | #include <linux/usb/ch9.h> |
| 252 | #include <linux/usb/gadget.h> | 254 | #include <linux/usb/gadget.h> |
| 253 | 255 | ||
| @@ -799,29 +801,9 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | |||
| 799 | 801 | ||
| 800 | /* Routines for unaligned data access */ | 802 | /* Routines for unaligned data access */ |
| 801 | 803 | ||
| 802 | static u16 get_be16(u8 *buf) | 804 | static u32 get_unaligned_be24(u8 *buf) |
| 803 | { | ||
| 804 | return ((u16) buf[0] << 8) | ((u16) buf[1]); | ||
| 805 | } | ||
| 806 | |||
| 807 | static u32 get_be32(u8 *buf) | ||
| 808 | { | ||
| 809 | return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | | ||
| 810 | ((u32) buf[2] << 8) | ((u32) buf[3]); | ||
| 811 | } | ||
| 812 | |||
| 813 | static void put_be16(u8 *buf, u16 val) | ||
| 814 | { | ||
| 815 | buf[0] = val >> 8; | ||
| 816 | buf[1] = val; | ||
| 817 | } | ||
| 818 | |||
| 819 | static void put_be32(u8 *buf, u32 val) | ||
| 820 | { | 805 | { |
| 821 | buf[0] = val >> 24; | 806 | return 0xffffff & (u32) get_unaligned_be32(buf - 1); |
| 822 | buf[1] = val >> 16; | ||
| 823 | buf[2] = val >> 8; | ||
| 824 | buf[3] = val & 0xff; | ||
| 825 | } | 807 | } |
| 826 | 808 | ||
| 827 | 809 | ||
| @@ -1582,9 +1564,9 @@ static int do_read(struct fsg_dev *fsg) | |||
| 1582 | /* Get the starting Logical Block Address and check that it's | 1564 | /* Get the starting Logical Block Address and check that it's |
| 1583 | * not too big */ | 1565 | * not too big */ |
| 1584 | if (fsg->cmnd[0] == SC_READ_6) | 1566 | if (fsg->cmnd[0] == SC_READ_6) |
| 1585 | lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]); | 1567 | lba = get_unaligned_be24(&fsg->cmnd[1]); |
| 1586 | else { | 1568 | else { |
| 1587 | lba = get_be32(&fsg->cmnd[2]); | 1569 | lba = get_unaligned_be32(&fsg->cmnd[2]); |
| 1588 | 1570 | ||
| 1589 | /* We allow DPO (Disable Page Out = don't save data in the | 1571 | /* We allow DPO (Disable Page Out = don't save data in the |
| 1590 | * cache) and FUA (Force Unit Access = don't read from the | 1572 | * cache) and FUA (Force Unit Access = don't read from the |
| @@ -1717,9 +1699,9 @@ static int do_write(struct fsg_dev *fsg) | |||
| 1717 | /* Get the starting Logical Block Address and check that it's | 1699 | /* Get the starting Logical Block Address and check that it's |
| 1718 | * not too big */ | 1700 | * not too big */ |
| 1719 | if (fsg->cmnd[0] == SC_WRITE_6) | 1701 | if (fsg->cmnd[0] == SC_WRITE_6) |
| 1720 | lba = (fsg->cmnd[1] << 16) | get_be16(&fsg->cmnd[2]); | 1702 | lba = get_unaligned_be24(&fsg->cmnd[1]); |
| 1721 | else { | 1703 | else { |
| 1722 | lba = get_be32(&fsg->cmnd[2]); | 1704 | lba = get_unaligned_be32(&fsg->cmnd[2]); |
| 1723 | 1705 | ||
| 1724 | /* We allow DPO (Disable Page Out = don't save data in the | 1706 | /* We allow DPO (Disable Page Out = don't save data in the |
| 1725 | * cache) and FUA (Force Unit Access = write directly to the | 1707 | * cache) and FUA (Force Unit Access = write directly to the |
| @@ -1940,7 +1922,7 @@ static int do_verify(struct fsg_dev *fsg) | |||
| 1940 | 1922 | ||
| 1941 | /* Get the starting Logical Block Address and check that it's | 1923 | /* Get the starting Logical Block Address and check that it's |
| 1942 | * not too big */ | 1924 | * not too big */ |
| 1943 | lba = get_be32(&fsg->cmnd[2]); | 1925 | lba = get_unaligned_be32(&fsg->cmnd[2]); |
| 1944 | if (lba >= curlun->num_sectors) { | 1926 | if (lba >= curlun->num_sectors) { |
| 1945 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1927 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1946 | return -EINVAL; | 1928 | return -EINVAL; |
| @@ -1953,7 +1935,7 @@ static int do_verify(struct fsg_dev *fsg) | |||
| 1953 | return -EINVAL; | 1935 | return -EINVAL; |
| 1954 | } | 1936 | } |
| 1955 | 1937 | ||
| 1956 | verification_length = get_be16(&fsg->cmnd[7]); | 1938 | verification_length = get_unaligned_be16(&fsg->cmnd[7]); |
| 1957 | if (unlikely(verification_length == 0)) | 1939 | if (unlikely(verification_length == 0)) |
| 1958 | return -EIO; // No default reply | 1940 | return -EIO; // No default reply |
| 1959 | 1941 | ||
| @@ -2103,7 +2085,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2103 | memset(buf, 0, 18); | 2085 | memset(buf, 0, 18); |
| 2104 | buf[0] = valid | 0x70; // Valid, current error | 2086 | buf[0] = valid | 0x70; // Valid, current error |
| 2105 | buf[2] = SK(sd); | 2087 | buf[2] = SK(sd); |
| 2106 | put_be32(&buf[3], sdinfo); // Sense information | 2088 | put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */ |
| 2107 | buf[7] = 18 - 8; // Additional sense length | 2089 | buf[7] = 18 - 8; // Additional sense length |
| 2108 | buf[12] = ASC(sd); | 2090 | buf[12] = ASC(sd); |
| 2109 | buf[13] = ASCQ(sd); | 2091 | buf[13] = ASCQ(sd); |
| @@ -2114,7 +2096,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2114 | static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) | 2096 | static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) |
| 2115 | { | 2097 | { |
| 2116 | struct lun *curlun = fsg->curlun; | 2098 | struct lun *curlun = fsg->curlun; |
| 2117 | u32 lba = get_be32(&fsg->cmnd[2]); | 2099 | u32 lba = get_unaligned_be32(&fsg->cmnd[2]); |
| 2118 | int pmi = fsg->cmnd[8]; | 2100 | int pmi = fsg->cmnd[8]; |
| 2119 | u8 *buf = (u8 *) bh->buf; | 2101 | u8 *buf = (u8 *) bh->buf; |
| 2120 | 2102 | ||
| @@ -2124,8 +2106,9 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2124 | return -EINVAL; | 2106 | return -EINVAL; |
| 2125 | } | 2107 | } |
| 2126 | 2108 | ||
| 2127 | put_be32(&buf[0], curlun->num_sectors - 1); // Max logical block | 2109 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); |
| 2128 | put_be32(&buf[4], 512); // Block length | 2110 | /* Max logical block */ |
| 2111 | put_unaligned_be32(512, &buf[4]); /* Block length */ | ||
| 2129 | return 8; | 2112 | return 8; |
| 2130 | } | 2113 | } |
| 2131 | 2114 | ||
| @@ -2144,7 +2127,7 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr) | |||
| 2144 | dest[0] = 0; /* Reserved */ | 2127 | dest[0] = 0; /* Reserved */ |
| 2145 | } else { | 2128 | } else { |
| 2146 | /* Absolute sector */ | 2129 | /* Absolute sector */ |
| 2147 | put_be32(dest, addr); | 2130 | put_unaligned_be32(addr, dest); |
| 2148 | } | 2131 | } |
| 2149 | } | 2132 | } |
| 2150 | 2133 | ||
| @@ -2152,7 +2135,7 @@ static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2152 | { | 2135 | { |
| 2153 | struct lun *curlun = fsg->curlun; | 2136 | struct lun *curlun = fsg->curlun; |
| 2154 | int msf = fsg->cmnd[1] & 0x02; | 2137 | int msf = fsg->cmnd[1] & 0x02; |
| 2155 | u32 lba = get_be32(&fsg->cmnd[2]); | 2138 | u32 lba = get_unaligned_be32(&fsg->cmnd[2]); |
| 2156 | u8 *buf = (u8 *) bh->buf; | 2139 | u8 *buf = (u8 *) bh->buf; |
| 2157 | 2140 | ||
| 2158 | if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */ | 2141 | if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */ |
| @@ -2252,10 +2235,13 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2252 | buf[2] = 0x04; // Write cache enable, | 2235 | buf[2] = 0x04; // Write cache enable, |
| 2253 | // Read cache not disabled | 2236 | // Read cache not disabled |
| 2254 | // No cache retention priorities | 2237 | // No cache retention priorities |
| 2255 | put_be16(&buf[4], 0xffff); // Don't disable prefetch | 2238 | put_unaligned_be16(0xffff, &buf[4]); |
| 2256 | // Minimum prefetch = 0 | 2239 | /* Don't disable prefetch */ |
| 2257 | put_be16(&buf[8], 0xffff); // Maximum prefetch | 2240 | /* Minimum prefetch = 0 */ |
| 2258 | put_be16(&buf[10], 0xffff); // Maximum prefetch ceiling | 2241 | put_unaligned_be16(0xffff, &buf[8]); |
| 2242 | /* Maximum prefetch */ | ||
| 2243 | put_unaligned_be16(0xffff, &buf[10]); | ||
| 2244 | /* Maximum prefetch ceiling */ | ||
| 2259 | } | 2245 | } |
| 2260 | buf += 12; | 2246 | buf += 12; |
| 2261 | } | 2247 | } |
| @@ -2272,7 +2258,7 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2272 | if (mscmnd == SC_MODE_SENSE_6) | 2258 | if (mscmnd == SC_MODE_SENSE_6) |
| 2273 | buf0[0] = len - 1; | 2259 | buf0[0] = len - 1; |
| 2274 | else | 2260 | else |
| 2275 | put_be16(buf0, len - 2); | 2261 | put_unaligned_be16(len - 2, buf0); |
| 2276 | return len; | 2262 | return len; |
| 2277 | } | 2263 | } |
| 2278 | 2264 | ||
| @@ -2360,9 +2346,10 @@ static int do_read_format_capacities(struct fsg_dev *fsg, | |||
| 2360 | buf[3] = 8; // Only the Current/Maximum Capacity Descriptor | 2346 | buf[3] = 8; // Only the Current/Maximum Capacity Descriptor |
| 2361 | buf += 4; | 2347 | buf += 4; |
| 2362 | 2348 | ||
| 2363 | put_be32(&buf[0], curlun->num_sectors); // Number of blocks | 2349 | put_unaligned_be32(curlun->num_sectors, &buf[0]); |
| 2364 | put_be32(&buf[4], 512); // Block length | 2350 | /* Number of blocks */ |
| 2365 | buf[4] = 0x02; // Current capacity | 2351 | put_unaligned_be32(512, &buf[4]); /* Block length */ |
| 2352 | buf[4] = 0x02; /* Current capacity */ | ||
| 2366 | return 12; | 2353 | return 12; |
| 2367 | } | 2354 | } |
| 2368 | 2355 | ||
| @@ -2882,7 +2869,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2882 | break; | 2869 | break; |
| 2883 | 2870 | ||
| 2884 | case SC_MODE_SELECT_10: | 2871 | case SC_MODE_SELECT_10: |
| 2885 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | 2872 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
| 2886 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | 2873 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, |
| 2887 | (1<<1) | (3<<7), 0, | 2874 | (1<<1) | (3<<7), 0, |
| 2888 | "MODE SELECT(10)")) == 0) | 2875 | "MODE SELECT(10)")) == 0) |
| @@ -2898,7 +2885,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2898 | break; | 2885 | break; |
| 2899 | 2886 | ||
| 2900 | case SC_MODE_SENSE_10: | 2887 | case SC_MODE_SENSE_10: |
| 2901 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | 2888 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
| 2902 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2889 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
| 2903 | (1<<1) | (1<<2) | (3<<7), 0, | 2890 | (1<<1) | (1<<2) | (3<<7), 0, |
| 2904 | "MODE SENSE(10)")) == 0) | 2891 | "MODE SENSE(10)")) == 0) |
| @@ -2923,7 +2910,8 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2923 | break; | 2910 | break; |
| 2924 | 2911 | ||
| 2925 | case SC_READ_10: | 2912 | case SC_READ_10: |
| 2926 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9; | 2913 | fsg->data_size_from_cmnd = |
| 2914 | get_unaligned_be16(&fsg->cmnd[7]) << 9; | ||
| 2927 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2915 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
| 2928 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2916 | (1<<1) | (0xf<<2) | (3<<7), 1, |
| 2929 | "READ(10)")) == 0) | 2917 | "READ(10)")) == 0) |
| @@ -2931,7 +2919,8 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2931 | break; | 2919 | break; |
| 2932 | 2920 | ||
| 2933 | case SC_READ_12: | 2921 | case SC_READ_12: |
| 2934 | fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9; | 2922 | fsg->data_size_from_cmnd = |
| 2923 | get_unaligned_be32(&fsg->cmnd[6]) << 9; | ||
| 2935 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, | 2924 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, |
| 2936 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2925 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
| 2937 | "READ(12)")) == 0) | 2926 | "READ(12)")) == 0) |
| @@ -2949,7 +2938,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2949 | case SC_READ_HEADER: | 2938 | case SC_READ_HEADER: |
| 2950 | if (!mod_data.cdrom) | 2939 | if (!mod_data.cdrom) |
| 2951 | goto unknown_cmnd; | 2940 | goto unknown_cmnd; |
| 2952 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | 2941 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
| 2953 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2942 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
| 2954 | (3<<7) | (0x1f<<1), 1, | 2943 | (3<<7) | (0x1f<<1), 1, |
| 2955 | "READ HEADER")) == 0) | 2944 | "READ HEADER")) == 0) |
| @@ -2959,7 +2948,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2959 | case SC_READ_TOC: | 2948 | case SC_READ_TOC: |
| 2960 | if (!mod_data.cdrom) | 2949 | if (!mod_data.cdrom) |
| 2961 | goto unknown_cmnd; | 2950 | goto unknown_cmnd; |
| 2962 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | 2951 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
| 2963 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2952 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
| 2964 | (7<<6) | (1<<1), 1, | 2953 | (7<<6) | (1<<1), 1, |
| 2965 | "READ TOC")) == 0) | 2954 | "READ TOC")) == 0) |
| @@ -2967,7 +2956,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 2967 | break; | 2956 | break; |
| 2968 | 2957 | ||
| 2969 | case SC_READ_FORMAT_CAPACITIES: | 2958 | case SC_READ_FORMAT_CAPACITIES: |
| 2970 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]); | 2959 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
| 2971 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2960 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, |
| 2972 | (3<<7), 1, | 2961 | (3<<7), 1, |
| 2973 | "READ FORMAT CAPACITIES")) == 0) | 2962 | "READ FORMAT CAPACITIES")) == 0) |
| @@ -3025,7 +3014,8 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 3025 | break; | 3014 | break; |
| 3026 | 3015 | ||
| 3027 | case SC_WRITE_10: | 3016 | case SC_WRITE_10: |
| 3028 | fsg->data_size_from_cmnd = get_be16(&fsg->cmnd[7]) << 9; | 3017 | fsg->data_size_from_cmnd = |
| 3018 | get_unaligned_be16(&fsg->cmnd[7]) << 9; | ||
| 3029 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | 3019 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, |
| 3030 | (1<<1) | (0xf<<2) | (3<<7), 1, | 3020 | (1<<1) | (0xf<<2) | (3<<7), 1, |
| 3031 | "WRITE(10)")) == 0) | 3021 | "WRITE(10)")) == 0) |
| @@ -3033,7 +3023,8 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
| 3033 | break; | 3023 | break; |
| 3034 | 3024 | ||
| 3035 | case SC_WRITE_12: | 3025 | case SC_WRITE_12: |
| 3036 | fsg->data_size_from_cmnd = get_be32(&fsg->cmnd[6]) << 9; | 3026 | fsg->data_size_from_cmnd = |
| 3027 | get_unaligned_be32(&fsg->cmnd[6]) << 9; | ||
| 3037 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, | 3028 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, |
| 3038 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 3029 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
| 3039 | "WRITE(12)")) == 0) | 3030 | "WRITE(12)")) == 0) |
