diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/floppy.c | 218 |
1 files changed, 107 insertions, 111 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 7743d6c2dd6b..b58ceae9d0b5 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3466,8 +3466,6 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3466 | unsigned long param) | 3466 | unsigned long param) |
3467 | { | 3467 | { |
3468 | #define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL)) | 3468 | #define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL)) |
3469 | #define OUT(c,x) case c: outparam = (const char *) (x); break | ||
3470 | #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 | ||
3471 | 3469 | ||
3472 | int drive = (long)bdev->bd_disk->private_data; | 3470 | int drive = (long)bdev->bd_disk->private_data; |
3473 | int type = ITYPE(UDRS->fd_device); | 3471 | int type = ITYPE(UDRS->fd_device); |
@@ -3509,122 +3507,120 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3509 | /* copyin */ | 3507 | /* copyin */ |
3510 | memset(&inparam, 0, sizeof(inparam)); | 3508 | memset(&inparam, 0, sizeof(inparam)); |
3511 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 3509 | if (_IOC_DIR(cmd) & _IOC_WRITE) |
3512 | ECALL(fd_copyin((void __user *)param, &inparam, size)) | 3510 | ECALL(fd_copyin((void __user *)param, &inparam, size)); |
3513 | 3511 | ||
3514 | switch (cmd) { | 3512 | switch (cmd) { |
3515 | case FDEJECT: | 3513 | case FDEJECT: |
3516 | if (UDRS->fd_ref != 1) | 3514 | if (UDRS->fd_ref != 1) |
3517 | /* somebody else has this drive open */ | 3515 | /* somebody else has this drive open */ |
3518 | return -EBUSY; | 3516 | return -EBUSY; |
3519 | LOCK_FDC(drive, 1); | 3517 | LOCK_FDC(drive, 1); |
3520 | |||
3521 | /* do the actual eject. Fails on | ||
3522 | * non-Sparc architectures */ | ||
3523 | ret = fd_eject(UNIT(drive)); | ||
3524 | |||
3525 | USETF(FD_DISK_CHANGED); | ||
3526 | USETF(FD_VERIFY); | ||
3527 | process_fd_request(); | ||
3528 | return ret; | ||
3529 | case FDCLRPRM: | ||
3530 | LOCK_FDC(drive, 1); | ||
3531 | current_type[drive] = NULL; | ||
3532 | floppy_sizes[drive] = MAX_DISK_SIZE << 1; | ||
3533 | UDRS->keep_data = 0; | ||
3534 | return invalidate_drive(bdev); | ||
3535 | case FDSETPRM: | ||
3536 | case FDDEFPRM: | ||
3537 | return set_geometry(cmd, &inparam.g, | ||
3538 | drive, type, bdev); | ||
3539 | case FDGETPRM: | ||
3540 | ECALL(get_floppy_geometry(drive, type, | ||
3541 | (struct floppy_struct **) | ||
3542 | &outparam)); | ||
3543 | break; | ||
3544 | |||
3545 | case FDMSGON: | ||
3546 | UDP->flags |= FTD_MSG; | ||
3547 | return 0; | ||
3548 | case FDMSGOFF: | ||
3549 | UDP->flags &= ~FTD_MSG; | ||
3550 | return 0; | ||
3551 | |||
3552 | case FDFMTBEG: | ||
3553 | LOCK_FDC(drive, 1); | ||
3554 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3555 | ret = UDRS->flags; | ||
3556 | process_fd_request(); | ||
3557 | if (ret & FD_VERIFY) | ||
3558 | return -ENODEV; | ||
3559 | if (!(ret & FD_DISK_WRITABLE)) | ||
3560 | return -EROFS; | ||
3561 | return 0; | ||
3562 | case FDFMTTRK: | ||
3563 | if (UDRS->fd_ref != 1) | ||
3564 | return -EBUSY; | ||
3565 | return do_format(drive, &inparam.f); | ||
3566 | case FDFMTEND: | ||
3567 | case FDFLUSH: | ||
3568 | LOCK_FDC(drive, 1); | ||
3569 | return invalidate_drive(bdev); | ||
3570 | |||
3571 | case FDSETEMSGTRESH: | ||
3572 | UDP->max_errors.reporting = | ||
3573 | (unsigned short)(param & 0x0f); | ||
3574 | return 0; | ||
3575 | OUT(FDGETMAXERRS, &UDP->max_errors); | ||
3576 | IN(FDSETMAXERRS, &UDP->max_errors, max_errors); | ||
3577 | |||
3578 | case FDGETDRVTYP: | ||
3579 | outparam = drive_name(type, drive); | ||
3580 | SUPBOUND(size, strlen(outparam) + 1); | ||
3581 | break; | ||
3582 | |||
3583 | IN(FDSETDRVPRM, UDP, dp); | ||
3584 | OUT(FDGETDRVPRM, UDP); | ||
3585 | |||
3586 | case FDPOLLDRVSTAT: | ||
3587 | LOCK_FDC(drive, 1); | ||
3588 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3589 | process_fd_request(); | ||
3590 | /* fall through */ | ||
3591 | OUT(FDGETDRVSTAT, UDRS); | ||
3592 | |||
3593 | case FDRESET: | ||
3594 | return user_reset_fdc(drive, (int)param, 1); | ||
3595 | |||
3596 | OUT(FDGETFDCSTAT, UFDCS); | ||
3597 | |||
3598 | case FDWERRORCLR: | ||
3599 | memset(UDRWE, 0, sizeof(*UDRWE)); | ||
3600 | return 0; | ||
3601 | OUT(FDWERRORGET, UDRWE); | ||
3602 | |||
3603 | case FDRAWCMD: | ||
3604 | if (type) | ||
3605 | return -EINVAL; | ||
3606 | LOCK_FDC(drive, 1); | ||
3607 | set_floppy(drive); | ||
3608 | CALL(i = raw_cmd_ioctl(cmd, (void __user *)param)); | ||
3609 | process_fd_request(); | ||
3610 | return i; | ||
3611 | 3518 | ||
3612 | case FDTWADDLE: | 3519 | /* do the actual eject. Fails on |
3613 | LOCK_FDC(drive, 1); | 3520 | * non-Sparc architectures */ |
3614 | twaddle(); | 3521 | ret = fd_eject(UNIT(drive)); |
3615 | process_fd_request(); | ||
3616 | return 0; | ||
3617 | 3522 | ||
3618 | default: | 3523 | USETF(FD_DISK_CHANGED); |
3524 | USETF(FD_VERIFY); | ||
3525 | process_fd_request(); | ||
3526 | return ret; | ||
3527 | case FDCLRPRM: | ||
3528 | LOCK_FDC(drive, 1); | ||
3529 | current_type[drive] = NULL; | ||
3530 | floppy_sizes[drive] = MAX_DISK_SIZE << 1; | ||
3531 | UDRS->keep_data = 0; | ||
3532 | return invalidate_drive(bdev); | ||
3533 | case FDSETPRM: | ||
3534 | case FDDEFPRM: | ||
3535 | return set_geometry(cmd, &inparam.g, drive, type, bdev); | ||
3536 | case FDGETPRM: | ||
3537 | ECALL(get_floppy_geometry(drive, type, | ||
3538 | (struct floppy_struct **) | ||
3539 | &outparam)); | ||
3540 | break; | ||
3541 | case FDMSGON: | ||
3542 | UDP->flags |= FTD_MSG; | ||
3543 | return 0; | ||
3544 | case FDMSGOFF: | ||
3545 | UDP->flags &= ~FTD_MSG; | ||
3546 | return 0; | ||
3547 | case FDFMTBEG: | ||
3548 | LOCK_FDC(drive, 1); | ||
3549 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3550 | ret = UDRS->flags; | ||
3551 | process_fd_request(); | ||
3552 | if (ret & FD_VERIFY) | ||
3553 | return -ENODEV; | ||
3554 | if (!(ret & FD_DISK_WRITABLE)) | ||
3555 | return -EROFS; | ||
3556 | return 0; | ||
3557 | case FDFMTTRK: | ||
3558 | if (UDRS->fd_ref != 1) | ||
3559 | return -EBUSY; | ||
3560 | return do_format(drive, &inparam.f); | ||
3561 | case FDFMTEND: | ||
3562 | case FDFLUSH: | ||
3563 | LOCK_FDC(drive, 1); | ||
3564 | return invalidate_drive(bdev); | ||
3565 | case FDSETEMSGTRESH: | ||
3566 | UDP->max_errors.reporting = (unsigned short)(param & 0x0f); | ||
3567 | return 0; | ||
3568 | case FDGETMAXERRS: | ||
3569 | outparam = (const char *)&UDP->max_errors; | ||
3570 | break; | ||
3571 | case FDSETMAXERRS: | ||
3572 | UDP->max_errors = inparam.max_errors; | ||
3573 | break; | ||
3574 | case FDGETDRVTYP: | ||
3575 | outparam = drive_name(type, drive); | ||
3576 | SUPBOUND(size, strlen(outparam) + 1); | ||
3577 | break; | ||
3578 | case FDSETDRVPRM: | ||
3579 | *UDP = inparam.dp; | ||
3580 | break; | ||
3581 | case FDGETDRVPRM: | ||
3582 | outparam = (const char *)UDP; | ||
3583 | break; | ||
3584 | case FDPOLLDRVSTAT: | ||
3585 | LOCK_FDC(drive, 1); | ||
3586 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3587 | process_fd_request(); | ||
3588 | /* fall through */ | ||
3589 | case FDGETDRVSTAT: | ||
3590 | outparam = (const char *)UDRS; | ||
3591 | break; | ||
3592 | case FDRESET: | ||
3593 | return user_reset_fdc(drive, (int)param, 1); | ||
3594 | case FDGETFDCSTAT: | ||
3595 | outparam = (const char *)UFDCS; | ||
3596 | break; | ||
3597 | case FDWERRORCLR: | ||
3598 | memset(UDRWE, 0, sizeof(*UDRWE)); | ||
3599 | return 0; | ||
3600 | case FDWERRORGET: | ||
3601 | outparam = (const char *)UDRWE; | ||
3602 | break; | ||
3603 | case FDRAWCMD: | ||
3604 | if (type) | ||
3619 | return -EINVAL; | 3605 | return -EINVAL; |
3620 | } | 3606 | LOCK_FDC(drive, 1); |
3607 | set_floppy(drive); | ||
3608 | CALL(i = raw_cmd_ioctl(cmd, (void __user *)param)); | ||
3609 | process_fd_request(); | ||
3610 | return i; | ||
3611 | case FDTWADDLE: | ||
3612 | LOCK_FDC(drive, 1); | ||
3613 | twaddle(); | ||
3614 | process_fd_request(); | ||
3615 | return 0; | ||
3616 | default: | ||
3617 | return -EINVAL; | ||
3618 | } | ||
3621 | 3619 | ||
3622 | if (_IOC_DIR(cmd) & _IOC_READ) | 3620 | if (_IOC_DIR(cmd) & _IOC_READ) |
3623 | return fd_copyout((void __user *)param, outparam, size); | 3621 | return fd_copyout((void __user *)param, outparam, size); |
3624 | else | 3622 | |
3625 | return 0; | 3623 | return 0; |
3626 | #undef OUT | ||
3627 | #undef IN | ||
3628 | } | 3624 | } |
3629 | 3625 | ||
3630 | static void __init config_types(void) | 3626 | static void __init config_types(void) |