take floppy compat ioctls to sodding floppy.c

all other drivers recognizing those ioctls are very much *not*
biarch.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 229b53c9 e5f699d4

+328 -340
-340
block/compat_ioctl.c
··· 4 4 #include <linux/cdrom.h> 5 5 #include <linux/compat.h> 6 6 #include <linux/elevator.h> 7 - #include <linux/fd.h> 8 7 #include <linux/hdreg.h> 9 8 #include <linux/slab.h> 10 9 #include <linux/syscalls.h> ··· 208 209 #define BLKBSZSET_32 _IOW(0x12, 113, int) 209 210 #define BLKGETSIZE64_32 _IOR(0x12, 114, int) 210 211 211 - struct compat_floppy_drive_params { 212 - char cmos; 213 - compat_ulong_t max_dtr; 214 - compat_ulong_t hlt; 215 - compat_ulong_t hut; 216 - compat_ulong_t srt; 217 - compat_ulong_t spinup; 218 - compat_ulong_t spindown; 219 - unsigned char spindown_offset; 220 - unsigned char select_delay; 221 - unsigned char rps; 222 - unsigned char tracks; 223 - compat_ulong_t timeout; 224 - unsigned char interleave_sect; 225 - struct floppy_max_errors max_errors; 226 - char flags; 227 - char read_track; 228 - short autodetect[8]; 229 - compat_int_t checkfreq; 230 - compat_int_t native_format; 231 - }; 232 - 233 - struct compat_floppy_drive_struct { 234 - signed char flags; 235 - compat_ulong_t spinup_date; 236 - compat_ulong_t select_date; 237 - compat_ulong_t first_read_date; 238 - short probed_format; 239 - short track; 240 - short maxblock; 241 - short maxtrack; 242 - compat_int_t generation; 243 - compat_int_t keep_data; 244 - compat_int_t fd_ref; 245 - compat_int_t fd_device; 246 - compat_int_t last_checked; 247 - compat_caddr_t dmabuf; 248 - compat_int_t bufblocks; 249 - }; 250 - 251 - struct compat_floppy_fdc_state { 252 - compat_int_t spec1; 253 - compat_int_t spec2; 254 - compat_int_t dtr; 255 - unsigned char version; 256 - unsigned char dor; 257 - compat_ulong_t address; 258 - unsigned int rawcmd:2; 259 - unsigned int reset:1; 260 - unsigned int need_configure:1; 261 - unsigned int perp_mode:2; 262 - unsigned int has_fifo:1; 263 - unsigned int driver_version; 264 - unsigned char track[4]; 265 - }; 266 - 267 - struct compat_floppy_write_errors { 268 - unsigned int write_errors; 269 - compat_ulong_t first_error_sector; 270 - compat_int_t first_error_generation; 271 - compat_ulong_t last_error_sector; 272 - compat_int_t last_error_generation; 273 - compat_uint_t badness; 274 - }; 275 - 276 - #define FDSETPRM32 _IOW(2, 0x42, struct compat_floppy_struct) 277 - #define FDDEFPRM32 _IOW(2, 0x43, struct compat_floppy_struct) 278 - #define FDSETDRVPRM32 _IOW(2, 0x90, struct compat_floppy_drive_params) 279 - #define FDGETDRVPRM32 _IOR(2, 0x11, struct compat_floppy_drive_params) 280 - #define FDGETDRVSTAT32 _IOR(2, 0x12, struct compat_floppy_drive_struct) 281 - #define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct compat_floppy_drive_struct) 282 - #define FDGETFDCSTAT32 _IOR(2, 0x15, struct compat_floppy_fdc_state) 283 - #define FDWERRORGET32 _IOR(2, 0x17, struct compat_floppy_write_errors) 284 - 285 - static struct { 286 - unsigned int cmd32; 287 - unsigned int cmd; 288 - } fd_ioctl_trans_table[] = { 289 - { FDSETPRM32, FDSETPRM }, 290 - { FDDEFPRM32, FDDEFPRM }, 291 - { FDGETPRM32, FDGETPRM }, 292 - { FDSETDRVPRM32, FDSETDRVPRM }, 293 - { FDGETDRVPRM32, FDGETDRVPRM }, 294 - { FDGETDRVSTAT32, FDGETDRVSTAT }, 295 - { FDPOLLDRVSTAT32, FDPOLLDRVSTAT }, 296 - { FDGETFDCSTAT32, FDGETFDCSTAT }, 297 - { FDWERRORGET32, FDWERRORGET } 298 - }; 299 - 300 - #define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table) 301 - 302 - static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode, 303 - unsigned int cmd, unsigned long arg) 304 - { 305 - mm_segment_t old_fs = get_fs(); 306 - void *karg = NULL; 307 - unsigned int kcmd = 0; 308 - int i, err; 309 - 310 - for (i = 0; i < NR_FD_IOCTL_TRANS; i++) 311 - if (cmd == fd_ioctl_trans_table[i].cmd32) { 312 - kcmd = fd_ioctl_trans_table[i].cmd; 313 - break; 314 - } 315 - if (!kcmd) 316 - return -EINVAL; 317 - 318 - switch (cmd) { 319 - case FDSETPRM32: 320 - case FDDEFPRM32: 321 - case FDGETPRM32: 322 - { 323 - compat_uptr_t name; 324 - struct compat_floppy_struct __user *uf; 325 - struct floppy_struct *f; 326 - 327 - uf = compat_ptr(arg); 328 - f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL); 329 - if (!karg) 330 - return -ENOMEM; 331 - if (cmd == FDGETPRM32) 332 - break; 333 - err = __get_user(f->size, &uf->size); 334 - err |= __get_user(f->sect, &uf->sect); 335 - err |= __get_user(f->head, &uf->head); 336 - err |= __get_user(f->track, &uf->track); 337 - err |= __get_user(f->stretch, &uf->stretch); 338 - err |= __get_user(f->gap, &uf->gap); 339 - err |= __get_user(f->rate, &uf->rate); 340 - err |= __get_user(f->spec1, &uf->spec1); 341 - err |= __get_user(f->fmt_gap, &uf->fmt_gap); 342 - err |= __get_user(name, &uf->name); 343 - f->name = compat_ptr(name); 344 - if (err) { 345 - err = -EFAULT; 346 - goto out; 347 - } 348 - break; 349 - } 350 - case FDSETDRVPRM32: 351 - case FDGETDRVPRM32: 352 - { 353 - struct compat_floppy_drive_params __user *uf; 354 - struct floppy_drive_params *f; 355 - 356 - uf = compat_ptr(arg); 357 - f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL); 358 - if (!karg) 359 - return -ENOMEM; 360 - if (cmd == FDGETDRVPRM32) 361 - break; 362 - err = __get_user(f->cmos, &uf->cmos); 363 - err |= __get_user(f->max_dtr, &uf->max_dtr); 364 - err |= __get_user(f->hlt, &uf->hlt); 365 - err |= __get_user(f->hut, &uf->hut); 366 - err |= __get_user(f->srt, &uf->srt); 367 - err |= __get_user(f->spinup, &uf->spinup); 368 - err |= __get_user(f->spindown, &uf->spindown); 369 - err |= __get_user(f->spindown_offset, &uf->spindown_offset); 370 - err |= __get_user(f->select_delay, &uf->select_delay); 371 - err |= __get_user(f->rps, &uf->rps); 372 - err |= __get_user(f->tracks, &uf->tracks); 373 - err |= __get_user(f->timeout, &uf->timeout); 374 - err |= __get_user(f->interleave_sect, &uf->interleave_sect); 375 - err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors)); 376 - err |= __get_user(f->flags, &uf->flags); 377 - err |= __get_user(f->read_track, &uf->read_track); 378 - err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect)); 379 - err |= __get_user(f->checkfreq, &uf->checkfreq); 380 - err |= __get_user(f->native_format, &uf->native_format); 381 - if (err) { 382 - err = -EFAULT; 383 - goto out; 384 - } 385 - break; 386 - } 387 - case FDGETDRVSTAT32: 388 - case FDPOLLDRVSTAT32: 389 - karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL); 390 - if (!karg) 391 - return -ENOMEM; 392 - break; 393 - case FDGETFDCSTAT32: 394 - karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL); 395 - if (!karg) 396 - return -ENOMEM; 397 - break; 398 - case FDWERRORGET32: 399 - karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL); 400 - if (!karg) 401 - return -ENOMEM; 402 - break; 403 - default: 404 - return -EINVAL; 405 - } 406 - set_fs(KERNEL_DS); 407 - err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg); 408 - set_fs(old_fs); 409 - if (err) 410 - goto out; 411 - switch (cmd) { 412 - case FDGETPRM32: 413 - { 414 - struct floppy_struct *f = karg; 415 - struct compat_floppy_struct __user *uf = compat_ptr(arg); 416 - 417 - err = __put_user(f->size, &uf->size); 418 - err |= __put_user(f->sect, &uf->sect); 419 - err |= __put_user(f->head, &uf->head); 420 - err |= __put_user(f->track, &uf->track); 421 - err |= __put_user(f->stretch, &uf->stretch); 422 - err |= __put_user(f->gap, &uf->gap); 423 - err |= __put_user(f->rate, &uf->rate); 424 - err |= __put_user(f->spec1, &uf->spec1); 425 - err |= __put_user(f->fmt_gap, &uf->fmt_gap); 426 - err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name); 427 - break; 428 - } 429 - case FDGETDRVPRM32: 430 - { 431 - struct compat_floppy_drive_params __user *uf; 432 - struct floppy_drive_params *f = karg; 433 - 434 - uf = compat_ptr(arg); 435 - err = __put_user(f->cmos, &uf->cmos); 436 - err |= __put_user(f->max_dtr, &uf->max_dtr); 437 - err |= __put_user(f->hlt, &uf->hlt); 438 - err |= __put_user(f->hut, &uf->hut); 439 - err |= __put_user(f->srt, &uf->srt); 440 - err |= __put_user(f->spinup, &uf->spinup); 441 - err |= __put_user(f->spindown, &uf->spindown); 442 - err |= __put_user(f->spindown_offset, &uf->spindown_offset); 443 - err |= __put_user(f->select_delay, &uf->select_delay); 444 - err |= __put_user(f->rps, &uf->rps); 445 - err |= __put_user(f->tracks, &uf->tracks); 446 - err |= __put_user(f->timeout, &uf->timeout); 447 - err |= __put_user(f->interleave_sect, &uf->interleave_sect); 448 - err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors)); 449 - err |= __put_user(f->flags, &uf->flags); 450 - err |= __put_user(f->read_track, &uf->read_track); 451 - err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect)); 452 - err |= __put_user(f->checkfreq, &uf->checkfreq); 453 - err |= __put_user(f->native_format, &uf->native_format); 454 - break; 455 - } 456 - case FDGETDRVSTAT32: 457 - case FDPOLLDRVSTAT32: 458 - { 459 - struct compat_floppy_drive_struct __user *uf; 460 - struct floppy_drive_struct *f = karg; 461 - 462 - uf = compat_ptr(arg); 463 - err = __put_user(f->flags, &uf->flags); 464 - err |= __put_user(f->spinup_date, &uf->spinup_date); 465 - err |= __put_user(f->select_date, &uf->select_date); 466 - err |= __put_user(f->first_read_date, &uf->first_read_date); 467 - err |= __put_user(f->probed_format, &uf->probed_format); 468 - err |= __put_user(f->track, &uf->track); 469 - err |= __put_user(f->maxblock, &uf->maxblock); 470 - err |= __put_user(f->maxtrack, &uf->maxtrack); 471 - err |= __put_user(f->generation, &uf->generation); 472 - err |= __put_user(f->keep_data, &uf->keep_data); 473 - err |= __put_user(f->fd_ref, &uf->fd_ref); 474 - err |= __put_user(f->fd_device, &uf->fd_device); 475 - err |= __put_user(f->last_checked, &uf->last_checked); 476 - err |= __put_user((u64)f->dmabuf, &uf->dmabuf); 477 - err |= __put_user((u64)f->bufblocks, &uf->bufblocks); 478 - break; 479 - } 480 - case FDGETFDCSTAT32: 481 - { 482 - struct compat_floppy_fdc_state __user *uf; 483 - struct floppy_fdc_state *f = karg; 484 - 485 - uf = compat_ptr(arg); 486 - err = __put_user(f->spec1, &uf->spec1); 487 - err |= __put_user(f->spec2, &uf->spec2); 488 - err |= __put_user(f->dtr, &uf->dtr); 489 - err |= __put_user(f->version, &uf->version); 490 - err |= __put_user(f->dor, &uf->dor); 491 - err |= __put_user(f->address, &uf->address); 492 - err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address), 493 - (char *)&f->address + sizeof(f->address), sizeof(int)); 494 - err |= __put_user(f->driver_version, &uf->driver_version); 495 - err |= __copy_to_user(uf->track, f->track, sizeof(f->track)); 496 - break; 497 - } 498 - case FDWERRORGET32: 499 - { 500 - struct compat_floppy_write_errors __user *uf; 501 - struct floppy_write_errors *f = karg; 502 - 503 - uf = compat_ptr(arg); 504 - err = __put_user(f->write_errors, &uf->write_errors); 505 - err |= __put_user(f->first_error_sector, &uf->first_error_sector); 506 - err |= __put_user(f->first_error_generation, &uf->first_error_generation); 507 - err |= __put_user(f->last_error_sector, &uf->last_error_sector); 508 - err |= __put_user(f->last_error_generation, &uf->last_error_generation); 509 - err |= __put_user(f->badness, &uf->badness); 510 - break; 511 - } 512 - default: 513 - break; 514 - } 515 - if (err) 516 - err = -EFAULT; 517 - 518 - out: 519 - kfree(karg); 520 - return err; 521 - } 522 - 523 212 static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, 524 213 unsigned cmd, unsigned long arg) 525 214 { ··· 224 537 case HDIO_GET_ADDRESS: 225 538 case HDIO_GET_BUSSTATE: 226 539 return compat_hdio_ioctl(bdev, mode, cmd, arg); 227 - case FDSETPRM32: 228 - case FDDEFPRM32: 229 - case FDGETPRM32: 230 - case FDSETDRVPRM32: 231 - case FDGETDRVPRM32: 232 - case FDGETDRVSTAT32: 233 - case FDPOLLDRVSTAT32: 234 - case FDGETFDCSTAT32: 235 - case FDWERRORGET32: 236 - return compat_fd_ioctl(bdev, mode, cmd, arg); 237 540 case CDROMREADAUDIO: 238 541 return compat_cdrom_read_audio(bdev, mode, cmd, arg); 239 542 case CDROM_SEND_PACKET: ··· 243 566 case HDIO_DRIVE_CMD: 244 567 /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */ 245 568 case 0x330: 246 - /* 0x02 -- Floppy ioctls */ 247 - case FDMSGON: 248 - case FDMSGOFF: 249 - case FDSETEMSGTRESH: 250 - case FDFLUSH: 251 - case FDWERRORCLR: 252 - case FDSETMAXERRS: 253 - case FDGETMAXERRS: 254 - case FDGETDRVTYP: 255 - case FDEJECT: 256 - case FDCLRPRM: 257 - case FDFMTBEG: 258 - case FDFMTEND: 259 - case FDRESET: 260 - case FDTWADDLE: 261 - case FDFMTTRK: 262 - case FDRAWCMD: 263 569 /* CDROM stuff */ 264 570 case CDROMPAUSE: 265 571 case CDROMRESUME:
+328
drivers/block/floppy.c
··· 192 192 #include <linux/io.h> 193 193 #include <linux/uaccess.h> 194 194 #include <linux/async.h> 195 + #include <linux/compat.h> 195 196 196 197 /* 197 198 * PS/2 floppies have much slower step rates than regular floppies. ··· 3569 3568 return ret; 3570 3569 } 3571 3570 3571 + #ifdef CONFIG_COMPAT 3572 + 3573 + struct compat_floppy_drive_params { 3574 + char cmos; 3575 + compat_ulong_t max_dtr; 3576 + compat_ulong_t hlt; 3577 + compat_ulong_t hut; 3578 + compat_ulong_t srt; 3579 + compat_ulong_t spinup; 3580 + compat_ulong_t spindown; 3581 + unsigned char spindown_offset; 3582 + unsigned char select_delay; 3583 + unsigned char rps; 3584 + unsigned char tracks; 3585 + compat_ulong_t timeout; 3586 + unsigned char interleave_sect; 3587 + struct floppy_max_errors max_errors; 3588 + char flags; 3589 + char read_track; 3590 + short autodetect[8]; 3591 + compat_int_t checkfreq; 3592 + compat_int_t native_format; 3593 + }; 3594 + 3595 + struct compat_floppy_drive_struct { 3596 + signed char flags; 3597 + compat_ulong_t spinup_date; 3598 + compat_ulong_t select_date; 3599 + compat_ulong_t first_read_date; 3600 + short probed_format; 3601 + short track; 3602 + short maxblock; 3603 + short maxtrack; 3604 + compat_int_t generation; 3605 + compat_int_t keep_data; 3606 + compat_int_t fd_ref; 3607 + compat_int_t fd_device; 3608 + compat_int_t last_checked; 3609 + compat_caddr_t dmabuf; 3610 + compat_int_t bufblocks; 3611 + }; 3612 + 3613 + struct compat_floppy_fdc_state { 3614 + compat_int_t spec1; 3615 + compat_int_t spec2; 3616 + compat_int_t dtr; 3617 + unsigned char version; 3618 + unsigned char dor; 3619 + compat_ulong_t address; 3620 + unsigned int rawcmd:2; 3621 + unsigned int reset:1; 3622 + unsigned int need_configure:1; 3623 + unsigned int perp_mode:2; 3624 + unsigned int has_fifo:1; 3625 + unsigned int driver_version; 3626 + unsigned char track[4]; 3627 + }; 3628 + 3629 + struct compat_floppy_write_errors { 3630 + unsigned int write_errors; 3631 + compat_ulong_t first_error_sector; 3632 + compat_int_t first_error_generation; 3633 + compat_ulong_t last_error_sector; 3634 + compat_int_t last_error_generation; 3635 + compat_uint_t badness; 3636 + }; 3637 + 3638 + #define FDSETPRM32 _IOW(2, 0x42, struct compat_floppy_struct) 3639 + #define FDDEFPRM32 _IOW(2, 0x43, struct compat_floppy_struct) 3640 + #define FDSETDRVPRM32 _IOW(2, 0x90, struct compat_floppy_drive_params) 3641 + #define FDGETDRVPRM32 _IOR(2, 0x11, struct compat_floppy_drive_params) 3642 + #define FDGETDRVSTAT32 _IOR(2, 0x12, struct compat_floppy_drive_struct) 3643 + #define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct compat_floppy_drive_struct) 3644 + #define FDGETFDCSTAT32 _IOR(2, 0x15, struct compat_floppy_fdc_state) 3645 + #define FDWERRORGET32 _IOR(2, 0x17, struct compat_floppy_write_errors) 3646 + 3647 + static int compat_set_geometry(struct block_device *bdev, fmode_t mode, unsigned int cmd, 3648 + struct compat_floppy_struct __user *arg) 3649 + { 3650 + struct floppy_struct v; 3651 + int drive, type; 3652 + int err; 3653 + 3654 + BUILD_BUG_ON(offsetof(struct floppy_struct, name) != 3655 + offsetof(struct compat_floppy_struct, name)); 3656 + 3657 + if (!(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL))) 3658 + return -EPERM; 3659 + 3660 + memset(&v, 0, sizeof(struct floppy_struct)); 3661 + if (copy_from_user(&v, arg, offsetof(struct floppy_struct, name))) 3662 + return -EFAULT; 3663 + 3664 + mutex_lock(&floppy_mutex); 3665 + drive = (long)bdev->bd_disk->private_data; 3666 + type = ITYPE(UDRS->fd_device); 3667 + err = set_geometry(cmd == FDSETPRM32 ? FDSETPRM : FDDEFPRM, 3668 + &v, drive, type, bdev); 3669 + mutex_unlock(&floppy_mutex); 3670 + return err; 3671 + } 3672 + 3673 + static int compat_get_prm(int drive, 3674 + struct compat_floppy_struct __user *arg) 3675 + { 3676 + struct compat_floppy_struct v; 3677 + struct floppy_struct *p; 3678 + int err; 3679 + 3680 + memset(&v, 0, sizeof(v)); 3681 + mutex_lock(&floppy_mutex); 3682 + err = get_floppy_geometry(drive, ITYPE(UDRS->fd_device), &p); 3683 + if (err) { 3684 + mutex_unlock(&floppy_mutex); 3685 + return err; 3686 + } 3687 + memcpy(&v, p, offsetof(struct floppy_struct, name)); 3688 + mutex_unlock(&floppy_mutex); 3689 + if (copy_to_user(arg, &v, sizeof(struct compat_floppy_struct))) 3690 + return -EFAULT; 3691 + return 0; 3692 + } 3693 + 3694 + static int compat_setdrvprm(int drive, 3695 + struct compat_floppy_drive_params __user *arg) 3696 + { 3697 + struct compat_floppy_drive_params v; 3698 + 3699 + if (!capable(CAP_SYS_ADMIN)) 3700 + return -EPERM; 3701 + if (copy_from_user(&v, arg, sizeof(struct compat_floppy_drive_params))) 3702 + return -EFAULT; 3703 + mutex_lock(&floppy_mutex); 3704 + UDP->cmos = v.cmos; 3705 + UDP->max_dtr = v.max_dtr; 3706 + UDP->hlt = v.hlt; 3707 + UDP->hut = v.hut; 3708 + UDP->srt = v.srt; 3709 + UDP->spinup = v.spinup; 3710 + UDP->spindown = v.spindown; 3711 + UDP->spindown_offset = v.spindown_offset; 3712 + UDP->select_delay = v.select_delay; 3713 + UDP->rps = v.rps; 3714 + UDP->tracks = v.tracks; 3715 + UDP->timeout = v.timeout; 3716 + UDP->interleave_sect = v.interleave_sect; 3717 + UDP->max_errors = v.max_errors; 3718 + UDP->flags = v.flags; 3719 + UDP->read_track = v.read_track; 3720 + memcpy(UDP->autodetect, v.autodetect, sizeof(v.autodetect)); 3721 + UDP->checkfreq = v.checkfreq; 3722 + UDP->native_format = v.native_format; 3723 + mutex_unlock(&floppy_mutex); 3724 + return 0; 3725 + } 3726 + 3727 + static int compat_getdrvprm(int drive, 3728 + struct compat_floppy_drive_params __user *arg) 3729 + { 3730 + struct compat_floppy_drive_params v; 3731 + 3732 + memset(&v, 0, sizeof(struct compat_floppy_drive_params)); 3733 + mutex_lock(&floppy_mutex); 3734 + v.cmos = UDP->cmos; 3735 + v.max_dtr = UDP->max_dtr; 3736 + v.hlt = UDP->hlt; 3737 + v.hut = UDP->hut; 3738 + v.srt = UDP->srt; 3739 + v.spinup = UDP->spinup; 3740 + v.spindown = UDP->spindown; 3741 + v.spindown_offset = UDP->spindown_offset; 3742 + v.select_delay = UDP->select_delay; 3743 + v.rps = UDP->rps; 3744 + v.tracks = UDP->tracks; 3745 + v.timeout = UDP->timeout; 3746 + v.interleave_sect = UDP->interleave_sect; 3747 + v.max_errors = UDP->max_errors; 3748 + v.flags = UDP->flags; 3749 + v.read_track = UDP->read_track; 3750 + memcpy(v.autodetect, UDP->autodetect, sizeof(v.autodetect)); 3751 + v.checkfreq = UDP->checkfreq; 3752 + v.native_format = UDP->native_format; 3753 + mutex_unlock(&floppy_mutex); 3754 + 3755 + if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_params))) 3756 + return -EFAULT; 3757 + return 0; 3758 + } 3759 + 3760 + static int compat_getdrvstat(int drive, bool poll, 3761 + struct compat_floppy_drive_struct __user *arg) 3762 + { 3763 + struct compat_floppy_drive_struct v; 3764 + 3765 + memset(&v, 0, sizeof(struct compat_floppy_drive_struct)); 3766 + mutex_lock(&floppy_mutex); 3767 + 3768 + if (poll) { 3769 + if (lock_fdc(drive)) 3770 + goto Eintr; 3771 + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) 3772 + goto Eintr; 3773 + process_fd_request(); 3774 + } 3775 + v.spinup_date = UDRS->spinup_date; 3776 + v.select_date = UDRS->select_date; 3777 + v.first_read_date = UDRS->first_read_date; 3778 + v.probed_format = UDRS->probed_format; 3779 + v.track = UDRS->track; 3780 + v.maxblock = UDRS->maxblock; 3781 + v.maxtrack = UDRS->maxtrack; 3782 + v.generation = UDRS->generation; 3783 + v.keep_data = UDRS->keep_data; 3784 + v.fd_ref = UDRS->fd_ref; 3785 + v.fd_device = UDRS->fd_device; 3786 + v.last_checked = UDRS->last_checked; 3787 + v.dmabuf = (uintptr_t)UDRS->dmabuf; 3788 + v.bufblocks = UDRS->bufblocks; 3789 + mutex_unlock(&floppy_mutex); 3790 + 3791 + if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_struct))) 3792 + return -EFAULT; 3793 + return 0; 3794 + Eintr: 3795 + mutex_unlock(&floppy_mutex); 3796 + return -EINTR; 3797 + } 3798 + 3799 + static int compat_getfdcstat(int drive, 3800 + struct compat_floppy_fdc_state __user *arg) 3801 + { 3802 + struct compat_floppy_fdc_state v32; 3803 + struct floppy_fdc_state v; 3804 + 3805 + mutex_lock(&floppy_mutex); 3806 + v = *UFDCS; 3807 + mutex_unlock(&floppy_mutex); 3808 + 3809 + memset(&v32, 0, sizeof(struct compat_floppy_fdc_state)); 3810 + v32.spec1 = v.spec1; 3811 + v32.spec2 = v.spec2; 3812 + v32.dtr = v.dtr; 3813 + v32.version = v.version; 3814 + v32.dor = v.dor; 3815 + v32.address = v.address; 3816 + v32.rawcmd = v.rawcmd; 3817 + v32.reset = v.reset; 3818 + v32.need_configure = v.need_configure; 3819 + v32.perp_mode = v.perp_mode; 3820 + v32.has_fifo = v.has_fifo; 3821 + v32.driver_version = v.driver_version; 3822 + memcpy(v32.track, v.track, 4); 3823 + if (copy_to_user(arg, &v32, sizeof(struct compat_floppy_fdc_state))) 3824 + return -EFAULT; 3825 + return 0; 3826 + } 3827 + 3828 + static int compat_werrorget(int drive, 3829 + struct compat_floppy_write_errors __user *arg) 3830 + { 3831 + struct compat_floppy_write_errors v32; 3832 + struct floppy_write_errors v; 3833 + 3834 + memset(&v32, 0, sizeof(struct compat_floppy_write_errors)); 3835 + mutex_lock(&floppy_mutex); 3836 + v = *UDRWE; 3837 + mutex_unlock(&floppy_mutex); 3838 + v32.write_errors = v.write_errors; 3839 + v32.first_error_sector = v.first_error_sector; 3840 + v32.first_error_generation = v.first_error_generation; 3841 + v32.last_error_sector = v.last_error_sector; 3842 + v32.last_error_generation = v.last_error_generation; 3843 + v32.badness = v.badness; 3844 + if (copy_to_user(arg, &v32, sizeof(struct compat_floppy_write_errors))) 3845 + return -EFAULT; 3846 + return 0; 3847 + } 3848 + 3849 + static int fd_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, 3850 + unsigned long param) 3851 + { 3852 + int drive = (long)bdev->bd_disk->private_data; 3853 + switch (cmd) { 3854 + case FDMSGON: 3855 + case FDMSGOFF: 3856 + case FDSETEMSGTRESH: 3857 + case FDFLUSH: 3858 + case FDWERRORCLR: 3859 + case FDEJECT: 3860 + case FDCLRPRM: 3861 + case FDFMTBEG: 3862 + case FDRESET: 3863 + case FDTWADDLE: 3864 + return fd_ioctl(bdev, mode, cmd, param); 3865 + case FDSETMAXERRS: 3866 + case FDGETMAXERRS: 3867 + case FDGETDRVTYP: 3868 + case FDFMTEND: 3869 + case FDFMTTRK: 3870 + case FDRAWCMD: 3871 + return fd_ioctl(bdev, mode, cmd, 3872 + (unsigned long)compat_ptr(param)); 3873 + case FDSETPRM32: 3874 + case FDDEFPRM32: 3875 + return compat_set_geometry(bdev, mode, cmd, compat_ptr(param)); 3876 + case FDGETPRM32: 3877 + return compat_get_prm(drive, compat_ptr(param)); 3878 + case FDSETDRVPRM32: 3879 + return compat_setdrvprm(drive, compat_ptr(param)); 3880 + case FDGETDRVPRM32: 3881 + return compat_getdrvprm(drive, compat_ptr(param)); 3882 + case FDPOLLDRVSTAT32: 3883 + return compat_getdrvstat(drive, true, compat_ptr(param)); 3884 + case FDGETDRVSTAT32: 3885 + return compat_getdrvstat(drive, false, compat_ptr(param)); 3886 + case FDGETFDCSTAT32: 3887 + return compat_getfdcstat(drive, compat_ptr(param)); 3888 + case FDWERRORGET32: 3889 + return compat_werrorget(drive, compat_ptr(param)); 3890 + } 3891 + return -EINVAL; 3892 + } 3893 + #endif 3894 + 3572 3895 static void __init config_types(void) 3573 3896 { 3574 3897 bool has_drive = false; ··· 4210 3885 .getgeo = fd_getgeo, 4211 3886 .check_events = floppy_check_events, 4212 3887 .revalidate_disk = floppy_revalidate, 3888 + #ifdef CONFIG_COMPAT 3889 + .compat_ioctl = fd_compat_ioctl, 3890 + #endif 4213 3891 }; 4214 3892 4215 3893 /*