aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/floppy.c73
1 files changed, 38 insertions, 35 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 4807203827cc..b7190fd582f4 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3126,6 +3126,7 @@ static inline int raw_cmd_copyout(int cmd, void __user *param,
3126 } 3126 }
3127 ptr = ptr->next; 3127 ptr = ptr->next;
3128 } 3128 }
3129
3129 return 0; 3130 return 0;
3130} 3131}
3131 3132
@@ -3156,18 +3157,19 @@ static inline int raw_cmd_copyin(int cmd, void __user *param,
3156 int i; 3157 int i;
3157 3158
3158 *rcmd = NULL; 3159 *rcmd = NULL;
3159 while (1) { 3160
3160 ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); 3161loop:
3161 if (!ptr) 3162 ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
3162 return -ENOMEM; 3163 if (!ptr)
3163 *rcmd = ptr; 3164 return -ENOMEM;
3164 ret = copy_from_user(ptr, param, sizeof(*ptr)); 3165 *rcmd = ptr;
3165 if (ret) 3166 ret = copy_from_user(ptr, param, sizeof(*ptr));
3166 return -EFAULT; 3167 if (ret)
3167 ptr->next = NULL; 3168 return -EFAULT;
3168 ptr->buffer_length = 0; 3169 ptr->next = NULL;
3169 param += sizeof(struct floppy_raw_cmd); 3170 ptr->buffer_length = 0;
3170 if (ptr->cmd_count > 33) 3171 param += sizeof(struct floppy_raw_cmd);
3172 if (ptr->cmd_count > 33)
3171 /* the command may now also take up the space 3173 /* the command may now also take up the space
3172 * initially intended for the reply & the 3174 * initially intended for the reply & the
3173 * reply count. Needed for long 82078 commands 3175 * reply count. Needed for long 82078 commands
@@ -3176,34 +3178,35 @@ static inline int raw_cmd_copyin(int cmd, void __user *param,
3176 * 16 bytes for a structure, you'll one day 3178 * 16 bytes for a structure, you'll one day
3177 * discover that you really need 17... 3179 * discover that you really need 17...
3178 */ 3180 */
3181 return -EINVAL;
3182
3183 for (i = 0; i < 16; i++)
3184 ptr->reply[i] = 0;
3185 ptr->resultcode = 0;
3186 ptr->kernel_data = NULL;
3187
3188 if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
3189 if (ptr->length <= 0)
3179 return -EINVAL; 3190 return -EINVAL;
3191 ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length);
3192 fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
3193 if (!ptr->kernel_data)
3194 return -ENOMEM;
3195 ptr->buffer_length = ptr->length;
3196 }
3197 if (ptr->flags & FD_RAW_WRITE) {
3198 ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length);
3199 if (ret)
3200 return ret;
3201 }
3180 3202
3181 for (i = 0; i < 16; i++) 3203 if (ptr->flags & FD_RAW_MORE) {
3182 ptr->reply[i] = 0;
3183 ptr->resultcode = 0;
3184 ptr->kernel_data = NULL;
3185
3186 if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
3187 if (ptr->length <= 0)
3188 return -EINVAL;
3189 ptr->kernel_data =
3190 (char *)fd_dma_mem_alloc(ptr->length);
3191 fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
3192 if (!ptr->kernel_data)
3193 return -ENOMEM;
3194 ptr->buffer_length = ptr->length;
3195 }
3196 if (ptr->flags & FD_RAW_WRITE) {
3197 ret = fd_copyin(ptr->data, ptr->kernel_data,
3198 ptr->length);
3199 if (ret)
3200 return ret;
3201 }
3202 rcmd = &(ptr->next); 3204 rcmd = &(ptr->next);
3203 if (!(ptr->flags & FD_RAW_MORE))
3204 return 0;
3205 ptr->rate &= 0x43; 3205 ptr->rate &= 0x43;
3206 goto loop;
3206 } 3207 }
3208
3209 return 0;
3207} 3210}
3208 3211
3209static int raw_cmd_ioctl(int cmd, void __user *param) 3212static int raw_cmd_ioctl(int cmd, void __user *param)