#define _CIFSPDU_H
 
 #include <net/sock.h>
+#include <asm/unaligned.h>
 #include "smbfsctl.h"
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        __u16 Mid;
        __u8 WordCount;
 } __attribute__((packed));
-/* given a pointer to an smb_hdr retrieve the value of byte count */
-#define BCC(smb_var) (*(__u16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
-#define BCC_LE(smb_var) (*(__le16 *)((char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount)))
+
+/* given a pointer to an smb_hdr retrieve a char pointer to the byte count */
+#define BCC(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + \
+                        (2 * (smb_var)->WordCount))
+
 /* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-#define pByteArea(smb_var) ((unsigned char *)(smb_var) + sizeof(struct smb_hdr) + (2 * (smb_var)->WordCount) + 2)
+#define pByteArea(smb_var) (BCC(smb_var) + 2)
+
+/* get the converted ByteCount for a SMB packet and return it */
+static inline __u16
+get_bcc(struct smb_hdr *hdr)
+{
+       __u16 *bc_ptr = (__u16 *)BCC(hdr);
+
+       return get_unaligned(bc_ptr);
+}
+
+/* get the unconverted ByteCount for a SMB packet and return it */
+static inline __u16
+get_bcc_le(struct smb_hdr *hdr)
+{
+       __le16 *bc_ptr = (__le16 *)BCC(hdr);
+
+       return get_unaligned_le16(bc_ptr);
+}
+
+/* set the ByteCount for a SMB packet in host-byte order */
+static inline void
+put_bcc(__u16 count, struct smb_hdr *hdr)
+{
+       __u16 *bc_ptr = (__u16 *)BCC(hdr);
+
+       put_unaligned(count, bc_ptr);
+}
+
+/* set the ByteCount for a SMB packet in little-endian */
+static inline void
+put_bcc_le(__u16 count, struct smb_hdr *hdr)
+{
+       __le16 *bc_ptr = (__le16 *)BCC(hdr);
+
+       put_unaligned_le16(count, bc_ptr);
+}
 
 /*
  * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
 
 {
        int rc = -EINVAL;
        int total_size;
-       char *pBCC;
 
        /* check for plausible wct, bcc and t2 data and parm sizes */
        /* check for parm and data offset going beyond end of smb */
                        if (total_size < 512) {
                                total_size +=
                                        le16_to_cpu(pSMB->t2_rsp.DataCount);
-                               /* BCC le converted in SendReceive */
-                               pBCC = (pSMB->hdr.WordCount * 2) +
-                                       sizeof(struct smb_hdr) +
-                                       (char *)pSMB;
-                               if ((total_size <= (*(u16 *)pBCC)) &&
-                                  (total_size <
-                                       CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) {
+                               if (total_size <= get_bcc(&pSMB->hdr) &&
+                                   total_size <
+                                       CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
                                        return 0;
                                }
                        }
                sizeof(struct smb_t2_rsp) + 16);
        return rc;
 }
+
 int
 CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 {
        }
 
        /* make sure list_len doesn't go past end of SMB */
-       end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr);
+       end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
        if ((char *)ea_response_data + list_len > end_of_smb) {
                cFYI(1, "EA list appears to go beyond SMB");
                rc = -EIO;
 
        memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
        total_in_buf += total_in_buf2;
        pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
-       byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
+       byte_count = get_bcc_le(pTargetSMB);
        byte_count += total_in_buf2;
-       BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
+       put_bcc_le(byte_count, pTargetSMB);
 
        byte_count = pTargetSMB->smb_buf_length;
        byte_count += total_in_buf2;
        TCONX_RSP *pSMBr;
        unsigned char *bcc_ptr;
        int rc = 0;
-       int length, bytes_left;
-       __u16 count;
+       int length;
+       __u16 bytes_left, count;
 
        if (ses == NULL)
                return -EIO;
                tcon->need_reconnect = false;
                tcon->tid = smb_buffer_response->Tid;
                bcc_ptr = pByteArea(smb_buffer_response);
-               bytes_left = BCC(smb_buffer_response);
+               bytes_left = get_bcc(smb_buffer_response);
                length = strnlen(bcc_ptr, bytes_left - 2);
                if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
                        is_unicode = true;
 
 smbCalcSize(struct smb_hdr *ptr)
 {
        return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
-               2 /* size of the bcc field */ + BCC(ptr));
+               2 /* size of the bcc field */ + get_bcc(ptr));
 }
 
 unsigned int
 smbCalcSize_LE(struct smb_hdr *ptr)
 {
        return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
-               2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));
+               2 /* size of the bcc field */ + get_bcc_le(ptr));
 }
 
 /* The following are taken from fs/ntfs/util.c */
 
 }
 
 static void
-decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
+decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses,
                      const struct nls_table *nls_cp)
 {
        int len;
        return;
 }
 
-static int decode_ascii_ssetup(char **pbcc_area, int bleft,
+static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
                               struct cifsSesInfo *ses,
                               const struct nls_table *nls_cp)
 {
        char *str_area;
        SESSION_SETUP_ANDX *pSMB;
        __u32 capabilities;
-       int count;
+       __u16 count;
        int resp_buf_type;
        struct kvec iov[3];
        enum securityEnum type;
-       __u16 action;
-       int bytes_remaining;
+       __u16 action, bytes_remaining;
        struct key *spnego_key = NULL;
        __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
        u16 blob_len;
        count = iov[1].iov_len + iov[2].iov_len;
        smb_buf->smb_buf_length += count;
 
-       BCC_LE(smb_buf) = cpu_to_le16(count);
+       put_bcc_le(count, smb_buf);
 
        rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
                          CIFS_LOG_ERROR);
        cFYI(1, "UID = %d ", ses->Suid);
        /* response can have either 3 or 4 word count - Samba sends 3 */
        /* and lanman response is 3 */
-       bytes_remaining = BCC(smb_buf);
+       bytes_remaining = get_bcc(smb_buf);
        bcc_ptr = pByteArea(smb_buf);
 
        if (smb_buf->WordCount == 4) {
 
        in_buf->smb_buf_length = sizeof(struct smb_hdr) - 4  + 2;
        in_buf->Command = SMB_COM_NT_CANCEL;
        in_buf->WordCount = 0;
-       BCC_LE(in_buf) = 0;
+       put_bcc_le(0, in_buf);
 
        mutex_lock(&server->srv_mutex);
        rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
                if (receive_len >= sizeof(struct smb_hdr) - 4
                    /* do not count RFC1001 header */  +
                    (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
-                       BCC(midQ->resp_buf) =
-                               le16_to_cpu(BCC_LE(midQ->resp_buf));
+                       put_bcc(get_bcc_le(midQ->resp_buf), midQ->resp_buf);
                if ((flags & CIFS_NO_RESP) == 0)
                        midQ->resp_buf = NULL;  /* mark it so buf will
                                                   not be freed by
                if (receive_len >= sizeof(struct smb_hdr) - 4
                    /* do not count RFC1001 header */  +
                    (2 * out_buf->WordCount) + 2 /* bcc */ )
-                       BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
+                       put_bcc(get_bcc_le(midQ->resp_buf), midQ->resp_buf);
        } else {
                rc = -EIO;
                cERROR(1, "Bad MID state?");
        if (receive_len >= sizeof(struct smb_hdr) - 4
            /* do not count RFC1001 header */  +
            (2 * out_buf->WordCount) + 2 /* bcc */ )
-               BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
+               put_bcc(get_bcc_le(out_buf), out_buf);
 
 out:
        delete_mid(midQ);