Lines Matching +full:i +full:- +full:drive

1 // SPDX-License-Identifier: GPL-2.0-only
11 * 02.12.91 - Changed to static variables to indicate need for reset
18 * This file is certainly a mess. I've tried my best to get it working,
19 * but I don't like programming floppies, and I have only one anyway.
20 * Urgel. I should check for more errors, and do more graceful error
21 * recovery. Seems there are problems with several drives. I've tried to
28 * handler may not sleep, or a kernel panic will happen. Thus I cannot
29 * call "floppy-on" directly, but have to set a special timer interrupt
34 * 28.02.92 - made track-buffering routines, based on the routines written
39 * Automatic floppy-detection and formatting written by Werner Almesberger
41 * the floppy-change signal detection.
45 * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
49 * 1992/9/17: Added DMA allocation & DMA functions. -- hhb.
56 * modeled after the freeware MS-DOS program fdformat/88 V1.8 by
58 * I have fixed the shift values to the ones I always use. Maybe a new
65 * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and
70 /* 1994/6/24 --bbroad-- added the floppy table entries and made
74 /* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more
79 * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger
83 /* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write
87 /* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks
89 * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's
90 * drives are "upside-down").
94 * 1995/8/26 -- Andreas Busse -- added Mips support.
98 * 1995/10/18 -- Ralf Baechle -- Portability cleanup; move machine dependent
103 * 1998/1/21 -- Richard Gooch <rgooch@atnf.csiro.au> -- devfs support
107 * 1998/05/07 -- Russell King -- More portability cleanups; moved definition of
113 * 1998/06/07 -- Alan Cox -- Merged the 2.0.34 fixes for resource allocation
118 * 1998/09/20 -- David Weinehall -- Added slow-down code for buggy PS/2-drives.
122 * 1999/08/13 -- Paul Slootman -- floppy stopped working on Alpha after 24
123 * days, 6 hours, 32 minutes and 32 seconds (i.e. MAXINT jiffies; ints were
128 * 2000/08/28 -- Arnaldo Carvalho de Melo <acme@conectiva.com.br>
129 * - get rid of check_region
130 * - s/suser/capable/
134 * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no
139 * 2002/02/07 -- Anton Altaparmakov - Fix io ports reservation to correct range
140 * (0x3f2-0x3f5, 0x3f7). This fix is a bit of a hack but the proper fix
141 * requires many non-obvious changes in arch dependent code.
144 /* 2003/07/28 -- Daniele Bellucci <bellucda@tiscali.it>.
240 * motor of these drives causes system hangs on some PCI computers. drive
241 * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
242 * a drive is allowed.
245 * some ports reference this variable from there. -DaveM
254 #include <linux/blk-mq.h>
302 #define UNIT(x) ((x) & 0x03) /* drive on fdc */
303 #define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */
304 /* reverse mapping from unit and fdc to drive */
307 #define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2)
308 #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
353 * this struct defines the different floppy drive types.
360 CMOS drive type
361 | Maximum data rate supported by drive type
373 | | | | | | | | | | | | | -Max Errors- flags */
394 /* | --autodetected formats--- | | |
413 * types (e.g. 360kB diskette in 1.2MB drive, etc.). Bit 1 of 'stretch'
415 * are located on side 1 of the disk but with a side 0 ID, and vice-versa.
416 * This is the same as the Sharp MZ-80 5.25" CP/M disk format, except that the
428 * Other parameters should be self-explanatory (see also setfdprm(8)).
482 /* Auto-detection: Disk type used until the next media change occurs. */
486 * User-provided type information. current_type points to
503 #define FD_COMMAND_NONE -1
569 #define NO_TRACK -1
570 #define NEED_1_RECAL -2
571 #define NEED_2_RECAL -3
576 static int buffer_track = -1;
577 static int buffer_drive = -1;
578 static int buffer_min = -1;
579 static int buffer_max = -1;
604 static inline bool drive_no_geom(int drive) in drive_no_geom() argument
606 return !current_type[drive] && !ITYPE(drive_state[drive].fd_device); in drive_no_geom()
610 static inline int fd_eject(int drive) in fd_eject() argument
612 return -EINVAL; in fd_eject()
631 pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer); in debugt()
669 #define MAXTIMEOUT -2
671 static void __reschedule_timeout(int drive, const char *message) in __reschedule_timeout() argument
675 if (drive < 0 || drive >= N_DRIVE) { in __reschedule_timeout()
677 drive = 0; in __reschedule_timeout()
679 delay = drive_params[drive].timeout; in __reschedule_timeout()
682 if (drive_params[drive].flags & FD_DEBUG) in __reschedule_timeout()
687 static void reschedule_timeout(int drive, const char *message) in reschedule_timeout() argument
692 __reschedule_timeout(drive, message); in reschedule_timeout()
704 * and also the main service loop (seek-configure-spinup-command)
714 * 1. The floppy has been changed after some i/o to that floppy already
716 * 2. No floppy disk is in the drive. This is done in order to ensure that
717 * requests are quickly flushed in case there is no disk in the drive. It
719 * the drive.
721 * For 1., maxblock is observed. Maxblock is 0 if no i/o has taken place yet.
725 * change line is set, this means either that no disk is in the drive, or
732 static int disk_change(int drive) in disk_change() argument
734 int fdc = FDC(drive); in disk_change()
736 if (time_before(jiffies, drive_state[drive].select_date + drive_params[drive].select_delay)) in disk_change()
738 if (!(fdc_state[fdc].dor & (0x10 << UNIT(drive))) || in disk_change()
739 (fdc_state[fdc].dor & 3) != UNIT(drive) || fdc != FDC(drive)) { in disk_change()
740 DPRINT("probing disk change on unselected drive\n"); in disk_change()
741 DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive), in disk_change()
745 debug_dcl(drive_params[drive].flags, in disk_change()
746 "checking disk change line for drive %d\n", drive); in disk_change()
747 debug_dcl(drive_params[drive].flags, "jiffies=%lu\n", jiffies); in disk_change()
748 debug_dcl(drive_params[drive].flags, "disk change line=%x\n", in disk_change()
750 debug_dcl(drive_params[drive].flags, "flags=%lx\n", in disk_change()
751 drive_state[drive].flags); in disk_change()
753 if (drive_params[drive].flags & FD_BROKEN_DCL) in disk_change()
755 &drive_state[drive].flags); in disk_change()
756 if ((fdc_inb(fdc, FD_DIR) ^ drive_params[drive].flags) & 0x80) { in disk_change()
757 set_bit(FD_VERIFY_BIT, &drive_state[drive].flags); in disk_change()
760 if (drive_state[drive].maxblock) /* mark it changed */ in disk_change()
762 &drive_state[drive].flags); in disk_change()
765 if (drive_state[drive].keep_data >= 0) { in disk_change()
766 if ((drive_params[drive].flags & FTD_MSG) && in disk_change()
767 current_type[drive] != NULL) in disk_change()
769 current_type[drive] = NULL; in disk_change()
770 floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; in disk_change()
775 drive_state[drive].last_checked = jiffies; in disk_change()
776 clear_bit(FD_DISK_NEWCHANGE_BIT, &drive_state[drive].flags); in disk_change()
795 unsigned char drive; in set_dor() local
799 if (fdc_state[fdc].address == -1) in set_dor()
800 return -1; in set_dor()
807 drive = REVDRIVE(fdc, unit); in set_dor()
808 debug_dcl(drive_params[drive].flags, in set_dor()
810 disk_change(drive); in set_dor()
817 drive = REVDRIVE(fdc, unit); in set_dor()
818 drive_state[drive].select_date = jiffies; in set_dor()
824 static void twaddle(int fdc, int drive) in twaddle() argument
826 if (drive_params[drive].select_delay) in twaddle()
828 fdc_outb(fdc_state[fdc].dor & ~(0x10 << UNIT(drive)), in twaddle()
831 drive_state[drive].select_date = jiffies; in twaddle()
840 int drive; in reset_fdc_info() local
842 fdc_state[fdc].spec1 = fdc_state[fdc].spec2 = -1; in reset_fdc_info()
846 for (drive = 0; drive < N_DRIVE; drive++) in reset_fdc_info()
847 if (FDC(drive) == fdc && in reset_fdc_info()
848 (mode || drive_state[drive].track != NEED_1_RECAL)) in reset_fdc_info()
849 drive_state[drive].track = NEED_2_RECAL; in reset_fdc_info()
853 * selects the fdc and drive, and enables the fdc's input/dma.
854 * Both current_drive and current_fdc are changed to match the new drive.
856 static void set_fdc(int drive) in set_fdc() argument
860 if (drive < 0 || drive >= N_DRIVE) { in set_fdc()
861 pr_info("bad drive value %d\n", drive); in set_fdc()
865 fdc = FDC(drive); in set_fdc()
873 set_dor(1 - fdc, ~8, 0); in set_fdc()
880 current_drive = drive; in set_fdc()
886 * Both current_drive and current_fdc are changed to match the new drive.
888 static int lock_fdc(int drive) in lock_fdc() argument
892 return -1; in lock_fdc()
895 return -EINTR; in lock_fdc()
899 reschedule_timeout(drive, "lock fdc"); in lock_fdc()
900 set_fdc(drive); in lock_fdc()
922 unsigned long nr = t - motor_off_timer; in motor_off_callback()
932 static void floppy_off(unsigned int drive) in floppy_off() argument
935 int fdc = FDC(drive); in floppy_off()
937 if (!(fdc_state[fdc].dor & (0x10 << UNIT(drive)))) in floppy_off()
940 del_timer(motor_off_timer + drive); in floppy_off()
944 if (drive_params[drive].rps) { in floppy_off()
945 delta = jiffies - drive_state[drive].first_read_date + HZ - in floppy_off()
946 drive_params[drive].spindown_offset; in floppy_off()
947 delta = ((delta * drive_params[drive].rps) % HZ) / drive_params[drive].rps; in floppy_off()
948 motor_off_timer[drive].expires = in floppy_off()
949 jiffies + drive_params[drive].spindown - delta; in floppy_off()
951 add_timer(motor_off_timer + drive); in floppy_off()
956 * stopping at current drive. This is done before any long operation, to
961 int i; in scandrives() local
962 int drive; in scandrives() local
969 for (i = 0; i < N_DRIVE; i++) { in scandrives()
970 drive = (saved_drive + i + 1) % N_DRIVE; in scandrives()
971 if (drive_state[drive].fd_ref == 0 || drive_params[drive].select_delay != 0) in scandrives()
973 set_fdc(drive); in scandrives()
974 if (!(set_dor(current_fdc, ~3, UNIT(drive) | (0x10 << UNIT(drive))) & in scandrives()
975 (0x10 << UNIT(drive)))) in scandrives()
978 set_dor(current_fdc, ~(0x10 << UNIT(drive)), 0); in scandrives()
1024 /* this function makes sure that the disk stays in the drive during the
1032 DPRINT("disk removed during i/o\n"); in fd_watchdog()
1034 cont->done(0); in fd_watchdog()
1046 cont->interrupt(); in main_command_interrupt()
1063 queue_delayed_work(floppy_wq, &fd_timer, expires - jiffies); in fd_wait_for_completion()
1073 if (raw_cmd->length == 0) { in setup_DMA()
1076 raw_cmd->fullcmd, raw_cmd->cmd_count, false); in setup_DMA()
1077 cont->done(0); in setup_DMA()
1081 if (((unsigned long)raw_cmd->kernel_data) % 512) { in setup_DMA()
1082 pr_info("non aligned address: %p\n", raw_cmd->kernel_data); in setup_DMA()
1083 cont->done(0); in setup_DMA()
1090 if (fd_dma_setup(raw_cmd->kernel_data, raw_cmd->length, in setup_DMA()
1091 (raw_cmd->flags & FD_RAW_READ) ? in setup_DMA()
1095 cont->done(0); in setup_DMA()
1102 fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length); in setup_DMA()
1103 fd_set_dma_mode((raw_cmd->flags & FD_RAW_READ) ? in setup_DMA()
1105 fd_set_dma_addr(raw_cmd->kernel_data); in setup_DMA()
1106 fd_set_dma_count(raw_cmd->length); in setup_DMA()
1122 return -1; in wait_til_ready()
1133 return -1; in wait_til_ready()
1142 return -1; in output_byte()
1158 return -1; in output_byte()
1164 int i; in result() local
1167 for (i = 0; i < FD_RAW_REPLY_SIZE; i++) { in result()
1174 resultsize = i; in result()
1175 return i; in result()
1178 reply_buffer[i] = fdc_inb(fdc, FD_DATA); in result()
1184 fdc, status, i); in result()
1188 return -1; in result()
1191 #define MORE_OUTPUT -2
1198 return -1; in need_more_output()
1207 * 82077 Now tested. 1Mbps data rate only possible with 82077-1.
1213 if (raw_cmd->rate & 0x40) { in perpendicular_mode()
1214 switch (raw_cmd->rate & 3) { in perpendicular_mode()
1223 cont->done(0); in perpendicular_mode()
1257 output_byte(fdc, 0); /* pre-compensation from track 0 upwards */ in fdc_configure()
1267 * to account for the data rate-based scaling done by the 82072 and 82077
1268 * FDC types. This parameter is ignored for other types of FDCs (i.e.
1282 static void fdc_specify(int fdc, int drive) in fdc_specify() argument
1300 switch (raw_cmd->rate & 0x03) { in fdc_specify()
1311 output_byte(fdc, UNIT(drive)); in fdc_specify()
1328 srt = 16 - DIV_ROUND_UP(drive_params[drive].srt * scale_dtr / 1000, in fdc_specify()
1336 hlt = DIV_ROUND_UP(drive_params[drive].hlt * scale_dtr / 2, in fdc_specify()
1343 hut = DIV_ROUND_UP(drive_params[drive].hut * scale_dtr / 16, in fdc_specify()
1363 /* Set the FDC's data transfer rate on behalf of the specified drive.
1365 * of the specify command (i.e. using the fdc_specify function).
1370 if ((raw_cmd->rate & 3) == fdc_state[current_fdc].dtr) in fdc_dtr()
1374 fdc_outb(raw_cmd->rate & 3, current_fdc, FD_DCR); in fdc_dtr()
1376 /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB) in fdc_dtr()
1381 fdc_state[current_fdc].dtr = raw_cmd->rate & 3; in fdc_dtr()
1436 DPRINT("-- FDC reply error\n"); in interpret_errors()
1445 return 0; /* occurs with pseudo-DMA */ in interpret_errors()
1448 DPRINT("Drive is write protected\n"); in interpret_errors()
1451 cont->done(0); in interpret_errors()
1458 DPRINT("Over/Underrun - retrying\n"); in interpret_errors()
1469 cont->done(0); in interpret_errors()
1473 cont->error(); in interpret_errors()
1482 * for the transfer (i.e. floppy motor is on, the correct floppy is
1487 int i; in setup_rw_floppy() local
1493 flags = raw_cmd->flags; in setup_rw_floppy()
1504 ready_date -= drive_params[current_drive].select_delay; in setup_rw_floppy()
1520 for (i = 0; i < raw_cmd->cmd_count; i++) in setup_rw_floppy()
1521 r |= output_byte(current_fdc, raw_cmd->fullcmd[i]); in setup_rw_floppy()
1526 cont->error(); in setup_rw_floppy()
1533 cont->interrupt(); in setup_rw_floppy()
1550 cont->error(); in seek_interrupt()
1551 cont->redo(); in seek_interrupt()
1570 static void check_wp(int fdc, int drive) in check_wp() argument
1572 if (test_bit(FD_VERIFY_BIT, &drive_state[drive].flags)) { in check_wp()
1575 output_byte(fdc, UNIT(drive)); in check_wp()
1580 clear_bit(FD_VERIFY_BIT, &drive_state[drive].flags); in check_wp()
1582 &drive_state[drive].flags); in check_wp()
1583 debug_dcl(drive_params[drive].flags, in check_wp()
1585 debug_dcl(drive_params[drive].flags, "wp=%x\n", in check_wp()
1589 &drive_state[drive].flags); in check_wp()
1592 &drive_state[drive].flags); in check_wp()
1606 disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { in seek_floppy()
1609 * the drive. in seek_floppy()
1613 cont->done(0); in seek_floppy()
1614 cont->redo(); in seek_floppy()
1621 (raw_cmd->flags & FD_RAW_NEED_DISK) && in seek_floppy()
1622 …(drive_state[current_drive].track <= NO_TRACK || drive_state[current_drive].track == raw_cmd->trac… in seek_floppy()
1623 /* we seek to clear the media-changed condition. Does anybody in seek_floppy()
1625 if (raw_cmd->track) in seek_floppy()
1626 track = raw_cmd->track - 1; in seek_floppy()
1631 raw_cmd->flags |= FD_RAW_NEED_SEEK; in seek_floppy()
1637 if (raw_cmd->track != drive_state[current_drive].track && in seek_floppy()
1638 (raw_cmd->flags & FD_RAW_NEED_SEEK)) in seek_floppy()
1639 track = raw_cmd->track; in seek_floppy()
1666 * reached track 0. Probably no drive. Raise an in recal_interrupt()
1668 * computers possessed by the Devil :-) */ in recal_interrupt()
1669 cont->error(); in recal_interrupt()
1670 cont->redo(); in recal_interrupt()
1705 int i; in print_result() local
1709 for (i = 0; i < inr; i++) in print_result()
1710 pr_cont("repl[%d]=%x ", i, reply_buffer[i]); in print_result()
1729 if (current_fdc >= N_FDC || fdc_state[current_fdc].address == -1) { in floppy_interrupt()
1760 max_sensei--; in floppy_interrupt()
1785 * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
1792 pr_info("reset set in interrupt, calling %ps\n", cont->error); in reset_interrupt()
1793 cont->error(); /* a reset just after a reset. BAD! */ in reset_interrupt()
1795 cont->redo(); in reset_interrupt()
1802 * cont's ->redo() to be called via reset_interrupt().
1812 /* Pseudo-DMA may intercept 'reset finished' interrupt. */ in reset_fdc()
1831 int i; in show_floppy() local
1835 pr_info("-------------------\n"); in show_floppy()
1837 jiffies, interruptjiffies, jiffies - interruptjiffies, in show_floppy()
1842 for (i = 0; i < OLOGSIZE; i++) in show_floppy()
1844 output_log[(i + output_log_pos) % OLOGSIZE].data, in show_floppy()
1845 output_log[(i + output_log_pos) % OLOGSIZE].status, in show_floppy()
1846 output_log[(i + output_log_pos) % OLOGSIZE].jiffies); in show_floppy()
1861 fd_timer.timer.expires - jiffies); in show_floppy()
1865 fd_timeout.timer.expires - jiffies); in show_floppy()
1885 /* avoid dma going to a random drive after shutdown */ in floppy_shutdown()
1891 cont->done(0); in floppy_shutdown()
1892 cont->redo(); /* this will recall reset when needed */ in floppy_shutdown()
1900 /* start motor, check media-changed condition and write protection */
1908 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR)) { in start_motor()
1911 /* no read since this drive is running */ in start_motor()
1942 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && in floppy_ready()
1945 * drive/controller combinations */ in floppy_ready()
1948 if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) { in floppy_ready()
1950 fd_chose_dma_mode(raw_cmd->kernel_data, raw_cmd->length); in floppy_ready()
1955 if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)) { in floppy_ready()
1960 if ((raw_cmd->flags & FD_RAW_READ) || in floppy_ready()
1961 (raw_cmd->flags & FD_RAW_WRITE)) in floppy_ready()
2015 * return -EINTR, in which case the driver will automatically be unlocked.
2032 return -EINTR; in wait_til_done()
2040 ret = -EIO; in wait_til_done()
2053 cont->done(1); in generic_success()
2058 cont->done(0); in generic_failure()
2064 cont->redo(); in success_and_wakeup()
2072 static int next_valid_format(int drive) in next_valid_format() argument
2076 probed_format = drive_state[drive].probed_format; in next_valid_format()
2079 !drive_params[drive].autodetect[probed_format]) { in next_valid_format()
2080 drive_state[drive].probed_format = 0; in next_valid_format()
2083 if (floppy_type[drive_params[drive].autodetect[probed_format]].sect) { in next_valid_format()
2084 drive_state[drive].probed_format = probed_format; in next_valid_format()
2103 cont->done(0); in bad_flp_intr()
2110 static void set_floppy(int drive) in set_floppy() argument
2112 int type = ITYPE(drive_state[drive].fd_device); in set_floppy()
2117 _floppy = current_type[drive]; in set_floppy()
2128 cont->error(); in format_interrupt()
2133 cont->done(1); in format_interrupt()
2135 cont->redo(); in format_interrupt()
2138 #define FM_MODE(x, y) ((y) & ~(((x)->rate & 0x80) >> 1))
2153 raw_cmd->track = track; in setup_format_params()
2155 raw_cmd->flags = (FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | in setup_format_params()
2157 raw_cmd->rate = _floppy->rate & 0x43; in setup_format_params()
2158 raw_cmd->cmd_count = NR_F; in setup_format_params()
2159 raw_cmd->cmd[COMMAND] = FM_MODE(_floppy, FD_FORMAT); in setup_format_params()
2160 raw_cmd->cmd[DR_SELECT] = UNIT(current_drive) + PH_HEAD(_floppy, format_req.head); in setup_format_params()
2161 raw_cmd->cmd[F_SIZECODE] = FD_SIZECODE(_floppy); in setup_format_params()
2162 raw_cmd->cmd[F_SECT_PER_TRACK] = _floppy->sect << 2 >> raw_cmd->cmd[F_SIZECODE]; in setup_format_params()
2163 raw_cmd->cmd[F_GAP] = _floppy->fmt_gap; in setup_format_params()
2164 raw_cmd->cmd[F_FILL] = FD_FILL_BYTE; in setup_format_params()
2166 raw_cmd->kernel_data = floppy_track_buffer; in setup_format_params()
2167 raw_cmd->length = 4 * raw_cmd->cmd[F_SECT_PER_TRACK]; in setup_format_params()
2169 if (!raw_cmd->cmd[F_SECT_PER_TRACK]) in setup_format_params()
2173 head_shift = (raw_cmd->cmd[F_SECT_PER_TRACK] + 5) / 6; in setup_format_params()
2180 % raw_cmd->cmd[F_SECT_PER_TRACK]; in setup_format_params()
2184 if (_floppy->fmt_gap < 0x22) in setup_format_params()
2188 for (count = 0; count < raw_cmd->cmd[F_SECT_PER_TRACK]; ++count) { in setup_format_params()
2192 here[count].size = raw_cmd->cmd[F_SIZECODE]; in setup_format_params()
2195 for (count = 1; count <= raw_cmd->cmd[F_SECT_PER_TRACK]; ++count) { in setup_format_params()
2197 n = (n + il) % raw_cmd->cmd[F_SECT_PER_TRACK]; in setup_format_params()
2200 if (n >= raw_cmd->cmd[F_SECT_PER_TRACK]) { in setup_format_params()
2201 n -= raw_cmd->cmd[F_SECT_PER_TRACK]; in setup_format_params()
2207 if (_floppy->stretch & FD_SECTBASEMASK) { in setup_format_params()
2208 for (count = 0; count < raw_cmd->cmd[F_SECT_PER_TRACK]; count++) in setup_format_params()
2209 here[count].sect += FD_SECTBASE(_floppy) - 1; in setup_format_params()
2215 buffer_track = -1; in redo_format()
2228 static int do_format(int drive, struct format_descr *tmp_format_req) in do_format() argument
2232 if (lock_fdc(drive)) in do_format()
2233 return -EINTR; in do_format()
2235 set_floppy(drive); in do_format()
2237 _floppy->track > drive_params[current_drive].tracks || in do_format()
2238 tmp_format_req->track >= _floppy->track || in do_format()
2239 tmp_format_req->head >= _floppy->head || in do_format()
2240 (_floppy->sect << 2) % (1 << FD_SIZECODE(_floppy)) || in do_format()
2241 !_floppy->fmt_gap) { in do_format()
2243 return -EINVAL; in do_format()
2249 if (ret == -EINTR) in do_format()
2250 return -EINTR; in do_format()
2263 unsigned int drive = (unsigned long)req->q->disk->private_data; in floppy_end_request() local
2273 floppy_off(drive); in floppy_end_request()
2299 if (block > _floppy->sect) in request_done()
2336 ssize = DIV_ROUND_UP(1 << raw_cmd->cmd[SIZECODE], 4); in rw_interrupt()
2343 if (raw_cmd->cmd[COMMAND] & 0x80) in rw_interrupt()
2348 nr_sectors = (((reply_buffer[R_TRACK] - raw_cmd->cmd[TRACK]) * heads + in rw_interrupt()
2349 reply_buffer[R_HEAD] - raw_cmd->cmd[HEAD]) * raw_cmd->cmd[SECT_PER_TRACK] + in rw_interrupt()
2350 reply_buffer[R_SECTOR] - raw_cmd->cmd[SECTOR] + eoc) << raw_cmd->cmd[SIZECODE] >> 2; in rw_interrupt()
2357 raw_cmd->cmd[SECTOR]); in rw_interrupt()
2359 raw_cmd->cmd[HEAD]); in rw_interrupt()
2361 raw_cmd->cmd[TRACK]); in rw_interrupt()
2364 raw_cmd->cmd[SECT_PER_TRACK], fsector_t, ssize); in rw_interrupt()
2368 nr_sectors -= in_sector_offset; in rw_interrupt()
2374 cont->redo(); in rw_interrupt()
2378 cont->error(); in rw_interrupt()
2379 cont->redo(); in rw_interrupt()
2385 cont->redo(); in rw_interrupt()
2389 floppy_sizes[TOMINOR(current_drive)] = _floppy->size; in rw_interrupt()
2395 DPRINT("Auto-detected floppy type %s in fd%d\n", in rw_interrupt()
2396 _floppy->name, current_drive); in rw_interrupt()
2398 floppy_sizes[TOMINOR(current_drive)] = _floppy->size; in rw_interrupt()
2402 if (CT(raw_cmd->cmd[COMMAND]) != FD_READ) { in rw_interrupt()
2404 cont->done(1); in rw_interrupt()
2406 buffer_track = raw_cmd->track; in rw_interrupt()
2410 cont->redo(); in rw_interrupt()
2419 max_sector -= (max_sector % _floppy->sect) % ssize; in transfer_size()
2422 current_count_sectors = max_sector - fsector_t; in transfer_size()
2432 int remaining; /* number of transferred 512-byte sectors */ in copy_buffer()
2442 if (current_count_sectors <= 0 && CT(raw_cmd->cmd[COMMAND]) == FD_WRITE && in copy_buffer()
2444 current_count_sectors = min_t(int, buffer_max - fsector_t, in copy_buffer()
2448 if (remaining > blk_rq_bytes(current_req) && CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) { in copy_buffer()
2452 pr_info("current_req->nr_sectors=%u\n", in copy_buffer()
2454 pr_info("current_req->current_nr_sectors=%u\n", in copy_buffer()
2462 dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9); in copy_buffer()
2476 (int)((floppy_track_buffer - dma_buffer) >> 9)); in copy_buffer()
2481 if (CT(raw_cmd->cmd[COMMAND]) == FD_READ) in copy_buffer()
2483 if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) in copy_buffer()
2488 if (CT(raw_cmd->cmd[COMMAND]) == FD_READ) in copy_buffer()
2493 remaining -= size; in copy_buffer()
2498 max_sector -= remaining >> 9; in copy_buffer()
2506 * transfer length: We use raw_cmd->cmd[SECT_PER_TRACK]. Unfortunately, this
2515 if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) { in virtualdmabug_workaround()
2516 raw_cmd->cmd[COMMAND] &= ~0x80; /* switch off multiple track mode */ in virtualdmabug_workaround()
2518 hard_sectors = raw_cmd->length >> (7 + raw_cmd->cmd[SIZECODE]); in virtualdmabug_workaround()
2519 end_sector = raw_cmd->cmd[SECTOR] + hard_sectors - 1; in virtualdmabug_workaround()
2520 if (end_sector > raw_cmd->cmd[SECT_PER_TRACK]) { in virtualdmabug_workaround()
2522 end_sector, raw_cmd->cmd[SECT_PER_TRACK]); in virtualdmabug_workaround()
2525 raw_cmd->cmd[SECT_PER_TRACK] = end_sector; in virtualdmabug_workaround()
2526 /* make sure raw_cmd->cmd[SECT_PER_TRACK] in virtualdmabug_workaround()
2549 if (WARN(max_buffer_sectors == 0, "VFS: Block I/O scheduled on unopened device\n")) in make_raw_rw_request()
2552 set_fdc((long)current_req->q->disk->private_data); in make_raw_rw_request()
2555 raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; in make_raw_rw_request()
2556 raw_cmd->cmd_count = NR_RW; in make_raw_rw_request()
2558 raw_cmd->flags |= FD_RAW_READ; in make_raw_rw_request()
2559 raw_cmd->cmd[COMMAND] = FM_MODE(_floppy, FD_READ); in make_raw_rw_request()
2561 raw_cmd->flags |= FD_RAW_WRITE; in make_raw_rw_request()
2562 raw_cmd->cmd[COMMAND] = FM_MODE(_floppy, FD_WRITE); in make_raw_rw_request()
2568 max_sector = _floppy->sect * _floppy->head; in make_raw_rw_request()
2570 raw_cmd->cmd[TRACK] = (int)blk_rq_pos(current_req) / max_sector; in make_raw_rw_request()
2572 if (_floppy->track && raw_cmd->cmd[TRACK] >= _floppy->track) { in make_raw_rw_request()
2579 raw_cmd->cmd[HEAD] = fsector_t / _floppy->sect; in make_raw_rw_request()
2581 if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || in make_raw_rw_request()
2583 fsector_t < _floppy->sect) in make_raw_rw_request()
2584 max_sector = _floppy->sect; in make_raw_rw_request()
2587 if ((_floppy->rate & FD_2M) && (!raw_cmd->cmd[TRACK]) && (!raw_cmd->cmd[HEAD])) { in make_raw_rw_request()
2588 max_sector = 2 * _floppy->sect / 3; in make_raw_rw_request()
2591 min_t(int, _floppy->sect - fsector_t, in make_raw_rw_request()
2595 raw_cmd->cmd[SIZECODE] = 2; in make_raw_rw_request()
2597 raw_cmd->cmd[SIZECODE] = FD_SIZECODE(_floppy); in make_raw_rw_request()
2598 raw_cmd->rate = _floppy->rate & 0x43; in make_raw_rw_request()
2599 if ((_floppy->rate & FD_2M) && in make_raw_rw_request()
2600 (raw_cmd->cmd[TRACK] || raw_cmd->cmd[HEAD]) && raw_cmd->rate == 2) in make_raw_rw_request()
2601 raw_cmd->rate = 1; in make_raw_rw_request()
2603 if (raw_cmd->cmd[SIZECODE]) in make_raw_rw_request()
2604 raw_cmd->cmd[SIZECODE2] = 0xff; in make_raw_rw_request()
2606 raw_cmd->cmd[SIZECODE2] = 0x80; in make_raw_rw_request()
2607 raw_cmd->track = raw_cmd->cmd[TRACK] << STRETCH(_floppy); in make_raw_rw_request()
2608 raw_cmd->cmd[DR_SELECT] = UNIT(current_drive) + PH_HEAD(_floppy, raw_cmd->cmd[HEAD]); in make_raw_rw_request()
2609 raw_cmd->cmd[GAP] = _floppy->gap; in make_raw_rw_request()
2610 ssize = DIV_ROUND_UP(1 << raw_cmd->cmd[SIZECODE], 4); in make_raw_rw_request()
2611 raw_cmd->cmd[SECT_PER_TRACK] = _floppy->sect << 2 >> raw_cmd->cmd[SIZECODE]; in make_raw_rw_request()
2612 raw_cmd->cmd[SECTOR] = ((fsector_t % _floppy->sect) << 2 >> raw_cmd->cmd[SIZECODE]) + in make_raw_rw_request()
2618 tracksize = _floppy->sect - _floppy->sect % ssize; in make_raw_rw_request()
2619 if (tracksize < _floppy->sect) { in make_raw_rw_request()
2620 raw_cmd->cmd[SECT_PER_TRACK]++; in make_raw_rw_request()
2621 if (tracksize <= fsector_t % _floppy->sect) in make_raw_rw_request()
2622 raw_cmd->cmd[SECTOR]--; in make_raw_rw_request()
2625 while (tracksize <= fsector_t % _floppy->sect) { in make_raw_rw_request()
2626 while (tracksize + ssize > _floppy->sect) { in make_raw_rw_request()
2627 raw_cmd->cmd[SIZECODE]--; in make_raw_rw_request()
2630 raw_cmd->cmd[SECTOR]++; in make_raw_rw_request()
2631 raw_cmd->cmd[SECT_PER_TRACK]++; in make_raw_rw_request()
2634 max_sector = raw_cmd->cmd[HEAD] * _floppy->sect + tracksize; in make_raw_rw_request()
2635 } else if (!raw_cmd->cmd[TRACK] && !raw_cmd->cmd[HEAD] && !(_floppy->rate & FD_2M) && probing) { in make_raw_rw_request()
2636 max_sector = _floppy->sect; in make_raw_rw_request()
2637 } else if (!raw_cmd->cmd[HEAD] && CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) { in make_raw_rw_request()
2639 max_sector = _floppy->sect; in make_raw_rw_request()
2642 in_sector_offset = (fsector_t % _floppy->sect) % ssize; in make_raw_rw_request()
2643 aligned_sector_t = fsector_t - in_sector_offset; in make_raw_rw_request()
2645 if ((raw_cmd->track == buffer_track) && in make_raw_rw_request()
2649 if (CT(raw_cmd->cmd[COMMAND]) == FD_READ) { in make_raw_rw_request()
2654 if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) { in make_raw_rw_request()
2663 raw_cmd->flags &= ~FD_RAW_WRITE; in make_raw_rw_request()
2664 raw_cmd->flags |= FD_RAW_READ; in make_raw_rw_request()
2665 raw_cmd->cmd[COMMAND] = FM_MODE(_floppy, FD_READ); in make_raw_rw_request()
2668 if (CT(raw_cmd->cmd[COMMAND]) == FD_READ) in make_raw_rw_request()
2672 if (buffer_track != raw_cmd->track || /* bad track */ in make_raw_rw_request()
2673 buffer_drive != current_drive || /* bad drive */ in make_raw_rw_request()
2676 ((CT(raw_cmd->cmd[COMMAND]) == FD_READ || in make_raw_rw_request()
2681 buffer_track = -1; in make_raw_rw_request()
2685 raw_cmd->kernel_data = floppy_track_buffer + in make_raw_rw_request()
2686 ((aligned_sector_t - buffer_min) << 9); in make_raw_rw_request()
2688 if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) { in make_raw_rw_request()
2693 if (in_sector_offset && buffer_track == -1) in make_raw_rw_request()
2695 buffer_track = raw_cmd->track; in make_raw_rw_request()
2701 2 * max_buffer_sectors + buffer_min - in make_raw_rw_request()
2705 raw_cmd->length = in_sector_offset + current_count_sectors; in make_raw_rw_request()
2706 raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; in make_raw_rw_request()
2707 raw_cmd->length <<= 9; in make_raw_rw_request()
2708 if ((raw_cmd->length < current_count_sectors << 9) || in make_raw_rw_request()
2709 (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE && in make_raw_rw_request()
2710 (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max || in make_raw_rw_request()
2712 raw_cmd->length % (128 << raw_cmd->cmd[SIZECODE]) || in make_raw_rw_request()
2713 raw_cmd->length <= 0 || current_count_sectors <= 0) { in make_raw_rw_request()
2715 raw_cmd->length, current_count_sectors); in make_raw_rw_request()
2717 (int)((raw_cmd->kernel_data - in make_raw_rw_request()
2722 pr_info("ssize=%x SIZECODE=%d\n", ssize, raw_cmd->cmd[SIZECODE]); in make_raw_rw_request()
2724 raw_cmd->cmd[COMMAND], raw_cmd->cmd[SECTOR], in make_raw_rw_request()
2725 raw_cmd->cmd[HEAD], raw_cmd->cmd[TRACK]); in make_raw_rw_request()
2726 pr_info("buffer drive=%d\n", buffer_drive); in make_raw_rw_request()
2733 if (raw_cmd->kernel_data < floppy_track_buffer || in make_raw_rw_request()
2735 raw_cmd->length < 0 || in make_raw_rw_request()
2736 raw_cmd->kernel_data + raw_cmd->length > in make_raw_rw_request()
2740 fsector_t, buffer_min, raw_cmd->length >> 9); in make_raw_rw_request()
2743 if (CT(raw_cmd->cmd[COMMAND]) == FD_READ) in make_raw_rw_request()
2745 if (CT(raw_cmd->cmd[COMMAND]) == FD_WRITE) in make_raw_rw_request()
2749 if (raw_cmd->length == 0) { in make_raw_rw_request()
2764 list_del_init(&current_req->queuelist); in set_next_request()
2775 int drive; in redo_fd_request() local
2794 drive = (long)current_req->q->disk->private_data; in redo_fd_request()
2795 set_fdc(drive); in redo_fd_request()
2798 set_floppy(drive); in redo_fd_request()
2800 raw_cmd->flags = 0; in redo_fd_request()
2855 blk_mq_start_request(bd->rq); in floppy_queue_rq()
2858 "VFS: %s called on non-open device\n", __func__)) in floppy_queue_rq()
2864 (__force unsigned long long) current_req->cmd_flags)) in floppy_queue_rq()
2875 list_add_tail(&bd->rq->queuelist, &floppy_reqs); in floppy_queue_rq()
2895 /* no auto-sense, just clear dcl */ in poll_drive()
2897 raw_cmd->flags = flag; in poll_drive()
2898 raw_cmd->track = 0; in poll_drive()
2899 raw_cmd->cmd_count = 0; in poll_drive()
2926 * Resets the FDC connected to drive <drive>.
2927 * Both current_drive and current_fdc are changed to match the new drive.
2929 static int user_reset_fdc(int drive, int arg, bool interruptible) in user_reset_fdc() argument
2933 if (lock_fdc(drive)) in user_reset_fdc()
2934 return -EINTR; in user_reset_fdc()
2944 if (ret == -EINTR) in user_reset_fdc()
2945 return -EINTR; in user_reset_fdc()
2958 return copy_to_user(param, address, size) ? -EFAULT : 0; in fd_copyout()
2964 return copy_from_user(address, param, size) ? -EFAULT : 0; in fd_copyin()
2967 static const char *drive_name(int type, int drive) in drive_name() argument
2974 if (drive_params[drive].native_format) in drive_name()
2975 floppy = floppy_type + drive_params[drive].native_format; in drive_name()
2979 if (floppy->name) in drive_name()
2980 return floppy->name; in drive_name()
2991 raw_cmd->flags |= FD_RAW_FAILURE; in raw_cmd_done()
2992 raw_cmd->flags |= FD_RAW_HARDFAILURE; in raw_cmd_done()
2994 raw_cmd->reply_count = inr; in raw_cmd_done()
2995 if (raw_cmd->reply_count > FD_RAW_REPLY_SIZE) in raw_cmd_done()
2996 raw_cmd->reply_count = 0; in raw_cmd_done()
2997 memcpy(raw_cmd->reply, reply_buffer, raw_cmd->reply_count); in raw_cmd_done()
2999 if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE)) { in raw_cmd_done()
3002 raw_cmd->length = fd_get_dma_residue(); in raw_cmd_done()
3006 if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) && in raw_cmd_done()
3007 (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0))) in raw_cmd_done()
3008 raw_cmd->flags |= FD_RAW_FAILURE; in raw_cmd_done()
3011 raw_cmd->flags |= FD_RAW_DISK_CHANGE; in raw_cmd_done()
3013 raw_cmd->flags &= ~FD_RAW_DISK_CHANGE; in raw_cmd_done()
3014 if (raw_cmd->flags & FD_RAW_NO_MOTOR_AFTER) in raw_cmd_done()
3017 if (raw_cmd->next && in raw_cmd_done()
3018 (!(raw_cmd->flags & FD_RAW_FAILURE) || in raw_cmd_done()
3019 !(raw_cmd->flags & FD_RAW_STOP_IF_FAILURE)) && in raw_cmd_done()
3020 ((raw_cmd->flags & FD_RAW_FAILURE) || in raw_cmd_done()
3021 !(raw_cmd->flags & FD_RAW_STOP_IF_SUCCESS))) { in raw_cmd_done()
3022 raw_cmd = raw_cmd->next; in raw_cmd_done()
3047 return -EFAULT; in raw_cmd_copyout()
3049 if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) { in raw_cmd_copyout()
3050 if (ptr->length >= 0 && in raw_cmd_copyout()
3051 ptr->length <= ptr->buffer_length) { in raw_cmd_copyout()
3052 long length = ptr->buffer_length - ptr->length; in raw_cmd_copyout()
3053 ret = fd_copyout(ptr->data, ptr->kernel_data, in raw_cmd_copyout()
3059 ptr = ptr->next; in raw_cmd_copyout()
3073 if (this->buffer_length) { in raw_cmd_free()
3074 fd_dma_mem_free((unsigned long)this->kernel_data, in raw_cmd_free()
3075 this->buffer_length); in raw_cmd_free()
3076 this->buffer_length = 0; in raw_cmd_free()
3078 next = this->next; in raw_cmd_free()
3097 return -ENOMEM; in raw_cmd_copyin()
3100 ptr->next = NULL; in raw_cmd_copyin()
3101 ptr->buffer_length = 0; in raw_cmd_copyin()
3102 ptr->kernel_data = NULL; in raw_cmd_copyin()
3104 return -EFAULT; in raw_cmd_copyin()
3106 if (ptr->cmd_count > FD_RAW_CMD_FULLSIZE) in raw_cmd_copyin()
3107 return -EINVAL; in raw_cmd_copyin()
3109 memset(ptr->reply, 0, FD_RAW_REPLY_SIZE); in raw_cmd_copyin()
3110 ptr->resultcode = 0; in raw_cmd_copyin()
3112 if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { in raw_cmd_copyin()
3113 if (ptr->length <= 0 || ptr->length > MAX_LEN) in raw_cmd_copyin()
3114 return -EINVAL; in raw_cmd_copyin()
3115 ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); in raw_cmd_copyin()
3116 fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); in raw_cmd_copyin()
3117 if (!ptr->kernel_data) in raw_cmd_copyin()
3118 return -ENOMEM; in raw_cmd_copyin()
3119 ptr->buffer_length = ptr->length; in raw_cmd_copyin()
3121 if (ptr->flags & FD_RAW_WRITE) { in raw_cmd_copyin()
3122 ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length); in raw_cmd_copyin()
3127 if (ptr->flags & FD_RAW_MORE) { in raw_cmd_copyin()
3128 rcmd = &(ptr->next); in raw_cmd_copyin()
3129 ptr->rate &= 0x43; in raw_cmd_copyin()
3139 int drive; in raw_cmd_ioctl() local
3145 for (drive = 0; drive < N_DRIVE; drive++) { in raw_cmd_ioctl()
3146 if (FDC(drive) != current_fdc) in raw_cmd_ioctl()
3148 if (drive == current_drive) { in raw_cmd_ioctl()
3149 if (drive_state[drive].fd_ref > 1) { in raw_cmd_ioctl()
3153 } else if (drive_state[drive].fd_ref) { in raw_cmd_ioctl()
3160 return -EIO; in raw_cmd_ioctl()
3174 if (ret != -EINTR && fdc_state[current_fdc].reset) in raw_cmd_ioctl()
3175 ret = -EIO; in raw_cmd_ioctl()
3186 static int floppy_raw_cmd_ioctl(int type, int drive, int cmd, in floppy_raw_cmd_ioctl() argument
3194 return -EINVAL; in floppy_raw_cmd_ioctl()
3195 if (lock_fdc(drive)) in floppy_raw_cmd_ioctl()
3196 return -EINTR; in floppy_raw_cmd_ioctl()
3197 set_floppy(drive); in floppy_raw_cmd_ioctl()
3199 if (ret == -EINTR) in floppy_raw_cmd_ioctl()
3200 return -EINTR; in floppy_raw_cmd_ioctl()
3207 static int floppy_raw_cmd_ioctl(int type, int drive, int cmd, in floppy_raw_cmd_ioctl() argument
3210 return -EOPNOTSUPP; in floppy_raw_cmd_ioctl()
3218 set_bit((long)disk->private_data, &fake_change); in invalidate_drive()
3221 bdev_mark_dead(disk->part0, true); in invalidate_drive()
3228 int drive, int type, struct block_device *bdev) in set_geometry() argument
3233 if ((int)g->sect <= 0 || in set_geometry()
3234 (int)g->head <= 0 || in set_geometry()
3236 (int)(g->sect * g->head) <= 0 || in set_geometry()
3237 /* check for zero in raw_cmd->cmd[F_SECT_PER_TRACK] */ in set_geometry()
3238 (unsigned char)((g->sect << 2) >> FD_SIZECODE(g)) == 0 || in set_geometry()
3239 g->track <= 0 || g->track > drive_params[drive].tracks >> STRETCH(g) || in set_geometry()
3241 (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0) in set_geometry()
3242 return -EINVAL; in set_geometry()
3245 return -EPERM; in set_geometry()
3247 if (lock_fdc(drive)) { in set_geometry()
3249 return -EINTR; in set_geometry()
3268 if (lock_fdc(drive)) in set_geometry()
3269 return -EINTR; in set_geometry()
3273 if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) in set_geometry()
3274 return -EINTR; in set_geometry()
3276 oldStretch = g->stretch; in set_geometry()
3277 user_params[drive] = *g; in set_geometry()
3278 if (buffer_drive == drive) in set_geometry()
3279 SUPBOUND(buffer_max, user_params[drive].sect); in set_geometry()
3280 current_type[drive] = &user_params[drive]; in set_geometry()
3281 floppy_sizes[drive] = user_params[drive].size; in set_geometry()
3283 drive_state[current_drive].keep_data = -1; in set_geometry()
3286 /* invalidation. Invalidate only when needed, i.e. in set_geometry()
3291 if (drive_state[current_drive].maxblock > user_params[drive].sect || in set_geometry()
3293 ((user_params[drive].sect ^ oldStretch) & in set_geometry()
3295 invalidate_drive(bdev->bd_disk); in set_geometry()
3333 int i; in normalize_ioctl() local
3335 for (i = 0; i < ARRAY_SIZE(ioctl_table); i++) { in normalize_ioctl()
3336 if ((*cmd & 0xffff) == (ioctl_table[i] & 0xffff)) { in normalize_ioctl()
3338 *cmd = ioctl_table[i]; in normalize_ioctl()
3341 return -EFAULT; in normalize_ioctl()
3346 return -EINVAL; in normalize_ioctl()
3349 static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) in get_floppy_geometry() argument
3354 if (lock_fdc(drive)) in get_floppy_geometry()
3355 return -EINTR; in get_floppy_geometry()
3356 if (poll_drive(false, 0) == -EINTR) in get_floppy_geometry()
3357 return -EINTR; in get_floppy_geometry()
3359 *g = current_type[drive]; in get_floppy_geometry()
3362 return -ENODEV; in get_floppy_geometry()
3368 int drive = (long)bdev->bd_disk->private_data; in fd_getgeo() local
3369 int type = ITYPE(drive_state[drive].fd_device); in fd_getgeo()
3373 ret = get_floppy_geometry(drive, type, &g); in fd_getgeo()
3377 geo->heads = g->head; in fd_getgeo()
3378 geo->sectors = g->sect; in fd_getgeo()
3379 geo->cylinders = g->track; in fd_getgeo()
3387 size_t i = 0; in valid_floppy_drive_params() local
3389 for (i = 0; i < FD_AUTODETECT_SIZE; ++i) { in valid_floppy_drive_params()
3390 if (autodetect[i] < 0 || in valid_floppy_drive_params()
3391 autodetect[i] >= floppy_type_size) in valid_floppy_drive_params()
3404 int drive = (long)bdev->bd_disk->private_data; in fd_locked_ioctl() local
3405 int type = ITYPE(drive_state[drive].fd_device); in fd_locked_ioctl()
3419 if (cmd == CDROMEJECT || /* CD-ROM eject */ in fd_locked_ioctl()
3422 DPRINT("please use floppycontrol --eject\n"); in fd_locked_ioctl()
3427 return -EINVAL; in fd_locked_ioctl()
3438 return -EPERM; in fd_locked_ioctl()
3441 return -EINVAL; in fd_locked_ioctl()
3453 if (drive_state[drive].fd_ref != 1) in fd_locked_ioctl()
3454 /* somebody else has this drive open */ in fd_locked_ioctl()
3455 return -EBUSY; in fd_locked_ioctl()
3456 if (lock_fdc(drive)) in fd_locked_ioctl()
3457 return -EINTR; in fd_locked_ioctl()
3460 * non-Sparc architectures */ in fd_locked_ioctl()
3461 ret = fd_eject(UNIT(drive)); in fd_locked_ioctl()
3463 set_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags); in fd_locked_ioctl()
3464 set_bit(FD_VERIFY_BIT, &drive_state[drive].flags); in fd_locked_ioctl()
3468 if (lock_fdc(drive)) in fd_locked_ioctl()
3469 return -EINTR; in fd_locked_ioctl()
3470 current_type[drive] = NULL; in fd_locked_ioctl()
3471 floppy_sizes[drive] = MAX_DISK_SIZE << 1; in fd_locked_ioctl()
3472 drive_state[drive].keep_data = 0; in fd_locked_ioctl()
3473 return invalidate_drive(bdev->bd_disk); in fd_locked_ioctl()
3476 return set_geometry(cmd, &inparam.g, drive, type, bdev); in fd_locked_ioctl()
3478 ret = get_floppy_geometry(drive, type, in fd_locked_ioctl()
3487 drive_params[drive].flags |= FTD_MSG; in fd_locked_ioctl()
3490 drive_params[drive].flags &= ~FTD_MSG; in fd_locked_ioctl()
3493 if (lock_fdc(drive)) in fd_locked_ioctl()
3494 return -EINTR; in fd_locked_ioctl()
3495 if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) in fd_locked_ioctl()
3496 return -EINTR; in fd_locked_ioctl()
3497 ret = drive_state[drive].flags; in fd_locked_ioctl()
3500 return -ENODEV; in fd_locked_ioctl()
3502 return -EROFS; in fd_locked_ioctl()
3505 if (drive_state[drive].fd_ref != 1) in fd_locked_ioctl()
3506 return -EBUSY; in fd_locked_ioctl()
3507 return do_format(drive, &inparam.f); in fd_locked_ioctl()
3510 if (lock_fdc(drive)) in fd_locked_ioctl()
3511 return -EINTR; in fd_locked_ioctl()
3512 return invalidate_drive(bdev->bd_disk); in fd_locked_ioctl()
3514 drive_params[drive].max_errors.reporting = (unsigned short)(param & 0x0f); in fd_locked_ioctl()
3517 outparam = &drive_params[drive].max_errors; in fd_locked_ioctl()
3520 drive_params[drive].max_errors = inparam.max_errors; in fd_locked_ioctl()
3523 outparam = drive_name(type, drive); in fd_locked_ioctl()
3529 return -EINVAL; in fd_locked_ioctl()
3530 drive_params[drive] = inparam.dp; in fd_locked_ioctl()
3533 outparam = &drive_params[drive]; in fd_locked_ioctl()
3536 if (lock_fdc(drive)) in fd_locked_ioctl()
3537 return -EINTR; in fd_locked_ioctl()
3538 if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) in fd_locked_ioctl()
3539 return -EINTR; in fd_locked_ioctl()
3543 outparam = &drive_state[drive]; in fd_locked_ioctl()
3546 return user_reset_fdc(drive, (int)param, true); in fd_locked_ioctl()
3548 outparam = &fdc_state[FDC(drive)]; in fd_locked_ioctl()
3551 memset(&write_errors[drive], 0, sizeof(write_errors[drive])); in fd_locked_ioctl()
3554 outparam = &write_errors[drive]; in fd_locked_ioctl()
3557 return floppy_raw_cmd_ioctl(type, drive, cmd, (void __user *)param); in fd_locked_ioctl()
3559 if (lock_fdc(drive)) in fd_locked_ioctl()
3560 return -EINTR; in fd_locked_ioctl()
3565 return -EINVAL; in fd_locked_ioctl()
3666 int drive, type; in compat_set_geometry() local
3673 return -EPERM; in compat_set_geometry()
3677 return -EFAULT; in compat_set_geometry()
3680 drive = (long)bdev->bd_disk->private_data; in compat_set_geometry()
3681 type = ITYPE(drive_state[drive].fd_device); in compat_set_geometry()
3683 &v, drive, type, bdev); in compat_set_geometry()
3688 static int compat_get_prm(int drive, in compat_get_prm() argument
3697 err = get_floppy_geometry(drive, ITYPE(drive_state[drive].fd_device), in compat_get_prm()
3706 return -EFAULT; in compat_get_prm()
3710 static int compat_setdrvprm(int drive, in compat_setdrvprm() argument
3716 return -EPERM; in compat_setdrvprm()
3718 return -EFAULT; in compat_setdrvprm()
3720 return -EINVAL; in compat_setdrvprm()
3722 drive_params[drive].cmos = v.cmos; in compat_setdrvprm()
3723 drive_params[drive].max_dtr = v.max_dtr; in compat_setdrvprm()
3724 drive_params[drive].hlt = v.hlt; in compat_setdrvprm()
3725 drive_params[drive].hut = v.hut; in compat_setdrvprm()
3726 drive_params[drive].srt = v.srt; in compat_setdrvprm()
3727 drive_params[drive].spinup = v.spinup; in compat_setdrvprm()
3728 drive_params[drive].spindown = v.spindown; in compat_setdrvprm()
3729 drive_params[drive].spindown_offset = v.spindown_offset; in compat_setdrvprm()
3730 drive_params[drive].select_delay = v.select_delay; in compat_setdrvprm()
3731 drive_params[drive].rps = v.rps; in compat_setdrvprm()
3732 drive_params[drive].tracks = v.tracks; in compat_setdrvprm()
3733 drive_params[drive].timeout = v.timeout; in compat_setdrvprm()
3734 drive_params[drive].interleave_sect = v.interleave_sect; in compat_setdrvprm()
3735 drive_params[drive].max_errors = v.max_errors; in compat_setdrvprm()
3736 drive_params[drive].flags = v.flags; in compat_setdrvprm()
3737 drive_params[drive].read_track = v.read_track; in compat_setdrvprm()
3738 memcpy(drive_params[drive].autodetect, v.autodetect, in compat_setdrvprm()
3740 drive_params[drive].checkfreq = v.checkfreq; in compat_setdrvprm()
3741 drive_params[drive].native_format = v.native_format; in compat_setdrvprm()
3746 static int compat_getdrvprm(int drive, in compat_getdrvprm() argument
3753 v.cmos = drive_params[drive].cmos; in compat_getdrvprm()
3754 v.max_dtr = drive_params[drive].max_dtr; in compat_getdrvprm()
3755 v.hlt = drive_params[drive].hlt; in compat_getdrvprm()
3756 v.hut = drive_params[drive].hut; in compat_getdrvprm()
3757 v.srt = drive_params[drive].srt; in compat_getdrvprm()
3758 v.spinup = drive_params[drive].spinup; in compat_getdrvprm()
3759 v.spindown = drive_params[drive].spindown; in compat_getdrvprm()
3760 v.spindown_offset = drive_params[drive].spindown_offset; in compat_getdrvprm()
3761 v.select_delay = drive_params[drive].select_delay; in compat_getdrvprm()
3762 v.rps = drive_params[drive].rps; in compat_getdrvprm()
3763 v.tracks = drive_params[drive].tracks; in compat_getdrvprm()
3764 v.timeout = drive_params[drive].timeout; in compat_getdrvprm()
3765 v.interleave_sect = drive_params[drive].interleave_sect; in compat_getdrvprm()
3766 v.max_errors = drive_params[drive].max_errors; in compat_getdrvprm()
3767 v.flags = drive_params[drive].flags; in compat_getdrvprm()
3768 v.read_track = drive_params[drive].read_track; in compat_getdrvprm()
3769 memcpy(v.autodetect, drive_params[drive].autodetect, in compat_getdrvprm()
3771 v.checkfreq = drive_params[drive].checkfreq; in compat_getdrvprm()
3772 v.native_format = drive_params[drive].native_format; in compat_getdrvprm()
3776 return -EFAULT; in compat_getdrvprm()
3780 static int compat_getdrvstat(int drive, bool poll, in compat_getdrvstat() argument
3789 if (lock_fdc(drive)) in compat_getdrvstat()
3791 if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) in compat_getdrvstat()
3795 v.spinup_date = drive_state[drive].spinup_date; in compat_getdrvstat()
3796 v.select_date = drive_state[drive].select_date; in compat_getdrvstat()
3797 v.first_read_date = drive_state[drive].first_read_date; in compat_getdrvstat()
3798 v.probed_format = drive_state[drive].probed_format; in compat_getdrvstat()
3799 v.track = drive_state[drive].track; in compat_getdrvstat()
3800 v.maxblock = drive_state[drive].maxblock; in compat_getdrvstat()
3801 v.maxtrack = drive_state[drive].maxtrack; in compat_getdrvstat()
3802 v.generation = drive_state[drive].generation; in compat_getdrvstat()
3803 v.keep_data = drive_state[drive].keep_data; in compat_getdrvstat()
3804 v.fd_ref = drive_state[drive].fd_ref; in compat_getdrvstat()
3805 v.fd_device = drive_state[drive].fd_device; in compat_getdrvstat()
3806 v.last_checked = drive_state[drive].last_checked; in compat_getdrvstat()
3807 v.dmabuf = (uintptr_t) drive_state[drive].dmabuf; in compat_getdrvstat()
3808 v.bufblocks = drive_state[drive].bufblocks; in compat_getdrvstat()
3812 return -EFAULT; in compat_getdrvstat()
3816 return -EINTR; in compat_getdrvstat()
3819 static int compat_getfdcstat(int drive, in compat_getfdcstat() argument
3826 v = fdc_state[FDC(drive)]; in compat_getfdcstat()
3844 return -EFAULT; in compat_getfdcstat()
3848 static int compat_werrorget(int drive, in compat_werrorget() argument
3856 v = write_errors[drive]; in compat_werrorget()
3865 return -EFAULT; in compat_werrorget()
3872 int drive = (long)bdev->bd_disk->private_data; in fd_compat_ioctl() local
3874 case CDROMEJECT: /* CD-ROM eject */ in fd_compat_ioctl()
3900 return compat_get_prm(drive, compat_ptr(param)); in fd_compat_ioctl()
3902 return compat_setdrvprm(drive, compat_ptr(param)); in fd_compat_ioctl()
3904 return compat_getdrvprm(drive, compat_ptr(param)); in fd_compat_ioctl()
3906 return compat_getdrvstat(drive, true, compat_ptr(param)); in fd_compat_ioctl()
3908 return compat_getdrvstat(drive, false, compat_ptr(param)); in fd_compat_ioctl()
3910 return compat_getfdcstat(drive, compat_ptr(param)); in fd_compat_ioctl()
3912 return compat_werrorget(drive, compat_ptr(param)); in fd_compat_ioctl()
3914 return -EINVAL; in fd_compat_ioctl()
3921 int drive; in config_types() local
3923 /* read drive info out of physical CMOS */ in config_types()
3924 drive = 0; in config_types()
3925 if (!drive_params[drive].cmos) in config_types()
3926 drive_params[drive].cmos = FLOPPY0_TYPE; in config_types()
3927 drive = 1; in config_types()
3928 if (!drive_params[drive].cmos) in config_types()
3929 drive_params[drive].cmos = FLOPPY1_TYPE; in config_types()
3931 /* FIXME: additional physical CMOS drive detection should go here */ in config_types()
3933 for (drive = 0; drive < N_DRIVE; drive++) { in config_types()
3934 unsigned int type = drive_params[drive].cmos; in config_types()
3943 allowed_drive_mask |= 1 << drive; in config_types()
3945 allowed_drive_mask &= ~(1 << drive); in config_types()
3957 pr_info("Floppy drive(s):"); in config_types()
3962 pr_cont("%s fd%d is %s", prepend, drive, name); in config_types()
3964 drive_params[drive] = *params; in config_types()
3973 int drive = (long)disk->private_data; in floppy_release() local
3977 if (!drive_state[drive].fd_ref--) { in floppy_release()
3979 drive_state[drive].fd_ref = 0; in floppy_release()
3981 if (!drive_state[drive].fd_ref) in floppy_release()
3982 opened_disk[drive] = NULL; in floppy_release()
3990 * drive with different device numbers.
3994 int drive = (long)disk->private_data; in floppy_open() local
3997 int res = -EBUSY; in floppy_open()
4002 old_dev = drive_state[drive].fd_device; in floppy_open()
4003 if (opened_disk[drive] && opened_disk[drive] != disk) in floppy_open()
4006 if (!drive_state[drive].fd_ref && (drive_params[drive].flags & FD_BROKEN_DCL)) { in floppy_open()
4007 set_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags); in floppy_open()
4008 set_bit(FD_VERIFY_BIT, &drive_state[drive].flags); in floppy_open()
4011 drive_state[drive].fd_ref++; in floppy_open()
4013 opened_disk[drive] = disk; in floppy_open()
4015 res = -ENXIO; in floppy_open()
4018 /* if opening an ED drive, reserve a big buffer, in floppy_open()
4020 if ((drive_params[drive].cmos == 6) || (drive_params[drive].cmos == 5)) in floppy_open()
4041 buffer_min = buffer_max = -1; in floppy_open()
4047 new_dev = disk->first_minor; in floppy_open()
4048 drive_state[drive].fd_device = new_dev; in floppy_open()
4049 set_capacity(disks[drive][ITYPE(new_dev)], floppy_sizes[new_dev]); in floppy_open()
4050 if (old_dev != -1 && old_dev != new_dev) { in floppy_open()
4051 if (buffer_drive == drive) in floppy_open()
4052 buffer_track = -1; in floppy_open()
4055 if (fdc_state[FDC(drive)].rawcmd == 1) in floppy_open()
4056 fdc_state[FDC(drive)].rawcmd = 2; in floppy_open()
4059 drive_state[drive].last_checked = 0; in floppy_open()
4061 &drive_state[drive].flags); in floppy_open()
4064 if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags)) in floppy_open()
4066 if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags)) in floppy_open()
4069 res = -EROFS; in floppy_open()
4071 !test_bit(FD_DISK_WRITABLE_BIT, &drive_state[drive].flags)) in floppy_open()
4078 drive_state[drive].fd_ref--; in floppy_open()
4080 if (!drive_state[drive].fd_ref) in floppy_open()
4081 opened_disk[drive] = NULL; in floppy_open()
4094 int drive = (long)disk->private_data; in floppy_check_events() local
4096 if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags) || in floppy_check_events()
4097 test_bit(FD_VERIFY_BIT, &drive_state[drive].flags)) in floppy_check_events()
4100 if (time_after(jiffies, drive_state[drive].last_checked + drive_params[drive].checkfreq)) { in floppy_check_events()
4101 if (lock_fdc(drive)) in floppy_check_events()
4107 if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags) || in floppy_check_events()
4108 test_bit(FD_VERIFY_BIT, &drive_state[drive].flags) || in floppy_check_events()
4109 test_bit(drive, &fake_change) || in floppy_check_events()
4110 drive_no_geom(drive)) in floppy_check_events()
4118 * a disk in the drive, and whether that disk is writable.
4122 int drive; member
4128 struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private; in floppy_rb0_cb()
4129 int drive = cbdata->drive; in floppy_rb0_cb() local
4131 if (bio->bi_status) { in floppy_rb0_cb()
4133 bio->bi_status); in floppy_rb0_cb()
4134 set_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags); in floppy_rb0_cb()
4136 complete(&cbdata->complete); in floppy_rb0_cb()
4139 static int __floppy_read_block_0(struct block_device *bdev, int drive) in __floppy_read_block_0() argument
4149 return -ENOMEM; in __floppy_read_block_0()
4152 cbdata.drive = drive; in __floppy_read_block_0()
4174 /* revalidate the floppy disk, i.e. trigger format autodetection by reading
4176 * there is a disk in the drive at all... Thus we also do it for fixed
4180 int drive = (long)disk->private_data; in floppy_revalidate() local
4184 if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags) || in floppy_revalidate()
4185 test_bit(FD_VERIFY_BIT, &drive_state[drive].flags) || in floppy_revalidate()
4186 test_bit(drive, &fake_change) || in floppy_revalidate()
4187 drive_no_geom(drive)) { in floppy_revalidate()
4189 "VFS: revalidate called on non-open device.\n")) in floppy_revalidate()
4190 return -EFAULT; in floppy_revalidate()
4192 res = lock_fdc(drive); in floppy_revalidate()
4195 cf = (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags) || in floppy_revalidate()
4196 test_bit(FD_VERIFY_BIT, &drive_state[drive].flags)); in floppy_revalidate()
4197 if (!(cf || test_bit(drive, &fake_change) || drive_no_geom(drive))) { in floppy_revalidate()
4201 drive_state[drive].maxblock = 0; in floppy_revalidate()
4202 drive_state[drive].maxtrack = 0; in floppy_revalidate()
4203 if (buffer_drive == drive) in floppy_revalidate()
4204 buffer_track = -1; in floppy_revalidate()
4205 clear_bit(drive, &fake_change); in floppy_revalidate()
4206 clear_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags); in floppy_revalidate()
4208 drive_state[drive].generation++; in floppy_revalidate()
4209 if (drive_no_geom(drive)) { in floppy_revalidate()
4210 /* auto-sensing */ in floppy_revalidate()
4211 res = __floppy_read_block_0(opened_disk[drive]->part0, in floppy_revalidate()
4212 drive); in floppy_revalidate()
4219 set_capacity(disk, floppy_sizes[drive_state[drive].fd_device]); in floppy_revalidate()
4278 pr_info("FDC %d is a pre-1991 82077\n", fdc); in get_fdc_version()
4279 return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know in get_fdc_version()
4295 pr_info("FDC %d is a post-1991 82077\n", fdc); in get_fdc_version()
4300 /* Either a 82078-1 or a 82078SL running at 5Volt */ in get_fdc_version()
4323 int i; in floppy_set_flags() local
4325 for (i = 0; i < ARRAY_SIZE(default_drive_params); i++) { in floppy_set_flags()
4327 default_drive_params[i].params.flags |= param2; in floppy_set_flags()
4329 default_drive_params[i].params.flags &= ~param2; in floppy_set_flags()
4336 int i; in daring() local
4338 for (i = 0; i < ARRAY_SIZE(default_drive_params); i++) { in daring()
4340 default_drive_params[i].params.select_delay = 0; in daring()
4341 default_drive_params[i].params.flags |= in daring()
4344 default_drive_params[i].params.select_delay = in daring()
4346 default_drive_params[i].params.flags &= in daring()
4363 DPRINT("bad drive for set_cmos\n"); in set_cmos()
4413 int i; in floppy_setup() local
4419 for (i = 0; i < ARRAY_SIZE(config_params); i++) { in floppy_setup()
4420 if (strcmp(str, config_params[i].name) == 0) { in floppy_setup()
4424 param = config_params[i].def_param; in floppy_setup()
4425 if (config_params[i].fn) in floppy_setup()
4426 config_params[i].fn(ints, param, in floppy_setup()
4427 config_params[i]. in floppy_setup()
4429 if (config_params[i].var) { in floppy_setup()
4431 *config_params[i].var = param; in floppy_setup()
4441 for (i = 0; i < ARRAY_SIZE(config_params); i++) in floppy_setup()
4442 pr_cont(" %s", config_params[i].name); in floppy_setup()
4446 DPRINT("Read Documentation/admin-guide/blockdev/floppy.rst\n"); in floppy_setup()
4450 static int have_no_fdc = -ENODEV;
4456 int drive; in floppy_cmos_show() local
4458 drive = p->id; in floppy_cmos_show()
4459 return sprintf(buf, "%X\n", drive_params[drive].cmos); in floppy_cmos_show()
4482 if (fdc_state[fdc].address != -1) in floppy_resume()
4507 static bool floppy_available(int drive) in floppy_available() argument
4509 if (!(allowed_drive_mask & (1 << drive))) in floppy_available()
4511 if (fdc_state[FDC(drive)].version == FDC_NONE) in floppy_available()
4516 static int floppy_alloc_disk(unsigned int drive, unsigned int type) in floppy_alloc_disk() argument
4524 disk = blk_mq_alloc_disk(&tag_sets[drive], &lim, NULL); in floppy_alloc_disk()
4528 disk->major = FLOPPY_MAJOR; in floppy_alloc_disk()
4529 disk->first_minor = TOMINOR(drive) | (type << 2); in floppy_alloc_disk()
4530 disk->minors = 1; in floppy_alloc_disk()
4531 disk->fops = &floppy_fops; in floppy_alloc_disk()
4532 disk->flags |= GENHD_FL_NO_PART; in floppy_alloc_disk()
4533 disk->events = DISK_EVENT_MEDIA_CHANGE; in floppy_alloc_disk()
4535 sprintf(disk->disk_name, "fd%d_type%d", drive, type); in floppy_alloc_disk()
4537 sprintf(disk->disk_name, "fd%d", drive); in floppy_alloc_disk()
4539 disk->private_data = (void *)(long)drive; in floppy_alloc_disk()
4540 disk->flags |= GENHD_FL_REMOVABLE; in floppy_alloc_disk()
4542 disks[drive][type] = disk; in floppy_alloc_disk()
4550 unsigned int drive = (MINOR(dev) & 3) | ((MINOR(dev) & 0x80) >> 5); in floppy_probe() local
4553 if (drive >= N_DRIVE || !floppy_available(drive) || in floppy_probe()
4558 if (disks[drive][type]) in floppy_probe()
4560 if (floppy_alloc_disk(drive, type)) in floppy_probe()
4562 if (add_disk(disks[drive][type])) in floppy_probe()
4569 put_disk(disks[drive][type]); in floppy_probe()
4570 disks[drive][type] = NULL; in floppy_probe()
4576 int i, unit, drive, err; in do_floppy_init() local
4583 return -ENODEV; in do_floppy_init()
4590 return -ENOMEM; in do_floppy_init()
4592 for (drive = 0; drive < N_DRIVE; drive++) { in do_floppy_init()
4593 memset(&tag_sets[drive], 0, sizeof(tag_sets[drive])); in do_floppy_init()
4594 tag_sets[drive].ops = &floppy_mq_ops; in do_floppy_init()
4595 tag_sets[drive].nr_hw_queues = 1; in do_floppy_init()
4596 tag_sets[drive].nr_maps = 1; in do_floppy_init()
4597 tag_sets[drive].queue_depth = 2; in do_floppy_init()
4598 tag_sets[drive].numa_node = NUMA_NO_NODE; in do_floppy_init()
4599 tag_sets[drive].flags = BLK_MQ_F_SHOULD_MERGE; in do_floppy_init()
4600 err = blk_mq_alloc_tag_set(&tag_sets[drive]); in do_floppy_init()
4604 err = floppy_alloc_disk(drive, 0); in do_floppy_init()
4606 blk_mq_free_tag_set(&tag_sets[drive]); in do_floppy_init()
4610 timer_setup(&motor_off_timer[drive], motor_off_callback, 0); in do_floppy_init()
4621 for (i = 0; i < 256; i++) in do_floppy_init()
4622 if (ITYPE(i)) in do_floppy_init()
4623 floppy_sizes[i] = floppy_type[ITYPE(i)].size; in do_floppy_init()
4625 floppy_sizes[i] = MAX_DISK_SIZE << 1; in do_floppy_init()
4630 for (i = 0; i < N_FDC; i++) { in do_floppy_init()
4631 memset(&fdc_state[i], 0, sizeof(*fdc_state)); in do_floppy_init()
4632 fdc_state[i].dtr = -1; in do_floppy_init()
4633 fdc_state[i].dor = 0x4; in do_floppy_init()
4639 fdc_state[i].version = FDC_82072A; in do_floppy_init()
4645 if (fdc_state[0].address == -1) { in do_floppy_init()
4647 err = -ENODEV; in do_floppy_init()
4658 err = -EBUSY; in do_floppy_init()
4662 /* initialise drive state */ in do_floppy_init()
4663 for (drive = 0; drive < N_DRIVE; drive++) { in do_floppy_init()
4664 memset(&drive_state[drive], 0, sizeof(drive_state[drive])); in do_floppy_init()
4665 memset(&write_errors[drive], 0, sizeof(write_errors[drive])); in do_floppy_init()
4666 set_bit(FD_DISK_NEWCHANGE_BIT, &drive_state[drive].flags); in do_floppy_init()
4667 set_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags); in do_floppy_init()
4668 set_bit(FD_VERIFY_BIT, &drive_state[drive].flags); in do_floppy_init()
4669 drive_state[drive].fd_device = -1; in do_floppy_init()
4680 for (i = 0; i < N_FDC; i++) { in do_floppy_init()
4681 fdc_state[i].driver_version = FD_DRIVER_VERSION; in do_floppy_init()
4683 fdc_state[i].track[unit] = 0; in do_floppy_init()
4684 if (fdc_state[i].address == -1) in do_floppy_init()
4686 fdc_state[i].rawcmd = 2; in do_floppy_init()
4687 if (user_reset_fdc(REVDRIVE(i, 0), FD_RESET_ALWAYS, false)) { in do_floppy_init()
4689 floppy_release_regions(i); in do_floppy_init()
4690 fdc_state[i].address = -1; in do_floppy_init()
4691 fdc_state[i].version = FDC_NONE; in do_floppy_init()
4695 fdc_state[i].version = get_fdc_version(i); in do_floppy_init()
4696 if (fdc_state[i].version == FDC_NONE) { in do_floppy_init()
4698 floppy_release_regions(i); in do_floppy_init()
4699 fdc_state[i].address = -1; in do_floppy_init()
4703 fdc_state[i].version < FDC_82072A) in do_floppy_init()
4711 user_reset_fdc(REVDRIVE(i, 0), FD_RESET_ALWAYS, false); in do_floppy_init()
4723 for (drive = 0; drive < N_DRIVE; drive++) { in do_floppy_init()
4724 if (!floppy_available(drive)) in do_floppy_init()
4727 floppy_device[drive].name = floppy_device_name; in do_floppy_init()
4728 floppy_device[drive].id = drive; in do_floppy_init()
4729 floppy_device[drive].dev.release = floppy_device_release; in do_floppy_init()
4730 floppy_device[drive].dev.groups = floppy_dev_groups; in do_floppy_init()
4732 err = platform_device_register(&floppy_device[drive]); in do_floppy_init()
4736 registered[drive] = true; in do_floppy_init()
4738 err = device_add_disk(&floppy_device[drive].dev, in do_floppy_init()
4739 disks[drive][0], NULL); in do_floppy_init()
4747 while (drive--) { in do_floppy_init()
4748 if (floppy_available(drive)) { in do_floppy_init()
4749 del_gendisk(disks[drive][0]); in do_floppy_init()
4750 if (registered[drive]) in do_floppy_init()
4751 platform_device_unregister(&floppy_device[drive]); in do_floppy_init()
4763 for (drive = 0; drive < N_DRIVE; drive++) { in do_floppy_init()
4764 if (!disks[drive][0]) in do_floppy_init()
4766 del_timer_sync(&motor_off_timer[drive]); in do_floppy_init()
4767 put_disk(disks[drive][0]); in do_floppy_init()
4768 blk_mq_free_tag_set(&tag_sets[drive]); in do_floppy_init()
4799 * Unfortunately, Adaptec doesn't know this :-(, */
4806 p--; in floppy_release_allocated_regions()
4807 release_region(fdc_state[fdc].address + p->offset, p->size); in floppy_release_allocated_regions()
4818 if (!request_region(fdc_state[fdc].address + p->offset, in floppy_request_regions()
4819 p->size, "floppy")) { in floppy_request_regions()
4820 DPRINT("Floppy io-port 0x%04lx in use\n", in floppy_request_regions()
4821 fdc_state[fdc].address + p->offset); in floppy_request_regions()
4823 return -EBUSY; in floppy_request_regions()
4851 return -1; in floppy_grab_irq_and_dma()
4861 return -1; in floppy_grab_irq_and_dma()
4866 if (fdc_state[fdc].address != -1) { in floppy_grab_irq_and_dma()
4872 if (fdc_state[fdc].address != -1) { in floppy_grab_irq_and_dma()
4881 if (fdc_state[fdc].address != -1) in floppy_grab_irq_and_dma()
4893 while (--fdc >= 0) in floppy_grab_irq_and_dma()
4897 return -1; in floppy_grab_irq_and_dma()
4904 int drive; in floppy_release_irq_and_dma() local
4928 buffer_min = buffer_max = -1; in floppy_release_irq_and_dma()
4932 for (drive = 0; drive < N_FDC * 4; drive++) in floppy_release_irq_and_dma()
4933 if (timer_pending(motor_off_timer + drive)) in floppy_release_irq_and_dma()
4934 pr_info("motor off timer %d still active\n", drive); in floppy_release_irq_and_dma()
4944 if (fdc_state[fdc].address != -1) in floppy_release_irq_and_dma()
4979 int drive, i; in floppy_module_exit() local
4986 for (drive = 0; drive < N_DRIVE; drive++) { in floppy_module_exit()
4987 del_timer_sync(&motor_off_timer[drive]); in floppy_module_exit()
4989 if (floppy_available(drive)) { in floppy_module_exit()
4990 for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { in floppy_module_exit()
4991 if (disks[drive][i]) in floppy_module_exit()
4992 del_gendisk(disks[drive][i]); in floppy_module_exit()
4994 if (registered[drive]) in floppy_module_exit()
4995 platform_device_unregister(&floppy_device[drive]); in floppy_module_exit()
4997 for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { in floppy_module_exit()
4998 if (disks[drive][i]) in floppy_module_exit()
4999 put_disk(disks[drive][i]); in floppy_module_exit()
5001 blk_mq_free_tag_set(&tag_sets[drive]); in floppy_module_exit()