|
@@ -3126,6 +3126,7 @@ static inline int raw_cmd_copyout(int cmd, void __user *param,
|
|
|
}
|
|
|
ptr = ptr->next;
|
|
|
}
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -3156,18 +3157,19 @@ static inline int raw_cmd_copyin(int cmd, void __user *param,
|
|
|
int i;
|
|
|
|
|
|
*rcmd = NULL;
|
|
|
- while (1) {
|
|
|
- ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
|
|
|
- if (!ptr)
|
|
|
- return -ENOMEM;
|
|
|
- *rcmd = ptr;
|
|
|
- ret = copy_from_user(ptr, param, sizeof(*ptr));
|
|
|
- if (ret)
|
|
|
- return -EFAULT;
|
|
|
- ptr->next = NULL;
|
|
|
- ptr->buffer_length = 0;
|
|
|
- param += sizeof(struct floppy_raw_cmd);
|
|
|
- if (ptr->cmd_count > 33)
|
|
|
+
|
|
|
+loop:
|
|
|
+ ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
|
|
|
+ if (!ptr)
|
|
|
+ return -ENOMEM;
|
|
|
+ *rcmd = ptr;
|
|
|
+ ret = copy_from_user(ptr, param, sizeof(*ptr));
|
|
|
+ if (ret)
|
|
|
+ return -EFAULT;
|
|
|
+ ptr->next = NULL;
|
|
|
+ ptr->buffer_length = 0;
|
|
|
+ param += sizeof(struct floppy_raw_cmd);
|
|
|
+ if (ptr->cmd_count > 33)
|
|
|
/* the command may now also take up the space
|
|
|
* initially intended for the reply & the
|
|
|
* reply count. Needed for long 82078 commands
|
|
@@ -3176,34 +3178,35 @@ static inline int raw_cmd_copyin(int cmd, void __user *param,
|
|
|
* 16 bytes for a structure, you'll one day
|
|
|
* discover that you really need 17...
|
|
|
*/
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ for (i = 0; i < 16; i++)
|
|
|
+ ptr->reply[i] = 0;
|
|
|
+ ptr->resultcode = 0;
|
|
|
+ ptr->kernel_data = NULL;
|
|
|
+
|
|
|
+ if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
|
|
|
+ if (ptr->length <= 0)
|
|
|
return -EINVAL;
|
|
|
+ ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length);
|
|
|
+ fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
|
|
|
+ if (!ptr->kernel_data)
|
|
|
+ return -ENOMEM;
|
|
|
+ ptr->buffer_length = ptr->length;
|
|
|
+ }
|
|
|
+ if (ptr->flags & FD_RAW_WRITE) {
|
|
|
+ ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
|
|
|
- for (i = 0; i < 16; i++)
|
|
|
- ptr->reply[i] = 0;
|
|
|
- ptr->resultcode = 0;
|
|
|
- ptr->kernel_data = NULL;
|
|
|
-
|
|
|
- if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
|
|
|
- if (ptr->length <= 0)
|
|
|
- return -EINVAL;
|
|
|
- ptr->kernel_data =
|
|
|
- (char *)fd_dma_mem_alloc(ptr->length);
|
|
|
- fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
|
|
|
- if (!ptr->kernel_data)
|
|
|
- return -ENOMEM;
|
|
|
- ptr->buffer_length = ptr->length;
|
|
|
- }
|
|
|
- if (ptr->flags & FD_RAW_WRITE) {
|
|
|
- ret = fd_copyin(ptr->data, ptr->kernel_data,
|
|
|
- ptr->length);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ if (ptr->flags & FD_RAW_MORE) {
|
|
|
rcmd = &(ptr->next);
|
|
|
- if (!(ptr->flags & FD_RAW_MORE))
|
|
|
- return 0;
|
|
|
ptr->rate &= 0x43;
|
|
|
+ goto loop;
|
|
|
}
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int raw_cmd_ioctl(int cmd, void __user *param)
|