Commit 91bf5ec3 authored by Jens Axboe's avatar Jens Axboe

Merge tag 'floppy-for-5.8' of https://github.com/evdenis/linux-floppy into for-5.8/drivers

Floppy patches for 5.8

Cleanups:
  - symbolic register names for x86,sparc64,sparc32,powerpc,parisc,m68k
  - split of local/global variables for drive,fdc
  - UBSAN warning suppress in setup_rw_floppy()

Changes were compile tested on arm, sparc64, powerpc, m68k. Many patches
introduce no binary changes by using defines instead of magic numbers.
The patches were also tested with syzkaller and simple write/read/format
tests on real hardware.
Signed-off-by: default avatarDenis Efremov <efremov@linux.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>

* tag 'floppy-for-5.8' of https://github.com/evdenis/linux-floppy: (31 commits)
  floppy: suppress UBSAN warning in setup_rw_floppy()
  floppy: add defines for sizes of cmd & reply buffers of floppy_raw_cmd
  floppy: add FD_AUTODETECT_SIZE define for struct floppy_drive_params
  floppy: use print_hex_dump() in setup_DMA()
  floppy: cleanup: make set_fdc() always set current_drive and current_fd
  floppy: cleanup: get rid of current_reqD in favor of current_drive
  floppy: make sure to reset all FDCs upon resume()
  floppy: cleanup: do not iterate on current_fdc in do_floppy_init()
  floppy: cleanup: add a few comments about expectations in certain functions
  floppy: cleanup: do not iterate on current_fdc in DMA grab/release functions
  floppy: cleanup: make get_fdc_version() not rely on current_fdc anymore
  floppy: cleanup: make next_valid_format() not rely on current_drive anymore
  floppy: cleanup: make check_wp() not rely on current_{fdc,drive} anymore
  floppy: cleanup: make fdc_specify() not rely on current_{fdc,drive} anymore
  floppy: cleanup: make fdc_configure() not rely on current_fdc anymore
  floppy: cleanup: make perpendicular_mode() not rely on current_fdc anymore
  floppy: cleanup: make need_more_output() not rely on current_fdc anymore
  floppy: cleanup: make result() not rely on current_fdc anymore
  floppy: cleanup: make output_byte() not rely on current_fdc anymore
  floppy: cleanup: make wait_til_ready() not rely on current_fdc anymore
  ...
