+static int bcm_char_ioctl_reg_read_private(void __user *argp, struct bcm_mini_adapter *Adapter)
+{
+ struct bcm_rdm_buffer sRdmBuffer = {0};
+ struct bcm_ioctl_buffer IoBuffer;
+ PCHAR temp_buff;
+ INT Status = STATUS_FAILURE;
+ UINT Bufflen;
+ u16 temp_value;
+ int bytes;
+
+ /* Copy Ioctl Buffer structure */
+ if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
+ return -EFAULT;
+
+ if (IoBuffer.InputLength > sizeof(sRdmBuffer))
+ return -EINVAL;
+
+ if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+ return -EFAULT;
+
+ if (IoBuffer.OutputLength > USHRT_MAX ||
+ IoBuffer.OutputLength == 0) {
+ return -EINVAL;
+ }
+
+ Bufflen = IoBuffer.OutputLength;
+ temp_value = 4 - (Bufflen % 4);
+ Bufflen += temp_value % 4;
+
+ temp_buff = kmalloc(Bufflen, GFP_KERNEL);
+ if (!temp_buff)
+ return -ENOMEM;
+
+ bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
+ (PUINT)temp_buff, Bufflen);
+ if (bytes > 0) {
+ Status = STATUS_SUCCESS;
+ if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
+ kfree(temp_buff);
+ return -EFAULT;
+ }
+ } else {
+ Status = bytes;
+ }
+
+ kfree(temp_buff);
+ return Status;
+}
+