#define DEBUGT 2
#define DCL_DEBUG /* debug disk change line */
+#ifdef DCL_DEBUG
+#define debug_dcl(test, fmt, args...) \
+ do { if ((test) & FD_DEBUG) DPRINT(fmt, ##args); } while (0)
+#else
+#define debug_dcl(test, fmt, args...) \
+ do { if (0) DPRINT(fmt, ##args); } while (0)
+#endif
+
+
/* do print messages for unexpected interrupts */
static int print_unex = 1;
#include <linux/module.h>
static int irqdma_allocated;
-#define DEVICE_NAME "floppy"
-
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
/* End dma memory related stuff */
static unsigned long fake_change;
-static int initialising = 1;
+static bool initialized;
#define ITYPE(x) (((x) >> 2) & 0x1f)
#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
#define DRS (&drive_state[current_drive])
#define DRWE (&write_errors[current_drive])
#define FDCS (&fdc_state[fdc])
-#define CLEARF(x) clear_bit(x##_BIT, &DRS->flags)
-#define SETF(x) set_bit(x##_BIT, &DRS->flags)
-#define TESTF(x) test_bit(x##_BIT, &DRS->flags)
#define UDP (&drive_params[drive])
#define UDRS (&drive_state[drive])
#define UDRWE (&write_errors[drive])
#define UFDCS (&fdc_state[FDC(drive)])
-#define UCLEARF(x) clear_bit(x##_BIT, &UDRS->flags)
-#define USETF(x) set_bit(x##_BIT, &UDRS->flags)
-#define UTESTF(x) test_bit(x##_BIT, &UDRS->flags)
#define DPRINT(format, args...) \
- pr_info(DEVICE_NAME "%d: " format, current_drive, ##args)
+ pr_info("floppy%d: " format, current_drive, ##args)
#define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2)
#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
-#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x)))
-
/* read/write */
#define COMMAND (raw_cmd->cmd[0])
#define DR_SELECT (raw_cmd->cmd[1])
static DECLARE_WAIT_QUEUE_HEAD(command_done);
#define NO_SIGNAL (!interruptible || !signal_pending(current))
-#define CALL(x) if ((x) == -EINTR) return -EINTR
-#define ECALL(x) if ((ret = (x))) return ret;
-#define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
-#define WAIT(x) _WAIT((x),interruptible)
-#define IWAIT(x) _WAIT((x),1)
/* Errors during formatting are counted here. */
static int format_errors;
* reset doesn't need to be tested before sending commands, because
* output_byte is automatically disabled when reset is set.
*/
-#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } }
static void reset_fdc(void);
/*
static inline void debugt(const char *message) { }
#endif /* DEBUGT */
-typedef void (*timeout_fn) (unsigned long);
+typedef void (*timeout_fn)(unsigned long);
static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
static const char *timeout_message;
static void is_alive(const char *message)
{
/* this routine checks whether the floppy driver is "alive" */
- if (test_bit(0, &fdc_busy) && command_status < 2
- && !timer_pending(&fd_timeout)) {
+ if (test_bit(0, &fdc_busy) && command_status < 2 &&
+ !timer_pending(&fd_timeout)) {
DPRINT("timeout handler died: %s\n", message);
}
}
}
#endif
-#ifdef DCL_DEBUG
- if (UDP->flags & FD_DEBUG) {
- DPRINT("checking disk change line for drive %d\n", drive);
- DPRINT("jiffies=%lu\n", jiffies);
- DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
- DPRINT("flags=%lx\n", UDRS->flags);
- }
-#endif
+ debug_dcl(UDP->flags,
+ "checking disk change line for drive %d\n", drive);
+ debug_dcl(UDP->flags, "jiffies=%lu\n", jiffies);
+ debug_dcl(UDP->flags, "disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
+ debug_dcl(UDP->flags, "flags=%lx\n", UDRS->flags);
+
if (UDP->flags & FD_BROKEN_DCL)
- return UTESTF(FD_DISK_CHANGED);
+ return test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) {
- USETF(FD_VERIFY); /* verify write protection */
- if (UDRS->maxblock) {
- /* mark it changed */
- USETF(FD_DISK_CHANGED);
- }
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
+ /* verify write protection */
+
+ if (UDRS->maxblock) /* mark it changed */
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
/* invalidate its geometry */
if (UDRS->keep_data >= 0) {
return 1;
} else {
UDRS->last_checked = jiffies;
- UCLEARF(FD_DISK_NEWCHANGE);
+ clear_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags);
}
return 0;
}
return ((dor & (0x10 << unit)) && (dor & 3) == unit);
}
+static bool is_ready_state(int status)
+{
+ int state = status & (STATUS_READY | STATUS_DIR | STATUS_DMA);
+ return state == STATUS_READY;
+}
+
static int set_dor(int fdc, char mask, char data)
{
unsigned char unit;
unit = olddor & 0x3;
if (is_selected(olddor, unit) && !is_selected(newdor, unit)) {
drive = REVDRIVE(fdc, unit);
-#ifdef DCL_DEBUG
- if (UDP->flags & FD_DEBUG)
- DPRINT("calling disk change from set_dor\n");
-#endif
+ debug_dcl(UDP->flags,
+ "calling disk change from set_dor\n");
disk_change(drive);
}
FDCS->dor = newdor;
DRS->select_date = jiffies;
}
-/* reset all driver information about the current fdc. This is needed after
- * a reset, and after a raw command. */
+/*
+ * Reset all driver information about the current fdc.
+ * This is needed after a reset, and after a raw command.
+ */
static void reset_fdc_info(int mode)
{
int drive;
}
/* locks the driver */
-static int _lock_fdc(int drive, int interruptible, int line)
+static int _lock_fdc(int drive, bool interruptible, int line)
{
if (!usage_count) {
pr_err("Trying to lock fdc while usage count=0 at line %d\n",
#define lock_fdc(drive, interruptible) \
_lock_fdc(drive, interruptible, __LINE__)
-#define LOCK_FDC(drive, interruptible) \
- if (lock_fdc(drive, interruptible)) \
- return -EINTR;
-
/* unlocks the driver */
static inline void unlock_fdc(void)
{
* transfer */
static void fd_watchdog(void)
{
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("calling disk change from watchdog\n");
-#endif
+ debug_dcl(DP->flags, "calling disk change from watchdog\n");
if (disk_change(current_drive)) {
DPRINT("disk removed during i/o\n");
reset_fdc();
} else {
del_timer(&fd_timer);
- fd_timer.function = (timeout_fn) fd_watchdog;
+ fd_timer.function = (timeout_fn)fd_watchdog;
fd_timer.expires = jiffies + HZ / 10;
add_timer(&fd_timer);
}
if (status & STATUS_READY)
return status;
}
- if (!initialising) {
+ if (initialized) {
DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc);
show_floppy();
}
/* sends a command byte to the fdc */
static int output_byte(char byte)
{
- int status;
+ int status = wait_til_ready();
- if ((status = wait_til_ready()) < 0)
+ if (status < 0)
return -1;
- if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) {
+
+ if (is_ready_state(status)) {
fd_outb(byte, FD_DATA);
#ifdef FLOPPY_SANITY_CHECK
output_log[output_log_pos].data = byte;
return 0;
}
FDCS->reset = 1;
- if (!initialising) {
+ if (initialized) {
DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
byte, fdc, status);
show_floppy();
return -1;
}
-#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;}
-
/* gets the response from the fdc */
static int result(void)
{
int status = 0;
for (i = 0; i < MAX_REPLIES; i++) {
- if ((status = wait_til_ready()) < 0)
+ status = wait_til_ready();
+ if (status < 0)
break;
status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
if ((status & ~STATUS_BUSY) == STATUS_READY) {
else
break;
}
- if (!initialising) {
- DPRINT
- ("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
- fdc, status, i);
+ if (initialized) {
+ DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
+ fdc, status, i);
show_floppy();
}
FDCS->reset = 1;
/* does the fdc need more output? */
static int need_more_output(void)
{
- int status;
+ int status = wait_til_ready();
- if ((status = wait_til_ready()) < 0)
+ if (status < 0)
return -1;
- if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
+
+ if (is_ready_state(status))
return MORE_OUTPUT;
+
return result();
}
default:
DPRINT("Invalid data rate for perpendicular mode!\n");
cont->done(0);
- FDCS->reset = 1; /* convenient way to return to
- * redo without to much hassle (deep
- * stack et al. */
+ FDCS->reset = 1;
+ /*
+ * convenient way to return to
+ * redo without too much hassle
+ * (deep stack et al.)
+ */
return;
}
} else
* Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
*/
FDCS->dtr = raw_cmd->rate & 3;
- return (fd_wait_for_completion(jiffies + 2UL * HZ / 100,
- (timeout_fn) floppy_ready));
+ return fd_wait_for_completion(jiffies + 2UL * HZ / 100,
+ (timeout_fn)floppy_ready);
} /* fdc_dtr */
static void tell_sector(void)
bad = 1;
if (ST1 & ST1_WP) {
DPRINT("Drive is write protected\n");
- CLEARF(FD_DISK_WRITABLE);
+ clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
cont->done(0);
bad = 2;
} else if (ST1 & ST1_ND) {
- SETF(FD_NEED_TWADDLE);
+ set_bit(FD_NEED_TWADDLE_BIT, &DRS->flags);
} else if (ST1 & ST1_OR) {
if (DP->flags & FTD_MSG)
DPRINT("Over/Underrun - retrying\n");
*/
if (time_after(ready_date, jiffies + DP->select_delay)) {
ready_date -= DP->select_delay;
- function = (timeout_fn) floppy_start;
+ function = (timeout_fn)floppy_start;
} else
- function = (timeout_fn) setup_rw_floppy;
+ function = (timeout_fn)setup_rw_floppy;
/* wait until the floppy is spinning fast enough */
if (fd_wait_for_completion(ready_date, function))
return;
}
if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) {
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("clearing NEWCHANGE flag because of effective seek\n");
- DPRINT("jiffies=%lu\n", jiffies);
- }
-#endif
- CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
+ debug_dcl(DP->flags,
+ "clearing NEWCHANGE flag because of effective seek\n");
+ debug_dcl(DP->flags, "jiffies=%lu\n", jiffies);
+ clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
+ /* effective seek */
DRS->select_date = jiffies;
}
DRS->track = ST1;
static void check_wp(void)
{
- if (TESTF(FD_VERIFY)) {
- /* check write protection */
+ if (test_bit(FD_VERIFY_BIT, &DRS->flags)) {
+ /* check write protection */
output_byte(FD_GETSTATUS);
output_byte(UNIT(current_drive));
if (result() != 1) {
FDCS->reset = 1;
return;
}
- CLEARF(FD_VERIFY);
- CLEARF(FD_NEED_TWADDLE);
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG) {
- DPRINT("checking whether disk is write protected\n");
- DPRINT("wp=%x\n", ST3 & 0x40);
- }
-#endif
+ clear_bit(FD_VERIFY_BIT, &DRS->flags);
+ clear_bit(FD_NEED_TWADDLE_BIT, &DRS->flags);
+ debug_dcl(DP->flags,
+ "checking whether disk is write protected\n");
+ debug_dcl(DP->flags, "wp=%x\n", ST3 & 0x40);
if (!(ST3 & 0x40))
- SETF(FD_DISK_WRITABLE);
+ set_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
else
- CLEARF(FD_DISK_WRITABLE);
+ clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags);
}
}
blind_seek = 0;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("calling disk change from seek\n");
-#endif
+ debug_dcl(DP->flags, "calling disk change from seek\n");
- if (!TESTF(FD_DISK_NEWCHANGE) &&
+ if (!test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) &&
disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) {
/* the media changed flag should be cleared after the seek.
* If it isn't, this means that there is really no disk in
* the drive.
*/
- SETF(FD_DISK_CHANGED);
+ set_bit(FD_DISK_CHANGED_BIT, &DRS->flags);
cont->done(0);
cont->redo();
return;
if (DRS->track <= NEED_1_RECAL) {
recalibrate_floppy();
return;
- } else if (TESTF(FD_DISK_NEWCHANGE) &&
+ } else if (test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) &&
(raw_cmd->flags & FD_RAW_NEED_DISK) &&
(DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
/* we seek to clear the media-changed condition. Does anybody
do_floppy = seek_interrupt;
output_byte(FD_SEEK);
output_byte(UNIT(current_drive));
- LAST_OUT(track);
+ if (output_byte(track) < 0) {
+ reset_fdc();
+ return;
+ }
debugt("seek command:");
}
* not to move at recalibration is to
* be already at track 0.) Clear the
* new change flag */
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
-#endif
+ debug_dcl(DP->flags,
+ "clearing NEWCHANGE flag because of second recalibrate\n");
- CLEARF(FD_DISK_NEWCHANGE);
+ clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
DRS->select_date = jiffies;
/* fall through */
default:
* activity.
*/
- do_print = !handler && print_unex && !initialising;
+ do_print = !handler && print_unex && initialized;
inr = result();
if (do_print)
if (do_print)
print_result("sensei", inr);
max_sensei--;
- } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2
- && max_sensei);
+ } while ((ST0 & 0x83) != UNIT(current_drive) &&
+ inr == 2 && max_sensei);
}
if (!handler) {
FDCS->reset = 1;
debugt("recalibrate floppy:");
do_floppy = recal_interrupt;
output_byte(FD_RECALIBRATE);
- LAST_OUT(UNIT(current_drive));
+ if (output_byte(UNIT(current_drive)) < 0) {
+ reset_fdc();
+ return;
+ }
}
/*
{
unsigned long flags;
- if (!initialising)
+ if (initialized)
show_floppy();
cancel_activity();
/* avoid dma going to a random drive after shutdown */
- if (!initialising)
+ if (initialized)
DPRINT("floppy timeout called\n");
FDCS->reset = 1;
if (cont) {
set_dor(fdc, mask, data);
/* wait_for_completion also schedules reset if needed. */
- return (fd_wait_for_completion(DRS->select_date + DP->select_delay,
- (timeout_fn) function));
+ return fd_wait_for_completion(DRS->select_date + DP->select_delay,
+ (timeout_fn)function);
}
static void floppy_ready(void)
{
- CHECK_RESET;
+ if (FDCS->reset) {
+ reset_fdc();
+ return;
+ }
if (start_motor(floppy_ready))
return;
if (fdc_dtr())
return;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("calling disk change from floppy_ready\n");
-#endif
+ debug_dcl(DP->flags, "calling disk change from floppy_ready\n");
if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
disk_change(current_drive) && !DP->select_delay)
- twaddle(); /* this clears the dcl on certain drive/controller
- * combinations */
+ twaddle(); /* this clears the dcl on certain
+ * drive/controller combinations */
#ifdef fd_chose_dma_mode
if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) {
reschedule_timeout(current_reqD, "floppy start", 0);
scandrives();
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("setting NEWCHANGE in floppy_start\n");
-#endif
- SETF(FD_DISK_NEWCHANGE);
+ debug_dcl(DP->flags, "setting NEWCHANGE in floppy_start\n");
+ set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
floppy_ready();
}
.done = (done_f)empty
};
-static int wait_til_done(void (*handler)(void), int interruptible)
+static int wait_til_done(void (*handler)(void), bool interruptible)
{
int ret;
{
int ret;
- LOCK_FDC(drive, 1);
+ if (lock_fdc(drive, true))
+ return -EINTR;
+
set_floppy(drive);
if (!_floppy ||
_floppy->track > DP->tracks ||
format_errors = 0;
cont = &format_cont;
errors = &format_errors;
- IWAIT(redo_format);
+ ret = wait_til_done(redo_format, true);
+ if (ret == -EINTR)
+ return -EINTR;
process_fd_request();
return ret;
}
HEAD = fsector_t / _floppy->sect;
if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) ||
- TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
+ test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) &&
+ fsector_t < _floppy->sect)
max_sector = _floppy->sect;
/* 2M disks have phantom sectors on the first track */
}
} else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) {
if (CT(COMMAND) == FD_WRITE) {
- if (fsector_t + blk_rq_sectors(current_req) > ssize &&
- fsector_t + blk_rq_sectors(current_req) < ssize + ssize)
+ unsigned int sectors;
+
+ sectors = fsector_t + blk_rq_sectors(current_req);
+ if (sectors > ssize && sectors < ssize + ssize)
max_size = ssize + ssize;
else
max_size = ssize;
* on a 64 bit machine!
*/
max_size = buffer_chain_size();
- dma_limit =
- (MAX_DMA_ADDRESS -
- ((unsigned long)current_req->buffer)) >> 9;
+ dma_limit = (MAX_DMA_ADDRESS -
+ ((unsigned long)current_req->buffer)) >> 9;
if ((unsigned long)max_size > dma_limit)
max_size = dma_limit;
/* 64 kb boundaries */
*/
if (!direct ||
(indirect * 2 > direct * 3 &&
- *errors < DP->max_errors.read_track && ((!probing
- || (DP->read_track & (1 << DRS->probed_format)))))) {
+ *errors < DP->max_errors.read_track &&
+ ((!probing ||
+ (DP->read_track & (1 << DRS->probed_format)))))) {
max_size = blk_rq_sectors(current_req);
} else {
raw_cmd->kernel_data = current_req->buffer;
raw_cmd->length = current_count_sectors << 9;
if (raw_cmd->length == 0) {
- DPRINT
- ("zero dma transfer attempted from make_raw_request\n");
- DPRINT("indirect=%d direct=%d fsector_t=%d",
+ DPRINT("zero dma transfer attempted from make_raw_request\n");
+ DPRINT("indirect=%d direct=%d fsector_t=%d\n",
indirect, direct, fsector_t);
return 0;
}
((CT(COMMAND) == FD_READ ||
(!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) &&
max_sector > 2 * max_buffer_sectors + buffer_min &&
- max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
- /* not enough space */
- ) {
+ max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)) {
+ /* not enough space */
buffer_track = -1;
buffer_drive = current_drive;
buffer_max = buffer_min = aligned_sector_t;
}
raw_cmd->kernel_data = floppy_track_buffer +
- ((aligned_sector_t - buffer_min) << 9);
+ ((aligned_sector_t - buffer_min) << 9);
if (CT(COMMAND) == FD_WRITE) {
/* copy write buffer to track buffer.
return;
disk_change(current_drive);
if (test_bit(current_drive, &fake_change) ||
- TESTF(FD_DISK_CHANGED)) {
+ test_bit(FD_DISK_CHANGED_BIT, &DRS->flags)) {
DPRINT("disk absent or changed during operation\n");
REPEAT;
}
continue;
}
- if (TESTF(FD_NEED_TWADDLE))
+ if (test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags))
twaddle();
schedule_bh(floppy_start);
debugt("queue fd request");
schedule_bh(redo_fd_request);
}
-static void do_fd_request(struct request_queue * q)
+static void do_fd_request(struct request_queue *q)
{
if (max_buffer_sectors == 0) {
pr_info("VFS: do_fd_request called on non-open device\n");
is_alive("do fd request, old request running");
return;
}
- lock_fdc(MAXTIMEOUT, 0);
+ lock_fdc(MAXTIMEOUT, false);
process_fd_request();
is_alive("do fd request");
}
.done = generic_done
};
-static int poll_drive(int interruptible, int flag)
+static int poll_drive(bool interruptible, int flag)
{
- int ret;
-
/* no auto-sense, just clear dcl */
raw_cmd = &default_raw_cmd;
raw_cmd->flags = flag;
raw_cmd->track = 0;
raw_cmd->cmd_count = 0;
cont = &poll_cont;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("setting NEWCHANGE in poll_drive\n");
-#endif
- SETF(FD_DISK_NEWCHANGE);
- WAIT(floppy_ready);
- return ret;
+ debug_dcl(DP->flags, "setting NEWCHANGE in poll_drive\n");
+ set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags);
+
+ return wait_til_done(floppy_ready, interruptible);
}
/*
.done = generic_done
};
-static int user_reset_fdc(int drive, int arg, int interruptible)
+static int user_reset_fdc(int drive, int arg, bool interruptible)
{
int ret;
- ret = 0;
- LOCK_FDC(drive, interruptible);
+ if (lock_fdc(drive, interruptible))
+ return -EINTR;
+
if (arg == FD_RESET_ALWAYS)
FDCS->reset = 1;
if (FDCS->reset) {
cont = &reset_cont;
- WAIT(reset_fdc);
+ ret = wait_til_done(reset_fdc, interruptible);
+ if (ret == -EINTR)
+ return -EINTR;
}
process_fd_request();
- return ret;
+ return 0;
}
/*
return copy_from_user(address, param, size) ? -EFAULT : 0;
}
-#define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) \
- ? -EFAULT : 0)
-#define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) \
- ? -EFAULT : 0)
-
-#define COPYOUT(x) ECALL(_COPYOUT(x))
-#define COPYIN(x) ECALL(_COPYIN(x))
-
static inline const char *drive_name(int type, int drive)
{
struct floppy_struct *floppy;
int ret;
while (ptr) {
- COPYOUT(*ptr);
+ ret = copy_to_user((void __user *)param, ptr, sizeof(*ptr));
+ if (ret)
+ return -EFAULT;
param += sizeof(struct floppy_raw_cmd);
if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) {
- if (ptr->length >= 0
- && ptr->length <= ptr->buffer_length)
- ECALL(fd_copyout
- (ptr->data, ptr->kernel_data,
- ptr->buffer_length - ptr->length));
+ if (ptr->length >= 0 &&
+ ptr->length <= ptr->buffer_length) {
+ long length = ptr->buffer_length - ptr->length;
+ ret = fd_copyout(ptr->data, ptr->kernel_data,
+ length);
+ if (ret)
+ return ret;
+ }
}
ptr = ptr->next;
}
if (!ptr)
return -ENOMEM;
*rcmd = ptr;
- COPYIN(*ptr);
+ ret = copy_from_user(ptr, (void __user *)param, sizeof(*ptr));
+ if (ret)
+ return -EFAULT;
ptr->next = NULL;
ptr->buffer_length = 0;
param += sizeof(struct floppy_raw_cmd);
return -ENOMEM;
ptr->buffer_length = ptr->length;
}
- if (ptr->flags & FD_RAW_WRITE)
- ECALL(fd_copyin(ptr->data, ptr->kernel_data,
- ptr->length));
+ if (ptr->flags & FD_RAW_WRITE) {
+ ret = fd_copyin(ptr->data, ptr->kernel_data,
+ ptr->length);
+ if (ret)
+ return ret;
+ }
rcmd = &(ptr->next);
if (!(ptr->flags & FD_RAW_MORE))
return 0;
raw_cmd = my_raw_cmd;
cont = &raw_cmd_cont;
- ret = wait_til_done(floppy_start, 1);
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG)
- DPRINT("calling disk change from raw_cmd ioctl\n");
-#endif
+ ret = wait_til_done(floppy_start, true);
+ debug_dcl(DP->flags, "calling disk change from raw_cmd ioctl\n");
if (ret != -EINTR && FDCS->reset)
ret = -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
mutex_lock(&open_lock);
- if (lock_fdc(drive, 1)) {
+ if (lock_fdc(drive, true)) {
mutex_unlock(&open_lock);
return -EINTR;
}
mutex_unlock(&open_lock);
} else {
int oldStretch;
- LOCK_FDC(drive, 1);
- if (cmd != FDDEFPRM)
+
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ if (cmd != FDDEFPRM) {
/* notice a disk change immediately, else
* we lose our settings immediately*/
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
+ if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+ return -EINTR;
+ }
oldStretch = g->stretch;
user_params[drive] = *g;
if (buffer_drive == drive)
if (type)
*g = &floppy_type[type];
else {
- LOCK_FDC(drive, 0);
- CALL(poll_drive(0, 0));
+ if (lock_fdc(drive, false))
+ return -EINTR;
+ if (poll_drive(false, 0) == -EINTR)
+ return -EINTR;
process_fd_request();
*g = current_type[drive];
}
unsigned long param)
{
#define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL))
-#define OUT(c,x) case c: outparam = (const char *) (x); break
-#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
int drive = (long)bdev->bd_disk->private_data;
int type = ITYPE(UDRS->fd_device);
return -EINVAL;
/* convert the old style command into a new style command */
- ECALL(normalize_ioctl(&cmd, &size));
+ ret = normalize_ioctl(&cmd, &size);
+ if (ret)
+ return ret;
/* permission checks */
if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) ||
return -EINVAL;
/* copyin */
- CLEARSTRUCT(&inparam);
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- ECALL(fd_copyin((void __user *)param, &inparam, size))
-
- switch (cmd) {
- case FDEJECT:
- if (UDRS->fd_ref != 1)
- /* somebody else has this drive open */
- return -EBUSY;
- LOCK_FDC(drive, 1);
-
- /* do the actual eject. Fails on
- * non-Sparc architectures */
- ret = fd_eject(UNIT(drive));
-
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
- process_fd_request();
+ memset(&inparam, 0, sizeof(inparam));
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ ret = fd_copyin((void __user *)param, &inparam, size);
+ if (ret)
return ret;
- case FDCLRPRM:
- LOCK_FDC(drive, 1);
- current_type[drive] = NULL;
- floppy_sizes[drive] = MAX_DISK_SIZE << 1;
- UDRS->keep_data = 0;
- return invalidate_drive(bdev);
- case FDSETPRM:
- case FDDEFPRM:
- return set_geometry(cmd, &inparam.g,
- drive, type, bdev);
- case FDGETPRM:
- ECALL(get_floppy_geometry(drive, type,
- (struct floppy_struct **)
- &outparam));
- break;
-
- case FDMSGON:
- UDP->flags |= FTD_MSG;
- return 0;
- case FDMSGOFF:
- UDP->flags &= ~FTD_MSG;
- return 0;
-
- case FDFMTBEG:
- LOCK_FDC(drive, 1);
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
- ret = UDRS->flags;
- process_fd_request();
- if (ret & FD_VERIFY)
- return -ENODEV;
- if (!(ret & FD_DISK_WRITABLE))
- return -EROFS;
- return 0;
- case FDFMTTRK:
- if (UDRS->fd_ref != 1)
- return -EBUSY;
- return do_format(drive, &inparam.f);
- case FDFMTEND:
- case FDFLUSH:
- LOCK_FDC(drive, 1);
- return invalidate_drive(bdev);
-
- case FDSETEMSGTRESH:
- UDP->max_errors.reporting =
- (unsigned short)(param & 0x0f);
- return 0;
- OUT(FDGETMAXERRS, &UDP->max_errors);
- IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
-
- case FDGETDRVTYP:
- outparam = drive_name(type, drive);
- SUPBOUND(size, strlen(outparam) + 1);
- break;
-
- IN(FDSETDRVPRM, UDP, dp);
- OUT(FDGETDRVPRM, UDP);
-
- case FDPOLLDRVSTAT:
- LOCK_FDC(drive, 1);
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
- process_fd_request();
- /* fall through */
- OUT(FDGETDRVSTAT, UDRS);
-
- case FDRESET:
- return user_reset_fdc(drive, (int)param, 1);
-
- OUT(FDGETFDCSTAT, UFDCS);
-
- case FDWERRORCLR:
- CLEARSTRUCT(UDRWE);
- return 0;
- OUT(FDWERRORGET, UDRWE);
+ }
- case FDRAWCMD:
- if (type)
- return -EINVAL;
- LOCK_FDC(drive, 1);
- set_floppy(drive);
- CALL(i = raw_cmd_ioctl(cmd, (void __user *)param));
- process_fd_request();
- return i;
+ switch (cmd) {
+ case FDEJECT:
+ if (UDRS->fd_ref != 1)
+ /* somebody else has this drive open */
+ return -EBUSY;
+ if (lock_fdc(drive, true))
+ return -EINTR;
- case FDTWADDLE:
- LOCK_FDC(drive, 1);
- twaddle();
- process_fd_request();
- return 0;
+ /* do the actual eject. Fails on
+ * non-Sparc architectures */
+ ret = fd_eject(UNIT(drive));
- default:
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
+ process_fd_request();
+ return ret;
+ case FDCLRPRM:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ current_type[drive] = NULL;
+ floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+ UDRS->keep_data = 0;
+ return invalidate_drive(bdev);
+ case FDSETPRM:
+ case FDDEFPRM:
+ return set_geometry(cmd, &inparam.g, drive, type, bdev);
+ case FDGETPRM:
+ ret = get_floppy_geometry(drive, type,
+ (struct floppy_struct **)
+ &outparam);
+ if (ret)
+ return ret;
+ break;
+ case FDMSGON:
+ UDP->flags |= FTD_MSG;
+ return 0;
+ case FDMSGOFF:
+ UDP->flags &= ~FTD_MSG;
+ return 0;
+ case FDFMTBEG:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+ return -EINTR;
+ ret = UDRS->flags;
+ process_fd_request();
+ if (ret & FD_VERIFY)
+ return -ENODEV;
+ if (!(ret & FD_DISK_WRITABLE))
+ return -EROFS;
+ return 0;
+ case FDFMTTRK:
+ if (UDRS->fd_ref != 1)
+ return -EBUSY;
+ return do_format(drive, &inparam.f);
+ case FDFMTEND:
+ case FDFLUSH:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ return invalidate_drive(bdev);
+ case FDSETEMSGTRESH:
+ UDP->max_errors.reporting = (unsigned short)(param & 0x0f);
+ return 0;
+ case FDGETMAXERRS:
+ outparam = (const char *)&UDP->max_errors;
+ break;
+ case FDSETMAXERRS:
+ UDP->max_errors = inparam.max_errors;
+ break;
+ case FDGETDRVTYP:
+ outparam = drive_name(type, drive);
+ SUPBOUND(size, strlen(outparam) + 1);
+ break;
+ case FDSETDRVPRM:
+ *UDP = inparam.dp;
+ break;
+ case FDGETDRVPRM:
+ outparam = (const char *)UDP;
+ break;
+ case FDPOLLDRVSTAT:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+ return -EINTR;
+ process_fd_request();
+ /* fall through */
+ case FDGETDRVSTAT:
+ outparam = (const char *)UDRS;
+ break;
+ case FDRESET:
+ return user_reset_fdc(drive, (int)param, true);
+ case FDGETFDCSTAT:
+ outparam = (const char *)UFDCS;
+ break;
+ case FDWERRORCLR:
+ memset(UDRWE, 0, sizeof(*UDRWE));
+ return 0;
+ case FDWERRORGET:
+ outparam = (const char *)UDRWE;
+ break;
+ case FDRAWCMD:
+ if (type)
return -EINVAL;
- }
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ set_floppy(drive);
+ i = raw_cmd_ioctl(cmd, (void __user *)param);
+ if (i == -EINTR)
+ return -EINTR;
+ process_fd_request();
+ return i;
+ case FDTWADDLE:
+ if (lock_fdc(drive, true))
+ return -EINTR;
+ twaddle();
+ process_fd_request();
+ return 0;
+ default:
+ return -EINVAL;
+ }
if (_IOC_DIR(cmd) & _IOC_READ)
return fd_copyout((void __user *)param, outparam, size);
- else
- return 0;
-#undef OUT
-#undef IN
+
+ return 0;
}
static void __init config_types(void)
goto out2;
if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) {
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
}
if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL)))
if (mode & (FMODE_READ|FMODE_WRITE)) {
UDRS->last_checked = 0;
check_disk_change(bdev);
- if (UTESTF(FD_DISK_CHANGED))
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags))
goto out;
}
res = -EROFS;
- if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE)))
+ if ((mode & FMODE_WRITE) &&
+ !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags))
goto out;
}
mutex_unlock(&open_lock);
{
int drive = (long)disk->private_data;
- if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags))
return 1;
if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
- lock_fdc(drive, 0);
- poll_drive(0, 0);
+ lock_fdc(drive, false);
+ poll_drive(false, 0);
process_fd_request();
}
- if (UTESTF(FD_DISK_CHANGED) ||
- UTESTF(FD_VERIFY) ||
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
test_bit(drive, &fake_change) ||
(!ITYPE(UDRS->fd_device) && !current_type[drive]))
return 1;
* a disk in the drive, and whether that disk is writable.
*/
-static void floppy_rb0_complete(struct bio *bio,
- int err)
+static void floppy_rb0_complete(struct bio *bio, int err)
{
complete((struct completion *)bio->bi_private);
}
int cf;
int res = 0;
- if (UTESTF(FD_DISK_CHANGED) ||
- UTESTF(FD_VERIFY) || test_bit(drive, &fake_change) || NO_GEOM) {
+ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags) ||
+ test_bit(drive, &fake_change) || NO_GEOM) {
if (usage_count == 0) {
pr_info("VFS: revalidate called on non-open device.\n");
return -EFAULT;
}
- lock_fdc(drive, 0);
- cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
+ lock_fdc(drive, false);
+ cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) ||
+ test_bit(FD_VERIFY_BIT, &UDRS->flags));
if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) {
process_fd_request(); /*already done by another thread */
return 0;
if (buffer_drive == drive)
buffer_track = -1;
clear_bit(drive, &fake_change);
- UCLEARF(FD_DISK_CHANGED);
+ clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
if (cf)
UDRS->generation++;
if (NO_GEOM) {
res = __floppy_read_block_0(opened_bdev[drive]);
} else {
if (cf)
- poll_drive(0, FD_RAW_NEED_DISK);
+ poll_drive(false, FD_RAW_NEED_DISK);
process_fd_request();
}
}
output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */
if (FDCS->reset)
return FDC_NONE;
- if ((r = result()) <= 0x00)
+ r = result();
+ if (r <= 0x00)
return FDC_NONE; /* No FDC present ??? */
if ((r == 1) && (reply_buffer[0] == 0x80)) {
pr_info("FDC %d is an 8272A\n", fdc);
r = result();
if ((r == 1) && (reply_buffer[0] == 0x80)) {
pr_info("FDC %d is a pre-1991 82077\n", fdc);
- return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
+ return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
* LOCK/UNLOCK */
}
if ((r != 1) || (reply_buffer[0] != 0x00)) {
else
param = config_params[i].def_param;
if (config_params[i].fn)
- config_params[i].
- fn(ints, param,
- config_params[i].param2);
+ config_params[i].fn(ints, param,
+ config_params[i].
+ param2);
if (config_params[i].var) {
DPRINT("%s=%d\n", str, param);
*config_params[i].var = param;
for (fdc = 0; fdc < N_FDC; fdc++)
if (FDCS->address != -1)
- user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+ user_reset_fdc(-1, FD_RESET_ALWAYS, false);
return 0;
}
static struct platform_driver floppy_driver = {
.driver = {
- .name = "floppy",
- .pm = &floppy_pm_ops,
+ .name = "floppy",
+ .pm = &floppy_pm_ops,
},
};
for (i = 0; i < N_FDC; i++) {
fdc = i;
- CLEARSTRUCT(FDCS);
+ memset(FDCS, 0, sizeof(*FDCS));
FDCS->dtr = -1;
FDCS->dor = 0x4;
#if defined(__sparc__) || defined(__mc68000__)
- /*sparcs/sun3x don't have a DOR reset which we can fall back on to */
+ /*sparcs/sun3x don't have a DOR reset which we can fall back on to */
#ifdef __mc68000__
if (MACH_IS_SUN3X)
#endif
/* initialise drive state */
for (drive = 0; drive < N_DRIVE; drive++) {
- CLEARSTRUCT(UDRS);
- CLEARSTRUCT(UDRWE);
- USETF(FD_DISK_NEWCHANGE);
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
+ memset(UDRS, 0, sizeof(*UDRS));
+ memset(UDRWE, 0, sizeof(*UDRWE));
+ set_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags);
+ set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags);
+ set_bit(FD_VERIFY_BIT, &UDRS->flags);
UDRS->fd_device = -1;
floppy_track_buffer = NULL;
max_buffer_sectors = 0;
if (FDCS->address == -1)
continue;
FDCS->rawcmd = 2;
- if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
+ if (user_reset_fdc(-1, FD_RESET_ALWAYS, false)) {
/* free ioports reserved by floppy_grab_irq_and_dma() */
floppy_release_regions(fdc);
FDCS->address = -1;
* properly, so force a reset for the standard FDC clones,
* to avoid interrupt garbage.
*/
- user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
+ user_reset_fdc(-1, FD_RESET_ALWAYS, false);
}
fdc = 0;
del_timer(&fd_timeout);
current_drive = 0;
- initialising = 0;
+ initialized = true;
if (have_no_fdc) {
DPRINT("no floppy controllers found\n");
err = have_no_fdc;
if (err)
goto out_flush_work;
- err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+ err = device_create_file(&floppy_device[drive].dev,
+ &dev_attr_cmos);
if (err)
goto out_unreg_platform_dev;
const struct io_region *p;
for (p = io_regions; p < ARRAY_END(io_regions); p++) {
- if (!request_region(FDCS->address + p->offset, p->size, "floppy")) {
- DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset);
+ if (!request_region(FDCS->address + p->offset,
+ p->size, "floppy")) {
+ DPRINT("Floppy io-port 0x%04lx in use\n",
+ FDCS->address + p->offset);
floppy_release_allocated_regions(fdc, p);
return -EBUSY;
}
char *ptr;
while (*cfg) {
- for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ;
+ ptr = cfg;
+ while (*cfg && *cfg != ' ' && *cfg != '\t')
+ cfg++;
if (*cfg) {
*cfg = '\0';
cfg++;