Lines Matching +full:i +full:- +full:drive
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>
39 #define DRIVER_VERSION "Version 0.2 (2008-10-30)"
41 #define REG(x) unsigned char x, x ## _pad[0x200 - 1];
63 #define swim_write(base, reg, v) out_8(&(base)->write_##reg, (v))
64 #define swim_read(base, reg) in_8(&(base)->read_##reg)
87 #define iwm_write(base, reg, v) out_8(&(base)->reg, (v))
88 #define iwm_read(base, reg) in_8(&(base)->reg)
154 /*----------------------------------------------------------------------------*/
170 enum drive_location location; /* internal or external drive */
171 int head_number; /* single- or double-sided drive */
184 /* in-use information */
312 swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */ in swim_drive()
313 swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */ in swim_drive()
315 swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */ in swim_drive()
316 swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */ in swim_drive()
324 int i; in swim_motor() local
328 for (i = 0; i < 2*HZ; i++) { in swim_motor()
343 int i; in swim_eject() local
347 for (i = 0; i < 2*HZ; i++) { in swim_eject()
359 /* wait drive is ready */ in swim_head()
382 return -1; in swim_step()
398 return -1; in swim_track00()
404 return -1; in swim_track00()
414 step = -step; in swim_seek()
418 for ( ; step > 0; step--) { in swim_seek()
420 return -1; in swim_seek()
428 struct swim __iomem *base = fs->swd->base; in swim_track()
431 ret = swim_seek(base, track - fs->track); in swim_track()
434 fs->track = track; in swim_track()
437 fs->track = 0; in swim_track()
445 struct swim __iomem *base = fs->swd->base; in floppy_eject()
447 swim_drive(base, fs->location); in floppy_eject()
451 fs->disk_in = 0; in floppy_eject()
452 fs->ejected = 1; in floppy_eject()
461 struct swim __iomem *base = fs->swd->base; in swim_read_sector()
464 int ret = -1; in swim_read_sector()
465 short i; in swim_read_sector() local
474 for (i = 0; i < 36; i++) { in swim_read_sector()
498 struct swim __iomem *base = fs->swd->base; in floppy_read_sectors()
501 int i, try; in floppy_read_sectors() local
504 swim_drive(base, fs->location); in floppy_read_sectors()
505 for (i = req_sector; i < req_sector + sectors_nb; i++) { in floppy_read_sectors()
507 track = i / fs->secpercyl; in floppy_read_sectors()
508 x = i % fs->secpercyl; in floppy_read_sectors()
509 side = x / fs->secpertrack; in floppy_read_sectors()
510 sector = x % fs->secpertrack + 1; in floppy_read_sectors()
516 if (try-- == 0) in floppy_read_sectors()
529 struct floppy_state *fs = hctx->queue->queuedata; in swim_queue_rq()
530 struct swim_priv *swd = fs->swd; in swim_queue_rq()
531 struct request *req = bd->rq; in swim_queue_rq()
534 if (!spin_trylock_irq(&swd->lock)) in swim_queue_rq()
539 if (!fs->disk_in || rq_data_dir(req) == WRITE) { in swim_queue_rq()
547 bio_data(req->bio)); in swim_queue_rq()
553 spin_unlock_irq(&swd->lock); in swim_queue_rq()
569 return -EINVAL; in get_floppy_geometry()
573 else if (fs->type == HD_MEDIA) /* High-Density media */ in get_floppy_geometry()
575 else if (fs->head_number == 2) /* double-sided */ in get_floppy_geometry()
585 struct swim __iomem *base = fs->swd->base; in setup_medium()
589 fs->disk_in = 1; in setup_medium()
590 fs->write_protected = swim_readbit(base, WRITE_PROT); in setup_medium()
598 fs->type = swim_readbit(base, TWOMEG_MEDIA) ? in setup_medium()
600 fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2; in setup_medium()
602 fs->total_secs = g->size; in setup_medium()
603 fs->secpercyl = g->head * g->sect; in setup_medium()
604 fs->secpertrack = g->sect; in setup_medium()
605 fs->track = 0; in setup_medium()
607 fs->disk_in = 0; in setup_medium()
613 struct floppy_state *fs = disk->private_data; in floppy_open()
614 struct swim __iomem *base = fs->swd->base; in floppy_open()
617 if (fs->ref_count == -1 || (fs->ref_count && mode & BLK_OPEN_EXCL)) in floppy_open()
618 return -EBUSY; in floppy_open()
620 fs->ref_count = -1; in floppy_open()
622 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()
641 if (disk_check_media_change(disk) && fs->disk_in) in floppy_open()
642 fs->ejected = 0; in floppy_open()
643 if ((mode & BLK_OPEN_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()
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()
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()
750 struct floppy_state *fs = &swd->unit[swd->floppy_count]; in swim_add_floppy()
751 struct swim __iomem *base = swd->base; in swim_add_floppy()
753 fs->location = location; in swim_add_floppy()
759 fs->type = HD_MEDIA; in swim_add_floppy()
760 fs->head_number = 2; in swim_add_floppy()
762 fs->ref_count = 0; in swim_add_floppy()
763 fs->ejected = 1; in swim_add_floppy()
765 swd->floppy_count++; in swim_add_floppy()
776 struct gendisk *disk = fs->disk; in swim_cleanup_floppy_disk()
781 if (fs->registered) in swim_cleanup_floppy_disk()
782 del_gendisk(fs->disk); in swim_cleanup_floppy_disk()
785 blk_mq_free_tag_set(&fs->tag_set); in swim_cleanup_floppy_disk()
794 int drive; in swim_floppy_init() local
795 struct swim __iomem *base = swd->base; in swim_floppy_init()
814 return -EBUSY; in swim_floppy_init()
817 spin_lock_init(&swd->lock); in swim_floppy_init()
819 for (drive = 0; drive < swd->floppy_count; drive++) { in swim_floppy_init()
820 err = blk_mq_alloc_sq_tag_set(&swd->unit[drive].tag_set, in swim_floppy_init()
825 swd->unit[drive].disk = in swim_floppy_init()
826 blk_mq_alloc_disk(&swd->unit[drive].tag_set, &lim, in swim_floppy_init()
827 &swd->unit[drive]); in swim_floppy_init()
828 if (IS_ERR(swd->unit[drive].disk)) { in swim_floppy_init()
829 blk_mq_free_tag_set(&swd->unit[drive].tag_set); in swim_floppy_init()
830 err = PTR_ERR(swd->unit[drive].disk); 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 swd->unit[drive].disk->minors = 1; in swim_floppy_init()
842 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); in swim_floppy_init()
843 swd->unit[drive].disk->fops = &floppy_fops; in swim_floppy_init()
844 swd->unit[drive].disk->flags |= GENHD_FL_NO_PART; in swim_floppy_init()
845 swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE; in swim_floppy_init()
846 swd->unit[drive].disk->private_data = &swd->unit[drive]; in swim_floppy_init()
847 set_capacity(swd->unit[drive].disk, 2880); in swim_floppy_init()
848 err = add_disk(swd->unit[drive].disk); in swim_floppy_init()
851 swd->unit[drive].registered = true; in swim_floppy_init()
859 swim_cleanup_floppy_disk(&swd->unit[drive]); in swim_floppy_init()
860 } while (drive--); in swim_floppy_init()
873 ret = -ENODEV; in swim_probe()
877 if (!request_mem_region(res->start, resource_size(res), CARDNAME)) { in swim_probe()
878 ret = -EBUSY; in swim_probe()
882 swim_base = (struct swim __iomem *)res->start; in swim_probe()
884 ret = -ENOMEM; in swim_probe()
893 ret = -ENODEV; in swim_probe()
901 ret = -ENOMEM; in swim_probe()
906 swd->base = swim_base; in swim_probe()
917 release_mem_region(res->start, resource_size(res)); in swim_probe()
925 int drive; in swim_remove() local
928 for (drive = 0; drive < swd->floppy_count; drive++) in swim_remove()
929 swim_cleanup_floppy_disk(&swd->unit[drive]); in swim_remove()
935 for (drive = 0; drive < swd->floppy_count; drive++) in swim_remove()
936 floppy_eject(&swd->unit[drive]); in swim_remove()
940 release_mem_region(res->start, resource_size(res)); in swim_remove()