Lines Matching +full:p1 +full:- +full:retry +full:- +full:params
1 // SPDX-License-Identifier: GPL-2.0-only
9 * - Driver now works interrupt driven
10 * - Support for two drives; should work, but I cannot test that :-(
11 * - Reading is done in whole tracks and buffered to speed up things
12 * - Disk change detection and drive deselecting after motor-off
14 * - Autodetection of disk format (DD/HD); untested yet, because I
15 * don't have an HD drive :-(
18 * - Autodetection works now
19 * - Support for 5 1/4'' disks
20 * - Removed drive type (unknown on atari)
21 * - Do seeks with 8 Mhz
24 * - After errors in multiple read mode try again reading single sectors
26 * - Clean up error handling
27 * - Set blk_size for proper size checking
28 * - Initialize track register when testing presence of floppy
29 * - Implement some ioctl's
32 * - When probing the floppies we should add the FDCCMDADD_H flag since
36 * - MFPDELAY() after each FDC access -> atari
37 * - more/other disk formats
38 * - DMA to the block buffer directly if we have a 32bit DMA
39 * - for medusa, the step rate is always 3ms
40 * - on medusa, use only cache_push()
42 * - Make disk format numbering independent from minors
43 * - Let user set max. supported drive type (speeds up format
47 * - implement some more ioctls
48 * - disk formatting
51 * - increase gap size at start of track for HD/ED disks
54 * - implemented FDSETPRM and FDDEFPRM ioctl
57 * - implemented missing BLK* ioctls
60 * - Formatting
61 * - Maybe a better strategy for disk change detection (does anyone
70 #include <linux/blk-mq.h>
108 #define FDCCMD_RESTORE (0x00) /* - */
112 #define FDCCMD_STOT (0x60) /* - */
113 #define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */
114 #define FDCCMD_WRSEC (0xa0) /* - " */
115 #define FDCCMD_RDADR (0xc0) /* - */
117 #define FDCCMD_WRTRA (0xf0) /* - */
118 #define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */
127 #define FDCCMDADD_H (0x08) /* wait for spin-up */
149 /* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */
240 /* some PC formats :-) */
241 { 8, TYPE_ED }, /* 9: E3280 <- was "CompaQ" == E2880 for PC */
245 { 3, TYPE_DD }, /* 13: H820 <- == D820, 82x10 */
263 { 6, TYPE_HD }, /* 31: H1640 <- was H1600 == h1600 for PC */
275 * MSch: User-provided type information. 'drive' points to
281 * User-provided permanent type information. 'drive' points to
284 * default_params[].blocks > 0 - a bit in unit[].flags might be used for this?)
295 int track; /* current head position or -1 if
340 * First, there is a DMA buffer in ST-RAM that is used for floppy DMA
358 static int UseTrackbuffer = -1; /* Do track buffering? */
364 static int read_track; /* non-zero if we are reading whole tracks */
366 #define SECTOR_BUFFER(sec) (TrackBuffer + ((sec)-1)*512)
383 static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
544 dma_wd.fdc_speed = UDT->fdc_speed; in fd_select_drive()
564 SelectedDrive = -1; in fd_deselect()
583 goto retry; in fd_motor_off_timer()
588 /* motor already turned off by FDC -> deselect drives */ in fd_motor_off_timer()
595 retry: in fd_motor_off_timer()
662 ulong *p1 = (ulong *)from, *p2 = (ulong *)to; in copy_buffer() local
665 for (cnt = 512/4; cnt; cnt--) in copy_buffer()
666 *p2++ = *p1++; in copy_buffer()
693 /* Error handling: If some error happened, retry some times, then
718 if (SelectedDrive != -1) in fd_error()
719 SUD.track = -1; in fd_error()
721 /* need to re-run request to recalibrate */ in fd_error()
735 /* ---------- Formatting ---------- */
752 type--; in do_format()
756 return -EINVAL; in do_format()
760 q = unit[drive].disk[type]->queue; in do_format()
774 if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { in do_format()
776 ret = -EINVAL; in do_format()
780 nsect = UDT->spt; in do_format()
784 BufferDrive = -1; in do_format()
793 *p++ = desc->track; in do_format()
794 *p++ = desc->head; in do_format()
795 *p++ = (nsect + sect - desc->sect_offset) % nsect + 1; in do_format()
806 FILL( TrackBuffer+BUFFER_SIZE-p, 0x4e ); in do_format()
810 ReqTrack = desc->track; in do_format()
811 ReqSide = desc->head; in do_format()
817 ret = FormatError ? -EIO : 0; in do_format()
866 if (UD.track == -1) in do_fd_action()
868 else if (UD.track != ReqTrack << UDT->stretch) in do_fd_action()
907 dma_wd.fdc_speed = SUDT->fdc_speed; in fd_calibrate_done()
925 if (SUD.track == ReqTrack << SUDT->stretch) { in fd_seek()
936 FDC_WRITE( FDCREG_DATA, ReqTrack << SUDT->stretch); in fd_seek()
955 dma_wd.fdc_speed = SUDT->fdc_speed; in fd_seek_done()
960 SUD.track = -1; in fd_seek_done()
964 SUD.track = ReqTrack << SUDT->stretch; in fd_seek_done()
1014 if (SUDT->stretch) { in fd_rwsec()
1017 FDC_WRITE( FDCREG_TRACK, track >> SUDT->stretch); in fd_rwsec()
1045 dma_wd.fdc_acces_seccount = read_track ? SUDT->spt : 1; in fd_rwsec()
1065 * search for the first non-existent sector and need 1 sec to in fd_rwsec()
1066 * recognise that it isn't present :-( in fd_rwsec()
1110 if (addr >= PhysTrackBuffer + SUDT->spt*512) { in fd_readtrack_check()
1121 /* No error until now -- the FDC would have interrupted in fd_readtrack_check()
1155 if (SUDT->stretch) { in fd_rwsec_done1()
1158 FDC_WRITE( FDCREG_TRACK, track << SUDT->stretch); in fd_rwsec_done1()
1177 searched for a non-existent sector! */ in fd_rwsec_done1()
1178 !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) { in fd_rwsec_done1()
1181 if (SUDT[-1].blocks > ReqBlock) { in fd_rwsec_done1()
1183 SUDT--; in fd_rwsec_done1()
1185 SUDT->blocks); in fd_rwsec_done1()
1191 printk(KERN_INFO "fd%d: Auto-detected floppy type %s\n", in fd_rwsec_done1()
1192 SelectedDrive, SUDT->name ); in fd_rwsec_done1()
1200 SUDT->blocks); in fd_rwsec_done1()
1206 dma_wd.fdc_speed = SUDT->fdc_speed; in fd_rwsec_done1()
1210 BufferDrive = -1; in fd_rwsec_done1()
1261 BufferDrive = -1; in fd_rwsec_done1()
1279 if (SUDT->stretch) { in fd_writetrack()
1282 FDC_WRITE(FDCREG_TRACK,track >> SUDT->stretch); in fd_writetrack()
1372 * no matter what :-( To save time, the seek goes to the track we're
1388 /* we must wait for the IRQ here, because the ST-DMA in finish_fdc()
1405 * last seek command, the WP bit still reads wrong :-(( in finish_fdc_done()
1420 /* The detection of disk changes is a dark chapter in Atari history :-(
1424 * problem by introducing tri-state logic ("maybe changed") and
1438 struct atari_floppy_struct *p = disk->private_data; in floppy_check_events()
1439 unsigned int drive = p - unit; in floppy_check_events()
1449 /* WP is on -> could be changed: to be sure, buffers should be in floppy_check_events()
1460 struct atari_floppy_struct *p = disk->private_data; in floppy_revalidate()
1461 unsigned int drive = p - unit; in floppy_revalidate()
1464 test_bit(drive, &fake_change) || !p->disktype) { in floppy_revalidate()
1467 BufferDrive = -1; in floppy_revalidate()
1471 formats, for 'permanent user-defined' parameter: in floppy_revalidate()
1488 ReqTrack = block / UDT->spt; in setup_req_params()
1489 ReqSector = block - ReqTrack * UDT->spt + 1; in setup_req_params()
1499 DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n",ReqSide, in setup_req_params()
1506 struct atari_floppy_struct *floppy = bd->rq->q->disk->private_data; in ataflop_queue_rq()
1507 int drive = floppy - unit; in ataflop_queue_rq()
1508 int type = floppy->type; in ataflop_queue_rq()
1511 drive, type, blk_rq_cur_sectors(bd->rq), in ataflop_queue_rq()
1512 blk_rq_sectors(bd->rq), bd->last)); in ataflop_queue_rq()
1523 fd_request = bd->rq; in ataflop_queue_rq()
1543 set_capacity(bd->rq->q->disk, UDT->blocks); in ataflop_queue_rq()
1549 if (--type >= NUM_DISK_MINORS) { in ataflop_queue_rq()
1563 set_capacity(bd->rq->q->disk, UDT->blocks); in ataflop_queue_rq()
1573 ReqBuffer = bio_data(fd_request->bio); in ataflop_queue_rq()
1587 struct gendisk *disk = bdev->bd_disk; in fd_locked_ioctl()
1588 struct atari_floppy_struct *floppy = disk->private_data; in fd_locked_ioctl()
1589 int drive = floppy - unit; in fd_locked_ioctl()
1590 int type = floppy->type; in fd_locked_ioctl()
1601 if (--type >= NUM_DISK_MINORS) in fd_locked_ioctl()
1602 return -ENODEV; in fd_locked_ioctl()
1604 return -ENODEV; in fd_locked_ioctl()
1609 drive, dtp, dtp->name); in fd_locked_ioctl()
1613 return -ENXIO; in fd_locked_ioctl()
1618 getprm.size = dtp->blocks; in fd_locked_ioctl()
1619 getprm.sect = dtp->spt; in fd_locked_ioctl()
1621 getprm.track = dtp->blocks/dtp->spt/2; in fd_locked_ioctl()
1622 getprm.stretch = dtp->stretch; in fd_locked_ioctl()
1624 return -EFAULT; in fd_locked_ioctl()
1632 * 'default' device params (minor == 0). in fd_locked_ioctl()
1640 if (floppy->ref != 1 && floppy->ref != -1) in fd_locked_ioctl()
1641 return -EBUSY; in fd_locked_ioctl()
1643 return -EFAULT; in fd_locked_ioctl()
1646 * or the next access will revalidate - and clear UDT :-( in fd_locked_ioctl()
1658 /* refuse to re-set a predefined type for now */ in fd_locked_ioctl()
1660 return -EINVAL; in fd_locked_ioctl()
1666 * TODO: add user-defined format to head of autoprobe list ? in fd_locked_ioctl()
1667 * Useful to include the user-type for future autodetection! in fd_locked_ioctl()
1680 if ( dtp->blocks == setprm.size in fd_locked_ioctl()
1681 && dtp->spt == setprm.sect in fd_locked_ioctl()
1682 && dtp->stretch == setprm.stretch ) { in fd_locked_ioctl()
1685 drive, dtp->name, dtp); in fd_locked_ioctl()
1687 set_capacity(disk, UDT->blocks); in fd_locked_ioctl()
1691 default_params[drive].name = dtp->name; in fd_locked_ioctl()
1692 default_params[drive].spt = dtp->spt; in fd_locked_ioctl()
1693 default_params[drive].blocks = dtp->blocks; in fd_locked_ioctl()
1694 default_params[drive].fdc_speed = dtp->fdc_speed; in fd_locked_ioctl()
1695 default_params[drive].stretch = dtp->stretch; in fd_locked_ioctl()
1703 /* no matching disk type found above - setting user_params */ in fd_locked_ioctl()
1712 dtp->name = "user format"; in fd_locked_ioctl()
1713 dtp->blocks = setprm.size; in fd_locked_ioctl()
1714 dtp->spt = setprm.sect; in fd_locked_ioctl()
1716 dtp->fdc_speed = 3; in fd_locked_ioctl()
1718 dtp->fdc_speed = 0; in fd_locked_ioctl()
1719 dtp->stretch = setprm.stretch; in fd_locked_ioctl()
1723 drive, dtp->blocks, dtp->spt, dtp->stretch); in fd_locked_ioctl()
1726 if (setprm.track != dtp->blocks/dtp->spt/2 || in fd_locked_ioctl()
1729 return -EINVAL; in fd_locked_ioctl()
1733 set_capacity(disk, UDT->blocks); in fd_locked_ioctl()
1743 return -EINVAL; in fd_locked_ioctl()
1747 if (floppy->ref != 1 && floppy->ref != -1) in fd_locked_ioctl()
1748 return -EBUSY; in fd_locked_ioctl()
1750 return -EFAULT; in fd_locked_ioctl()
1761 BufferDrive = -1; in fd_locked_ioctl()
1764 bdev_mark_dead(disk->part0, true); in fd_locked_ioctl()
1769 return -EINVAL; in fd_locked_ioctl()
1810 default: /* should be -1 for "not set by user" */ in fd_probe()
1826 * (and there is no hardware failure :-) Otherwise, the drive is
1874 * floppies, additionally start the disk-change and motor-off timers.
1899 * interrupts on this IRQ line :-( in config_types()
1922 struct atari_floppy_struct *p = disk->private_data; in floppy_open()
1923 int type = disk->first_minor >> 2; in floppy_open()
1926 if (p->ref && p->type != type) in floppy_open()
1927 return -EBUSY; in floppy_open()
1929 if (p->ref == -1 || (p->ref && mode & BLK_OPEN_EXCL)) in floppy_open()
1930 return -EBUSY; in floppy_open()
1932 p->ref = -1; in floppy_open()
1934 p->ref++; in floppy_open()
1936 p->type = type; in floppy_open()
1945 if (p->wpstat) { in floppy_open()
1946 if (p->ref < 0) in floppy_open()
1947 p->ref = 0; in floppy_open()
1949 p->ref--; in floppy_open()
1950 return -EROFS; in floppy_open()
1970 struct atari_floppy_struct *p = disk->private_data; in floppy_release()
1972 if (p->ref < 0) in floppy_release()
1973 p->ref = 0; in floppy_release()
1974 else if (!p->ref--) { in floppy_release()
1976 p->ref = 0; in floppy_release()
2004 disk->major = FLOPPY_MAJOR; in ataflop_alloc_disk()
2005 disk->first_minor = drive + (type << 2); in ataflop_alloc_disk()
2006 disk->minors = 1; in ataflop_alloc_disk()
2007 sprintf(disk->disk_name, "fd%d", drive); in ataflop_alloc_disk()
2008 disk->fops = &floppy_fops; in ataflop_alloc_disk()
2009 disk->flags |= GENHD_FL_NO_PART; in ataflop_alloc_disk()
2010 disk->events = DISK_EVENT_MEDIA_CHANGE; in ataflop_alloc_disk()
2011 disk->private_data = &unit[drive]; in ataflop_alloc_disk()
2024 type--; in ataflop_probe()
2066 if (!fs->disk[type]) in atari_cleanup_floppy_disk()
2068 if (fs->registered[type]) in atari_cleanup_floppy_disk()
2069 del_gendisk(fs->disk[type]); in atari_cleanup_floppy_disk()
2070 put_disk(fs->disk[type]); in atari_cleanup_floppy_disk()
2072 blk_mq_free_tag_set(&fs->tag_set); in atari_cleanup_floppy_disk()
2081 /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ in atari_floppy_init()
2082 return -ENODEV; in atari_floppy_init()
2104 /* not set by user -> use default: for now, we turn in atari_floppy_init()
2107 card. But the test is too hard :-( */ in atari_floppy_init()
2111 SelectedDrive = -1; in atari_floppy_init()
2112 BufferDrive = -1; in atari_floppy_init()
2117 ret = -ENOMEM; in atari_floppy_init()
2123 BufferDrive = BufferSide = BufferTrack = -1; in atari_floppy_init()
2126 unit[i].track = -1; in atari_floppy_init()
2149 while (--i >= 0) in atari_floppy_init()
2182 for( i = 3; i <= ints[0] && i-3 < FD_MAX_UNITS; ++i ) { in atari_floppy_setup()
2186 UserSteprate[i-3] = ints[i]; in atari_floppy_setup()