Lines Matching +full:mips +full:- +full:cpc
1 // SPDX-License-Identifier: GPL-2.0-only
11 * 02.12.91 - Changed to static variables to indicate need for reset
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
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
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 <[email protected]> -- 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
128 * 2000/08/28 -- Arnaldo Carvalho de Melo <[email protected]>
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 <[email protected]>.
245 * some ports reference this variable from there. -DaveM
254 #include <linux/blk-mq.h>
307 #define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2)
308 #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
373 | | | | | | | | | | | | | -Max Errors- flags */
394 /* | --autodetected formats--- | | |
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
426 * For Amstrad CPC disks it is 0xC1 (represented as 0xC0<<2).
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;
612 return -EINVAL; in fd_eject()
631 pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer); in debugt()
669 #define MAXTIMEOUT -2
704 * and also the main service loop (seek-configure-spinup-command)
799 if (fdc_state[fdc].address == -1) in set_dor()
800 return -1; in set_dor()
842 fdc_state[fdc].spec1 = fdc_state[fdc].spec2 = -1; in reset_fdc_info()
873 set_dor(1 - fdc, ~8, 0); in set_fdc()
892 return -1; in lock_fdc()
895 return -EINTR; in lock_fdc()
922 unsigned long nr = t - motor_off_timer; in motor_off_callback()
945 delta = jiffies - drive_state[drive].first_read_date + HZ - in floppy_off()
949 jiffies + drive_params[drive].spindown - delta; in floppy_off()
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()
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
1300 switch (raw_cmd->rate & 0x03) { in fdc_specify()
1328 srt = 16 - DIV_ROUND_UP(drive_params[drive].srt * scale_dtr / 1000, in fdc_specify()
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()
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()
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()
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()
1606 disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { 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()
1668 * computers possessed by the Devil :-) */ in recal_interrupt()
1669 cont->error(); in recal_interrupt()
1670 cont->redo(); in recal_interrupt()
1729 if (current_fdc >= N_FDC || fdc_state[current_fdc].address == -1) { in floppy_interrupt()
1760 max_sensei--; in floppy_interrupt()
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()
1835 pr_info("-------------------\n"); in show_floppy()
1837 jiffies, interruptjiffies, jiffies - interruptjiffies, in show_floppy()
1861 fd_timer.timer.expires - jiffies); in show_floppy()
1865 fd_timeout.timer.expires - jiffies); in show_floppy()
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()
1942 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && 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()
2103 cont->done(0); in bad_flp_intr()
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()
2233 return -EINTR; 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()
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()
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()
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()
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(¤t_req->queuelist); in set_next_request()
2794 drive = (long)current_req->q->disk->private_data; 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()
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()
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()
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()
3194 return -EINVAL; in floppy_raw_cmd_ioctl()
3196 return -EINTR; in floppy_raw_cmd_ioctl()
3199 if (ret == -EINTR) in floppy_raw_cmd_ioctl()
3200 return -EINTR; in floppy_raw_cmd_ioctl()
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()
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()
3249 return -EINTR; 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()
3283 drive_state[current_drive].keep_data = -1; in set_geometry()
3295 invalidate_drive(bdev->bd_disk); in set_geometry()
3341 return -EFAULT; in normalize_ioctl()
3346 return -EINVAL; in normalize_ioctl()
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()
3362 return -ENODEV; in get_floppy_geometry()
3368 int drive = (long)bdev->bd_disk->private_data; 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()
3404 int drive = (long)bdev->bd_disk->private_data; 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()
3455 return -EBUSY; in fd_locked_ioctl()
3457 return -EINTR; in fd_locked_ioctl()
3460 * non-Sparc architectures */ in fd_locked_ioctl()
3469 return -EINTR; in fd_locked_ioctl()
3473 return invalidate_drive(bdev->bd_disk); 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()
3500 return -ENODEV; in fd_locked_ioctl()
3502 return -EROFS; in fd_locked_ioctl()
3506 return -EBUSY; in fd_locked_ioctl()
3511 return -EINTR; in fd_locked_ioctl()
3512 return invalidate_drive(bdev->bd_disk); in fd_locked_ioctl()
3529 return -EINVAL; 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()
3560 return -EINTR; in fd_locked_ioctl()
3565 return -EINVAL; in fd_locked_ioctl()
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()
3706 return -EFAULT; in compat_get_prm()
3716 return -EPERM; in compat_setdrvprm()
3718 return -EFAULT; in compat_setdrvprm()
3720 return -EINVAL; in compat_setdrvprm()
3776 return -EFAULT; in compat_getdrvprm()
3791 if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) in compat_getdrvstat()
3812 return -EFAULT; in compat_getdrvstat()
3816 return -EINTR; in compat_getdrvstat()
3844 return -EFAULT; in compat_getfdcstat()
3865 return -EFAULT; in compat_werrorget()
3872 int drive = (long)bdev->bd_disk->private_data; in fd_compat_ioctl()
3874 case CDROMEJECT: /* CD-ROM eject */ in fd_compat_ioctl()
3914 return -EINVAL; in fd_compat_ioctl()
3973 int drive = (long)disk->private_data; in floppy_release()
3977 if (!drive_state[drive].fd_ref--) { in floppy_release()
3994 int drive = (long)disk->private_data; in floppy_open()
3997 int res = -EBUSY; in floppy_open()
4015 res = -ENXIO; in floppy_open()
4041 buffer_min = buffer_max = -1; in floppy_open()
4047 new_dev = disk->first_minor; in floppy_open()
4050 if (old_dev != -1 && old_dev != new_dev) { in floppy_open()
4052 buffer_track = -1; in floppy_open()
4069 res = -EROFS; in floppy_open()
4078 drive_state[drive].fd_ref--; in floppy_open()
4094 int drive = (long)disk->private_data; in floppy_check_events()
4128 struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private; in floppy_rb0_cb()
4129 int drive = cbdata->drive; in floppy_rb0_cb()
4131 if (bio->bi_status) { in floppy_rb0_cb()
4133 bio->bi_status); in floppy_rb0_cb()
4136 complete(&cbdata->complete); in floppy_rb0_cb()
4149 return -ENOMEM; in __floppy_read_block_0()
4180 int drive = (long)disk->private_data; in floppy_revalidate()
4189 "VFS: revalidate called on non-open device.\n")) in floppy_revalidate()
4190 return -EFAULT; in floppy_revalidate()
4204 buffer_track = -1; in floppy_revalidate()
4210 /* auto-sensing */ in floppy_revalidate()
4211 res = __floppy_read_block_0(opened_disk[drive]->part0, 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()
4446 DPRINT("Read Documentation/admin-guide/blockdev/floppy.rst\n"); in floppy_setup()
4450 static int have_no_fdc = -ENODEV;
4458 drive = p->id; in floppy_cmos_show()
4482 if (fdc_state[fdc].address != -1) in floppy_resume()
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()
4583 return -ENODEV; in do_floppy_init()
4590 return -ENOMEM; in do_floppy_init()
4631 fdc_state[i].dtr = -1; in do_floppy_init()
4644 if (fdc_state[0].address == -1) { in do_floppy_init()
4646 err = -ENODEV; in do_floppy_init()
4657 err = -EBUSY; in do_floppy_init()
4668 drive_state[drive].fd_device = -1; in do_floppy_init()
4683 if (fdc_state[i].address == -1) in do_floppy_init()
4689 fdc_state[i].address = -1; in do_floppy_init()
4698 fdc_state[i].address = -1; in do_floppy_init()
4746 while (drive--) { in do_floppy_init()
4798 * Unfortunately, Adaptec doesn't know this :-(, */
4805 p--; in floppy_release_allocated_regions()
4806 release_region(fdc_state[fdc].address + p->offset, p->size); in floppy_release_allocated_regions()
4817 if (!request_region(fdc_state[fdc].address + p->offset, in floppy_request_regions()
4818 p->size, "floppy")) { in floppy_request_regions()
4819 DPRINT("Floppy io-port 0x%04lx in use\n", in floppy_request_regions()
4820 fdc_state[fdc].address + p->offset); in floppy_request_regions()
4822 return -EBUSY; in floppy_request_regions()
4850 return -1; in floppy_grab_irq_and_dma()
4860 return -1; in floppy_grab_irq_and_dma()
4865 if (fdc_state[fdc].address != -1) { in floppy_grab_irq_and_dma()
4871 if (fdc_state[fdc].address != -1) { in floppy_grab_irq_and_dma()
4880 if (fdc_state[fdc].address != -1) in floppy_grab_irq_and_dma()
4892 while (--fdc >= 0) in floppy_grab_irq_and_dma()
4896 return -1; in floppy_grab_irq_and_dma()
4927 buffer_min = buffer_max = -1; in floppy_release_irq_and_dma()
4943 if (fdc_state[fdc].address != -1) in floppy_release_irq_and_dma()