Commit da1f5f86 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] first cut ftape conversion

(Paulo Andre)
parent 818fb102
...@@ -66,6 +66,7 @@ int ft_mach2 = CONFIG_FT_MACH2; ...@@ -66,6 +66,7 @@ int ft_mach2 = CONFIG_FT_MACH2;
/* Local vars. /* Local vars.
*/ */
static spinlock_t fdc_io_lock;
static unsigned int fdc_calibr_count; static unsigned int fdc_calibr_count;
static unsigned int fdc_calibr_time; static unsigned int fdc_calibr_time;
static int fdc_status; static int fdc_status;
...@@ -89,14 +90,13 @@ void fdc_catch_stray_interrupts(int count) ...@@ -89,14 +90,13 @@ void fdc_catch_stray_interrupts(int count)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli();
if (count == 0) { if (count == 0) {
ft_expected_stray_interrupts = 0; ft_expected_stray_interrupts = 0;
} else { } else {
ft_expected_stray_interrupts += count; ft_expected_stray_interrupts += count;
} }
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
} }
/* Wait during a timeout period for a given FDC status. /* Wait during a timeout period for a given FDC status.
...@@ -194,8 +194,7 @@ int fdc_command(const __u8 * cmd_data, int cmd_len) ...@@ -194,8 +194,7 @@ int fdc_command(const __u8 * cmd_data, int cmd_len)
TRACE_FUN(ft_t_any); TRACE_FUN(ft_t_any);
fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli();
if (!in_interrupt()) if (!in_interrupt())
/* Yes, I know, too much comments inside this function /* Yes, I know, too much comments inside this function
* ... * ...
...@@ -242,12 +241,11 @@ int fdc_command(const __u8 * cmd_data, int cmd_len) ...@@ -242,12 +241,11 @@ int fdc_command(const __u8 * cmd_data, int cmd_len)
} }
fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */ fdc_usec_wait(FT_RQM_DELAY); /* wait for valid RQM status */
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli();
} }
fdc_status = inb(fdc.msr); fdc_status = inb(fdc.msr);
if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) { if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_IN_READY) {
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready"); TRACE_ABORT(-EBUSY, ft_t_err, "fdc not ready");
} }
fdc_mode = *cmd_data; /* used by isr */ fdc_mode = *cmd_data; /* used by isr */
...@@ -289,7 +287,7 @@ int fdc_command(const __u8 * cmd_data, int cmd_len) ...@@ -289,7 +287,7 @@ int fdc_command(const __u8 * cmd_data, int cmd_len)
last_time = ftape_timestamp(); last_time = ftape_timestamp();
} }
#endif #endif
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
TRACE_EXIT result; TRACE_EXIT result;
} }
...@@ -305,15 +303,14 @@ int fdc_result(__u8 * res_data, int res_len) ...@@ -305,15 +303,14 @@ int fdc_result(__u8 * res_data, int res_len)
int retry = 0; int retry = 0;
TRACE_FUN(ft_t_any); TRACE_FUN(ft_t_any);
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli();
fdc_status = inb(fdc.msr); fdc_status = inb(fdc.msr);
if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) { if ((fdc_status & FDC_DATA_READY_MASK) != FDC_DATA_OUT_READY) {
TRACE(ft_t_err, "fdc not ready"); TRACE(ft_t_err, "fdc not ready");
result = -EBUSY; result = -EBUSY;
} else while (count) { } else while (count) {
if (!(fdc_status & FDC_BUSY)) { if (!(fdc_status & FDC_BUSY)) {
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase"); TRACE_ABORT(-EIO, ft_t_err, "premature end of result phase");
} }
result = fdc_read(res_data); result = fdc_read(res_data);
...@@ -336,7 +333,7 @@ int fdc_result(__u8 * res_data, int res_len) ...@@ -336,7 +333,7 @@ int fdc_result(__u8 * res_data, int res_len)
++res_data; ++res_data;
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
fdc_usec_wait(FT_RQM_DELAY); /* allow FDC to negate BSY */ fdc_usec_wait(FT_RQM_DELAY); /* allow FDC to negate BSY */
TRACE_EXIT result; TRACE_EXIT result;
} }
...@@ -609,8 +606,7 @@ void fdc_reset(void) ...@@ -609,8 +606,7 @@ void fdc_reset(void)
unsigned long flags; unsigned long flags;
TRACE_FUN(ft_t_any); TRACE_FUN(ft_t_any);
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli();
fdc_dor_reset(1); /* keep unit selected */ fdc_dor_reset(1); /* keep unit selected */
...@@ -629,7 +625,7 @@ void fdc_reset(void) ...@@ -629,7 +625,7 @@ void fdc_reset(void)
*/ */
fdc_update_dsr(); /* restore data rate and precomp */ fdc_update_dsr(); /* restore data rate and precomp */
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
/* /*
* Wait for first polling cycle to complete * Wait for first polling cycle to complete
...@@ -928,8 +924,7 @@ int fdc_setup_formatting(buffer_struct * buff) ...@@ -928,8 +924,7 @@ int fdc_setup_formatting(buffer_struct * buff)
*/ */
TRACE(ft_t_fdc_dma, TRACE(ft_t_fdc_dma,
"phys. addr. = %lx", virt_to_bus((void*) buff->ptr)); "phys. addr. = %lx", virt_to_bus((void*) buff->ptr));
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli(); /* could be called from ISR ! */
fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4); fdc_setup_dma(DMA_MODE_WRITE, buff->ptr, FT_SECTORS_PER_SEGMENT * 4);
/* Issue FDC command to start reading/writing. /* Issue FDC command to start reading/writing.
*/ */
...@@ -937,7 +932,7 @@ int fdc_setup_formatting(buffer_struct * buff) ...@@ -937,7 +932,7 @@ int fdc_setup_formatting(buffer_struct * buff)
out[4] = buff->gap3; out[4] = buff->gap3;
TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)), TRACE_CATCH(fdc_setup_error = fdc_command(out, sizeof(out)),
restore_flags(flags); fdc_mode = fdc_idle); restore_flags(flags); fdc_mode = fdc_idle);
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
TRACE_EXIT 0; TRACE_EXIT 0;
} }
...@@ -977,11 +972,10 @@ int fdc_setup_read_write(buffer_struct * buff, __u8 operation) ...@@ -977,11 +972,10 @@ int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
break; break;
default: default:
TRACE_ABORT(-EIO, TRACE_ABORT(-EIO,
ft_t_bug, "bug: illegal operation parameter"); ft_t_bug, "bug: invalid operation parameter");
} }
TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr)); TRACE(ft_t_fdc_dma, "phys. addr. = %lx",virt_to_bus((void*)buff->ptr));
save_flags(flags); spin_lock_irqsave(&fdc_io_lock, flags);
cli(); /* could be called from ISR ! */
if (operation != FDC_VERIFY) { if (operation != FDC_VERIFY) {
fdc_setup_dma(dma_mode, buff->ptr, fdc_setup_dma(dma_mode, buff->ptr,
FT_SECTOR_SIZE * buff->sector_count); FT_SECTOR_SIZE * buff->sector_count);
...@@ -999,7 +993,7 @@ int fdc_setup_read_write(buffer_struct * buff, __u8 operation) ...@@ -999,7 +993,7 @@ int fdc_setup_read_write(buffer_struct * buff, __u8 operation)
out[8] = 0xff; /* No limit to transfer size. */ out[8] = 0xff; /* No limit to transfer size. */
TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x", TRACE(ft_t_fdc_dma, "C: 0x%02x, H: 0x%02x, R: 0x%02x, cnt: 0x%02x",
out[2], out[3], out[4], out[6] - out[4] + 1); out[2], out[3], out[4], out[6] - out[4] + 1);
restore_flags(flags); spin_unlock_irqrestore(&fdc_io_lock, flags);
TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle); TRACE_CATCH(fdc_setup_error = fdc_command(out, 9),fdc_mode = fdc_idle);
TRACE_EXIT 0; TRACE_EXIT 0;
} }
......
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
static unsigned long ps_per_cycle = 0; static unsigned long ps_per_cycle = 0;
#endif #endif
static spinlock_t calibr_lock;
/* /*
* Note: On Intel PCs, the clock ticks at 100 Hz (HZ==100) which is * Note: On Intel PCs, the clock ticks at 100 Hz (HZ==100) which is
* too slow for certain timeouts (and that clock doesn't even tick * too slow for certain timeouts (and that clock doesn't even tick
...@@ -75,13 +77,12 @@ unsigned int ftape_timestamp(void) ...@@ -75,13 +77,12 @@ unsigned int ftape_timestamp(void)
__u16 lo; __u16 lo;
__u16 hi; __u16 hi;
save_flags(flags); spin_lock_irqsave(&calibr_lock, flags);
cli();
outb_p(0x00, 0x43); /* latch the count ASAP */ outb_p(0x00, 0x43); /* latch the count ASAP */
lo = inb_p(0x40); /* read the latched count */ lo = inb_p(0x40); /* read the latched count */
lo |= inb(0x40) << 8; lo |= inb(0x40) << 8;
hi = jiffies; hi = jiffies;
restore_flags(flags); spin_unlock_irqrestore(&calibr_lock, flags);
return ((hi + 1) * (unsigned int) LATCH) - lo; /* downcounter ! */ return ((hi + 1) * (unsigned int) LATCH) - lo; /* downcounter ! */
#endif #endif
} }
...@@ -94,12 +95,11 @@ static unsigned int short_ftape_timestamp(void) ...@@ -94,12 +95,11 @@ static unsigned int short_ftape_timestamp(void)
unsigned int count; unsigned int count;
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&calibr_lock, flags);
cli();
outb_p(0x00, 0x43); /* latch the count ASAP */ outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */ count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8; count |= inb(0x40) << 8;
restore_flags(flags); spin_unlock_irqrestore(&calibr_lock, flags);
return (LATCH - count); /* normal: downcounter */ return (LATCH - count); /* normal: downcounter */
#endif #endif
} }
...@@ -150,14 +150,13 @@ static void time_inb(void) ...@@ -150,14 +150,13 @@ static void time_inb(void)
int status; int status;
TRACE_FUN(ft_t_any); TRACE_FUN(ft_t_any);
save_flags(flags); spin_lock_irqsave(&calibr_lock, flags);
cli();
t0 = short_ftape_timestamp(); t0 = short_ftape_timestamp();
for (i = 0; i < 1000; ++i) { for (i = 0; i < 1000; ++i) {
status = inb(fdc.msr); status = inb(fdc.msr);
} }
t1 = short_ftape_timestamp(); t1 = short_ftape_timestamp();
restore_flags(flags); spin_unlock_irqrestore(&calibr_lock, flags);
TRACE(ft_t_info, "inb() duration: %d nsec", ftape_timediff(t0, t1)); TRACE(ft_t_info, "inb() duration: %d nsec", ftape_timediff(t0, t1));
TRACE_EXIT; TRACE_EXIT;
} }
...@@ -241,8 +240,7 @@ void ftape_calibrate(char *name, ...@@ -241,8 +240,7 @@ void ftape_calibrate(char *name,
*calibr_count = *calibr_count =
*calibr_time = count; /* set TC to 1 */ *calibr_time = count; /* set TC to 1 */
save_flags(flags); spin_lock_irqsave(&calibr_lock, flags);
cli();
fun(0); /* dummy, get code into cache */ fun(0); /* dummy, get code into cache */
t0 = short_ftape_timestamp(); t0 = short_ftape_timestamp();
fun(0); /* overhead + one test */ fun(0); /* overhead + one test */
...@@ -252,7 +250,7 @@ void ftape_calibrate(char *name, ...@@ -252,7 +250,7 @@ void ftape_calibrate(char *name,
fun(count); /* overhead + count tests */ fun(count); /* overhead + count tests */
t1 = short_ftape_timestamp(); t1 = short_ftape_timestamp();
multiple = diff(t0, t1); multiple = diff(t0, t1);
restore_flags(flags); spin_unlock_irqrestore(&calibr_lock, flags);
time = ftape_timediff(0, multiple - once); time = ftape_timediff(0, multiple - once);
tc = (1000 * time) / (count - 1); tc = (1000 * time) / (count - 1);
TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns", TRACE(ft_t_any, "once:%3d us,%6d times:%6d us, TC:%5d ns",
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#define FT_FMT_SEGS_PER_BUF (FT_BUFF_SIZE/(4*FT_SECTORS_PER_SEGMENT)) #define FT_FMT_SEGS_PER_BUF (FT_BUFF_SIZE/(4*FT_SECTORS_PER_SEGMENT))
#endif #endif
static spinlock_t ftape_format_lock;
/* /*
* first segment of the new buffer * first segment of the new buffer
*/ */
...@@ -129,9 +131,9 @@ int ftape_format_track(const unsigned int track, const __u8 gap3) ...@@ -129,9 +131,9 @@ int ftape_format_track(const unsigned int track, const __u8 gap3)
head->status = formatting; head->status = formatting;
TRACE_CATCH(ftape_seek_head_to_track(track),); TRACE_CATCH(ftape_seek_head_to_track(track),);
TRACE_CATCH(ftape_command(QIC_LOGICAL_FORWARD),); TRACE_CATCH(ftape_command(QIC_LOGICAL_FORWARD),);
save_flags(flags); cli(); spin_lock_irqsave(&ftape_format_lock, flags);
TRACE_CATCH(fdc_setup_formatting(head), restore_flags(flags)); TRACE_CATCH(fdc_setup_formatting(head), restore_flags(flags));
restore_flags(flags); spin_unlock_irqrestore(&ftape_format_lock, flags);
TRACE_EXIT 0; TRACE_EXIT 0;
} }
......
...@@ -118,7 +118,7 @@ static int zft_open(struct inode *ino, struct file *filep) ...@@ -118,7 +118,7 @@ static int zft_open(struct inode *ino, struct file *filep)
> >
FTAPE_SEL_D) { FTAPE_SEL_D) {
clear_bit(0,&busy_flag); clear_bit(0,&busy_flag);
TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr"); TRACE_ABORT(-ENXIO, ft_t_err, "failed: invalid unit nr");
} }
orig_sigmask = current->blocked; orig_sigmask = current->blocked;
sigfillset(&current->blocked); sigfillset(&current->blocked);
......
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