^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the SWIM3 (Super Woz Integrated Machine 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * floppy controller found on Power Macintoshes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1996 Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * handle 2 drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * handle GCR disks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/fd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/blk-mq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/dbdma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/mediabay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/pmac_feature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MAX_FLOPPIES 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static DEFINE_MUTEX(swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct gendisk *disks[MAX_FLOPPIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) enum swim_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) locating,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) seeking,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) settling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) do_transfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) jogging,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) revalidating,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ejecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define REG(x) unsigned char x; char x ## _pad[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * The names for these registers mostly represent speculation on my part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * It will be interesting to see how close they are to the names Apple uses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct swim3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) REG(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) REG(timer); /* counts down at 1MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) REG(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) REG(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) REG(select); /* controls CA0, CA1, CA2 and LSTRB signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) REG(setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) REG(control); /* writing bits clears them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) REG(status); /* writing bits sets them in control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) REG(intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) REG(nseek); /* # tracks to seek */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) REG(ctrack); /* current track number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) REG(csect); /* current sector number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) REG(gap3); /* size of gap 3 in track format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) REG(sector); /* sector # to read or write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) REG(nsect); /* # sectors to read or write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) REG(intr_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define control_bic control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define control_bis status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Bits in select register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define CA_MASK 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define LSTRB 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Bits in control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define DO_SEEK 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FORMAT 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SELECT 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define WRITE_SECTORS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define DO_ACTION 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define DRIVE2_ENABLE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define DRIVE_ENABLE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define INTR_ENABLE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Bits in status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define FIFO_1BYTE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define FIFO_2BYTE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ERROR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define DATA 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define RDDATA 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define INTR_PENDING 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MARK_BYTE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Bits in intr and intr_enable registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ERROR_INTR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define DATA_CHANGED 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define TRANSFER_DONE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define SEEN_SECTOR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define SEEK_DONE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define TIMER_DONE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Bits in error register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define ERR_DATA_CRC 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define ERR_ADDR_CRC 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define ERR_OVERRUN 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ERR_UNDERRUN 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Bits in setup register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define S_SW_RESET 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define S_GCR_WRITE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define S_IBM_DRIVE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define S_TEST_MODE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define S_FCLK_DIV2 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define S_GCR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define S_COPY_PROT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define S_INV_WDATA 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Select values for swim3_action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define SEEK_POSITIVE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define SEEK_NEGATIVE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define MOTOR_ON 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define MOTOR_OFF 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define INDEX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define EJECT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SETMFM 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SETGCR 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Select values for swim3_select and swim3_readbit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define STEP_DIR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define STEPPING 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define MOTOR_ON 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define RELAX 3 /* also eject in progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define READ_DATA_0 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define ONEMEG_DRIVE 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define SINGLE_SIDED 6 /* drive or diskette is 4MB type? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define DRIVE_PRESENT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define DISK_IN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define WRITE_PROT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define TRACK_ZERO 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define TACHO 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define READ_DATA_1 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define GCR_MODE 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define SEEK_COMPLETE 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define TWOMEG_MEDIA 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Definitions of values used in writing and formatting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define DATA_ESCAPE 0x99
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define GCR_SYNC_EXC 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define GCR_SYNC_CONV 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define GCR_FIRST_MARK 0xd5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define GCR_SECOND_MARK 0xaa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define GCR_ADDR_MARK "\xd5\xaa\x00"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define GCR_DATA_MARK "\xd5\xaa\x0b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define GCR_SLIP_BYTE "\x27\xaa"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define GCR_SELF_SYNC "\x3f\xbf\x1e\x34\x3c\x3f"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define DATA_99 "\x99\x99"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define MFM_ADDR_MARK "\x99\xa1\x99\xa1\x99\xa1\x99\xfe"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define MFM_INDEX_MARK "\x99\xc2\x99\xc2\x99\xc2\x99\xfc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define MFM_GAP_LEN 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct floppy_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) enum swim_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct swim3 __iomem *swim3; /* hardware registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct dbdma_regs __iomem *dma; /* DMA controller registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int swim3_intr; /* interrupt number for SWIM3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int dma_intr; /* interrupt number for DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int cur_cyl; /* cylinder head is on, or -1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int cur_sector; /* last sector we saw go past */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int req_cyl; /* the cylinder for the current r/w request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int head; /* head number ditto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int req_sector; /* sector number ditto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int scount; /* # sectors we're transferring at present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int secpercyl; /* disk geometry information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int secpertrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int total_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int write_prot; /* 1 if write-protected, 0 if not, -1 dunno */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct dbdma_cmd *dma_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int expect_cyl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct timer_list timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int timeout_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int ejected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) wait_queue_head_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct macio_dev *mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct request *cur_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct blk_mq_tag_set tag_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define swim3_err(fmt, arg...) dev_err(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define swim3_warn(fmt, arg...) dev_warn(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define swim3_info(fmt, arg...) dev_info(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define swim3_dbg(fmt, arg...) dev_dbg(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define swim3_dbg(fmt, arg...) do { } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static struct floppy_state floppy_states[MAX_FLOPPIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int floppy_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static DEFINE_SPINLOCK(swim3_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static unsigned short write_preamble[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, /* gap field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 0, 0, 0, 0, 0, 0, /* sync field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 0x99a1, 0x99a1, 0x99a1, 0x99fb, /* data address mark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 0x990f /* no escape for 512 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static unsigned short write_postamble[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 0x9904, /* insert CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 0x4e4e, 0x4e4e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 0x9908, /* stop writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 0, 0, 0, 0, 0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void seek_track(struct floppy_state *fs, int n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void act(struct floppy_state *fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static void scan_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void seek_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static void settle_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static void xfer_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static irqreturn_t swim3_interrupt(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /*static void fd_dma_interrupt(int irq, void *dev_id);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int grab_drive(struct floppy_state *fs, enum swim_state state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int interruptible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void release_drive(struct floppy_state *fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int fd_eject(struct floppy_state *fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned int cmd, unsigned long param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int floppy_open(struct block_device *bdev, fmode_t mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static void floppy_release(struct gendisk *disk, fmode_t mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static unsigned int floppy_check_events(struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unsigned int clearing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static int floppy_revalidate(struct gendisk *disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static bool swim3_end_request(struct floppy_state *fs, blk_status_t err, unsigned int nr_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct request *req = fs->cur_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) swim3_dbg(" end request, err=%d nr_bytes=%d, cur_req=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) err, nr_bytes, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) nr_bytes = blk_rq_cur_bytes(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (blk_update_request(req, err, nr_bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) __blk_mq_end_request(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) fs->cur_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static void swim3_select(struct floppy_state *fs, int sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (sel & 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) out_8(&sw->control_bis, SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) out_8(&sw->control_bic, SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) out_8(&sw->select, sel & CA_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void swim3_action(struct floppy_state *fs, int action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) swim3_select(fs, action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) out_8(&sw->select, sw->select | LSTRB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) out_8(&sw->select, sw->select & ~LSTRB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int swim3_readbit(struct floppy_state *fs, int bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) swim3_select(fs, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) stat = in_8(&sw->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return (stat & DATA) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static blk_status_t swim3_queue_rq(struct blk_mq_hw_ctx *hctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) const struct blk_mq_queue_data *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct floppy_state *fs = hctx->queue->queuedata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct request *req = bd->rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned long x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) spin_lock_irq(&swim3_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (fs->cur_req || fs->state != idle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) spin_unlock_irq(&swim3_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return BLK_STS_DEV_RESOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) blk_mq_start_request(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) fs->cur_req = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (fs->mdev->media_bay &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) check_media_bay(fs->mdev->media_bay) != MB_FD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) swim3_dbg("%s", " media bay absent, dropping req\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (fs->ejected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) swim3_dbg("%s", " disk ejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (rq_data_dir(req) == WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (fs->write_prot < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) fs->write_prot = swim3_readbit(fs, WRITE_PROT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (fs->write_prot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) swim3_dbg("%s", " try to write, disk write protected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Do not remove the cast. blk_rq_pos(req) is now a sector_t and can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * 64 bits, but it will never go past 32 bits for this driver anyway, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * we can safely cast it down and not have to do a 64/32 division
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) fs->req_cyl = ((long)blk_rq_pos(req)) / fs->secpercyl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) x = ((long)blk_rq_pos(req)) % fs->secpercyl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) fs->head = x / fs->secpertrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) fs->req_sector = x % fs->secpertrack + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) fs->state = do_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) fs->retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) spin_unlock_irq(&swim3_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return BLK_STS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static void set_timeout(struct floppy_state *fs, int nticks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) void (*proc)(struct timer_list *t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (fs->timeout_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) del_timer(&fs->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) fs->timeout.expires = jiffies + nticks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) fs->timeout.function = proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) add_timer(&fs->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) fs->timeout_pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static inline void scan_track(struct floppy_state *fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) swim3_select(fs, READ_DATA_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) in_8(&sw->intr); /* clear SEEN_SECTOR bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) in_8(&sw->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) out_8(&sw->intr_enable, SEEN_SECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) out_8(&sw->control_bis, DO_ACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* enable intr when track found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) set_timeout(fs, HZ, scan_timeout); /* enable timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static inline void seek_track(struct floppy_state *fs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (n >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) swim3_action(fs, SEEK_POSITIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) sw->nseek = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) swim3_action(fs, SEEK_NEGATIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) sw->nseek = -n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) fs->expect_cyl = (fs->cur_cyl >= 0)? fs->cur_cyl + n: -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) swim3_select(fs, STEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) in_8(&sw->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* enable intr when seek finished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) out_8(&sw->intr_enable, SEEK_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) out_8(&sw->control_bis, DO_SEEK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) set_timeout(fs, 3*HZ, seek_timeout); /* enable timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) fs->settle_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static inline void init_dma(struct dbdma_cmd *cp, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) void *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cp->req_count = cpu_to_le16(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) cp->command = cpu_to_le16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) cp->phy_addr = cpu_to_le32(virt_to_bus(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) cp->xfer_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static inline void setup_transfer(struct floppy_state *fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct dbdma_cmd *cp = fs->dma_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct dbdma_regs __iomem *dr = fs->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct request *req = fs->cur_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (blk_rq_cur_sectors(req) <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) swim3_warn("%s", "Transfer 0 sectors ?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (rq_data_dir(req) == WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) n = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) n = fs->secpertrack - fs->req_sector + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (n > blk_rq_cur_sectors(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) n = blk_rq_cur_sectors(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) swim3_dbg(" setup xfer at sect %d (of %d) head %d for %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) fs->req_sector, fs->secpertrack, fs->head, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) fs->scount = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) out_8(&sw->sector, fs->req_sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) out_8(&sw->nsect, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) out_8(&sw->gap3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) out_le32(&dr->cmdptr, virt_to_bus(cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (rq_data_dir(req) == WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* Set up 3 dma commands: write preamble, data, postamble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) init_dma(cp, OUTPUT_MORE, bio_data(req->bio), 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) init_dma(cp, OUTPUT_LAST, write_postamble, sizeof(write_postamble));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) init_dma(cp, INPUT_LAST, bio_data(req->bio), n * 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) out_le16(&cp->command, DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) in_8(&sw->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (rq_data_dir(req) == WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) out_8(&sw->control_bis, WRITE_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) in_8(&sw->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) out_le32(&dr->control, (RUN << 16) | RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* enable intr when transfer complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) out_8(&sw->intr_enable, TRANSFER_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) out_8(&sw->control_bis, DO_ACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) set_timeout(fs, 2*HZ, xfer_timeout); /* enable timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static void act(struct floppy_state *fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) swim3_dbg(" act loop, state=%d, req_cyl=%d, cur_cyl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) fs->state, fs->req_cyl, fs->cur_cyl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) switch (fs->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case idle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return; /* XXX shouldn't get here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case locating:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (swim3_readbit(fs, TRACK_ZERO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) swim3_dbg("%s", " locate track 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) fs->cur_cyl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (fs->req_cyl == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) fs->state = do_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) fs->state = seeking;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) scan_track(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case seeking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (fs->cur_cyl < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) fs->expect_cyl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) fs->state = locating;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (fs->req_cyl == fs->cur_cyl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) swim3_warn("%s", "Whoops, seeking 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) fs->state = do_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) seek_track(fs, fs->req_cyl - fs->cur_cyl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case settling:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* check for SEEK_COMPLETE after 30ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) fs->settle_time = (HZ + 32) / 33;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) set_timeout(fs, fs->settle_time, settle_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) case do_transfer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (fs->cur_cyl != fs->req_cyl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (fs->retries > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) swim3_err("Wrong cylinder in transfer, want: %d got %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) fs->req_cyl, fs->cur_cyl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) fs->state = seeking;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) setup_transfer(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) case jogging:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) seek_track(fs, -5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) swim3_err("Unknown state %d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void scan_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct floppy_state *fs = from_timer(fs, t, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) swim3_dbg("* scan timeout, state=%d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) fs->cur_cyl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (fs->retries > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) fs->state = jogging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static void seek_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct floppy_state *fs = from_timer(fs, t, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) swim3_dbg("* seek timeout, state=%d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) out_8(&sw->control_bic, DO_SEEK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) swim3_err("%s", "Seek timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static void settle_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct floppy_state *fs = from_timer(fs, t, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) swim3_dbg("* settle timeout, state=%d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (swim3_readbit(fs, SEEK_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) fs->state = locating;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (fs->settle_time < 2*HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ++fs->settle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) set_timeout(fs, 1, settle_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) swim3_err("%s", "Seek settle timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void xfer_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct floppy_state *fs = from_timer(fs, t, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct dbdma_regs __iomem *dr = fs->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) swim3_dbg("* xfer timeout, state=%d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) out_le32(&dr->control, RUN << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* We must wait a bit for dbdma to stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for (n = 0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) swim3_err("Timeout %sing sector %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) (rq_data_dir(fs->cur_req)==WRITE? "writ": "read"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) (long)blk_rq_pos(fs->cur_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static irqreturn_t swim3_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct floppy_state *fs = (struct floppy_state *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int intr, err, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int stat, resid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct dbdma_regs __iomem *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct dbdma_cmd *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct request *req = fs->cur_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) swim3_dbg("* interrupt, state=%d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) intr = in_8(&sw->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if ((intr & ERROR_INTR) && fs->state != do_transfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) swim3_err("Non-transfer error interrupt: state=%d, dir=%x, intr=%x, err=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) fs->state, rq_data_dir(req), intr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) switch (fs->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case locating:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (intr & SEEN_SECTOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) del_timer(&fs->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (sw->ctrack == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) swim3_err("%s", "Seen sector but cyl=ff?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) fs->cur_cyl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (fs->retries > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) fs->state = jogging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) fs->cur_cyl = sw->ctrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) fs->cur_sector = sw->csect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (fs->expect_cyl != -1 && fs->expect_cyl != fs->cur_cyl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) swim3_err("Expected cyl %d, got %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) fs->expect_cyl, fs->cur_cyl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) fs->state = do_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) case seeking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case jogging:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (sw->nseek == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) out_8(&sw->control_bic, DO_SEEK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) del_timer(&fs->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (fs->state == seeking)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ++fs->retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) fs->state = settling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case settling:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) del_timer(&fs->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case do_transfer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if ((intr & (ERROR_INTR | TRANSFER_DONE)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) out_8(&sw->select, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) del_timer(&fs->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) fs->timeout_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) dr = fs->dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) cp = fs->dma_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (rq_data_dir(req) == WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * Check that the main data transfer has finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * On writing, the swim3 sometimes doesn't use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * up all the bytes of the postamble, so we can still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * see DMA active here. That doesn't matter as long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * as all the sector data has been transferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if ((intr & ERROR_INTR) == 0 && cp->xfer_status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* wait a little while for DMA to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) for (n = 0; n < 100; ++n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (cp->xfer_status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* turn off DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) out_le32(&dr->control, (RUN | PAUSE) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) stat = le16_to_cpu(cp->xfer_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) resid = le16_to_cpu(cp->res_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (intr & ERROR_INTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) n = fs->scount - 1 - resid / 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (n > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) blk_update_request(req, 0, n << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) fs->req_sector += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (fs->retries < 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ++fs->retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) swim3_err("Error %sing block %ld (err=%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) rq_data_dir(req) == WRITE? "writ": "read",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) (long)blk_rq_pos(req), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if ((stat & ACTIVE) == 0 || resid != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* musta been an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) swim3_err("fd dma error: stat=%x resid=%d\n", stat, resid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) swim3_err(" state=%d, dir=%x, intr=%x, err=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) fs->state, rq_data_dir(req), intr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) swim3_end_request(fs, BLK_STS_IOERR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) fs->retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (swim3_end_request(fs, 0, fs->scount << 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) fs->req_sector += fs->scount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (fs->req_sector > fs->secpertrack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) fs->req_sector -= fs->secpertrack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (++fs->head > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) fs->head = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ++fs->req_cyl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) act(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) swim3_err("Don't know what to do in state %d\n", fs->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static void fd_dma_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* Called under the mutex to grab exclusive access to a drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static int grab_drive(struct floppy_state *fs, enum swim_state state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int interruptible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) swim3_dbg("%s", "-> grab drive\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (fs->state != idle && fs->state != available) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ++fs->wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* this will enable irqs in order to sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (!interruptible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) wait_event_lock_irq(fs->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) fs->state == available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) swim3_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) else if (wait_event_interruptible_lock_irq(fs->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) fs->state == available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) swim3_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) --fs->wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) --fs->wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) fs->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static void release_drive(struct floppy_state *fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct request_queue *q = disks[fs->index]->queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) swim3_dbg("%s", "-> release drive\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) spin_lock_irqsave(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) spin_unlock_irqrestore(&swim3_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) blk_mq_freeze_queue(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) blk_mq_quiesce_queue(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) blk_mq_unquiesce_queue(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) blk_mq_unfreeze_queue(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static int fd_eject(struct floppy_state *fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) int err, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) err = grab_drive(fs, ejecting, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) swim3_action(fs, EJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) for (n = 20; n > 0; --n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) err = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) schedule_timeout_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (swim3_readbit(fs, DISK_IN) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) udelay(150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) fs->ejected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) release_drive(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static struct floppy_struct floppy_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static int floppy_locked_ioctl(struct block_device *bdev, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) unsigned int cmd, unsigned long param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct floppy_state *fs = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (fs->mdev->media_bay &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) check_media_bay(fs->mdev->media_bay) != MB_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) case FDEJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (fs->ref_count != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) err = fd_eject(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) case FDGETPRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (copy_to_user((void __user *) param, &floppy_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) sizeof(struct floppy_struct)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) unsigned int cmd, unsigned long param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) mutex_lock(&swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ret = floppy_locked_ioctl(bdev, mode, cmd, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) mutex_unlock(&swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static int floppy_open(struct block_device *bdev, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct floppy_state *fs = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int n, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (fs->ref_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (fs->mdev->media_bay &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) check_media_bay(fs->mdev->media_bay) != MB_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) out_8(&sw->control_bic, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) out_8(&sw->mode, 0x95);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) swim3_action(fs, MOTOR_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) fs->write_prot = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) fs->cur_cyl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) for (n = 0; n < 2 * HZ; ++n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (n >= HZ/30 && swim3_readbit(fs, SEEK_COMPLETE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) err = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) schedule_timeout_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) || swim3_readbit(fs, DISK_IN) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) swim3_action(fs, SETMFM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) } else if (fs->ref_count == -1 || mode & FMODE_EXCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (err == 0 && (mode & FMODE_NDELAY) == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) && (mode & (FMODE_READ|FMODE_WRITE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (bdev_check_media_change(bdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) floppy_revalidate(bdev->bd_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (fs->ejected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (err == 0 && (mode & FMODE_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (fs->write_prot < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) fs->write_prot = swim3_readbit(fs, WRITE_PROT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (fs->write_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) err = -EROFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (fs->ref_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) swim3_action(fs, MOTOR_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) out_8(&sw->control_bic, DRIVE_ENABLE | INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (mode & FMODE_EXCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) fs->ref_count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ++fs->ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) mutex_lock(&swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ret = floppy_open(bdev, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) mutex_unlock(&swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) static void floppy_release(struct gendisk *disk, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct floppy_state *fs = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct swim3 __iomem *sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) mutex_lock(&swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (fs->ref_count > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) --fs->ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) else if (fs->ref_count == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) fs->ref_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (fs->ref_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) swim3_action(fs, MOTOR_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) out_8(&sw->control_bic, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) mutex_unlock(&swim3_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static unsigned int floppy_check_events(struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) unsigned int clearing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct floppy_state *fs = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int floppy_revalidate(struct gendisk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct floppy_state *fs = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct swim3 __iomem *sw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int ret, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (fs->mdev->media_bay &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) check_media_bay(fs->mdev->media_bay) != MB_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) grab_drive(fs, revalidating, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) out_8(&sw->control_bis, DRIVE_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) swim3_action(fs, MOTOR_ON); /* necessary? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) fs->write_prot = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) fs->cur_cyl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) for (n = HZ; n > 0; --n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (swim3_readbit(fs, SEEK_COMPLETE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) schedule_timeout_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ret = swim3_readbit(fs, SEEK_COMPLETE) == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) || swim3_readbit(fs, DISK_IN) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) swim3_action(fs, MOTOR_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) fs->ejected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) swim3_action(fs, SETMFM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) swim3_select(fs, RELAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) release_drive(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static const struct block_device_operations floppy_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .open = floppy_unlocked_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .release = floppy_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .ioctl = floppy_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .check_events = floppy_check_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static const struct blk_mq_ops swim3_mq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .queue_rq = swim3_queue_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static void swim3_mb_event(struct macio_dev* mdev, int mb_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct floppy_state *fs = macio_get_drvdata(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct swim3 __iomem *sw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (!fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) sw = fs->swim3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (mb_state != MB_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* Clear state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) out_8(&sw->intr_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) in_8(&sw->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) in_8(&sw->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static int swim3_add_device(struct macio_dev *mdev, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct device_node *swim = mdev->ofdev.dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct floppy_state *fs = &floppy_states[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) int rc = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) fs->mdev = mdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) fs->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* Check & Request resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (macio_resource_count(mdev) < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) swim3_err("%s", "No address in device-tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (macio_irq_count(mdev) < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) swim3_err("%s", "No interrupt in device-tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) swim3_err("%s", "Can't request mmio resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) swim3_err("%s", "Can't request dma resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) macio_release_resource(mdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) dev_set_drvdata(&mdev->ofdev.dev, fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (mdev->media_bay == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) fs->state = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) fs->swim3 = (struct swim3 __iomem *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ioremap(macio_resource_start(mdev, 0), 0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (fs->swim3 == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) swim3_err("%s", "Couldn't map mmio registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) fs->dma = (struct dbdma_regs __iomem *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ioremap(macio_resource_start(mdev, 1), 0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (fs->dma == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) swim3_err("%s", "Couldn't map dma registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) iounmap(fs->swim3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) fs->swim3_intr = macio_irq(mdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) fs->dma_intr = macio_irq(mdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) fs->cur_cyl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) fs->cur_sector = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) fs->secpercyl = 36;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) fs->secpertrack = 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) fs->total_secs = 2880;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) init_waitqueue_head(&fs->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) fs->dma_cmd[1].command = cpu_to_le16(DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (mdev->media_bay == NULL || check_media_bay(mdev->media_bay) == MB_FD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) swim3_mb_event(mdev, MB_FD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) swim3_err("%s", "Couldn't request interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) timer_setup(&fs->timeout, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) swim3_info("SWIM3 floppy controller %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) mdev->media_bay ? "in media bay" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) iounmap(fs->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) iounmap(fs->swim3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) macio_release_resource(mdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) macio_release_resource(mdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static int swim3_attach(struct macio_dev *mdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) const struct of_device_id *match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct floppy_state *fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct gendisk *disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (floppy_count >= MAX_FLOPPIES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (floppy_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) rc = register_blkdev(FLOPPY_MAJOR, "fd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) disk = alloc_disk(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (disk == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) fs = &floppy_states[floppy_count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) memset(fs, 0, sizeof(*fs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) disk->queue = blk_mq_init_sq_queue(&fs->tag_set, &swim3_mq_ops, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) BLK_MQ_F_SHOULD_MERGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (IS_ERR(disk->queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) rc = PTR_ERR(disk->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) disk->queue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) goto out_put_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) disk->queue->queuedata = fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) rc = swim3_add_device(mdev, floppy_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) goto out_cleanup_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) disk->major = FLOPPY_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) disk->first_minor = floppy_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) disk->fops = &floppy_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) disk->private_data = fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) disk->events = DISK_EVENT_MEDIA_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) disk->flags |= GENHD_FL_REMOVABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) sprintf(disk->disk_name, "fd%d", floppy_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) set_capacity(disk, 2880);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) add_disk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) disks[floppy_count++] = disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) out_cleanup_queue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) blk_cleanup_queue(disk->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) disk->queue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) blk_mq_free_tag_set(&fs->tag_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) out_put_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) put_disk(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) out_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (floppy_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) unregister_blkdev(FLOPPY_MAJOR, "fd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) static const struct of_device_id swim3_match[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .name = "swim3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .compatible = "ohare-swim3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .compatible = "swim3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) { /* end of list */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static struct macio_driver swim3_driver =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .name = "swim3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .of_match_table = swim3_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) .probe = swim3_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) #ifdef CONFIG_PMAC_MEDIABAY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) .mediabay_event = swim3_mb_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .suspend = swim3_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) .resume = swim3_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) int swim3_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) macio_register_driver(&swim3_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) module_init(swim3_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) MODULE_AUTHOR("Paul Mackerras");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);