parents 92decf11 0836275d
......@@ -11,8 +11,8 @@
#define __ASM_ALPHA_FLOPPY_H
#define fd_inb(port) inb_p(port)
#define fd_outb(value,port) outb_p(value,port)
#define fd_inb(base, reg) inb_p((base) + (reg))
#define fd_outb(value, base, reg) outb_p(value, (base) + (reg))
#define fd_enable_dma() enable_dma(FLOPPY_DMA)
#define fd_disable_dma() disable_dma(FLOPPY_DMA)
......
......@@ -9,20 +9,20 @@
#ifndef __ASM_ARM_FLOPPY_H
#define __ASM_ARM_FLOPPY_H
#define fd_outb(val,port) \
#define fd_outb(val, base, reg) \
do { \
int new_val = (val); \
if (((port) & 7) == FD_DOR) { \
if ((reg) == FD_DOR) { \
if (new_val & 0xf0) \
new_val = (new_val & 0x0c) | \
floppy_selects[new_val & 3]; \
else \
new_val &= 0x0c; \
} \
outb(new_val, (port)); \
outb(new_val, (base) + (reg)); \
} while(0)
#define fd_inb(port) inb((port))
#define fd_inb(base, reg) inb((base) + (reg))
#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
0,"floppy",NULL)
#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL)
......
......@@ -63,21 +63,21 @@ static __inline__ void release_dma_lock(unsigned long flags)
}
static __inline__ unsigned char fd_inb(int port)
static __inline__ unsigned char fd_inb(int base, int reg)
{
if(MACH_IS_Q40)
return inb_p(port);
return inb_p(base + reg);
else if(MACH_IS_SUN3X)
return sun3x_82072_fd_inb(port);
return sun3x_82072_fd_inb(base + reg);
return 0;
}
static __inline__ void fd_outb(unsigned char value, int port)
static __inline__ void fd_outb(unsigned char value, int base, int reg)
{
if(MACH_IS_Q40)
outb_p(value, port);
outb_p(value, base + reg);
else if(MACH_IS_SUN3X)
sun3x_82072_fd_outb(value, port);
sun3x_82072_fd_outb(value, base + reg);
}
......@@ -211,26 +211,27 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id)
st=1;
for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
lcount; lcount--, lptr++) {
st=inb(virtual_dma_port+4) & 0xa0 ;
if(st != 0xa0)
st = inb(virtual_dma_port + FD_STATUS);
st &= STATUS_DMA | STATUS_READY;
if (st != (STATUS_DMA | STATUS_READY))
break;
if(virtual_dma_mode)
outb_p(*lptr, virtual_dma_port+5);
outb_p(*lptr, virtual_dma_port + FD_DATA);
else
*lptr = inb_p(virtual_dma_port+5);
*lptr = inb_p(virtual_dma_port + FD_DATA);
}
virtual_dma_count = lcount;
virtual_dma_addr = lptr;
st = inb(virtual_dma_port+4);
st = inb(virtual_dma_port + FD_STATUS);
}
#ifdef TRACE_FLPY_INT
calls++;
#endif
if(st == 0x20)
if (st == STATUS_DMA)
return IRQ_HANDLED;
if(!(st & 0x20)) {
if (!(st & STATUS_DMA)) {
virtual_dma_residue += virtual_dma_count;
virtual_dma_count=0;
#ifdef TRACE_FLPY_INT
......
......@@ -26,14 +26,14 @@
/*
* How to access the FDC's registers.
*/
static inline unsigned char fd_inb(unsigned int port)
static inline unsigned char fd_inb(unsigned int base, unsigned int reg)
{
return inb_p(port);
return inb_p(base + reg);
}
static inline void fd_outb(unsigned char value, unsigned int port)
static inline void fd_outb(unsigned char value, unsigned int base, unsigned int reg)
{
outb_p(value, port);
outb_p(value, base + reg);
}
/*
......
......@@ -17,19 +17,19 @@
#include <asm/jazzdma.h>
#include <asm/pgtable.h>
static inline unsigned char fd_inb(unsigned int port)
static inline unsigned char fd_inb(unsigned int base, unsigned int reg)
{
unsigned char c;
c = *(volatile unsigned char *) port;
c = *(volatile unsigned char *) (base + reg);
udelay(1);
return c;
}
static inline void fd_outb(unsigned char value, unsigned int port)
static inline void fd_outb(unsigned char value, unsigned int base, unsigned int reg)
{
*(volatile unsigned char *) port = value;
*(volatile unsigned char *) (base + reg) = value;
}
/*
......
......@@ -29,8 +29,8 @@
#define CSW fd_routine[can_use_virtual_dma & 1]
#define fd_inb(port) readb(port)
#define fd_outb(value, port) writeb(value, port)
#define fd_inb(base, reg) readb((base) + (reg))
#define fd_outb(value, base, reg) writeb(value, (base) + (reg))
#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy")
#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)
......@@ -75,27 +75,28 @@ static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
register char *lptr = virtual_dma_addr;
for (lcount = virtual_dma_count; lcount; lcount--) {
st = fd_inb(virtual_dma_port+4) & 0xa0 ;
if (st != 0xa0)
st = fd_inb(virtual_dma_port, FD_STATUS);
st &= STATUS_DMA | STATUS_READY;
if (st != (STATUS_DMA | STATUS_READY))
break;
if (virtual_dma_mode) {
fd_outb(*lptr, virtual_dma_port+5);
fd_outb(*lptr, virtual_dma_port, FD_DATA);
} else {
*lptr = fd_inb(virtual_dma_port+5);
*lptr = fd_inb(virtual_dma_port, FD_DATA);
}
lptr++;
}
virtual_dma_count = lcount;
virtual_dma_addr = lptr;
st = fd_inb(virtual_dma_port+4);
st = fd_inb(virtual_dma_port, FD_STATUS);
}
#ifdef TRACE_FLPY_INT
calls++;
#endif
if (st == 0x20)
if (st == STATUS_DMA)
return;
if (!(st & 0x20)) {
if (!(st & STATUS_DMA)) {
virtual_dma_residue += virtual_dma_count;
virtual_dma_count = 0;
#ifdef TRACE_FLPY_INT
......
......@@ -13,8 +13,8 @@
#include <asm/machdep.h>
#define fd_inb(port) inb_p(port)
#define fd_outb(value,port) outb_p(value,port)
#define fd_inb(base, reg) inb_p((base) + (reg))
#define fd_outb(value, base, reg) outb_p(value, (base) + (reg))
#define fd_enable_dma() enable_dma(FLOPPY_DMA)
#define fd_disable_dma() fd_ops->_disable_dma(FLOPPY_DMA)
......@@ -61,21 +61,22 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id)
st = 1;
for (lcount=virtual_dma_count, lptr=virtual_dma_addr;
lcount; lcount--, lptr++) {
st=inb(virtual_dma_port+4) & 0xa0 ;
if (st != 0xa0)
st = inb(virtual_dma_port + FD_STATUS);
st &= STATUS_DMA | STATUS_READY;
if (st != (STATUS_DMA | STATUS_READY))
break;
if (virtual_dma_mode)
outb_p(*lptr, virtual_dma_port+5);
outb_p(*lptr, virtual_dma_port + FD_DATA);
else
*lptr = inb_p(virtual_dma_port+5);
*lptr = inb_p(virtual_dma_port + FD_DATA);
}
virtual_dma_count = lcount;
virtual_dma_addr = lptr;
st = inb(virtual_dma_port+4);
st = inb(virtual_dma_port + FD_STATUS);
if (st == 0x20)
if (st == STATUS_DMA)
return IRQ_HANDLED;
if (!(st & 0x20)) {
if (!(st & STATUS_DMA)) {
virtual_dma_residue += virtual_dma_count;
virtual_dma_count=0;
doing_vdma = 0;
......
......@@ -59,8 +59,8 @@ struct sun_floppy_ops {
static struct sun_floppy_ops sun_fdops;
#define fd_inb(port) sun_fdops.fd_inb(port)
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
#define fd_inb(base, reg) sun_fdops.fd_inb(reg)
#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, reg)
#define fd_enable_dma() sun_fd_enable_dma()
#define fd_disable_dma() sun_fd_disable_dma()
#define fd_request_dma() (0) /* nothing... */
......@@ -114,15 +114,15 @@ static unsigned char sun_read_dir(void)
static unsigned char sun_82072_fd_inb(int port)
{
udelay(5);
switch(port & 7) {
switch (port) {
default:
printk("floppy: Asked to read unknown port %d\n", port);
panic("floppy: Port bolixed.");
case 4: /* FD_STATUS */
case FD_STATUS:
return sun_fdc->status_82072 & ~STATUS_DMA;
case 5: /* FD_DATA */
case FD_DATA:
return sun_fdc->data_82072;
case 7: /* FD_DIR */
case FD_DIR:
return sun_read_dir();
}
panic("sun_82072_fd_inb: How did I get here?");
......@@ -131,20 +131,20 @@ static unsigned char sun_82072_fd_inb(int port)
static void sun_82072_fd_outb(unsigned char value, int port)
{
udelay(5);
switch(port & 7) {
switch (port) {
default:
printk("floppy: Asked to write to unknown port %d\n", port);
panic("floppy: Port bolixed.");
case 2: /* FD_DOR */
case FD_DOR:
sun_set_dor(value, 0);
break;
case 5: /* FD_DATA */
case FD_DATA:
sun_fdc->data_82072 = value;
break;
case 7: /* FD_DCR */
case FD_DCR:
sun_fdc->dcr_82072 = value;
break;
case 4: /* FD_STATUS */
case FD_DSR:
sun_fdc->status_82072 = value;
break;
}
......@@ -154,23 +154,23 @@ static void sun_82072_fd_outb(unsigned char value, int port)
static unsigned char sun_82077_fd_inb(int port)
{
udelay(5);
switch(port & 7) {
switch (port) {
default:
printk("floppy: Asked to read unknown port %d\n", port);
panic("floppy: Port bolixed.");
case 0: /* FD_STATUS_0 */
case FD_SRA:
return sun_fdc->status1_82077;
case 1: /* FD_STATUS_1 */
case FD_SRB:
return sun_fdc->status2_82077;
case 2: /* FD_DOR */
case FD_DOR:
return sun_fdc->dor_82077;
case 3: /* FD_TDR */
case FD_TDR:
return sun_fdc->tapectl_82077;
case 4: /* FD_STATUS */
case FD_STATUS:
return sun_fdc->status_82077 & ~STATUS_DMA;
case 5: /* FD_DATA */
case FD_DATA:
return sun_fdc->data_82077;
case 7: /* FD_DIR */
case FD_DIR:
return sun_read_dir();
}
panic("sun_82077_fd_inb: How did I get here?");
......@@ -179,23 +179,23 @@ static unsigned char sun_82077_fd_inb(int port)
static void sun_82077_fd_outb(unsigned char value, int port)
{
udelay(5);
switch(port & 7) {
switch (port) {
default:
printk("floppy: Asked to write to unknown port %d\n", port);
panic("floppy: Port bolixed.");
case 2: /* FD_DOR */
case FD_DOR:
sun_set_dor(value, 1);
break;
case 5: /* FD_DATA */
case FD_DATA:
sun_fdc->data_82077 = value;
break;
case 7: /* FD_DCR */
case FD_DCR:
sun_fdc->dcr_82077 = value;
break;
case 4: /* FD_STATUS */
case FD_DSR:
sun_fdc->status_82077 = value;
break;
case 3: /* FD_TDR */
case FD_TDR:
sun_fdc->tapectl_82077 = value;
break;
}
......
......@@ -47,8 +47,9 @@ unsigned long fdc_status;
static struct platform_device *floppy_op = NULL;
struct sun_floppy_ops {
unsigned char (*fd_inb) (unsigned long port);
void (*fd_outb) (unsigned char value, unsigned long port);
unsigned char (*fd_inb) (unsigned long port, unsigned int reg);
void (*fd_outb) (unsigned char value, unsigned long base,
unsigned int reg);
void (*fd_enable_dma) (void);
void (*fd_disable_dma) (void);
void (*fd_set_dma_mode) (int);
......@@ -62,8 +63,8 @@ struct sun_floppy_ops {
static struct sun_floppy_ops sun_fdops;
#define fd_inb(port) sun_fdops.fd_inb(port)
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
#define fd_inb(base, reg) sun_fdops.fd_inb(base, reg)
#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, base, reg)
#define fd_enable_dma() sun_fdops.fd_enable_dma()
#define fd_disable_dma() sun_fdops.fd_disable_dma()
#define fd_request_dma() (0) /* nothing... */
......@@ -97,42 +98,43 @@ static int sun_floppy_types[2] = { 0, 0 };
/* No 64k boundary crossing problems on the Sparc. */
#define CROSS_64KB(a,s) (0)
static unsigned char sun_82077_fd_inb(unsigned long port)
static unsigned char sun_82077_fd_inb(unsigned long base, unsigned int reg)
{
udelay(5);
switch(port & 7) {
switch (reg) {
default:
printk("floppy: Asked to read unknown port %lx\n", port);
printk("floppy: Asked to read unknown port %x\n", reg);
panic("floppy: Port bolixed.");
case 4: /* FD_STATUS */
case FD_STATUS:
return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
case 5: /* FD_DATA */
case FD_DATA:
return sbus_readb(&sun_fdc->data_82077);
case 7: /* FD_DIR */
case FD_DIR:
/* XXX: Is DCL on 0x80 in sun4m? */
return sbus_readb(&sun_fdc->dir_82077);
}
panic("sun_82072_fd_inb: How did I get here?");
}
static void sun_82077_fd_outb(unsigned char value, unsigned long port)
static void sun_82077_fd_outb(unsigned char value, unsigned long base,
unsigned int reg)
{
udelay(5);
switch(port & 7) {
switch (reg) {
default:
printk("floppy: Asked to write to unknown port %lx\n", port);
printk("floppy: Asked to write to unknown port %x\n", reg);
panic("floppy: Port bolixed.");
case 2: /* FD_DOR */
case FD_DOR:
/* Happily, the 82077 has a real DOR register. */
sbus_writeb(value, &sun_fdc->dor_82077);
break;
case 5: /* FD_DATA */
case FD_DATA:
sbus_writeb(value, &sun_fdc->data_82077);
break;
case 7: /* FD_DCR */
case FD_DCR:
sbus_writeb(value, &sun_fdc->dcr_82077);
break;
case 4: /* FD_STATUS */
case FD_DSR:
sbus_writeb(value, &sun_fdc->status_82077);
break;
}
......@@ -298,19 +300,21 @@ static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
irqreturn_t floppy_interrupt(int irq, void *dev_id);
static unsigned char sun_pci_fd_inb(unsigned long port)
static unsigned char sun_pci_fd_inb(unsigned long base, unsigned int reg)
{
udelay(5);
return inb(port);
return inb(base + reg);
}
static void sun_pci_fd_outb(unsigned char val, unsigned long port)
static void sun_pci_fd_outb(unsigned char val, unsigned long base,
unsigned int reg)
{
udelay(5);
outb(val, port);
outb(val, base + reg);
}
static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
static void sun_pci_fd_broken_outb(unsigned char val, unsigned long base,
unsigned int reg)
{
udelay(5);
/*
......@@ -320,16 +324,17 @@ static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
* this does not hurt correct hardware like the AXmp.
* (Eddie, Sep 12 1998).
*/
if (port == ((unsigned long)sun_fdc) + 2) {
if (reg == FD_DOR) {
if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
val |= 0x10;
}
}
outb(val, port);
outb(val, base + reg);
}
#ifdef PCI_FDC_SWAP_DRIVES
static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long base,
unsigned int reg)
{
udelay(5);
/*
......@@ -339,13 +344,13 @@ static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
* this does not hurt correct hardware like the AXmp.
* (Eddie, Sep 12 1998).
*/
if (port == ((unsigned long)sun_fdc) + 2) {
if (reg == FD_DOR) {
if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
val &= ~(0x03);
val |= 0x21;
}
}
outb(val, port);
outb(val, base + reg);
}
#endif /* PCI_FDC_SWAP_DRIVES */
......
......@@ -31,8 +31,8 @@
#define CSW fd_routine[can_use_virtual_dma & 1]
#define fd_inb(port) inb_p(port)
#define fd_outb(value, port) outb_p(value, port)
#define fd_inb(base, reg) inb_p((base) + (reg))
#define fd_outb(value, base, reg) outb_p(value, (base) + (reg))
#define fd_request_dma() CSW._request_dma(FLOPPY_DMA, "floppy")
#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)
......@@ -77,25 +77,26 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id)
st = 1;
for (lcount = virtual_dma_count, lptr = virtual_dma_addr;
lcount; lcount--, lptr++) {
st = inb(virtual_dma_port + 4) & 0xa0;
if (st != 0xa0)
st = inb(virtual_dma_port + FD_STATUS);
st &= STATUS_DMA | STATUS_READY;
if (st != (STATUS_DMA | STATUS_READY))
break;
if (virtual_dma_mode)
outb_p(*lptr, virtual_dma_port + 5);
outb_p(*lptr, virtual_dma_port + FD_DATA);
else
*lptr = inb_p(virtual_dma_port + 5);
*lptr = inb_p(virtual_dma_port + FD_DATA);
}
virtual_dma_count = lcount;
virtual_dma_addr = lptr;
st = inb(virtual_dma_port + 4);
st = inb(virtual_dma_port + FD_STATUS);
}
#ifdef TRACE_FLPY_INT
calls++;
#endif
if (st == 0x20)
if (st == STATUS_DMA)
return IRQ_HANDLED;
if (!(st & 0x20)) {
if (!(st & STATUS_DMA)) {
virtual_dma_residue += virtual_dma_count;
virtual_dma_count = 0;
#ifdef TRACE_FLPY_INT
......
This diff is collapsed.
......@@ -172,7 +172,10 @@ struct floppy_drive_params {
* used in succession to try to read the disk. If the FDC cannot lock onto
* the disk, the next format is tried. This uses the variable 'probing'.
*/
short autodetect[8]; /* autodetected formats */
#define FD_AUTODETECT_SIZE 8
short autodetect[FD_AUTODETECT_SIZE]; /* autodetected formats */
int checkfreq; /* how often should the drive be checked for disk
* changes */
......@@ -357,10 +360,25 @@ struct floppy_raw_cmd {
int buffer_length; /* length of allocated buffer */
unsigned char rate;
#define FD_RAW_CMD_SIZE 16
#define FD_RAW_REPLY_SIZE 16
#define FD_RAW_CMD_FULLSIZE (FD_RAW_CMD_SIZE + 1 + FD_RAW_REPLY_SIZE)
/* The command may take up the space initially intended for the reply
* and the reply count. Needed for long 82078 commands such as RESTORE,
* which takes 17 command bytes.
*/
unsigned char cmd_count;
unsigned char cmd[16];
unsigned char reply_count;
unsigned char reply[16];
union {
struct {
unsigned char cmd[FD_RAW_CMD_SIZE];
unsigned char reply_count;
unsigned char reply[FD_RAW_REPLY_SIZE];
};
unsigned char fullcmd[FD_RAW_CMD_FULLSIZE];
};
int track;
int resultcode;
......
......@@ -7,13 +7,23 @@
* Handbook", Sanches and Canton.
*/
/* Fd controller regs. S&C, about page 340 */
#define FD_STATUS 4
#define FD_DATA 5
/* 82077's auxiliary status registers A & B (R) */
#define FD_SRA 0
#define FD_SRB 1
/* Digital Output Register */
#define FD_DOR 2
/* 82077's tape drive register (R/W) */
#define FD_TDR 3
/* 82077's data rate select register (W) */
#define FD_DSR 4
/* Fd controller regs. S&C, about page 340 */
#define FD_STATUS 4
#define FD_DATA 5
/* Digital Input Register (read) */
#define FD_DIR 7
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment