Lines Matching +full:drive +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-or-later
11 * 2004-08-21 (lv) - Initial implementation
12 * 2008-10-30 (lv) - Port to 2.6
18 #include <linux/blk-mq.h>
38 #define DRIVER_VERSION "Version 0.2 (2008-10-30)"
40 #define REG(x) unsigned char x, x ## _pad[0x200 - 1];
62 #define swim_write(base, reg, v) out_8(&(base)->write_##reg, (v))
63 #define swim_read(base, reg) in_8(&(base)->read_##reg)
86 #define iwm_write(base, reg, v) out_8(&(base)->reg, (v))
87 #define iwm_read(base, reg) in_8(&(base)->reg)
143 /* bits in mode register */
153 /*----------------------------------------------------------------------------*/
169 enum drive_location location; /* internal or external drive */
170 int head_number; /* single- or double-sided drive */
183 /* in-use information */
310 swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */ in swim_drive()
311 swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */ in swim_drive()
313 swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */ in swim_drive()
314 swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */ in swim_drive()
357 /* wait drive is ready */ in swim_head()
380 return -1; in swim_step()
396 return -1; in swim_track00()
402 return -1; in swim_track00()
412 step = -step; in swim_seek()
416 for ( ; step > 0; step--) { in swim_seek()
418 return -1; in swim_seek()
426 struct swim __iomem *base = fs->swd->base; in swim_track()
429 ret = swim_seek(base, track - fs->track); in swim_track()
432 fs->track = track; in swim_track()
435 fs->track = 0; in swim_track()
443 struct swim __iomem *base = fs->swd->base; in floppy_eject()
445 swim_drive(base, fs->location); in floppy_eject()
449 fs->disk_in = 0; in floppy_eject()
450 fs->ejected = 1; in floppy_eject()
459 struct swim __iomem *base = fs->swd->base; in swim_read_sector()
462 int ret = -1; in swim_read_sector()
496 struct swim __iomem *base = fs->swd->base; in floppy_read_sectors()
502 swim_drive(base, fs->location); in floppy_read_sectors()
505 track = i / fs->secpercyl; in floppy_read_sectors()
506 x = i % fs->secpercyl; in floppy_read_sectors()
507 side = x / fs->secpertrack; in floppy_read_sectors()
508 sector = x % fs->secpertrack + 1; in floppy_read_sectors()
514 if (try-- == 0) in floppy_read_sectors()
527 struct floppy_state *fs = hctx->queue->queuedata; in swim_queue_rq()
528 struct swim_priv *swd = fs->swd; in swim_queue_rq()
529 struct request *req = bd->rq; in swim_queue_rq()
532 if (!spin_trylock_irq(&swd->lock)) in swim_queue_rq()
537 if (!fs->disk_in || rq_data_dir(req) == WRITE) { in swim_queue_rq()
545 bio_data(req->bio)); in swim_queue_rq()
551 spin_unlock_irq(&swd->lock); in swim_queue_rq()
567 return -EINVAL; in get_floppy_geometry()
571 else if (fs->type == HD_MEDIA) /* High-Density media */ in get_floppy_geometry()
573 else if (fs->head_number == 2) /* double-sided */ in get_floppy_geometry()
583 struct swim __iomem *base = fs->swd->base; in setup_medium()
587 fs->disk_in = 1; in setup_medium()
588 fs->write_protected = swim_readbit(base, WRITE_PROT); in setup_medium()
596 fs->type = swim_readbit(base, TWOMEG_MEDIA) ? in setup_medium()
598 fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2; in setup_medium()
600 fs->total_secs = g->size; in setup_medium()
601 fs->secpercyl = g->head * g->sect; in setup_medium()
602 fs->secpertrack = g->sect; in setup_medium()
603 fs->track = 0; in setup_medium()
605 fs->disk_in = 0; in setup_medium()
609 static int floppy_open(struct block_device *bdev, fmode_t mode) in floppy_open() argument
611 struct floppy_state *fs = bdev->bd_disk->private_data; in floppy_open()
612 struct swim __iomem *base = fs->swd->base; in floppy_open()
615 if (fs->ref_count == -1 || (fs->ref_count && mode & FMODE_EXCL)) in floppy_open()
616 return -EBUSY; in floppy_open()
618 if (mode & FMODE_EXCL) in floppy_open()
619 fs->ref_count = -1; in floppy_open()
621 fs->ref_count++; in floppy_open()
625 swim_drive(base, fs->location); in floppy_open()
628 if (fs->ejected) in floppy_open()
630 if (!fs->disk_in) { in floppy_open()
631 err = -ENXIO; in floppy_open()
635 set_capacity(fs->disk, fs->total_secs); in floppy_open()
637 if (mode & FMODE_NDELAY) in floppy_open()
640 if (mode & (FMODE_READ|FMODE_WRITE)) { in floppy_open()
641 if (bdev_check_media_change(bdev) && fs->disk_in) in floppy_open()
642 fs->ejected = 0; in floppy_open()
643 if ((mode & FMODE_WRITE) && fs->write_protected) { in floppy_open()
644 err = -EROFS; in floppy_open()
650 if (fs->ref_count < 0) in floppy_open()
651 fs->ref_count = 0; in floppy_open()
652 else if (fs->ref_count > 0) in floppy_open()
653 --fs->ref_count; in floppy_open()
655 if (fs->ref_count == 0) in floppy_open()
660 static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) in floppy_unlocked_open() argument
665 ret = floppy_open(bdev, mode); in floppy_unlocked_open()
671 static void floppy_release(struct gendisk *disk, fmode_t mode) in floppy_release() argument
673 struct floppy_state *fs = disk->private_data; in floppy_release()
674 struct swim __iomem *base = fs->swd->base; in floppy_release()
677 if (fs->ref_count < 0) in floppy_release()
678 fs->ref_count = 0; in floppy_release()
679 else if (fs->ref_count > 0) in floppy_release()
680 --fs->ref_count; in floppy_release()
682 if (fs->ref_count == 0) in floppy_release()
687 static int floppy_ioctl(struct block_device *bdev, fmode_t mode, in floppy_ioctl() argument
690 struct floppy_state *fs = bdev->bd_disk->private_data; in floppy_ioctl()
694 return -EPERM; in floppy_ioctl()
698 if (fs->ref_count != 1) in floppy_ioctl()
699 return -EBUSY; in floppy_ioctl()
708 return -EFAULT; in floppy_ioctl()
711 return -ENOTTY; in floppy_ioctl()
716 struct floppy_state *fs = bdev->bd_disk->private_data; in floppy_getgeo()
724 geo->heads = g->head; in floppy_getgeo()
725 geo->sectors = g->sect; in floppy_getgeo()
726 geo->cylinders = g->track; in floppy_getgeo()
734 struct floppy_state *fs = disk->private_data; in floppy_check_events()
736 return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0; in floppy_check_events()
751 int drive = (*part & 3); in floppy_find() local
753 if (drive >= swd->floppy_count) in floppy_find()
757 return get_disk_and_module(swd->unit[drive].disk); in floppy_find()
762 struct floppy_state *fs = &swd->unit[swd->floppy_count]; in swim_add_floppy()
763 struct swim __iomem *base = swd->base; in swim_add_floppy()
765 fs->location = location; in swim_add_floppy()
771 fs->type = HD_MEDIA; in swim_add_floppy()
772 fs->head_number = 2; in swim_add_floppy()
774 fs->ref_count = 0; in swim_add_floppy()
775 fs->ejected = 1; in swim_add_floppy()
777 swd->floppy_count++; in swim_add_floppy()
789 int drive; in swim_floppy_init() local
790 struct swim __iomem *base = swd->base; in swim_floppy_init()
809 return -EBUSY; in swim_floppy_init()
812 spin_lock_init(&swd->lock); in swim_floppy_init()
814 for (drive = 0; drive < swd->floppy_count; drive++) { in swim_floppy_init()
817 swd->unit[drive].disk = alloc_disk(1); in swim_floppy_init()
818 if (swd->unit[drive].disk == NULL) { in swim_floppy_init()
819 err = -ENOMEM; in swim_floppy_init()
823 q = blk_mq_init_sq_queue(&swd->unit[drive].tag_set, &swim_mq_ops, in swim_floppy_init()
830 swd->unit[drive].disk->queue = q; in swim_floppy_init()
831 blk_queue_bounce_limit(swd->unit[drive].disk->queue, in swim_floppy_init()
833 swd->unit[drive].disk->queue->queuedata = &swd->unit[drive]; in swim_floppy_init()
834 swd->unit[drive].swd = swd; in swim_floppy_init()
837 for (drive = 0; drive < swd->floppy_count; drive++) { in swim_floppy_init()
838 swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE; in swim_floppy_init()
839 swd->unit[drive].disk->major = FLOPPY_MAJOR; in swim_floppy_init()
840 swd->unit[drive].disk->first_minor = drive; in swim_floppy_init()
841 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); in swim_floppy_init()
842 swd->unit[drive].disk->fops = &floppy_fops; in swim_floppy_init()
843 swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE; in swim_floppy_init()
844 swd->unit[drive].disk->private_data = &swd->unit[drive]; in swim_floppy_init()
845 set_capacity(swd->unit[drive].disk, 2880); in swim_floppy_init()
846 add_disk(swd->unit[drive].disk); in swim_floppy_init()
857 struct gendisk *disk = swd->unit[drive].disk; in swim_floppy_init()
860 if (disk->queue) { in swim_floppy_init()
861 blk_cleanup_queue(disk->queue); in swim_floppy_init()
862 disk->queue = NULL; in swim_floppy_init()
864 blk_mq_free_tag_set(&swd->unit[drive].tag_set); in swim_floppy_init()
867 } while (drive--); in swim_floppy_init()
880 ret = -ENODEV; in swim_probe()
884 if (!request_mem_region(res->start, resource_size(res), CARDNAME)) { in swim_probe()
885 ret = -EBUSY; in swim_probe()
889 swim_base = (struct swim __iomem *)res->start; in swim_probe()
891 ret = -ENOMEM; in swim_probe()
900 ret = -ENODEV; in swim_probe()
908 ret = -ENOMEM; in swim_probe()
913 swd->base = swim_base; in swim_probe()
924 release_mem_region(res->start, resource_size(res)); in swim_probe()
932 int drive; in swim_remove() local
937 for (drive = 0; drive < swd->floppy_count; drive++) { in swim_remove()
938 del_gendisk(swd->unit[drive].disk); in swim_remove()
939 blk_cleanup_queue(swd->unit[drive].disk->queue); in swim_remove()
940 blk_mq_free_tag_set(&swd->unit[drive].tag_set); in swim_remove()
941 put_disk(swd->unit[drive].disk); in swim_remove()
948 for (drive = 0; drive < swd->floppy_count; drive++) in swim_remove()
949 floppy_eject(&swd->unit[drive]); in swim_remove()
953 release_mem_region(res->start, resource_size(res)); in swim_remove()