diff options
Diffstat (limited to 'drivers/block/floppy.c')
-rw-r--r-- | drivers/block/floppy.c | 1493 |
1 files changed, 737 insertions, 756 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index b9b117059b62..90c4038702da 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -144,13 +144,23 @@ | |||
144 | * Better audit of register_blkdev. | 144 | * Better audit of register_blkdev. |
145 | */ | 145 | */ |
146 | 146 | ||
147 | #define FLOPPY_SANITY_CHECK | ||
148 | #undef FLOPPY_SILENT_DCL_CLEAR | 147 | #undef FLOPPY_SILENT_DCL_CLEAR |
149 | 148 | ||
150 | #define REALLY_SLOW_IO | 149 | #define REALLY_SLOW_IO |
151 | 150 | ||
152 | #define DEBUGT 2 | 151 | #define DEBUGT 2 |
153 | #define DCL_DEBUG /* debug disk change line */ | 152 | |
153 | #define DPRINT(format, args...) \ | ||
154 | pr_info("floppy%d: " format, current_drive, ##args) | ||
155 | |||
156 | #define DCL_DEBUG /* debug disk change line */ | ||
157 | #ifdef DCL_DEBUG | ||
158 | #define debug_dcl(test, fmt, args...) \ | ||
159 | do { if ((test) & FD_DEBUG) DPRINT(fmt, ##args); } while (0) | ||
160 | #else | ||
161 | #define debug_dcl(test, fmt, args...) \ | ||
162 | do { if (0) DPRINT(fmt, ##args); } while (0) | ||
163 | #endif | ||
154 | 164 | ||
155 | /* do print messages for unexpected interrupts */ | 165 | /* do print messages for unexpected interrupts */ |
156 | static int print_unex = 1; | 166 | static int print_unex = 1; |
@@ -180,6 +190,8 @@ static int print_unex = 1; | |||
180 | #include <linux/mod_devicetable.h> | 190 | #include <linux/mod_devicetable.h> |
181 | #include <linux/buffer_head.h> /* for invalidate_buffers() */ | 191 | #include <linux/buffer_head.h> /* for invalidate_buffers() */ |
182 | #include <linux/mutex.h> | 192 | #include <linux/mutex.h> |
193 | #include <linux/io.h> | ||
194 | #include <linux/uaccess.h> | ||
183 | 195 | ||
184 | /* | 196 | /* |
185 | * PS/2 floppies have much slower step rates than regular floppies. | 197 | * PS/2 floppies have much slower step rates than regular floppies. |
@@ -191,8 +203,6 @@ static int slow_floppy; | |||
191 | #include <asm/dma.h> | 203 | #include <asm/dma.h> |
192 | #include <asm/irq.h> | 204 | #include <asm/irq.h> |
193 | #include <asm/system.h> | 205 | #include <asm/system.h> |
194 | #include <asm/io.h> | ||
195 | #include <asm/uaccess.h> | ||
196 | 206 | ||
197 | static int FLOPPY_IRQ = 6; | 207 | static int FLOPPY_IRQ = 6; |
198 | static int FLOPPY_DMA = 2; | 208 | static int FLOPPY_DMA = 2; |
@@ -241,8 +251,6 @@ static int allowed_drive_mask = 0x33; | |||
241 | 251 | ||
242 | static int irqdma_allocated; | 252 | static int irqdma_allocated; |
243 | 253 | ||
244 | #define DEVICE_NAME "floppy" | ||
245 | |||
246 | #include <linux/blkdev.h> | 254 | #include <linux/blkdev.h> |
247 | #include <linux/blkpg.h> | 255 | #include <linux/blkpg.h> |
248 | #include <linux/cdrom.h> /* for the compatibility eject ioctl */ | 256 | #include <linux/cdrom.h> /* for the compatibility eject ioctl */ |
@@ -250,7 +258,7 @@ static int irqdma_allocated; | |||
250 | 258 | ||
251 | static struct request *current_req; | 259 | static struct request *current_req; |
252 | static struct request_queue *floppy_queue; | 260 | static struct request_queue *floppy_queue; |
253 | static void do_fd_request(struct request_queue * q); | 261 | static void do_fd_request(struct request_queue *q); |
254 | 262 | ||
255 | #ifndef fd_get_dma_residue | 263 | #ifndef fd_get_dma_residue |
256 | #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) | 264 | #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) |
@@ -263,7 +271,7 @@ static void do_fd_request(struct request_queue * q); | |||
263 | #endif | 271 | #endif |
264 | 272 | ||
265 | #ifndef fd_dma_mem_alloc | 273 | #ifndef fd_dma_mem_alloc |
266 | #define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size)) | 274 | #define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL, get_order(size)) |
267 | #endif | 275 | #endif |
268 | 276 | ||
269 | static inline void fallback_on_nodma_alloc(char **addr, size_t l) | 277 | static inline void fallback_on_nodma_alloc(char **addr, size_t l) |
@@ -273,7 +281,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) | |||
273 | return; /* we have the memory */ | 281 | return; /* we have the memory */ |
274 | if (can_use_virtual_dma != 2) | 282 | if (can_use_virtual_dma != 2) |
275 | return; /* no fallback allowed */ | 283 | return; /* no fallback allowed */ |
276 | printk("DMA memory shortage. Temporarily falling back on virtual DMA\n"); | 284 | pr_info("DMA memory shortage. Temporarily falling back on virtual DMA\n"); |
277 | *addr = (char *)nodma_mem_alloc(l); | 285 | *addr = (char *)nodma_mem_alloc(l); |
278 | #else | 286 | #else |
279 | return; | 287 | return; |
@@ -283,59 +291,50 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) | |||
283 | /* End dma memory related stuff */ | 291 | /* End dma memory related stuff */ |
284 | 292 | ||
285 | static unsigned long fake_change; | 293 | static unsigned long fake_change; |
286 | static int initialising = 1; | 294 | static bool initialized; |
287 | 295 | ||
288 | #define ITYPE(x) (((x)>>2) & 0x1f) | 296 | #define ITYPE(x) (((x) >> 2) & 0x1f) |
289 | #define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) | 297 | #define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) |
290 | #define UNIT(x) ((x) & 0x03) /* drive on fdc */ | 298 | #define UNIT(x) ((x) & 0x03) /* drive on fdc */ |
291 | #define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ | 299 | #define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ |
292 | /* reverse mapping from unit and fdc to drive */ | 300 | /* reverse mapping from unit and fdc to drive */ |
293 | #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) | 301 | #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) |
294 | #define DP (&drive_params[current_drive]) | ||
295 | #define DRS (&drive_state[current_drive]) | ||
296 | #define DRWE (&write_errors[current_drive]) | ||
297 | #define FDCS (&fdc_state[fdc]) | ||
298 | #define CLEARF(x) clear_bit(x##_BIT, &DRS->flags) | ||
299 | #define SETF(x) set_bit(x##_BIT, &DRS->flags) | ||
300 | #define TESTF(x) test_bit(x##_BIT, &DRS->flags) | ||
301 | 302 | ||
302 | #define UDP (&drive_params[drive]) | 303 | #define DP (&drive_params[current_drive]) |
303 | #define UDRS (&drive_state[drive]) | 304 | #define DRS (&drive_state[current_drive]) |
304 | #define UDRWE (&write_errors[drive]) | 305 | #define DRWE (&write_errors[current_drive]) |
305 | #define UFDCS (&fdc_state[FDC(drive)]) | 306 | #define FDCS (&fdc_state[fdc]) |
306 | #define UCLEARF(x) clear_bit(x##_BIT, &UDRS->flags) | ||
307 | #define USETF(x) set_bit(x##_BIT, &UDRS->flags) | ||
308 | #define UTESTF(x) test_bit(x##_BIT, &UDRS->flags) | ||
309 | 307 | ||
310 | #define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args) | 308 | #define UDP (&drive_params[drive]) |
309 | #define UDRS (&drive_state[drive]) | ||
310 | #define UDRWE (&write_errors[drive]) | ||
311 | #define UFDCS (&fdc_state[FDC(drive)]) | ||
311 | 312 | ||
312 | #define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2) | 313 | #define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2) |
313 | #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) | 314 | #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) |
314 | |||
315 | #define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x))) | ||
316 | 315 | ||
317 | /* read/write */ | 316 | /* read/write */ |
318 | #define COMMAND raw_cmd->cmd[0] | 317 | #define COMMAND (raw_cmd->cmd[0]) |
319 | #define DR_SELECT raw_cmd->cmd[1] | 318 | #define DR_SELECT (raw_cmd->cmd[1]) |
320 | #define TRACK raw_cmd->cmd[2] | 319 | #define TRACK (raw_cmd->cmd[2]) |
321 | #define HEAD raw_cmd->cmd[3] | 320 | #define HEAD (raw_cmd->cmd[3]) |
322 | #define SECTOR raw_cmd->cmd[4] | 321 | #define SECTOR (raw_cmd->cmd[4]) |
323 | #define SIZECODE raw_cmd->cmd[5] | 322 | #define SIZECODE (raw_cmd->cmd[5]) |
324 | #define SECT_PER_TRACK raw_cmd->cmd[6] | 323 | #define SECT_PER_TRACK (raw_cmd->cmd[6]) |
325 | #define GAP raw_cmd->cmd[7] | 324 | #define GAP (raw_cmd->cmd[7]) |
326 | #define SIZECODE2 raw_cmd->cmd[8] | 325 | #define SIZECODE2 (raw_cmd->cmd[8]) |
327 | #define NR_RW 9 | 326 | #define NR_RW 9 |
328 | 327 | ||
329 | /* format */ | 328 | /* format */ |
330 | #define F_SIZECODE raw_cmd->cmd[2] | 329 | #define F_SIZECODE (raw_cmd->cmd[2]) |
331 | #define F_SECT_PER_TRACK raw_cmd->cmd[3] | 330 | #define F_SECT_PER_TRACK (raw_cmd->cmd[3]) |
332 | #define F_GAP raw_cmd->cmd[4] | 331 | #define F_GAP (raw_cmd->cmd[4]) |
333 | #define F_FILL raw_cmd->cmd[5] | 332 | #define F_FILL (raw_cmd->cmd[5]) |
334 | #define NR_F 6 | 333 | #define NR_F 6 |
335 | 334 | ||
336 | /* | 335 | /* |
337 | * Maximum disk size (in kilobytes). This default is used whenever the | 336 | * Maximum disk size (in kilobytes). |
338 | * current disk size is unknown. | 337 | * This default is used whenever the current disk size is unknown. |
339 | * [Now it is rather a minimum] | 338 | * [Now it is rather a minimum] |
340 | */ | 339 | */ |
341 | #define MAX_DISK_SIZE 4 /* 3984 */ | 340 | #define MAX_DISK_SIZE 4 /* 3984 */ |
@@ -345,16 +344,17 @@ static int initialising = 1; | |||
345 | */ | 344 | */ |
346 | #define MAX_REPLIES 16 | 345 | #define MAX_REPLIES 16 |
347 | static unsigned char reply_buffer[MAX_REPLIES]; | 346 | static unsigned char reply_buffer[MAX_REPLIES]; |
348 | static int inr; /* size of reply buffer, when called from interrupt */ | 347 | static int inr; /* size of reply buffer, when called from interrupt */ |
349 | #define ST0 (reply_buffer[0]) | 348 | #define ST0 (reply_buffer[0]) |
350 | #define ST1 (reply_buffer[1]) | 349 | #define ST1 (reply_buffer[1]) |
351 | #define ST2 (reply_buffer[2]) | 350 | #define ST2 (reply_buffer[2]) |
352 | #define ST3 (reply_buffer[0]) /* result of GETSTATUS */ | 351 | #define ST3 (reply_buffer[0]) /* result of GETSTATUS */ |
353 | #define R_TRACK (reply_buffer[3]) | 352 | #define R_TRACK (reply_buffer[3]) |
354 | #define R_HEAD (reply_buffer[4]) | 353 | #define R_HEAD (reply_buffer[4]) |
355 | #define R_SECTOR (reply_buffer[5]) | 354 | #define R_SECTOR (reply_buffer[5]) |
356 | #define R_SIZECODE (reply_buffer[6]) | 355 | #define R_SIZECODE (reply_buffer[6]) |
357 | #define SEL_DLY (2*HZ/100) | 356 | |
357 | #define SEL_DLY (2 * HZ / 100) | ||
358 | 358 | ||
359 | /* | 359 | /* |
360 | * this struct defines the different floppy drive types. | 360 | * this struct defines the different floppy drive types. |
@@ -505,9 +505,9 @@ static char floppy_device_name[] = "floppy"; | |||
505 | static int probing; | 505 | static int probing; |
506 | 506 | ||
507 | /* Synchronization of FDC access. */ | 507 | /* Synchronization of FDC access. */ |
508 | #define FD_COMMAND_NONE -1 | 508 | #define FD_COMMAND_NONE -1 |
509 | #define FD_COMMAND_ERROR 2 | 509 | #define FD_COMMAND_ERROR 2 |
510 | #define FD_COMMAND_OKAY 3 | 510 | #define FD_COMMAND_OKAY 3 |
511 | 511 | ||
512 | static volatile int command_status = FD_COMMAND_NONE; | 512 | static volatile int command_status = FD_COMMAND_NONE; |
513 | static unsigned long fdc_busy; | 513 | static unsigned long fdc_busy; |
@@ -515,11 +515,6 @@ static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); | |||
515 | static DECLARE_WAIT_QUEUE_HEAD(command_done); | 515 | static DECLARE_WAIT_QUEUE_HEAD(command_done); |
516 | 516 | ||
517 | #define NO_SIGNAL (!interruptible || !signal_pending(current)) | 517 | #define NO_SIGNAL (!interruptible || !signal_pending(current)) |
518 | #define CALL(x) if ((x) == -EINTR) return -EINTR | ||
519 | #define ECALL(x) if ((ret = (x))) return ret; | ||
520 | #define _WAIT(x,i) CALL(ret=wait_til_done((x),i)) | ||
521 | #define WAIT(x) _WAIT((x),interruptible) | ||
522 | #define IWAIT(x) _WAIT((x),1) | ||
523 | 518 | ||
524 | /* Errors during formatting are counted here. */ | 519 | /* Errors during formatting are counted here. */ |
525 | static int format_errors; | 520 | static int format_errors; |
@@ -545,8 +540,9 @@ static int max_buffer_sectors; | |||
545 | static int *errors; | 540 | static int *errors; |
546 | typedef void (*done_f)(int); | 541 | typedef void (*done_f)(int); |
547 | static struct cont_t { | 542 | static struct cont_t { |
548 | void (*interrupt)(void); /* this is called after the interrupt of the | 543 | void (*interrupt)(void); |
549 | * main command */ | 544 | /* this is called after the interrupt of the |
545 | * main command */ | ||
550 | void (*redo)(void); /* this is called to retry the operation */ | 546 | void (*redo)(void); /* this is called to retry the operation */ |
551 | void (*error)(void); /* this is called to tally an error */ | 547 | void (*error)(void); /* this is called to tally an error */ |
552 | done_f done; /* this is called to say if the operation has | 548 | done_f done; /* this is called to say if the operation has |
@@ -571,7 +567,6 @@ static void floppy_release_irq_and_dma(void); | |||
571 | * reset doesn't need to be tested before sending commands, because | 567 | * reset doesn't need to be tested before sending commands, because |
572 | * output_byte is automatically disabled when reset is set. | 568 | * output_byte is automatically disabled when reset is set. |
573 | */ | 569 | */ |
574 | #define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } } | ||
575 | static void reset_fdc(void); | 570 | static void reset_fdc(void); |
576 | 571 | ||
577 | /* | 572 | /* |
@@ -579,9 +574,9 @@ static void reset_fdc(void); | |||
579 | * information to interrupts. They are the data used for the current | 574 | * information to interrupts. They are the data used for the current |
580 | * request. | 575 | * request. |
581 | */ | 576 | */ |
582 | #define NO_TRACK -1 | 577 | #define NO_TRACK -1 |
583 | #define NEED_1_RECAL -2 | 578 | #define NEED_1_RECAL -2 |
584 | #define NEED_2_RECAL -3 | 579 | #define NEED_2_RECAL -3 |
585 | 580 | ||
586 | static int usage_count; | 581 | static int usage_count; |
587 | 582 | ||
@@ -621,39 +616,35 @@ static inline void set_debugt(void) | |||
621 | debugtimer = jiffies; | 616 | debugtimer = jiffies; |
622 | } | 617 | } |
623 | 618 | ||
624 | static inline void debugt(const char *message) | 619 | static inline void debugt(const char *func, const char *msg) |
625 | { | 620 | { |
626 | if (DP->flags & DEBUGT) | 621 | if (DP->flags & DEBUGT) |
627 | printk("%s dtime=%lu\n", message, jiffies - debugtimer); | 622 | pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer); |
628 | } | 623 | } |
629 | #else | 624 | #else |
630 | static inline void set_debugt(void) { } | 625 | static inline void set_debugt(void) { } |
631 | static inline void debugt(const char *message) { } | 626 | static inline void debugt(const char *func, const char *msg) { } |
632 | #endif /* DEBUGT */ | 627 | #endif /* DEBUGT */ |
633 | 628 | ||
634 | typedef void (*timeout_fn) (unsigned long); | 629 | typedef void (*timeout_fn)(unsigned long); |
635 | static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); | 630 | static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); |
636 | 631 | ||
637 | static const char *timeout_message; | 632 | static const char *timeout_message; |
638 | 633 | ||
639 | #ifdef FLOPPY_SANITY_CHECK | 634 | static void is_alive(const char *func, const char *message) |
640 | static void is_alive(const char *message) | ||
641 | { | 635 | { |
642 | /* this routine checks whether the floppy driver is "alive" */ | 636 | /* this routine checks whether the floppy driver is "alive" */ |
643 | if (test_bit(0, &fdc_busy) && command_status < 2 | 637 | if (test_bit(0, &fdc_busy) && command_status < 2 && |
644 | && !timer_pending(&fd_timeout)) { | 638 | !timer_pending(&fd_timeout)) { |
645 | DPRINT("timeout handler died: %s\n", message); | 639 | DPRINT("%s: timeout handler died. %s\n", func, message); |
646 | } | 640 | } |
647 | } | 641 | } |
648 | #endif | ||
649 | 642 | ||
650 | static void (*do_floppy) (void) = NULL; | 643 | static void (*do_floppy)(void) = NULL; |
651 | |||
652 | #ifdef FLOPPY_SANITY_CHECK | ||
653 | 644 | ||
654 | #define OLOGSIZE 20 | 645 | #define OLOGSIZE 20 |
655 | 646 | ||
656 | static void (*lasthandler) (void); | 647 | static void (*lasthandler)(void); |
657 | static unsigned long interruptjiffies; | 648 | static unsigned long interruptjiffies; |
658 | static unsigned long resultjiffies; | 649 | static unsigned long resultjiffies; |
659 | static int resultsize; | 650 | static int resultsize; |
@@ -666,12 +657,11 @@ static struct output_log { | |||
666 | } output_log[OLOGSIZE]; | 657 | } output_log[OLOGSIZE]; |
667 | 658 | ||
668 | static int output_log_pos; | 659 | static int output_log_pos; |
669 | #endif | ||
670 | 660 | ||
671 | #define current_reqD -1 | 661 | #define current_reqD -1 |
672 | #define MAXTIMEOUT -2 | 662 | #define MAXTIMEOUT -2 |
673 | 663 | ||
674 | static void __reschedule_timeout(int drive, const char *message, int marg) | 664 | static void __reschedule_timeout(int drive, const char *message) |
675 | { | 665 | { |
676 | if (drive == current_reqD) | 666 | if (drive == current_reqD) |
677 | drive = current_drive; | 667 | drive = current_drive; |
@@ -682,25 +672,22 @@ static void __reschedule_timeout(int drive, const char *message, int marg) | |||
682 | } else | 672 | } else |
683 | fd_timeout.expires = jiffies + UDP->timeout; | 673 | fd_timeout.expires = jiffies + UDP->timeout; |
684 | add_timer(&fd_timeout); | 674 | add_timer(&fd_timeout); |
685 | if (UDP->flags & FD_DEBUG) { | 675 | if (UDP->flags & FD_DEBUG) |
686 | DPRINT("reschedule timeout "); | 676 | DPRINT("reschedule timeout %s\n", message); |
687 | printk(message, marg); | ||
688 | printk("\n"); | ||
689 | } | ||
690 | timeout_message = message; | 677 | timeout_message = message; |
691 | } | 678 | } |
692 | 679 | ||
693 | static void reschedule_timeout(int drive, const char *message, int marg) | 680 | static void reschedule_timeout(int drive, const char *message) |
694 | { | 681 | { |
695 | unsigned long flags; | 682 | unsigned long flags; |
696 | 683 | ||
697 | spin_lock_irqsave(&floppy_lock, flags); | 684 | spin_lock_irqsave(&floppy_lock, flags); |
698 | __reschedule_timeout(drive, message, marg); | 685 | __reschedule_timeout(drive, message); |
699 | spin_unlock_irqrestore(&floppy_lock, flags); | 686 | spin_unlock_irqrestore(&floppy_lock, flags); |
700 | } | 687 | } |
701 | 688 | ||
702 | #define INFBOUND(a,b) (a)=max_t(int, a, b) | 689 | #define INFBOUND(a, b) (a) = max_t(int, a, b) |
703 | #define SUPBOUND(a,b) (a)=min_t(int, a, b) | 690 | #define SUPBOUND(a, b) (a) = min_t(int, a, b) |
704 | 691 | ||
705 | /* | 692 | /* |
706 | * Bottom half floppy driver. | 693 | * Bottom half floppy driver. |
@@ -739,7 +726,6 @@ static int disk_change(int drive) | |||
739 | { | 726 | { |
740 | int fdc = FDC(drive); | 727 | int fdc = FDC(drive); |
741 | 728 | ||
742 | #ifdef FLOPPY_SANITY_CHECK | ||
743 | if (time_before(jiffies, UDRS->select_date + UDP->select_delay)) | 729 | if (time_before(jiffies, UDRS->select_date + UDP->select_delay)) |
744 | DPRINT("WARNING disk change called early\n"); | 730 | DPRINT("WARNING disk change called early\n"); |
745 | if (!(FDCS->dor & (0x10 << UNIT(drive))) || | 731 | if (!(FDCS->dor & (0x10 << UNIT(drive))) || |
@@ -748,31 +734,27 @@ static int disk_change(int drive) | |||
748 | DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive), | 734 | DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive), |
749 | (unsigned int)FDCS->dor); | 735 | (unsigned int)FDCS->dor); |
750 | } | 736 | } |
751 | #endif | ||
752 | 737 | ||
753 | #ifdef DCL_DEBUG | 738 | debug_dcl(UDP->flags, |
754 | if (UDP->flags & FD_DEBUG) { | 739 | "checking disk change line for drive %d\n", drive); |
755 | DPRINT("checking disk change line for drive %d\n", drive); | 740 | debug_dcl(UDP->flags, "jiffies=%lu\n", jiffies); |
756 | DPRINT("jiffies=%lu\n", jiffies); | 741 | debug_dcl(UDP->flags, "disk change line=%x\n", fd_inb(FD_DIR) & 0x80); |
757 | DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80); | 742 | debug_dcl(UDP->flags, "flags=%lx\n", UDRS->flags); |
758 | DPRINT("flags=%lx\n", UDRS->flags); | 743 | |
759 | } | ||
760 | #endif | ||
761 | if (UDP->flags & FD_BROKEN_DCL) | 744 | if (UDP->flags & FD_BROKEN_DCL) |
762 | return UTESTF(FD_DISK_CHANGED); | 745 | return test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
763 | if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) { | 746 | if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) { |
764 | USETF(FD_VERIFY); /* verify write protection */ | 747 | set_bit(FD_VERIFY_BIT, &UDRS->flags); |
765 | if (UDRS->maxblock) { | 748 | /* verify write protection */ |
766 | /* mark it changed */ | 749 | |
767 | USETF(FD_DISK_CHANGED); | 750 | if (UDRS->maxblock) /* mark it changed */ |
768 | } | 751 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
769 | 752 | ||
770 | /* invalidate its geometry */ | 753 | /* invalidate its geometry */ |
771 | if (UDRS->keep_data >= 0) { | 754 | if (UDRS->keep_data >= 0) { |
772 | if ((UDP->flags & FTD_MSG) && | 755 | if ((UDP->flags & FTD_MSG) && |
773 | current_type[drive] != NULL) | 756 | current_type[drive] != NULL) |
774 | DPRINT("Disk type is undefined after " | 757 | DPRINT("Disk type is undefined after disk change\n"); |
775 | "disk change\n"); | ||
776 | current_type[drive] = NULL; | 758 | current_type[drive] = NULL; |
777 | floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; | 759 | floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; |
778 | } | 760 | } |
@@ -780,7 +762,7 @@ static int disk_change(int drive) | |||
780 | return 1; | 762 | return 1; |
781 | } else { | 763 | } else { |
782 | UDRS->last_checked = jiffies; | 764 | UDRS->last_checked = jiffies; |
783 | UCLEARF(FD_DISK_NEWCHANGE); | 765 | clear_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags); |
784 | } | 766 | } |
785 | return 0; | 767 | return 0; |
786 | } | 768 | } |
@@ -790,6 +772,12 @@ static inline int is_selected(int dor, int unit) | |||
790 | return ((dor & (0x10 << unit)) && (dor & 3) == unit); | 772 | return ((dor & (0x10 << unit)) && (dor & 3) == unit); |
791 | } | 773 | } |
792 | 774 | ||
775 | static bool is_ready_state(int status) | ||
776 | { | ||
777 | int state = status & (STATUS_READY | STATUS_DIR | STATUS_DMA); | ||
778 | return state == STATUS_READY; | ||
779 | } | ||
780 | |||
793 | static int set_dor(int fdc, char mask, char data) | 781 | static int set_dor(int fdc, char mask, char data) |
794 | { | 782 | { |
795 | unsigned char unit; | 783 | unsigned char unit; |
@@ -806,11 +794,8 @@ static int set_dor(int fdc, char mask, char data) | |||
806 | unit = olddor & 0x3; | 794 | unit = olddor & 0x3; |
807 | if (is_selected(olddor, unit) && !is_selected(newdor, unit)) { | 795 | if (is_selected(olddor, unit) && !is_selected(newdor, unit)) { |
808 | drive = REVDRIVE(fdc, unit); | 796 | drive = REVDRIVE(fdc, unit); |
809 | #ifdef DCL_DEBUG | 797 | debug_dcl(UDP->flags, |
810 | if (UDP->flags & FD_DEBUG) { | 798 | "calling disk change from set_dor\n"); |
811 | DPRINT("calling disk change from set_dor\n"); | ||
812 | } | ||
813 | #endif | ||
814 | disk_change(drive); | 799 | disk_change(drive); |
815 | } | 800 | } |
816 | FDCS->dor = newdor; | 801 | FDCS->dor = newdor; |
@@ -834,8 +819,10 @@ static void twaddle(void) | |||
834 | DRS->select_date = jiffies; | 819 | DRS->select_date = jiffies; |
835 | } | 820 | } |
836 | 821 | ||
837 | /* reset all driver information about the current fdc. This is needed after | 822 | /* |
838 | * a reset, and after a raw command. */ | 823 | * Reset all driver information about the current fdc. |
824 | * This is needed after a reset, and after a raw command. | ||
825 | */ | ||
839 | static void reset_fdc_info(int mode) | 826 | static void reset_fdc_info(int mode) |
840 | { | 827 | { |
841 | int drive; | 828 | int drive; |
@@ -857,7 +844,7 @@ static void set_fdc(int drive) | |||
857 | current_drive = drive; | 844 | current_drive = drive; |
858 | } | 845 | } |
859 | if (fdc != 1 && fdc != 0) { | 846 | if (fdc != 1 && fdc != 0) { |
860 | printk("bad fdc value\n"); | 847 | pr_info("bad fdc value\n"); |
861 | return; | 848 | return; |
862 | } | 849 | } |
863 | set_dor(fdc, ~0, 8); | 850 | set_dor(fdc, ~0, 8); |
@@ -871,11 +858,10 @@ static void set_fdc(int drive) | |||
871 | } | 858 | } |
872 | 859 | ||
873 | /* locks the driver */ | 860 | /* locks the driver */ |
874 | static int _lock_fdc(int drive, int interruptible, int line) | 861 | static int _lock_fdc(int drive, bool interruptible, int line) |
875 | { | 862 | { |
876 | if (!usage_count) { | 863 | if (!usage_count) { |
877 | printk(KERN_ERR | 864 | pr_err("Trying to lock fdc while usage count=0 at line %d\n", |
878 | "Trying to lock fdc while usage count=0 at line %d\n", | ||
879 | line); | 865 | line); |
880 | return -1; | 866 | return -1; |
881 | } | 867 | } |
@@ -904,15 +890,13 @@ static int _lock_fdc(int drive, int interruptible, int line) | |||
904 | } | 890 | } |
905 | command_status = FD_COMMAND_NONE; | 891 | command_status = FD_COMMAND_NONE; |
906 | 892 | ||
907 | __reschedule_timeout(drive, "lock fdc", 0); | 893 | __reschedule_timeout(drive, "lock fdc"); |
908 | set_fdc(drive); | 894 | set_fdc(drive); |
909 | return 0; | 895 | return 0; |
910 | } | 896 | } |
911 | 897 | ||
912 | #define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__) | 898 | #define lock_fdc(drive, interruptible) \ |
913 | 899 | _lock_fdc(drive, interruptible, __LINE__) | |
914 | #define LOCK_FDC(drive,interruptible) \ | ||
915 | if (lock_fdc(drive,interruptible)) return -EINTR; | ||
916 | 900 | ||
917 | /* unlocks the driver */ | 901 | /* unlocks the driver */ |
918 | static inline void unlock_fdc(void) | 902 | static inline void unlock_fdc(void) |
@@ -924,7 +908,7 @@ static inline void unlock_fdc(void) | |||
924 | DPRINT("FDC access conflict!\n"); | 908 | DPRINT("FDC access conflict!\n"); |
925 | 909 | ||
926 | if (do_floppy) | 910 | if (do_floppy) |
927 | DPRINT("device interrupt still active at FDC release: %p!\n", | 911 | DPRINT("device interrupt still active at FDC release: %pf!\n", |
928 | do_floppy); | 912 | do_floppy); |
929 | command_status = FD_COMMAND_NONE; | 913 | command_status = FD_COMMAND_NONE; |
930 | spin_lock_irqsave(&floppy_lock, flags); | 914 | spin_lock_irqsave(&floppy_lock, flags); |
@@ -1003,7 +987,7 @@ static void empty(void) | |||
1003 | 987 | ||
1004 | static DECLARE_WORK(floppy_work, NULL); | 988 | static DECLARE_WORK(floppy_work, NULL); |
1005 | 989 | ||
1006 | static void schedule_bh(void (*handler) (void)) | 990 | static void schedule_bh(void (*handler)(void)) |
1007 | { | 991 | { |
1008 | PREPARE_WORK(&floppy_work, (work_func_t)handler); | 992 | PREPARE_WORK(&floppy_work, (work_func_t)handler); |
1009 | schedule_work(&floppy_work); | 993 | schedule_work(&floppy_work); |
@@ -1026,11 +1010,7 @@ static void cancel_activity(void) | |||
1026 | * transfer */ | 1010 | * transfer */ |
1027 | static void fd_watchdog(void) | 1011 | static void fd_watchdog(void) |
1028 | { | 1012 | { |
1029 | #ifdef DCL_DEBUG | 1013 | debug_dcl(DP->flags, "calling disk change from watchdog\n"); |
1030 | if (DP->flags & FD_DEBUG) { | ||
1031 | DPRINT("calling disk change from watchdog\n"); | ||
1032 | } | ||
1033 | #endif | ||
1034 | 1014 | ||
1035 | if (disk_change(current_drive)) { | 1015 | if (disk_change(current_drive)) { |
1036 | DPRINT("disk removed during i/o\n"); | 1016 | DPRINT("disk removed during i/o\n"); |
@@ -1039,7 +1019,7 @@ static void fd_watchdog(void) | |||
1039 | reset_fdc(); | 1019 | reset_fdc(); |
1040 | } else { | 1020 | } else { |
1041 | del_timer(&fd_timer); | 1021 | del_timer(&fd_timer); |
1042 | fd_timer.function = (timeout_fn) fd_watchdog; | 1022 | fd_timer.function = (timeout_fn)fd_watchdog; |
1043 | fd_timer.expires = jiffies + HZ / 10; | 1023 | fd_timer.expires = jiffies + HZ / 10; |
1044 | add_timer(&fd_timer); | 1024 | add_timer(&fd_timer); |
1045 | } | 1025 | } |
@@ -1105,25 +1085,23 @@ static void setup_DMA(void) | |||
1105 | { | 1085 | { |
1106 | unsigned long f; | 1086 | unsigned long f; |
1107 | 1087 | ||
1108 | #ifdef FLOPPY_SANITY_CHECK | ||
1109 | if (raw_cmd->length == 0) { | 1088 | if (raw_cmd->length == 0) { |
1110 | int i; | 1089 | int i; |
1111 | 1090 | ||
1112 | printk("zero dma transfer size:"); | 1091 | pr_info("zero dma transfer size:"); |
1113 | for (i = 0; i < raw_cmd->cmd_count; i++) | 1092 | for (i = 0; i < raw_cmd->cmd_count; i++) |
1114 | printk("%x,", raw_cmd->cmd[i]); | 1093 | pr_cont("%x,", raw_cmd->cmd[i]); |
1115 | printk("\n"); | 1094 | pr_cont("\n"); |
1116 | cont->done(0); | 1095 | cont->done(0); |
1117 | FDCS->reset = 1; | 1096 | FDCS->reset = 1; |
1118 | return; | 1097 | return; |
1119 | } | 1098 | } |
1120 | if (((unsigned long)raw_cmd->kernel_data) % 512) { | 1099 | if (((unsigned long)raw_cmd->kernel_data) % 512) { |
1121 | printk("non aligned address: %p\n", raw_cmd->kernel_data); | 1100 | pr_info("non aligned address: %p\n", raw_cmd->kernel_data); |
1122 | cont->done(0); | 1101 | cont->done(0); |
1123 | FDCS->reset = 1; | 1102 | FDCS->reset = 1; |
1124 | return; | 1103 | return; |
1125 | } | 1104 | } |
1126 | #endif | ||
1127 | f = claim_dma_lock(); | 1105 | f = claim_dma_lock(); |
1128 | fd_disable_dma(); | 1106 | fd_disable_dma(); |
1129 | #ifdef fd_dma_setup | 1107 | #ifdef fd_dma_setup |
@@ -1165,7 +1143,7 @@ static int wait_til_ready(void) | |||
1165 | if (status & STATUS_READY) | 1143 | if (status & STATUS_READY) |
1166 | return status; | 1144 | return status; |
1167 | } | 1145 | } |
1168 | if (!initialising) { | 1146 | if (initialized) { |
1169 | DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc); | 1147 | DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc); |
1170 | show_floppy(); | 1148 | show_floppy(); |
1171 | } | 1149 | } |
@@ -1176,22 +1154,21 @@ static int wait_til_ready(void) | |||
1176 | /* sends a command byte to the fdc */ | 1154 | /* sends a command byte to the fdc */ |
1177 | static int output_byte(char byte) | 1155 | static int output_byte(char byte) |
1178 | { | 1156 | { |
1179 | int status; | 1157 | int status = wait_til_ready(); |
1180 | 1158 | ||
1181 | if ((status = wait_til_ready()) < 0) | 1159 | if (status < 0) |
1182 | return -1; | 1160 | return -1; |
1183 | if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) { | 1161 | |
1162 | if (is_ready_state(status)) { | ||
1184 | fd_outb(byte, FD_DATA); | 1163 | fd_outb(byte, FD_DATA); |
1185 | #ifdef FLOPPY_SANITY_CHECK | ||
1186 | output_log[output_log_pos].data = byte; | 1164 | output_log[output_log_pos].data = byte; |
1187 | output_log[output_log_pos].status = status; | 1165 | output_log[output_log_pos].status = status; |
1188 | output_log[output_log_pos].jiffies = jiffies; | 1166 | output_log[output_log_pos].jiffies = jiffies; |
1189 | output_log_pos = (output_log_pos + 1) % OLOGSIZE; | 1167 | output_log_pos = (output_log_pos + 1) % OLOGSIZE; |
1190 | #endif | ||
1191 | return 0; | 1168 | return 0; |
1192 | } | 1169 | } |
1193 | FDCS->reset = 1; | 1170 | FDCS->reset = 1; |
1194 | if (!initialising) { | 1171 | if (initialized) { |
1195 | DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n", | 1172 | DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n", |
1196 | byte, fdc, status); | 1173 | byte, fdc, status); |
1197 | show_floppy(); | 1174 | show_floppy(); |
@@ -1199,8 +1176,6 @@ static int output_byte(char byte) | |||
1199 | return -1; | 1176 | return -1; |
1200 | } | 1177 | } |
1201 | 1178 | ||
1202 | #define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;} | ||
1203 | |||
1204 | /* gets the response from the fdc */ | 1179 | /* gets the response from the fdc */ |
1205 | static int result(void) | 1180 | static int result(void) |
1206 | { | 1181 | { |
@@ -1208,14 +1183,13 @@ static int result(void) | |||
1208 | int status = 0; | 1183 | int status = 0; |
1209 | 1184 | ||
1210 | for (i = 0; i < MAX_REPLIES; i++) { | 1185 | for (i = 0; i < MAX_REPLIES; i++) { |
1211 | if ((status = wait_til_ready()) < 0) | 1186 | status = wait_til_ready(); |
1187 | if (status < 0) | ||
1212 | break; | 1188 | break; |
1213 | status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA; | 1189 | status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA; |
1214 | if ((status & ~STATUS_BUSY) == STATUS_READY) { | 1190 | if ((status & ~STATUS_BUSY) == STATUS_READY) { |
1215 | #ifdef FLOPPY_SANITY_CHECK | ||
1216 | resultjiffies = jiffies; | 1191 | resultjiffies = jiffies; |
1217 | resultsize = i; | 1192 | resultsize = i; |
1218 | #endif | ||
1219 | return i; | 1193 | return i; |
1220 | } | 1194 | } |
1221 | if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY)) | 1195 | if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY)) |
@@ -1223,10 +1197,9 @@ static int result(void) | |||
1223 | else | 1197 | else |
1224 | break; | 1198 | break; |
1225 | } | 1199 | } |
1226 | if (!initialising) { | 1200 | if (initialized) { |
1227 | DPRINT | 1201 | DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n", |
1228 | ("get result error. Fdc=%d Last status=%x Read bytes=%d\n", | 1202 | fdc, status, i); |
1229 | fdc, status, i); | ||
1230 | show_floppy(); | 1203 | show_floppy(); |
1231 | } | 1204 | } |
1232 | FDCS->reset = 1; | 1205 | FDCS->reset = 1; |
@@ -1237,12 +1210,14 @@ static int result(void) | |||
1237 | /* does the fdc need more output? */ | 1210 | /* does the fdc need more output? */ |
1238 | static int need_more_output(void) | 1211 | static int need_more_output(void) |
1239 | { | 1212 | { |
1240 | int status; | 1213 | int status = wait_til_ready(); |
1241 | 1214 | ||
1242 | if ((status = wait_til_ready()) < 0) | 1215 | if (status < 0) |
1243 | return -1; | 1216 | return -1; |
1244 | if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) | 1217 | |
1218 | if (is_ready_state(status)) | ||
1245 | return MORE_OUTPUT; | 1219 | return MORE_OUTPUT; |
1220 | |||
1246 | return result(); | 1221 | return result(); |
1247 | } | 1222 | } |
1248 | 1223 | ||
@@ -1264,9 +1239,12 @@ static inline void perpendicular_mode(void) | |||
1264 | default: | 1239 | default: |
1265 | DPRINT("Invalid data rate for perpendicular mode!\n"); | 1240 | DPRINT("Invalid data rate for perpendicular mode!\n"); |
1266 | cont->done(0); | 1241 | cont->done(0); |
1267 | FDCS->reset = 1; /* convenient way to return to | 1242 | FDCS->reset = 1; |
1268 | * redo without to much hassle (deep | 1243 | /* |
1269 | * stack et al. */ | 1244 | * convenient way to return to |
1245 | * redo without too much hassle | ||
1246 | * (deep stack et al.) | ||
1247 | */ | ||
1270 | return; | 1248 | return; |
1271 | } | 1249 | } |
1272 | } else | 1250 | } else |
@@ -1366,9 +1344,9 @@ static void fdc_specify(void) | |||
1366 | 1344 | ||
1367 | /* Convert step rate from microseconds to milliseconds and 4 bits */ | 1345 | /* Convert step rate from microseconds to milliseconds and 4 bits */ |
1368 | srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR); | 1346 | srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR); |
1369 | if (slow_floppy) { | 1347 | if (slow_floppy) |
1370 | srt = srt / 4; | 1348 | srt = srt / 4; |
1371 | } | 1349 | |
1372 | SUPBOUND(srt, 0xf); | 1350 | SUPBOUND(srt, 0xf); |
1373 | INFBOUND(srt, 0); | 1351 | INFBOUND(srt, 0); |
1374 | 1352 | ||
@@ -1415,16 +1393,46 @@ static int fdc_dtr(void) | |||
1415 | * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) | 1393 | * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) |
1416 | */ | 1394 | */ |
1417 | FDCS->dtr = raw_cmd->rate & 3; | 1395 | FDCS->dtr = raw_cmd->rate & 3; |
1418 | return (fd_wait_for_completion(jiffies + 2UL * HZ / 100, | 1396 | return fd_wait_for_completion(jiffies + 2UL * HZ / 100, |
1419 | (timeout_fn) floppy_ready)); | 1397 | (timeout_fn)floppy_ready); |
1420 | } /* fdc_dtr */ | 1398 | } /* fdc_dtr */ |
1421 | 1399 | ||
1422 | static void tell_sector(void) | 1400 | static void tell_sector(void) |
1423 | { | 1401 | { |
1424 | printk(": track %d, head %d, sector %d, size %d", | 1402 | pr_cont(": track %d, head %d, sector %d, size %d", |
1425 | R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); | 1403 | R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); |
1426 | } /* tell_sector */ | 1404 | } /* tell_sector */ |
1427 | 1405 | ||
1406 | static void print_errors(void) | ||
1407 | { | ||
1408 | DPRINT(""); | ||
1409 | if (ST0 & ST0_ECE) { | ||
1410 | pr_cont("Recalibrate failed!"); | ||
1411 | } else if (ST2 & ST2_CRC) { | ||
1412 | pr_cont("data CRC error"); | ||
1413 | tell_sector(); | ||
1414 | } else if (ST1 & ST1_CRC) { | ||
1415 | pr_cont("CRC error"); | ||
1416 | tell_sector(); | ||
1417 | } else if ((ST1 & (ST1_MAM | ST1_ND)) || | ||
1418 | (ST2 & ST2_MAM)) { | ||
1419 | if (!probing) { | ||
1420 | pr_cont("sector not found"); | ||
1421 | tell_sector(); | ||
1422 | } else | ||
1423 | pr_cont("probe failed..."); | ||
1424 | } else if (ST2 & ST2_WC) { /* seek error */ | ||
1425 | pr_cont("wrong cylinder"); | ||
1426 | } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ | ||
1427 | pr_cont("bad cylinder"); | ||
1428 | } else { | ||
1429 | pr_cont("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", | ||
1430 | ST0, ST1, ST2); | ||
1431 | tell_sector(); | ||
1432 | } | ||
1433 | pr_cont("\n"); | ||
1434 | } | ||
1435 | |||
1428 | /* | 1436 | /* |
1429 | * OK, this error interpreting routine is called after a | 1437 | * OK, this error interpreting routine is called after a |
1430 | * DMA read/write has succeeded | 1438 | * DMA read/write has succeeded |
@@ -1437,7 +1445,7 @@ static int interpret_errors(void) | |||
1437 | char bad; | 1445 | char bad; |
1438 | 1446 | ||
1439 | if (inr != 7) { | 1447 | if (inr != 7) { |
1440 | DPRINT("-- FDC reply error"); | 1448 | DPRINT("-- FDC reply error\n"); |
1441 | FDCS->reset = 1; | 1449 | FDCS->reset = 1; |
1442 | return 1; | 1450 | return 1; |
1443 | } | 1451 | } |
@@ -1450,43 +1458,17 @@ static int interpret_errors(void) | |||
1450 | bad = 1; | 1458 | bad = 1; |
1451 | if (ST1 & ST1_WP) { | 1459 | if (ST1 & ST1_WP) { |
1452 | DPRINT("Drive is write protected\n"); | 1460 | DPRINT("Drive is write protected\n"); |
1453 | CLEARF(FD_DISK_WRITABLE); | 1461 | clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); |
1454 | cont->done(0); | 1462 | cont->done(0); |
1455 | bad = 2; | 1463 | bad = 2; |
1456 | } else if (ST1 & ST1_ND) { | 1464 | } else if (ST1 & ST1_ND) { |
1457 | SETF(FD_NEED_TWADDLE); | 1465 | set_bit(FD_NEED_TWADDLE_BIT, &DRS->flags); |
1458 | } else if (ST1 & ST1_OR) { | 1466 | } else if (ST1 & ST1_OR) { |
1459 | if (DP->flags & FTD_MSG) | 1467 | if (DP->flags & FTD_MSG) |
1460 | DPRINT("Over/Underrun - retrying\n"); | 1468 | DPRINT("Over/Underrun - retrying\n"); |
1461 | bad = 0; | 1469 | bad = 0; |
1462 | } else if (*errors >= DP->max_errors.reporting) { | 1470 | } else if (*errors >= DP->max_errors.reporting) { |
1463 | DPRINT(""); | 1471 | print_errors(); |
1464 | if (ST0 & ST0_ECE) { | ||
1465 | printk("Recalibrate failed!"); | ||
1466 | } else if (ST2 & ST2_CRC) { | ||
1467 | printk("data CRC error"); | ||
1468 | tell_sector(); | ||
1469 | } else if (ST1 & ST1_CRC) { | ||
1470 | printk("CRC error"); | ||
1471 | tell_sector(); | ||
1472 | } else if ((ST1 & (ST1_MAM | ST1_ND)) | ||
1473 | || (ST2 & ST2_MAM)) { | ||
1474 | if (!probing) { | ||
1475 | printk("sector not found"); | ||
1476 | tell_sector(); | ||
1477 | } else | ||
1478 | printk("probe failed..."); | ||
1479 | } else if (ST2 & ST2_WC) { /* seek error */ | ||
1480 | printk("wrong cylinder"); | ||
1481 | } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ | ||
1482 | printk("bad cylinder"); | ||
1483 | } else { | ||
1484 | printk | ||
1485 | ("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", | ||
1486 | ST0, ST1, ST2); | ||
1487 | tell_sector(); | ||
1488 | } | ||
1489 | printk("\n"); | ||
1490 | } | 1472 | } |
1491 | if (ST2 & ST2_WC || ST2 & ST2_BC) | 1473 | if (ST2 & ST2_WC || ST2 & ST2_BC) |
1492 | /* wrong cylinder => recal */ | 1474 | /* wrong cylinder => recal */ |
@@ -1531,9 +1513,9 @@ static void setup_rw_floppy(void) | |||
1531 | */ | 1513 | */ |
1532 | if (time_after(ready_date, jiffies + DP->select_delay)) { | 1514 | if (time_after(ready_date, jiffies + DP->select_delay)) { |
1533 | ready_date -= DP->select_delay; | 1515 | ready_date -= DP->select_delay; |
1534 | function = (timeout_fn) floppy_start; | 1516 | function = (timeout_fn)floppy_start; |
1535 | } else | 1517 | } else |
1536 | function = (timeout_fn) setup_rw_floppy; | 1518 | function = (timeout_fn)setup_rw_floppy; |
1537 | 1519 | ||
1538 | /* wait until the floppy is spinning fast enough */ | 1520 | /* wait until the floppy is spinning fast enough */ |
1539 | if (fd_wait_for_completion(ready_date, function)) | 1521 | if (fd_wait_for_completion(ready_date, function)) |
@@ -1551,7 +1533,7 @@ static void setup_rw_floppy(void) | |||
1551 | for (i = 0; i < raw_cmd->cmd_count; i++) | 1533 | for (i = 0; i < raw_cmd->cmd_count; i++) |
1552 | r |= output_byte(raw_cmd->cmd[i]); | 1534 | r |= output_byte(raw_cmd->cmd[i]); |
1553 | 1535 | ||
1554 | debugt("rw_command: "); | 1536 | debugt(__func__, "rw_command"); |
1555 | 1537 | ||
1556 | if (r) { | 1538 | if (r) { |
1557 | cont->error(); | 1539 | cont->error(); |
@@ -1574,7 +1556,7 @@ static int blind_seek; | |||
1574 | */ | 1556 | */ |
1575 | static void seek_interrupt(void) | 1557 | static void seek_interrupt(void) |
1576 | { | 1558 | { |
1577 | debugt("seek interrupt:"); | 1559 | debugt(__func__, ""); |
1578 | if (inr != 2 || (ST0 & 0xF8) != 0x20) { | 1560 | if (inr != 2 || (ST0 & 0xF8) != 0x20) { |
1579 | DPRINT("seek failed\n"); | 1561 | DPRINT("seek failed\n"); |
1580 | DRS->track = NEED_2_RECAL; | 1562 | DRS->track = NEED_2_RECAL; |
@@ -1583,14 +1565,11 @@ static void seek_interrupt(void) | |||
1583 | return; | 1565 | return; |
1584 | } | 1566 | } |
1585 | if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) { | 1567 | if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) { |
1586 | #ifdef DCL_DEBUG | 1568 | debug_dcl(DP->flags, |
1587 | if (DP->flags & FD_DEBUG) { | 1569 | "clearing NEWCHANGE flag because of effective seek\n"); |
1588 | DPRINT | 1570 | debug_dcl(DP->flags, "jiffies=%lu\n", jiffies); |
1589 | ("clearing NEWCHANGE flag because of effective seek\n"); | 1571 | clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
1590 | DPRINT("jiffies=%lu\n", jiffies); | 1572 | /* effective seek */ |
1591 | } | ||
1592 | #endif | ||
1593 | CLEARF(FD_DISK_NEWCHANGE); /* effective seek */ | ||
1594 | DRS->select_date = jiffies; | 1573 | DRS->select_date = jiffies; |
1595 | } | 1574 | } |
1596 | DRS->track = ST1; | 1575 | DRS->track = ST1; |
@@ -1599,26 +1578,23 @@ static void seek_interrupt(void) | |||
1599 | 1578 | ||
1600 | static void check_wp(void) | 1579 | static void check_wp(void) |
1601 | { | 1580 | { |
1602 | if (TESTF(FD_VERIFY)) { | 1581 | if (test_bit(FD_VERIFY_BIT, &DRS->flags)) { |
1603 | /* check write protection */ | 1582 | /* check write protection */ |
1604 | output_byte(FD_GETSTATUS); | 1583 | output_byte(FD_GETSTATUS); |
1605 | output_byte(UNIT(current_drive)); | 1584 | output_byte(UNIT(current_drive)); |
1606 | if (result() != 1) { | 1585 | if (result() != 1) { |
1607 | FDCS->reset = 1; | 1586 | FDCS->reset = 1; |
1608 | return; | 1587 | return; |
1609 | } | 1588 | } |
1610 | CLEARF(FD_VERIFY); | 1589 | clear_bit(FD_VERIFY_BIT, &DRS->flags); |
1611 | CLEARF(FD_NEED_TWADDLE); | 1590 | clear_bit(FD_NEED_TWADDLE_BIT, &DRS->flags); |
1612 | #ifdef DCL_DEBUG | 1591 | debug_dcl(DP->flags, |
1613 | if (DP->flags & FD_DEBUG) { | 1592 | "checking whether disk is write protected\n"); |
1614 | DPRINT("checking whether disk is write protected\n"); | 1593 | debug_dcl(DP->flags, "wp=%x\n", ST3 & 0x40); |
1615 | DPRINT("wp=%x\n", ST3 & 0x40); | ||
1616 | } | ||
1617 | #endif | ||
1618 | if (!(ST3 & 0x40)) | 1594 | if (!(ST3 & 0x40)) |
1619 | SETF(FD_DISK_WRITABLE); | 1595 | set_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); |
1620 | else | 1596 | else |
1621 | CLEARF(FD_DISK_WRITABLE); | 1597 | clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); |
1622 | } | 1598 | } |
1623 | } | 1599 | } |
1624 | 1600 | ||
@@ -1628,19 +1604,15 @@ static void seek_floppy(void) | |||
1628 | 1604 | ||
1629 | blind_seek = 0; | 1605 | blind_seek = 0; |
1630 | 1606 | ||
1631 | #ifdef DCL_DEBUG | 1607 | debug_dcl(DP->flags, "calling disk change from %s\n", __func__); |
1632 | if (DP->flags & FD_DEBUG) { | ||
1633 | DPRINT("calling disk change from seek\n"); | ||
1634 | } | ||
1635 | #endif | ||
1636 | 1608 | ||
1637 | if (!TESTF(FD_DISK_NEWCHANGE) && | 1609 | if (!test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) && |
1638 | disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { | 1610 | disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { |
1639 | /* the media changed flag should be cleared after the seek. | 1611 | /* the media changed flag should be cleared after the seek. |
1640 | * If it isn't, this means that there is really no disk in | 1612 | * If it isn't, this means that there is really no disk in |
1641 | * the drive. | 1613 | * the drive. |
1642 | */ | 1614 | */ |
1643 | SETF(FD_DISK_CHANGED); | 1615 | set_bit(FD_DISK_CHANGED_BIT, &DRS->flags); |
1644 | cont->done(0); | 1616 | cont->done(0); |
1645 | cont->redo(); | 1617 | cont->redo(); |
1646 | return; | 1618 | return; |
@@ -1648,7 +1620,7 @@ static void seek_floppy(void) | |||
1648 | if (DRS->track <= NEED_1_RECAL) { | 1620 | if (DRS->track <= NEED_1_RECAL) { |
1649 | recalibrate_floppy(); | 1621 | recalibrate_floppy(); |
1650 | return; | 1622 | return; |
1651 | } else if (TESTF(FD_DISK_NEWCHANGE) && | 1623 | } else if (test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) && |
1652 | (raw_cmd->flags & FD_RAW_NEED_DISK) && | 1624 | (raw_cmd->flags & FD_RAW_NEED_DISK) && |
1653 | (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) { | 1625 | (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) { |
1654 | /* we seek to clear the media-changed condition. Does anybody | 1626 | /* we seek to clear the media-changed condition. Does anybody |
@@ -1677,19 +1649,22 @@ static void seek_floppy(void) | |||
1677 | do_floppy = seek_interrupt; | 1649 | do_floppy = seek_interrupt; |
1678 | output_byte(FD_SEEK); | 1650 | output_byte(FD_SEEK); |
1679 | output_byte(UNIT(current_drive)); | 1651 | output_byte(UNIT(current_drive)); |
1680 | LAST_OUT(track); | 1652 | if (output_byte(track) < 0) { |
1681 | debugt("seek command:"); | 1653 | reset_fdc(); |
1654 | return; | ||
1655 | } | ||
1656 | debugt(__func__, ""); | ||
1682 | } | 1657 | } |
1683 | 1658 | ||
1684 | static void recal_interrupt(void) | 1659 | static void recal_interrupt(void) |
1685 | { | 1660 | { |
1686 | debugt("recal interrupt:"); | 1661 | debugt(__func__, ""); |
1687 | if (inr != 2) | 1662 | if (inr != 2) |
1688 | FDCS->reset = 1; | 1663 | FDCS->reset = 1; |
1689 | else if (ST0 & ST0_ECE) { | 1664 | else if (ST0 & ST0_ECE) { |
1690 | switch (DRS->track) { | 1665 | switch (DRS->track) { |
1691 | case NEED_1_RECAL: | 1666 | case NEED_1_RECAL: |
1692 | debugt("recal interrupt need 1 recal:"); | 1667 | debugt(__func__, "need 1 recal"); |
1693 | /* after a second recalibrate, we still haven't | 1668 | /* after a second recalibrate, we still haven't |
1694 | * reached track 0. Probably no drive. Raise an | 1669 | * reached track 0. Probably no drive. Raise an |
1695 | * error, as failing immediately might upset | 1670 | * error, as failing immediately might upset |
@@ -1698,25 +1673,21 @@ static void recal_interrupt(void) | |||
1698 | cont->redo(); | 1673 | cont->redo(); |
1699 | return; | 1674 | return; |
1700 | case NEED_2_RECAL: | 1675 | case NEED_2_RECAL: |
1701 | debugt("recal interrupt need 2 recal:"); | 1676 | debugt(__func__, "need 2 recal"); |
1702 | /* If we already did a recalibrate, | 1677 | /* If we already did a recalibrate, |
1703 | * and we are not at track 0, this | 1678 | * and we are not at track 0, this |
1704 | * means we have moved. (The only way | 1679 | * means we have moved. (The only way |
1705 | * not to move at recalibration is to | 1680 | * not to move at recalibration is to |
1706 | * be already at track 0.) Clear the | 1681 | * be already at track 0.) Clear the |
1707 | * new change flag */ | 1682 | * new change flag */ |
1708 | #ifdef DCL_DEBUG | 1683 | debug_dcl(DP->flags, |
1709 | if (DP->flags & FD_DEBUG) { | 1684 | "clearing NEWCHANGE flag because of second recalibrate\n"); |
1710 | DPRINT | ||
1711 | ("clearing NEWCHANGE flag because of second recalibrate\n"); | ||
1712 | } | ||
1713 | #endif | ||
1714 | 1685 | ||
1715 | CLEARF(FD_DISK_NEWCHANGE); | 1686 | clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
1716 | DRS->select_date = jiffies; | 1687 | DRS->select_date = jiffies; |
1717 | /* fall through */ | 1688 | /* fall through */ |
1718 | default: | 1689 | default: |
1719 | debugt("recal interrupt default:"); | 1690 | debugt(__func__, "default"); |
1720 | /* Recalibrate moves the head by at | 1691 | /* Recalibrate moves the head by at |
1721 | * most 80 steps. If after one | 1692 | * most 80 steps. If after one |
1722 | * recalibrate we don't have reached | 1693 | * recalibrate we don't have reached |
@@ -1738,8 +1709,8 @@ static void print_result(char *message, int inr) | |||
1738 | DPRINT("%s ", message); | 1709 | DPRINT("%s ", message); |
1739 | if (inr >= 0) | 1710 | if (inr >= 0) |
1740 | for (i = 0; i < inr; i++) | 1711 | for (i = 0; i < inr; i++) |
1741 | printk("repl[%d]=%x ", i, reply_buffer[i]); | 1712 | pr_cont("repl[%d]=%x ", i, reply_buffer[i]); |
1742 | printk("\n"); | 1713 | pr_cont("\n"); |
1743 | } | 1714 | } |
1744 | 1715 | ||
1745 | /* interrupt handler. Note that this can be called externally on the Sparc */ | 1716 | /* interrupt handler. Note that this can be called externally on the Sparc */ |
@@ -1760,10 +1731,10 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1760 | do_floppy = NULL; | 1731 | do_floppy = NULL; |
1761 | if (fdc >= N_FDC || FDCS->address == -1) { | 1732 | if (fdc >= N_FDC || FDCS->address == -1) { |
1762 | /* we don't even know which FDC is the culprit */ | 1733 | /* we don't even know which FDC is the culprit */ |
1763 | printk("DOR0=%x\n", fdc_state[0].dor); | 1734 | pr_info("DOR0=%x\n", fdc_state[0].dor); |
1764 | printk("floppy interrupt on bizarre fdc %d\n", fdc); | 1735 | pr_info("floppy interrupt on bizarre fdc %d\n", fdc); |
1765 | printk("handler=%p\n", handler); | 1736 | pr_info("handler=%pf\n", handler); |
1766 | is_alive("bizarre fdc"); | 1737 | is_alive(__func__, "bizarre fdc"); |
1767 | return IRQ_NONE; | 1738 | return IRQ_NONE; |
1768 | } | 1739 | } |
1769 | 1740 | ||
@@ -1777,7 +1748,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1777 | * activity. | 1748 | * activity. |
1778 | */ | 1749 | */ |
1779 | 1750 | ||
1780 | do_print = !handler && print_unex && !initialising; | 1751 | do_print = !handler && print_unex && initialized; |
1781 | 1752 | ||
1782 | inr = result(); | 1753 | inr = result(); |
1783 | if (do_print) | 1754 | if (do_print) |
@@ -1790,15 +1761,15 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1790 | if (do_print) | 1761 | if (do_print) |
1791 | print_result("sensei", inr); | 1762 | print_result("sensei", inr); |
1792 | max_sensei--; | 1763 | max_sensei--; |
1793 | } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2 | 1764 | } while ((ST0 & 0x83) != UNIT(current_drive) && |
1794 | && max_sensei); | 1765 | inr == 2 && max_sensei); |
1795 | } | 1766 | } |
1796 | if (!handler) { | 1767 | if (!handler) { |
1797 | FDCS->reset = 1; | 1768 | FDCS->reset = 1; |
1798 | return IRQ_NONE; | 1769 | return IRQ_NONE; |
1799 | } | 1770 | } |
1800 | schedule_bh(handler); | 1771 | schedule_bh(handler); |
1801 | is_alive("normal interrupt end"); | 1772 | is_alive(__func__, "normal interrupt end"); |
1802 | 1773 | ||
1803 | /* FIXME! Was it really for us? */ | 1774 | /* FIXME! Was it really for us? */ |
1804 | return IRQ_HANDLED; | 1775 | return IRQ_HANDLED; |
@@ -1806,10 +1777,11 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1806 | 1777 | ||
1807 | static void recalibrate_floppy(void) | 1778 | static void recalibrate_floppy(void) |
1808 | { | 1779 | { |
1809 | debugt("recalibrate floppy:"); | 1780 | debugt(__func__, ""); |
1810 | do_floppy = recal_interrupt; | 1781 | do_floppy = recal_interrupt; |
1811 | output_byte(FD_RECALIBRATE); | 1782 | output_byte(FD_RECALIBRATE); |
1812 | LAST_OUT(UNIT(current_drive)); | 1783 | if (output_byte(UNIT(current_drive)) < 0) |
1784 | reset_fdc(); | ||
1813 | } | 1785 | } |
1814 | 1786 | ||
1815 | /* | 1787 | /* |
@@ -1817,10 +1789,10 @@ static void recalibrate_floppy(void) | |||
1817 | */ | 1789 | */ |
1818 | static void reset_interrupt(void) | 1790 | static void reset_interrupt(void) |
1819 | { | 1791 | { |
1820 | debugt("reset interrupt:"); | 1792 | debugt(__func__, ""); |
1821 | result(); /* get the status ready for set_fdc */ | 1793 | result(); /* get the status ready for set_fdc */ |
1822 | if (FDCS->reset) { | 1794 | if (FDCS->reset) { |
1823 | printk("reset set in interrupt, calling %p\n", cont->error); | 1795 | pr_info("reset set in interrupt, calling %pf\n", cont->error); |
1824 | cont->error(); /* a reset just after a reset. BAD! */ | 1796 | cont->error(); /* a reset just after a reset. BAD! */ |
1825 | } | 1797 | } |
1826 | cont->redo(); | 1798 | cont->redo(); |
@@ -1858,53 +1830,49 @@ static void show_floppy(void) | |||
1858 | { | 1830 | { |
1859 | int i; | 1831 | int i; |
1860 | 1832 | ||
1861 | printk("\n"); | 1833 | pr_info("\n"); |
1862 | printk("floppy driver state\n"); | 1834 | pr_info("floppy driver state\n"); |
1863 | printk("-------------------\n"); | 1835 | pr_info("-------------------\n"); |
1864 | printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n", | 1836 | pr_info("now=%lu last interrupt=%lu diff=%lu last called handler=%pf\n", |
1865 | jiffies, interruptjiffies, jiffies - interruptjiffies, | 1837 | jiffies, interruptjiffies, jiffies - interruptjiffies, |
1866 | lasthandler); | 1838 | lasthandler); |
1867 | 1839 | ||
1868 | #ifdef FLOPPY_SANITY_CHECK | 1840 | pr_info("timeout_message=%s\n", timeout_message); |
1869 | printk("timeout_message=%s\n", timeout_message); | 1841 | pr_info("last output bytes:\n"); |
1870 | printk("last output bytes:\n"); | ||
1871 | for (i = 0; i < OLOGSIZE; i++) | 1842 | for (i = 0; i < OLOGSIZE; i++) |
1872 | printk("%2x %2x %lu\n", | 1843 | pr_info("%2x %2x %lu\n", |
1873 | output_log[(i + output_log_pos) % OLOGSIZE].data, | 1844 | output_log[(i + output_log_pos) % OLOGSIZE].data, |
1874 | output_log[(i + output_log_pos) % OLOGSIZE].status, | 1845 | output_log[(i + output_log_pos) % OLOGSIZE].status, |
1875 | output_log[(i + output_log_pos) % OLOGSIZE].jiffies); | 1846 | output_log[(i + output_log_pos) % OLOGSIZE].jiffies); |
1876 | printk("last result at %lu\n", resultjiffies); | 1847 | pr_info("last result at %lu\n", resultjiffies); |
1877 | printk("last redo_fd_request at %lu\n", lastredo); | 1848 | pr_info("last redo_fd_request at %lu\n", lastredo); |
1878 | for (i = 0; i < resultsize; i++) { | 1849 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, |
1879 | printk("%2x ", reply_buffer[i]); | 1850 | reply_buffer, resultsize, true); |
1880 | } | 1851 | |
1881 | printk("\n"); | 1852 | pr_info("status=%x\n", fd_inb(FD_STATUS)); |
1882 | #endif | 1853 | pr_info("fdc_busy=%lu\n", fdc_busy); |
1883 | |||
1884 | printk("status=%x\n", fd_inb(FD_STATUS)); | ||
1885 | printk("fdc_busy=%lu\n", fdc_busy); | ||
1886 | if (do_floppy) | 1854 | if (do_floppy) |
1887 | printk("do_floppy=%p\n", do_floppy); | 1855 | pr_info("do_floppy=%pf\n", do_floppy); |
1888 | if (work_pending(&floppy_work)) | 1856 | if (work_pending(&floppy_work)) |
1889 | printk("floppy_work.func=%p\n", floppy_work.func); | 1857 | pr_info("floppy_work.func=%pf\n", floppy_work.func); |
1890 | if (timer_pending(&fd_timer)) | 1858 | if (timer_pending(&fd_timer)) |
1891 | printk("fd_timer.function=%p\n", fd_timer.function); | 1859 | pr_info("fd_timer.function=%pf\n", fd_timer.function); |
1892 | if (timer_pending(&fd_timeout)) { | 1860 | if (timer_pending(&fd_timeout)) { |
1893 | printk("timer_function=%p\n", fd_timeout.function); | 1861 | pr_info("timer_function=%pf\n", fd_timeout.function); |
1894 | printk("expires=%lu\n", fd_timeout.expires - jiffies); | 1862 | pr_info("expires=%lu\n", fd_timeout.expires - jiffies); |
1895 | printk("now=%lu\n", jiffies); | 1863 | pr_info("now=%lu\n", jiffies); |
1896 | } | 1864 | } |
1897 | printk("cont=%p\n", cont); | 1865 | pr_info("cont=%p\n", cont); |
1898 | printk("current_req=%p\n", current_req); | 1866 | pr_info("current_req=%p\n", current_req); |
1899 | printk("command_status=%d\n", command_status); | 1867 | pr_info("command_status=%d\n", command_status); |
1900 | printk("\n"); | 1868 | pr_info("\n"); |
1901 | } | 1869 | } |
1902 | 1870 | ||
1903 | static void floppy_shutdown(unsigned long data) | 1871 | static void floppy_shutdown(unsigned long data) |
1904 | { | 1872 | { |
1905 | unsigned long flags; | 1873 | unsigned long flags; |
1906 | 1874 | ||
1907 | if (!initialising) | 1875 | if (initialized) |
1908 | show_floppy(); | 1876 | show_floppy(); |
1909 | cancel_activity(); | 1877 | cancel_activity(); |
1910 | 1878 | ||
@@ -1916,17 +1884,17 @@ static void floppy_shutdown(unsigned long data) | |||
1916 | 1884 | ||
1917 | /* avoid dma going to a random drive after shutdown */ | 1885 | /* avoid dma going to a random drive after shutdown */ |
1918 | 1886 | ||
1919 | if (!initialising) | 1887 | if (initialized) |
1920 | DPRINT("floppy timeout called\n"); | 1888 | DPRINT("floppy timeout called\n"); |
1921 | FDCS->reset = 1; | 1889 | FDCS->reset = 1; |
1922 | if (cont) { | 1890 | if (cont) { |
1923 | cont->done(0); | 1891 | cont->done(0); |
1924 | cont->redo(); /* this will recall reset when needed */ | 1892 | cont->redo(); /* this will recall reset when needed */ |
1925 | } else { | 1893 | } else { |
1926 | printk("no cont in shutdown!\n"); | 1894 | pr_info("no cont in shutdown!\n"); |
1927 | process_fd_request(); | 1895 | process_fd_request(); |
1928 | } | 1896 | } |
1929 | is_alive("floppy shutdown"); | 1897 | is_alive(__func__, ""); |
1930 | } | 1898 | } |
1931 | 1899 | ||
1932 | /* start motor, check media-changed condition and write protection */ | 1900 | /* start motor, check media-changed condition and write protection */ |
@@ -1954,27 +1922,26 @@ static int start_motor(void (*function)(void)) | |||
1954 | set_dor(fdc, mask, data); | 1922 | set_dor(fdc, mask, data); |
1955 | 1923 | ||
1956 | /* wait_for_completion also schedules reset if needed. */ | 1924 | /* wait_for_completion also schedules reset if needed. */ |
1957 | return (fd_wait_for_completion(DRS->select_date + DP->select_delay, | 1925 | return fd_wait_for_completion(DRS->select_date + DP->select_delay, |
1958 | (timeout_fn) function)); | 1926 | (timeout_fn)function); |
1959 | } | 1927 | } |
1960 | 1928 | ||
1961 | static void floppy_ready(void) | 1929 | static void floppy_ready(void) |
1962 | { | 1930 | { |
1963 | CHECK_RESET; | 1931 | if (FDCS->reset) { |
1932 | reset_fdc(); | ||
1933 | return; | ||
1934 | } | ||
1964 | if (start_motor(floppy_ready)) | 1935 | if (start_motor(floppy_ready)) |
1965 | return; | 1936 | return; |
1966 | if (fdc_dtr()) | 1937 | if (fdc_dtr()) |
1967 | return; | 1938 | return; |
1968 | 1939 | ||
1969 | #ifdef DCL_DEBUG | 1940 | debug_dcl(DP->flags, "calling disk change from floppy_ready\n"); |
1970 | if (DP->flags & FD_DEBUG) { | ||
1971 | DPRINT("calling disk change from floppy_ready\n"); | ||
1972 | } | ||
1973 | #endif | ||
1974 | if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && | 1941 | if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && |
1975 | disk_change(current_drive) && !DP->select_delay) | 1942 | disk_change(current_drive) && !DP->select_delay) |
1976 | twaddle(); /* this clears the dcl on certain drive/controller | 1943 | twaddle(); /* this clears the dcl on certain |
1977 | * combinations */ | 1944 | * drive/controller combinations */ |
1978 | 1945 | ||
1979 | #ifdef fd_chose_dma_mode | 1946 | #ifdef fd_chose_dma_mode |
1980 | if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) { | 1947 | if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) { |
@@ -1998,15 +1965,11 @@ static void floppy_ready(void) | |||
1998 | 1965 | ||
1999 | static void floppy_start(void) | 1966 | static void floppy_start(void) |
2000 | { | 1967 | { |
2001 | reschedule_timeout(current_reqD, "floppy start", 0); | 1968 | reschedule_timeout(current_reqD, "floppy start"); |
2002 | 1969 | ||
2003 | scandrives(); | 1970 | scandrives(); |
2004 | #ifdef DCL_DEBUG | 1971 | debug_dcl(DP->flags, "setting NEWCHANGE in floppy_start\n"); |
2005 | if (DP->flags & FD_DEBUG) { | 1972 | set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
2006 | DPRINT("setting NEWCHANGE in floppy_start\n"); | ||
2007 | } | ||
2008 | #endif | ||
2009 | SETF(FD_DISK_NEWCHANGE); | ||
2010 | floppy_ready(); | 1973 | floppy_ready(); |
2011 | } | 1974 | } |
2012 | 1975 | ||
@@ -2026,7 +1989,7 @@ static void floppy_start(void) | |||
2026 | 1989 | ||
2027 | static void do_wakeup(void) | 1990 | static void do_wakeup(void) |
2028 | { | 1991 | { |
2029 | reschedule_timeout(MAXTIMEOUT, "do wakeup", 0); | 1992 | reschedule_timeout(MAXTIMEOUT, "do wakeup"); |
2030 | cont = NULL; | 1993 | cont = NULL; |
2031 | command_status += 2; | 1994 | command_status += 2; |
2032 | wake_up(&command_done); | 1995 | wake_up(&command_done); |
@@ -2046,7 +2009,7 @@ static struct cont_t intr_cont = { | |||
2046 | .done = (done_f)empty | 2009 | .done = (done_f)empty |
2047 | }; | 2010 | }; |
2048 | 2011 | ||
2049 | static int wait_til_done(void (*handler)(void), int interruptible) | 2012 | static int wait_til_done(void (*handler)(void), bool interruptible) |
2050 | { | 2013 | { |
2051 | int ret; | 2014 | int ret; |
2052 | 2015 | ||
@@ -2064,7 +2027,7 @@ static int wait_til_done(void (*handler)(void), int interruptible) | |||
2064 | if (command_status >= 2 || !NO_SIGNAL) | 2027 | if (command_status >= 2 || !NO_SIGNAL) |
2065 | break; | 2028 | break; |
2066 | 2029 | ||
2067 | is_alive("wait_til_done"); | 2030 | is_alive(__func__, ""); |
2068 | schedule(); | 2031 | schedule(); |
2069 | } | 2032 | } |
2070 | 2033 | ||
@@ -2180,9 +2143,9 @@ static void format_interrupt(void) | |||
2180 | cont->redo(); | 2143 | cont->redo(); |
2181 | } | 2144 | } |
2182 | 2145 | ||
2183 | #define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2) | 2146 | #define FM_MODE(x, y) ((y) & ~(((x)->rate & 0x80) >> 1)) |
2184 | #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1)) | ||
2185 | #define CT(x) ((x) | 0xc0) | 2147 | #define CT(x) ((x) | 0xc0) |
2148 | |||
2186 | static void setup_format_params(int track) | 2149 | static void setup_format_params(int track) |
2187 | { | 2150 | { |
2188 | int n; | 2151 | int n; |
@@ -2197,8 +2160,8 @@ static void setup_format_params(int track) | |||
2197 | raw_cmd = &default_raw_cmd; | 2160 | raw_cmd = &default_raw_cmd; |
2198 | raw_cmd->track = track; | 2161 | raw_cmd->track = track; |
2199 | 2162 | ||
2200 | raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | | 2163 | raw_cmd->flags = (FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | |
2201 | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; | 2164 | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK); |
2202 | raw_cmd->rate = _floppy->rate & 0x43; | 2165 | raw_cmd->rate = _floppy->rate & 0x43; |
2203 | raw_cmd->cmd_count = NR_F; | 2166 | raw_cmd->cmd_count = NR_F; |
2204 | COMMAND = FM_MODE(_floppy, FD_FORMAT); | 2167 | COMMAND = FM_MODE(_floppy, FD_FORMAT); |
@@ -2257,7 +2220,7 @@ static void redo_format(void) | |||
2257 | buffer_track = -1; | 2220 | buffer_track = -1; |
2258 | setup_format_params(format_req.track << STRETCH(_floppy)); | 2221 | setup_format_params(format_req.track << STRETCH(_floppy)); |
2259 | floppy_start(); | 2222 | floppy_start(); |
2260 | debugt("queue format request"); | 2223 | debugt(__func__, "queue format request"); |
2261 | } | 2224 | } |
2262 | 2225 | ||
2263 | static struct cont_t format_cont = { | 2226 | static struct cont_t format_cont = { |
@@ -2271,7 +2234,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req) | |||
2271 | { | 2234 | { |
2272 | int ret; | 2235 | int ret; |
2273 | 2236 | ||
2274 | LOCK_FDC(drive, 1); | 2237 | if (lock_fdc(drive, true)) |
2238 | return -EINTR; | ||
2239 | |||
2275 | set_floppy(drive); | 2240 | set_floppy(drive); |
2276 | if (!_floppy || | 2241 | if (!_floppy || |
2277 | _floppy->track > DP->tracks || | 2242 | _floppy->track > DP->tracks || |
@@ -2286,7 +2251,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req) | |||
2286 | format_errors = 0; | 2251 | format_errors = 0; |
2287 | cont = &format_cont; | 2252 | cont = &format_cont; |
2288 | errors = &format_errors; | 2253 | errors = &format_errors; |
2289 | IWAIT(redo_format); | 2254 | ret = wait_til_done(redo_format, true); |
2255 | if (ret == -EINTR) | ||
2256 | return -EINTR; | ||
2290 | process_fd_request(); | 2257 | process_fd_request(); |
2291 | return ret; | 2258 | return ret; |
2292 | } | 2259 | } |
@@ -2320,12 +2287,14 @@ static void request_done(int uptodate) | |||
2320 | struct request *req = current_req; | 2287 | struct request *req = current_req; |
2321 | unsigned long flags; | 2288 | unsigned long flags; |
2322 | int block; | 2289 | int block; |
2290 | char msg[sizeof("request done ") + sizeof(int) * 3]; | ||
2323 | 2291 | ||
2324 | probing = 0; | 2292 | probing = 0; |
2325 | reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate); | 2293 | snprintf(msg, sizeof(msg), "request done %d", uptodate); |
2294 | reschedule_timeout(MAXTIMEOUT, msg); | ||
2326 | 2295 | ||
2327 | if (!req) { | 2296 | if (!req) { |
2328 | printk("floppy.c: no request in request_done\n"); | 2297 | pr_info("floppy.c: no request in request_done\n"); |
2329 | return; | 2298 | return; |
2330 | } | 2299 | } |
2331 | 2300 | ||
@@ -2377,7 +2346,7 @@ static void rw_interrupt(void) | |||
2377 | DRS->first_read_date = jiffies; | 2346 | DRS->first_read_date = jiffies; |
2378 | 2347 | ||
2379 | nr_sectors = 0; | 2348 | nr_sectors = 0; |
2380 | CODE2SIZE; | 2349 | ssize = DIV_ROUND_UP(1 << SIZECODE, 4); |
2381 | 2350 | ||
2382 | if (ST1 & ST1_EOC) | 2351 | if (ST1 & ST1_EOC) |
2383 | eoc = 1; | 2352 | eoc = 1; |
@@ -2393,20 +2362,18 @@ static void rw_interrupt(void) | |||
2393 | R_HEAD - HEAD) * SECT_PER_TRACK + | 2362 | R_HEAD - HEAD) * SECT_PER_TRACK + |
2394 | R_SECTOR - SECTOR + eoc) << SIZECODE >> 2; | 2363 | R_SECTOR - SECTOR + eoc) << SIZECODE >> 2; |
2395 | 2364 | ||
2396 | #ifdef FLOPPY_SANITY_CHECK | ||
2397 | if (nr_sectors / ssize > | 2365 | if (nr_sectors / ssize > |
2398 | DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) { | 2366 | DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) { |
2399 | DPRINT("long rw: %x instead of %lx\n", | 2367 | DPRINT("long rw: %x instead of %lx\n", |
2400 | nr_sectors, current_count_sectors); | 2368 | nr_sectors, current_count_sectors); |
2401 | printk("rs=%d s=%d\n", R_SECTOR, SECTOR); | 2369 | pr_info("rs=%d s=%d\n", R_SECTOR, SECTOR); |
2402 | printk("rh=%d h=%d\n", R_HEAD, HEAD); | 2370 | pr_info("rh=%d h=%d\n", R_HEAD, HEAD); |
2403 | printk("rt=%d t=%d\n", R_TRACK, TRACK); | 2371 | pr_info("rt=%d t=%d\n", R_TRACK, TRACK); |
2404 | printk("heads=%d eoc=%d\n", heads, eoc); | 2372 | pr_info("heads=%d eoc=%d\n", heads, eoc); |
2405 | printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK, | 2373 | pr_info("spt=%d st=%d ss=%d\n", |
2406 | fsector_t, ssize); | 2374 | SECT_PER_TRACK, fsector_t, ssize); |
2407 | printk("in_sector_offset=%d\n", in_sector_offset); | 2375 | pr_info("in_sector_offset=%d\n", in_sector_offset); |
2408 | } | 2376 | } |
2409 | #endif | ||
2410 | 2377 | ||
2411 | nr_sectors -= in_sector_offset; | 2378 | nr_sectors -= in_sector_offset; |
2412 | INFBOUND(nr_sectors, 0); | 2379 | INFBOUND(nr_sectors, 0); |
@@ -2511,19 +2478,17 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) | |||
2511 | blk_rq_sectors(current_req)); | 2478 | blk_rq_sectors(current_req)); |
2512 | 2479 | ||
2513 | remaining = current_count_sectors << 9; | 2480 | remaining = current_count_sectors << 9; |
2514 | #ifdef FLOPPY_SANITY_CHECK | ||
2515 | if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) { | 2481 | if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) { |
2516 | DPRINT("in copy buffer\n"); | 2482 | DPRINT("in copy buffer\n"); |
2517 | printk("current_count_sectors=%ld\n", current_count_sectors); | 2483 | pr_info("current_count_sectors=%ld\n", current_count_sectors); |
2518 | printk("remaining=%d\n", remaining >> 9); | 2484 | pr_info("remaining=%d\n", remaining >> 9); |
2519 | printk("current_req->nr_sectors=%u\n", | 2485 | pr_info("current_req->nr_sectors=%u\n", |
2520 | blk_rq_sectors(current_req)); | 2486 | blk_rq_sectors(current_req)); |
2521 | printk("current_req->current_nr_sectors=%u\n", | 2487 | pr_info("current_req->current_nr_sectors=%u\n", |
2522 | blk_rq_cur_sectors(current_req)); | 2488 | blk_rq_cur_sectors(current_req)); |
2523 | printk("max_sector=%d\n", max_sector); | 2489 | pr_info("max_sector=%d\n", max_sector); |
2524 | printk("ssize=%d\n", ssize); | 2490 | pr_info("ssize=%d\n", ssize); |
2525 | } | 2491 | } |
2526 | #endif | ||
2527 | 2492 | ||
2528 | buffer_max = max(max_sector, buffer_max); | 2493 | buffer_max = max(max_sector, buffer_max); |
2529 | 2494 | ||
@@ -2539,26 +2504,24 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) | |||
2539 | SUPBOUND(size, remaining); | 2504 | SUPBOUND(size, remaining); |
2540 | 2505 | ||
2541 | buffer = page_address(bv->bv_page) + bv->bv_offset; | 2506 | buffer = page_address(bv->bv_page) + bv->bv_offset; |
2542 | #ifdef FLOPPY_SANITY_CHECK | ||
2543 | if (dma_buffer + size > | 2507 | if (dma_buffer + size > |
2544 | floppy_track_buffer + (max_buffer_sectors << 10) || | 2508 | floppy_track_buffer + (max_buffer_sectors << 10) || |
2545 | dma_buffer < floppy_track_buffer) { | 2509 | dma_buffer < floppy_track_buffer) { |
2546 | DPRINT("buffer overrun in copy buffer %d\n", | 2510 | DPRINT("buffer overrun in copy buffer %d\n", |
2547 | (int)((floppy_track_buffer - | 2511 | (int)((floppy_track_buffer - dma_buffer) >> 9)); |
2548 | dma_buffer) >> 9)); | 2512 | pr_info("fsector_t=%d buffer_min=%d\n", |
2549 | printk("fsector_t=%d buffer_min=%d\n", | 2513 | fsector_t, buffer_min); |
2550 | fsector_t, buffer_min); | 2514 | pr_info("current_count_sectors=%ld\n", |
2551 | printk("current_count_sectors=%ld\n", | 2515 | current_count_sectors); |
2552 | current_count_sectors); | ||
2553 | if (CT(COMMAND) == FD_READ) | 2516 | if (CT(COMMAND) == FD_READ) |
2554 | printk("read\n"); | 2517 | pr_info("read\n"); |
2555 | if (CT(COMMAND) == FD_WRITE) | 2518 | if (CT(COMMAND) == FD_WRITE) |
2556 | printk("write\n"); | 2519 | pr_info("write\n"); |
2557 | break; | 2520 | break; |
2558 | } | 2521 | } |
2559 | if (((unsigned long)buffer) % 512) | 2522 | if (((unsigned long)buffer) % 512) |
2560 | DPRINT("%p buffer not aligned\n", buffer); | 2523 | DPRINT("%p buffer not aligned\n", buffer); |
2561 | #endif | 2524 | |
2562 | if (CT(COMMAND) == FD_READ) | 2525 | if (CT(COMMAND) == FD_READ) |
2563 | memcpy(buffer, dma_buffer, size); | 2526 | memcpy(buffer, dma_buffer, size); |
2564 | else | 2527 | else |
@@ -2567,13 +2530,11 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) | |||
2567 | remaining -= size; | 2530 | remaining -= size; |
2568 | dma_buffer += size; | 2531 | dma_buffer += size; |
2569 | } | 2532 | } |
2570 | #ifdef FLOPPY_SANITY_CHECK | ||
2571 | if (remaining) { | 2533 | if (remaining) { |
2572 | if (remaining > 0) | 2534 | if (remaining > 0) |
2573 | max_sector -= remaining >> 9; | 2535 | max_sector -= remaining >> 9; |
2574 | DPRINT("weirdness: remaining %d\n", remaining >> 9); | 2536 | DPRINT("weirdness: remaining %d\n", remaining >> 9); |
2575 | } | 2537 | } |
2576 | #endif | ||
2577 | } | 2538 | } |
2578 | 2539 | ||
2579 | /* work around a bug in pseudo DMA | 2540 | /* work around a bug in pseudo DMA |
@@ -2593,15 +2554,14 @@ static void virtualdmabug_workaround(void) | |||
2593 | 2554 | ||
2594 | hard_sectors = raw_cmd->length >> (7 + SIZECODE); | 2555 | hard_sectors = raw_cmd->length >> (7 + SIZECODE); |
2595 | end_sector = SECTOR + hard_sectors - 1; | 2556 | end_sector = SECTOR + hard_sectors - 1; |
2596 | #ifdef FLOPPY_SANITY_CHECK | ||
2597 | if (end_sector > SECT_PER_TRACK) { | 2557 | if (end_sector > SECT_PER_TRACK) { |
2598 | printk("too many sectors %d > %d\n", | 2558 | pr_info("too many sectors %d > %d\n", |
2599 | end_sector, SECT_PER_TRACK); | 2559 | end_sector, SECT_PER_TRACK); |
2600 | return; | 2560 | return; |
2601 | } | 2561 | } |
2602 | #endif | 2562 | SECT_PER_TRACK = end_sector; |
2603 | SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points | 2563 | /* make sure SECT_PER_TRACK |
2604 | * to end of transfer */ | 2564 | * points to end of transfer */ |
2605 | } | 2565 | } |
2606 | } | 2566 | } |
2607 | 2567 | ||
@@ -2624,7 +2584,7 @@ static int make_raw_rw_request(void) | |||
2624 | int ssize; | 2584 | int ssize; |
2625 | 2585 | ||
2626 | if (max_buffer_sectors == 0) { | 2586 | if (max_buffer_sectors == 0) { |
2627 | printk("VFS: Block I/O scheduled on unopened device\n"); | 2587 | pr_info("VFS: Block I/O scheduled on unopened device\n"); |
2628 | return 0; | 2588 | return 0; |
2629 | } | 2589 | } |
2630 | 2590 | ||
@@ -2641,7 +2601,7 @@ static int make_raw_rw_request(void) | |||
2641 | raw_cmd->flags |= FD_RAW_WRITE; | 2601 | raw_cmd->flags |= FD_RAW_WRITE; |
2642 | COMMAND = FM_MODE(_floppy, FD_WRITE); | 2602 | COMMAND = FM_MODE(_floppy, FD_WRITE); |
2643 | } else { | 2603 | } else { |
2644 | DPRINT("make_raw_rw_request: unknown command\n"); | 2604 | DPRINT("%s: unknown command\n", __func__); |
2645 | return 0; | 2605 | return 0; |
2646 | } | 2606 | } |
2647 | 2607 | ||
@@ -2659,7 +2619,8 @@ static int make_raw_rw_request(void) | |||
2659 | HEAD = fsector_t / _floppy->sect; | 2619 | HEAD = fsector_t / _floppy->sect; |
2660 | 2620 | ||
2661 | if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || | 2621 | if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || |
2662 | TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect) | 2622 | test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) && |
2623 | fsector_t < _floppy->sect) | ||
2663 | max_sector = _floppy->sect; | 2624 | max_sector = _floppy->sect; |
2664 | 2625 | ||
2665 | /* 2M disks have phantom sectors on the first track */ | 2626 | /* 2M disks have phantom sectors on the first track */ |
@@ -2685,7 +2646,7 @@ static int make_raw_rw_request(void) | |||
2685 | raw_cmd->track = TRACK << STRETCH(_floppy); | 2646 | raw_cmd->track = TRACK << STRETCH(_floppy); |
2686 | DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD); | 2647 | DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD); |
2687 | GAP = _floppy->gap; | 2648 | GAP = _floppy->gap; |
2688 | CODE2SIZE; | 2649 | ssize = DIV_ROUND_UP(1 << SIZECODE, 4); |
2689 | SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; | 2650 | SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; |
2690 | SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + | 2651 | SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + |
2691 | FD_SECTBASE(_floppy); | 2652 | FD_SECTBASE(_floppy); |
@@ -2730,8 +2691,10 @@ static int make_raw_rw_request(void) | |||
2730 | } | 2691 | } |
2731 | } else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) { | 2692 | } else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) { |
2732 | if (CT(COMMAND) == FD_WRITE) { | 2693 | if (CT(COMMAND) == FD_WRITE) { |
2733 | if (fsector_t + blk_rq_sectors(current_req) > ssize && | 2694 | unsigned int sectors; |
2734 | fsector_t + blk_rq_sectors(current_req) < ssize + ssize) | 2695 | |
2696 | sectors = fsector_t + blk_rq_sectors(current_req); | ||
2697 | if (sectors > ssize && sectors < ssize + ssize) | ||
2735 | max_size = ssize + ssize; | 2698 | max_size = ssize + ssize; |
2736 | else | 2699 | else |
2737 | max_size = ssize; | 2700 | max_size = ssize; |
@@ -2752,12 +2715,10 @@ static int make_raw_rw_request(void) | |||
2752 | * on a 64 bit machine! | 2715 | * on a 64 bit machine! |
2753 | */ | 2716 | */ |
2754 | max_size = buffer_chain_size(); | 2717 | max_size = buffer_chain_size(); |
2755 | dma_limit = | 2718 | dma_limit = (MAX_DMA_ADDRESS - |
2756 | (MAX_DMA_ADDRESS - | 2719 | ((unsigned long)current_req->buffer)) >> 9; |
2757 | ((unsigned long)current_req->buffer)) >> 9; | 2720 | if ((unsigned long)max_size > dma_limit) |
2758 | if ((unsigned long)max_size > dma_limit) { | ||
2759 | max_size = dma_limit; | 2721 | max_size = dma_limit; |
2760 | } | ||
2761 | /* 64 kb boundaries */ | 2722 | /* 64 kb boundaries */ |
2762 | if (CROSS_64KB(current_req->buffer, max_size << 9)) | 2723 | if (CROSS_64KB(current_req->buffer, max_size << 9)) |
2763 | max_size = (K_64 - | 2724 | max_size = (K_64 - |
@@ -2773,16 +2734,16 @@ static int make_raw_rw_request(void) | |||
2773 | */ | 2734 | */ |
2774 | if (!direct || | 2735 | if (!direct || |
2775 | (indirect * 2 > direct * 3 && | 2736 | (indirect * 2 > direct * 3 && |
2776 | *errors < DP->max_errors.read_track && ((!probing | 2737 | *errors < DP->max_errors.read_track && |
2777 | || (DP->read_track & (1 << DRS->probed_format)))))) { | 2738 | ((!probing || |
2739 | (DP->read_track & (1 << DRS->probed_format)))))) { | ||
2778 | max_size = blk_rq_sectors(current_req); | 2740 | max_size = blk_rq_sectors(current_req); |
2779 | } else { | 2741 | } else { |
2780 | raw_cmd->kernel_data = current_req->buffer; | 2742 | raw_cmd->kernel_data = current_req->buffer; |
2781 | raw_cmd->length = current_count_sectors << 9; | 2743 | raw_cmd->length = current_count_sectors << 9; |
2782 | if (raw_cmd->length == 0) { | 2744 | if (raw_cmd->length == 0) { |
2783 | DPRINT | 2745 | DPRINT("%s: zero dma transfer attempted\n", __func__); |
2784 | ("zero dma transfer attempted from make_raw_request\n"); | 2746 | DPRINT("indirect=%d direct=%d fsector_t=%d\n", |
2785 | DPRINT("indirect=%d direct=%d fsector_t=%d", | ||
2786 | indirect, direct, fsector_t); | 2747 | indirect, direct, fsector_t); |
2787 | return 0; | 2748 | return 0; |
2788 | } | 2749 | } |
@@ -2802,25 +2763,22 @@ static int make_raw_rw_request(void) | |||
2802 | ((CT(COMMAND) == FD_READ || | 2763 | ((CT(COMMAND) == FD_READ || |
2803 | (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) && | 2764 | (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) && |
2804 | max_sector > 2 * max_buffer_sectors + buffer_min && | 2765 | max_sector > 2 * max_buffer_sectors + buffer_min && |
2805 | max_size + fsector_t > 2 * max_buffer_sectors + buffer_min) | 2766 | max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)) { |
2806 | /* not enough space */ | 2767 | /* not enough space */ |
2807 | ) { | ||
2808 | buffer_track = -1; | 2768 | buffer_track = -1; |
2809 | buffer_drive = current_drive; | 2769 | buffer_drive = current_drive; |
2810 | buffer_max = buffer_min = aligned_sector_t; | 2770 | buffer_max = buffer_min = aligned_sector_t; |
2811 | } | 2771 | } |
2812 | raw_cmd->kernel_data = floppy_track_buffer + | 2772 | raw_cmd->kernel_data = floppy_track_buffer + |
2813 | ((aligned_sector_t - buffer_min) << 9); | 2773 | ((aligned_sector_t - buffer_min) << 9); |
2814 | 2774 | ||
2815 | if (CT(COMMAND) == FD_WRITE) { | 2775 | if (CT(COMMAND) == FD_WRITE) { |
2816 | /* copy write buffer to track buffer. | 2776 | /* copy write buffer to track buffer. |
2817 | * if we get here, we know that the write | 2777 | * if we get here, we know that the write |
2818 | * is either aligned or the data already in the buffer | 2778 | * is either aligned or the data already in the buffer |
2819 | * (buffer will be overwritten) */ | 2779 | * (buffer will be overwritten) */ |
2820 | #ifdef FLOPPY_SANITY_CHECK | ||
2821 | if (in_sector_offset && buffer_track == -1) | 2780 | if (in_sector_offset && buffer_track == -1) |
2822 | DPRINT("internal error offset !=0 on write\n"); | 2781 | DPRINT("internal error offset !=0 on write\n"); |
2823 | #endif | ||
2824 | buffer_track = raw_cmd->track; | 2782 | buffer_track = raw_cmd->track; |
2825 | buffer_drive = current_drive; | 2783 | buffer_drive = current_drive; |
2826 | copy_buffer(ssize, max_sector, | 2784 | copy_buffer(ssize, max_sector, |
@@ -2834,7 +2792,6 @@ static int make_raw_rw_request(void) | |||
2834 | raw_cmd->length = in_sector_offset + current_count_sectors; | 2792 | raw_cmd->length = in_sector_offset + current_count_sectors; |
2835 | raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; | 2793 | raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; |
2836 | raw_cmd->length <<= 9; | 2794 | raw_cmd->length <<= 9; |
2837 | #ifdef FLOPPY_SANITY_CHECK | ||
2838 | if ((raw_cmd->length < current_count_sectors << 9) || | 2795 | if ((raw_cmd->length < current_count_sectors << 9) || |
2839 | (raw_cmd->kernel_data != current_req->buffer && | 2796 | (raw_cmd->kernel_data != current_req->buffer && |
2840 | CT(COMMAND) == FD_WRITE && | 2797 | CT(COMMAND) == FD_WRITE && |
@@ -2845,19 +2802,19 @@ static int make_raw_rw_request(void) | |||
2845 | DPRINT("fractionary current count b=%lx s=%lx\n", | 2802 | DPRINT("fractionary current count b=%lx s=%lx\n", |
2846 | raw_cmd->length, current_count_sectors); | 2803 | raw_cmd->length, current_count_sectors); |
2847 | if (raw_cmd->kernel_data != current_req->buffer) | 2804 | if (raw_cmd->kernel_data != current_req->buffer) |
2848 | printk("addr=%d, length=%ld\n", | 2805 | pr_info("addr=%d, length=%ld\n", |
2849 | (int)((raw_cmd->kernel_data - | 2806 | (int)((raw_cmd->kernel_data - |
2850 | floppy_track_buffer) >> 9), | 2807 | floppy_track_buffer) >> 9), |
2851 | current_count_sectors); | 2808 | current_count_sectors); |
2852 | printk("st=%d ast=%d mse=%d msi=%d\n", | 2809 | pr_info("st=%d ast=%d mse=%d msi=%d\n", |
2853 | fsector_t, aligned_sector_t, max_sector, max_size); | 2810 | fsector_t, aligned_sector_t, max_sector, max_size); |
2854 | printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); | 2811 | pr_info("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); |
2855 | printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", | 2812 | pr_info("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", |
2856 | COMMAND, SECTOR, HEAD, TRACK); | 2813 | COMMAND, SECTOR, HEAD, TRACK); |
2857 | printk("buffer drive=%d\n", buffer_drive); | 2814 | pr_info("buffer drive=%d\n", buffer_drive); |
2858 | printk("buffer track=%d\n", buffer_track); | 2815 | pr_info("buffer track=%d\n", buffer_track); |
2859 | printk("buffer_min=%d\n", buffer_min); | 2816 | pr_info("buffer_min=%d\n", buffer_min); |
2860 | printk("buffer_max=%d\n", buffer_max); | 2817 | pr_info("buffer_max=%d\n", buffer_max); |
2861 | return 0; | 2818 | return 0; |
2862 | } | 2819 | } |
2863 | 2820 | ||
@@ -2868,14 +2825,14 @@ static int make_raw_rw_request(void) | |||
2868 | raw_cmd->kernel_data + raw_cmd->length > | 2825 | raw_cmd->kernel_data + raw_cmd->length > |
2869 | floppy_track_buffer + (max_buffer_sectors << 10)) { | 2826 | floppy_track_buffer + (max_buffer_sectors << 10)) { |
2870 | DPRINT("buffer overrun in schedule dma\n"); | 2827 | DPRINT("buffer overrun in schedule dma\n"); |
2871 | printk("fsector_t=%d buffer_min=%d current_count=%ld\n", | 2828 | pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n", |
2872 | fsector_t, buffer_min, raw_cmd->length >> 9); | 2829 | fsector_t, buffer_min, raw_cmd->length >> 9); |
2873 | printk("current_count_sectors=%ld\n", | 2830 | pr_info("current_count_sectors=%ld\n", |
2874 | current_count_sectors); | 2831 | current_count_sectors); |
2875 | if (CT(COMMAND) == FD_READ) | 2832 | if (CT(COMMAND) == FD_READ) |
2876 | printk("read\n"); | 2833 | pr_info("read\n"); |
2877 | if (CT(COMMAND) == FD_WRITE) | 2834 | if (CT(COMMAND) == FD_WRITE) |
2878 | printk("write\n"); | 2835 | pr_info("write\n"); |
2879 | return 0; | 2836 | return 0; |
2880 | } | 2837 | } |
2881 | } else if (raw_cmd->length > blk_rq_bytes(current_req) || | 2838 | } else if (raw_cmd->length > blk_rq_bytes(current_req) || |
@@ -2884,14 +2841,13 @@ static int make_raw_rw_request(void) | |||
2884 | return 0; | 2841 | return 0; |
2885 | } else if (raw_cmd->length < current_count_sectors << 9) { | 2842 | } else if (raw_cmd->length < current_count_sectors << 9) { |
2886 | DPRINT("more sectors than bytes\n"); | 2843 | DPRINT("more sectors than bytes\n"); |
2887 | printk("bytes=%ld\n", raw_cmd->length >> 9); | 2844 | pr_info("bytes=%ld\n", raw_cmd->length >> 9); |
2888 | printk("sectors=%ld\n", current_count_sectors); | 2845 | pr_info("sectors=%ld\n", current_count_sectors); |
2889 | } | 2846 | } |
2890 | if (raw_cmd->length == 0) { | 2847 | if (raw_cmd->length == 0) { |
2891 | DPRINT("zero dma transfer attempted from make_raw_request\n"); | 2848 | DPRINT("zero dma transfer attempted from make_raw_request\n"); |
2892 | return 0; | 2849 | return 0; |
2893 | } | 2850 | } |
2894 | #endif | ||
2895 | 2851 | ||
2896 | virtualdmabug_workaround(); | 2852 | virtualdmabug_workaround(); |
2897 | return 2; | 2853 | return 2; |
@@ -2899,7 +2855,6 @@ static int make_raw_rw_request(void) | |||
2899 | 2855 | ||
2900 | static void redo_fd_request(void) | 2856 | static void redo_fd_request(void) |
2901 | { | 2857 | { |
2902 | #define REPEAT {request_done(0); continue; } | ||
2903 | int drive; | 2858 | int drive; |
2904 | int tmp; | 2859 | int tmp; |
2905 | 2860 | ||
@@ -2907,63 +2862,63 @@ static void redo_fd_request(void) | |||
2907 | if (current_drive < N_DRIVE) | 2862 | if (current_drive < N_DRIVE) |
2908 | floppy_off(current_drive); | 2863 | floppy_off(current_drive); |
2909 | 2864 | ||
2910 | for (;;) { | 2865 | do_request: |
2911 | if (!current_req) { | 2866 | if (!current_req) { |
2912 | struct request *req; | 2867 | struct request *req; |
2913 | |||
2914 | spin_lock_irq(floppy_queue->queue_lock); | ||
2915 | req = blk_fetch_request(floppy_queue); | ||
2916 | spin_unlock_irq(floppy_queue->queue_lock); | ||
2917 | if (!req) { | ||
2918 | do_floppy = NULL; | ||
2919 | unlock_fdc(); | ||
2920 | return; | ||
2921 | } | ||
2922 | current_req = req; | ||
2923 | } | ||
2924 | drive = (long)current_req->rq_disk->private_data; | ||
2925 | set_fdc(drive); | ||
2926 | reschedule_timeout(current_reqD, "redo fd request", 0); | ||
2927 | 2868 | ||
2928 | set_floppy(drive); | 2869 | spin_lock_irq(floppy_queue->queue_lock); |
2929 | raw_cmd = &default_raw_cmd; | 2870 | req = blk_fetch_request(floppy_queue); |
2930 | raw_cmd->flags = 0; | 2871 | spin_unlock_irq(floppy_queue->queue_lock); |
2931 | if (start_motor(redo_fd_request)) | 2872 | if (!req) { |
2873 | do_floppy = NULL; | ||
2874 | unlock_fdc(); | ||
2932 | return; | 2875 | return; |
2933 | disk_change(current_drive); | ||
2934 | if (test_bit(current_drive, &fake_change) || | ||
2935 | TESTF(FD_DISK_CHANGED)) { | ||
2936 | DPRINT("disk absent or changed during operation\n"); | ||
2937 | REPEAT; | ||
2938 | } | ||
2939 | if (!_floppy) { /* Autodetection */ | ||
2940 | if (!probing) { | ||
2941 | DRS->probed_format = 0; | ||
2942 | if (next_valid_format()) { | ||
2943 | DPRINT("no autodetectable formats\n"); | ||
2944 | _floppy = NULL; | ||
2945 | REPEAT; | ||
2946 | } | ||
2947 | } | ||
2948 | probing = 1; | ||
2949 | _floppy = | ||
2950 | floppy_type + DP->autodetect[DRS->probed_format]; | ||
2951 | } else | ||
2952 | probing = 0; | ||
2953 | errors = &(current_req->errors); | ||
2954 | tmp = make_raw_rw_request(); | ||
2955 | if (tmp < 2) { | ||
2956 | request_done(tmp); | ||
2957 | continue; | ||
2958 | } | 2876 | } |
2877 | current_req = req; | ||
2878 | } | ||
2879 | drive = (long)current_req->rq_disk->private_data; | ||
2880 | set_fdc(drive); | ||
2881 | reschedule_timeout(current_reqD, "redo fd request"); | ||
2959 | 2882 | ||
2960 | if (TESTF(FD_NEED_TWADDLE)) | 2883 | set_floppy(drive); |
2961 | twaddle(); | 2884 | raw_cmd = &default_raw_cmd; |
2962 | schedule_bh(floppy_start); | 2885 | raw_cmd->flags = 0; |
2963 | debugt("queue fd request"); | 2886 | if (start_motor(redo_fd_request)) |
2964 | return; | 2887 | return; |
2888 | |||
2889 | disk_change(current_drive); | ||
2890 | if (test_bit(current_drive, &fake_change) || | ||
2891 | test_bit(FD_DISK_CHANGED_BIT, &DRS->flags)) { | ||
2892 | DPRINT("disk absent or changed during operation\n"); | ||
2893 | request_done(0); | ||
2894 | goto do_request; | ||
2895 | } | ||
2896 | if (!_floppy) { /* Autodetection */ | ||
2897 | if (!probing) { | ||
2898 | DRS->probed_format = 0; | ||
2899 | if (next_valid_format()) { | ||
2900 | DPRINT("no autodetectable formats\n"); | ||
2901 | _floppy = NULL; | ||
2902 | request_done(0); | ||
2903 | goto do_request; | ||
2904 | } | ||
2905 | } | ||
2906 | probing = 1; | ||
2907 | _floppy = floppy_type + DP->autodetect[DRS->probed_format]; | ||
2908 | } else | ||
2909 | probing = 0; | ||
2910 | errors = &(current_req->errors); | ||
2911 | tmp = make_raw_rw_request(); | ||
2912 | if (tmp < 2) { | ||
2913 | request_done(tmp); | ||
2914 | goto do_request; | ||
2965 | } | 2915 | } |
2966 | #undef REPEAT | 2916 | |
2917 | if (test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) | ||
2918 | twaddle(); | ||
2919 | schedule_bh(floppy_start); | ||
2920 | debugt(__func__, "queue fd request"); | ||
2921 | return; | ||
2967 | } | 2922 | } |
2968 | 2923 | ||
2969 | static struct cont_t rw_cont = { | 2924 | static struct cont_t rw_cont = { |
@@ -2979,30 +2934,30 @@ static void process_fd_request(void) | |||
2979 | schedule_bh(redo_fd_request); | 2934 | schedule_bh(redo_fd_request); |
2980 | } | 2935 | } |
2981 | 2936 | ||
2982 | static void do_fd_request(struct request_queue * q) | 2937 | static void do_fd_request(struct request_queue *q) |
2983 | { | 2938 | { |
2984 | if (max_buffer_sectors == 0) { | 2939 | if (max_buffer_sectors == 0) { |
2985 | printk("VFS: do_fd_request called on non-open device\n"); | 2940 | pr_info("VFS: %s called on non-open device\n", __func__); |
2986 | return; | 2941 | return; |
2987 | } | 2942 | } |
2988 | 2943 | ||
2989 | if (usage_count == 0) { | 2944 | if (usage_count == 0) { |
2990 | printk("warning: usage count=0, current_req=%p exiting\n", | 2945 | pr_info("warning: usage count=0, current_req=%p exiting\n", |
2991 | current_req); | 2946 | current_req); |
2992 | printk("sect=%ld type=%x flags=%x\n", | 2947 | pr_info("sect=%ld type=%x flags=%x\n", |
2993 | (long)blk_rq_pos(current_req), current_req->cmd_type, | 2948 | (long)blk_rq_pos(current_req), current_req->cmd_type, |
2994 | current_req->cmd_flags); | 2949 | current_req->cmd_flags); |
2995 | return; | 2950 | return; |
2996 | } | 2951 | } |
2997 | if (test_bit(0, &fdc_busy)) { | 2952 | if (test_bit(0, &fdc_busy)) { |
2998 | /* fdc busy, this new request will be treated when the | 2953 | /* fdc busy, this new request will be treated when the |
2999 | current one is done */ | 2954 | current one is done */ |
3000 | is_alive("do fd request, old request running"); | 2955 | is_alive(__func__, "old request running"); |
3001 | return; | 2956 | return; |
3002 | } | 2957 | } |
3003 | lock_fdc(MAXTIMEOUT, 0); | 2958 | lock_fdc(MAXTIMEOUT, false); |
3004 | process_fd_request(); | 2959 | process_fd_request(); |
3005 | is_alive("do fd request"); | 2960 | is_alive(__func__, ""); |
3006 | } | 2961 | } |
3007 | 2962 | ||
3008 | static struct cont_t poll_cont = { | 2963 | static struct cont_t poll_cont = { |
@@ -3012,24 +2967,18 @@ static struct cont_t poll_cont = { | |||
3012 | .done = generic_done | 2967 | .done = generic_done |
3013 | }; | 2968 | }; |
3014 | 2969 | ||
3015 | static int poll_drive(int interruptible, int flag) | 2970 | static int poll_drive(bool interruptible, int flag) |
3016 | { | 2971 | { |
3017 | int ret; | ||
3018 | |||
3019 | /* no auto-sense, just clear dcl */ | 2972 | /* no auto-sense, just clear dcl */ |
3020 | raw_cmd = &default_raw_cmd; | 2973 | raw_cmd = &default_raw_cmd; |
3021 | raw_cmd->flags = flag; | 2974 | raw_cmd->flags = flag; |
3022 | raw_cmd->track = 0; | 2975 | raw_cmd->track = 0; |
3023 | raw_cmd->cmd_count = 0; | 2976 | raw_cmd->cmd_count = 0; |
3024 | cont = &poll_cont; | 2977 | cont = &poll_cont; |
3025 | #ifdef DCL_DEBUG | 2978 | debug_dcl(DP->flags, "setting NEWCHANGE in poll_drive\n"); |
3026 | if (DP->flags & FD_DEBUG) { | 2979 | set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
3027 | DPRINT("setting NEWCHANGE in poll_drive\n"); | 2980 | |
3028 | } | 2981 | return wait_til_done(floppy_ready, interruptible); |
3029 | #endif | ||
3030 | SETF(FD_DISK_NEWCHANGE); | ||
3031 | WAIT(floppy_ready); | ||
3032 | return ret; | ||
3033 | } | 2982 | } |
3034 | 2983 | ||
3035 | /* | 2984 | /* |
@@ -3039,7 +2988,7 @@ static int poll_drive(int interruptible, int flag) | |||
3039 | 2988 | ||
3040 | static void reset_intr(void) | 2989 | static void reset_intr(void) |
3041 | { | 2990 | { |
3042 | printk("weird, reset interrupt called\n"); | 2991 | pr_info("weird, reset interrupt called\n"); |
3043 | } | 2992 | } |
3044 | 2993 | ||
3045 | static struct cont_t reset_cont = { | 2994 | static struct cont_t reset_cont = { |
@@ -3049,20 +2998,23 @@ static struct cont_t reset_cont = { | |||
3049 | .done = generic_done | 2998 | .done = generic_done |
3050 | }; | 2999 | }; |
3051 | 3000 | ||
3052 | static int user_reset_fdc(int drive, int arg, int interruptible) | 3001 | static int user_reset_fdc(int drive, int arg, bool interruptible) |
3053 | { | 3002 | { |
3054 | int ret; | 3003 | int ret; |
3055 | 3004 | ||
3056 | ret = 0; | 3005 | if (lock_fdc(drive, interruptible)) |
3057 | LOCK_FDC(drive, interruptible); | 3006 | return -EINTR; |
3007 | |||
3058 | if (arg == FD_RESET_ALWAYS) | 3008 | if (arg == FD_RESET_ALWAYS) |
3059 | FDCS->reset = 1; | 3009 | FDCS->reset = 1; |
3060 | if (FDCS->reset) { | 3010 | if (FDCS->reset) { |
3061 | cont = &reset_cont; | 3011 | cont = &reset_cont; |
3062 | WAIT(reset_fdc); | 3012 | ret = wait_til_done(reset_fdc, interruptible); |
3013 | if (ret == -EINTR) | ||
3014 | return -EINTR; | ||
3063 | } | 3015 | } |
3064 | process_fd_request(); | 3016 | process_fd_request(); |
3065 | return ret; | 3017 | return 0; |
3066 | } | 3018 | } |
3067 | 3019 | ||
3068 | /* | 3020 | /* |
@@ -3075,17 +3027,12 @@ static inline int fd_copyout(void __user *param, const void *address, | |||
3075 | return copy_to_user(param, address, size) ? -EFAULT : 0; | 3027 | return copy_to_user(param, address, size) ? -EFAULT : 0; |
3076 | } | 3028 | } |
3077 | 3029 | ||
3078 | static inline int fd_copyin(void __user *param, void *address, unsigned long size) | 3030 | static inline int fd_copyin(void __user *param, void *address, |
3031 | unsigned long size) | ||
3079 | { | 3032 | { |
3080 | return copy_from_user(address, param, size) ? -EFAULT : 0; | 3033 | return copy_from_user(address, param, size) ? -EFAULT : 0; |
3081 | } | 3034 | } |
3082 | 3035 | ||
3083 | #define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) ? -EFAULT : 0) | ||
3084 | #define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) ? -EFAULT : 0) | ||
3085 | |||
3086 | #define COPYOUT(x) ECALL(_COPYOUT(x)) | ||
3087 | #define COPYIN(x) ECALL(_COPYIN(x)) | ||
3088 | |||
3089 | static inline const char *drive_name(int type, int drive) | 3036 | static inline const char *drive_name(int type, int drive) |
3090 | { | 3037 | { |
3091 | struct floppy_struct *floppy; | 3038 | struct floppy_struct *floppy; |
@@ -3156,23 +3103,29 @@ static struct cont_t raw_cmd_cont = { | |||
3156 | .done = raw_cmd_done | 3103 | .done = raw_cmd_done |
3157 | }; | 3104 | }; |
3158 | 3105 | ||
3159 | static inline int raw_cmd_copyout(int cmd, char __user *param, | 3106 | static inline int raw_cmd_copyout(int cmd, void __user *param, |
3160 | struct floppy_raw_cmd *ptr) | 3107 | struct floppy_raw_cmd *ptr) |
3161 | { | 3108 | { |
3162 | int ret; | 3109 | int ret; |
3163 | 3110 | ||
3164 | while (ptr) { | 3111 | while (ptr) { |
3165 | COPYOUT(*ptr); | 3112 | ret = copy_to_user(param, ptr, sizeof(*ptr)); |
3113 | if (ret) | ||
3114 | return -EFAULT; | ||
3166 | param += sizeof(struct floppy_raw_cmd); | 3115 | param += sizeof(struct floppy_raw_cmd); |
3167 | if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) { | 3116 | if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) { |
3168 | if (ptr->length >= 0 | 3117 | if (ptr->length >= 0 && |
3169 | && ptr->length <= ptr->buffer_length) | 3118 | ptr->length <= ptr->buffer_length) { |
3170 | ECALL(fd_copyout | 3119 | long length = ptr->buffer_length - ptr->length; |
3171 | (ptr->data, ptr->kernel_data, | 3120 | ret = fd_copyout(ptr->data, ptr->kernel_data, |
3172 | ptr->buffer_length - ptr->length)); | 3121 | length); |
3122 | if (ret) | ||
3123 | return ret; | ||
3124 | } | ||
3173 | } | 3125 | } |
3174 | ptr = ptr->next; | 3126 | ptr = ptr->next; |
3175 | } | 3127 | } |
3128 | |||
3176 | return 0; | 3129 | return 0; |
3177 | } | 3130 | } |
3178 | 3131 | ||
@@ -3195,7 +3148,7 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr) | |||
3195 | } | 3148 | } |
3196 | } | 3149 | } |
3197 | 3150 | ||
3198 | static inline int raw_cmd_copyin(int cmd, char __user *param, | 3151 | static inline int raw_cmd_copyin(int cmd, void __user *param, |
3199 | struct floppy_raw_cmd **rcmd) | 3152 | struct floppy_raw_cmd **rcmd) |
3200 | { | 3153 | { |
3201 | struct floppy_raw_cmd *ptr; | 3154 | struct floppy_raw_cmd *ptr; |
@@ -3203,17 +3156,19 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, | |||
3203 | int i; | 3156 | int i; |
3204 | 3157 | ||
3205 | *rcmd = NULL; | 3158 | *rcmd = NULL; |
3206 | while (1) { | 3159 | |
3207 | ptr = (struct floppy_raw_cmd *) | 3160 | loop: |
3208 | kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); | 3161 | ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); |
3209 | if (!ptr) | 3162 | if (!ptr) |
3210 | return -ENOMEM; | 3163 | return -ENOMEM; |
3211 | *rcmd = ptr; | 3164 | *rcmd = ptr; |
3212 | COPYIN(*ptr); | 3165 | ret = copy_from_user(ptr, param, sizeof(*ptr)); |
3213 | ptr->next = NULL; | 3166 | if (ret) |
3214 | ptr->buffer_length = 0; | 3167 | return -EFAULT; |
3215 | param += sizeof(struct floppy_raw_cmd); | 3168 | ptr->next = NULL; |
3216 | if (ptr->cmd_count > 33) | 3169 | ptr->buffer_length = 0; |
3170 | param += sizeof(struct floppy_raw_cmd); | ||
3171 | if (ptr->cmd_count > 33) | ||
3217 | /* the command may now also take up the space | 3172 | /* the command may now also take up the space |
3218 | * initially intended for the reply & the | 3173 | * initially intended for the reply & the |
3219 | * reply count. Needed for long 82078 commands | 3174 | * reply count. Needed for long 82078 commands |
@@ -3222,31 +3177,35 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, | |||
3222 | * 16 bytes for a structure, you'll one day | 3177 | * 16 bytes for a structure, you'll one day |
3223 | * discover that you really need 17... | 3178 | * discover that you really need 17... |
3224 | */ | 3179 | */ |
3180 | return -EINVAL; | ||
3181 | |||
3182 | for (i = 0; i < 16; i++) | ||
3183 | ptr->reply[i] = 0; | ||
3184 | ptr->resultcode = 0; | ||
3185 | ptr->kernel_data = NULL; | ||
3186 | |||
3187 | if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { | ||
3188 | if (ptr->length <= 0) | ||
3225 | return -EINVAL; | 3189 | return -EINVAL; |
3190 | ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); | ||
3191 | fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); | ||
3192 | if (!ptr->kernel_data) | ||
3193 | return -ENOMEM; | ||
3194 | ptr->buffer_length = ptr->length; | ||
3195 | } | ||
3196 | if (ptr->flags & FD_RAW_WRITE) { | ||
3197 | ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length); | ||
3198 | if (ret) | ||
3199 | return ret; | ||
3200 | } | ||
3226 | 3201 | ||
3227 | for (i = 0; i < 16; i++) | 3202 | if (ptr->flags & FD_RAW_MORE) { |
3228 | ptr->reply[i] = 0; | ||
3229 | ptr->resultcode = 0; | ||
3230 | ptr->kernel_data = NULL; | ||
3231 | |||
3232 | if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { | ||
3233 | if (ptr->length <= 0) | ||
3234 | return -EINVAL; | ||
3235 | ptr->kernel_data = | ||
3236 | (char *)fd_dma_mem_alloc(ptr->length); | ||
3237 | fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); | ||
3238 | if (!ptr->kernel_data) | ||
3239 | return -ENOMEM; | ||
3240 | ptr->buffer_length = ptr->length; | ||
3241 | } | ||
3242 | if (ptr->flags & FD_RAW_WRITE) | ||
3243 | ECALL(fd_copyin(ptr->data, ptr->kernel_data, | ||
3244 | ptr->length)); | ||
3245 | rcmd = &(ptr->next); | 3203 | rcmd = &(ptr->next); |
3246 | if (!(ptr->flags & FD_RAW_MORE)) | ||
3247 | return 0; | ||
3248 | ptr->rate &= 0x43; | 3204 | ptr->rate &= 0x43; |
3205 | goto loop; | ||
3249 | } | 3206 | } |
3207 | |||
3208 | return 0; | ||
3250 | } | 3209 | } |
3251 | 3210 | ||
3252 | static int raw_cmd_ioctl(int cmd, void __user *param) | 3211 | static int raw_cmd_ioctl(int cmd, void __user *param) |
@@ -3283,12 +3242,8 @@ static int raw_cmd_ioctl(int cmd, void __user *param) | |||
3283 | 3242 | ||
3284 | raw_cmd = my_raw_cmd; | 3243 | raw_cmd = my_raw_cmd; |
3285 | cont = &raw_cmd_cont; | 3244 | cont = &raw_cmd_cont; |
3286 | ret = wait_til_done(floppy_start, 1); | 3245 | ret = wait_til_done(floppy_start, true); |
3287 | #ifdef DCL_DEBUG | 3246 | debug_dcl(DP->flags, "calling disk change from raw_cmd ioctl\n"); |
3288 | if (DP->flags & FD_DEBUG) { | ||
3289 | DPRINT("calling disk change from raw_cmd ioctl\n"); | ||
3290 | } | ||
3291 | #endif | ||
3292 | 3247 | ||
3293 | if (ret != -EINTR && FDCS->reset) | 3248 | if (ret != -EINTR && FDCS->reset) |
3294 | ret = -EIO; | 3249 | ret = -EIO; |
@@ -3327,7 +3282,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3327 | if (!capable(CAP_SYS_ADMIN)) | 3282 | if (!capable(CAP_SYS_ADMIN)) |
3328 | return -EPERM; | 3283 | return -EPERM; |
3329 | mutex_lock(&open_lock); | 3284 | mutex_lock(&open_lock); |
3330 | if (lock_fdc(drive, 1)) { | 3285 | if (lock_fdc(drive, true)) { |
3331 | mutex_unlock(&open_lock); | 3286 | mutex_unlock(&open_lock); |
3332 | return -EINTR; | 3287 | return -EINTR; |
3333 | } | 3288 | } |
@@ -3346,11 +3301,15 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3346 | mutex_unlock(&open_lock); | 3301 | mutex_unlock(&open_lock); |
3347 | } else { | 3302 | } else { |
3348 | int oldStretch; | 3303 | int oldStretch; |
3349 | LOCK_FDC(drive, 1); | 3304 | |
3350 | if (cmd != FDDEFPRM) | 3305 | if (lock_fdc(drive, true)) |
3306 | return -EINTR; | ||
3307 | if (cmd != FDDEFPRM) { | ||
3351 | /* notice a disk change immediately, else | 3308 | /* notice a disk change immediately, else |
3352 | * we lose our settings immediately*/ | 3309 | * we lose our settings immediately*/ |
3353 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | 3310 | if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) |
3311 | return -EINTR; | ||
3312 | } | ||
3354 | oldStretch = g->stretch; | 3313 | oldStretch = g->stretch; |
3355 | user_params[drive] = *g; | 3314 | user_params[drive] = *g; |
3356 | if (buffer_drive == drive) | 3315 | if (buffer_drive == drive) |
@@ -3415,7 +3374,7 @@ static inline int normalize_ioctl(int *cmd, int *size) | |||
3415 | *size = _IOC_SIZE(*cmd); | 3374 | *size = _IOC_SIZE(*cmd); |
3416 | *cmd = ioctl_table[i]; | 3375 | *cmd = ioctl_table[i]; |
3417 | if (*size > _IOC_SIZE(*cmd)) { | 3376 | if (*size > _IOC_SIZE(*cmd)) { |
3418 | printk("ioctl not yet supported\n"); | 3377 | pr_info("ioctl not yet supported\n"); |
3419 | return -EFAULT; | 3378 | return -EFAULT; |
3420 | } | 3379 | } |
3421 | return 0; | 3380 | return 0; |
@@ -3429,8 +3388,10 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) | |||
3429 | if (type) | 3388 | if (type) |
3430 | *g = &floppy_type[type]; | 3389 | *g = &floppy_type[type]; |
3431 | else { | 3390 | else { |
3432 | LOCK_FDC(drive, 0); | 3391 | if (lock_fdc(drive, false)) |
3433 | CALL(poll_drive(0, 0)); | 3392 | return -EINTR; |
3393 | if (poll_drive(false, 0) == -EINTR) | ||
3394 | return -EINTR; | ||
3434 | process_fd_request(); | 3395 | process_fd_request(); |
3435 | *g = current_type[drive]; | 3396 | *g = current_type[drive]; |
3436 | } | 3397 | } |
@@ -3459,10 +3420,6 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
3459 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | 3420 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, |
3460 | unsigned long param) | 3421 | unsigned long param) |
3461 | { | 3422 | { |
3462 | #define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL)) | ||
3463 | #define OUT(c,x) case c: outparam = (const char *) (x); break | ||
3464 | #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 | ||
3465 | |||
3466 | int drive = (long)bdev->bd_disk->private_data; | 3423 | int drive = (long)bdev->bd_disk->private_data; |
3467 | int type = ITYPE(UDRS->fd_device); | 3424 | int type = ITYPE(UDRS->fd_device); |
3468 | int i; | 3425 | int i; |
@@ -3474,26 +3431,28 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3474 | struct floppy_max_errors max_errors; | 3431 | struct floppy_max_errors max_errors; |
3475 | struct floppy_drive_params dp; | 3432 | struct floppy_drive_params dp; |
3476 | } inparam; /* parameters coming from user space */ | 3433 | } inparam; /* parameters coming from user space */ |
3477 | const char *outparam; /* parameters passed back to user space */ | 3434 | const void *outparam; /* parameters passed back to user space */ |
3478 | 3435 | ||
3479 | /* convert compatibility eject ioctls into floppy eject ioctl. | 3436 | /* convert compatibility eject ioctls into floppy eject ioctl. |
3480 | * We do this in order to provide a means to eject floppy disks before | 3437 | * We do this in order to provide a means to eject floppy disks before |
3481 | * installing the new fdutils package */ | 3438 | * installing the new fdutils package */ |
3482 | if (cmd == CDROMEJECT || /* CD-ROM eject */ | 3439 | if (cmd == CDROMEJECT || /* CD-ROM eject */ |
3483 | cmd == 0x6470 /* SunOS floppy eject */ ) { | 3440 | cmd == 0x6470) { /* SunOS floppy eject */ |
3484 | DPRINT("obsolete eject ioctl\n"); | 3441 | DPRINT("obsolete eject ioctl\n"); |
3485 | DPRINT("please use floppycontrol --eject\n"); | 3442 | DPRINT("please use floppycontrol --eject\n"); |
3486 | cmd = FDEJECT; | 3443 | cmd = FDEJECT; |
3487 | } | 3444 | } |
3488 | 3445 | ||
3489 | /* convert the old style command into a new style command */ | 3446 | if (!((cmd & 0xff00) == 0x0200)) |
3490 | if ((cmd & 0xff00) == 0x0200) { | ||
3491 | ECALL(normalize_ioctl(&cmd, &size)); | ||
3492 | } else | ||
3493 | return -EINVAL; | 3447 | return -EINVAL; |
3494 | 3448 | ||
3449 | /* convert the old style command into a new style command */ | ||
3450 | ret = normalize_ioctl(&cmd, &size); | ||
3451 | if (ret) | ||
3452 | return ret; | ||
3453 | |||
3495 | /* permission checks */ | 3454 | /* permission checks */ |
3496 | if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) || | 3455 | if (((cmd & 0x40) && !(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL))) || |
3497 | ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) | 3456 | ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) |
3498 | return -EPERM; | 3457 | return -EPERM; |
3499 | 3458 | ||
@@ -3501,129 +3460,142 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3501 | return -EINVAL; | 3460 | return -EINVAL; |
3502 | 3461 | ||
3503 | /* copyin */ | 3462 | /* copyin */ |
3504 | CLEARSTRUCT(&inparam); | 3463 | memset(&inparam, 0, sizeof(inparam)); |
3505 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 3464 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
3506 | ECALL(fd_copyin((void __user *)param, &inparam, size)) | 3465 | ret = fd_copyin((void __user *)param, &inparam, size); |
3507 | 3466 | if (ret) | |
3508 | switch (cmd) { | ||
3509 | case FDEJECT: | ||
3510 | if (UDRS->fd_ref != 1) | ||
3511 | /* somebody else has this drive open */ | ||
3512 | return -EBUSY; | ||
3513 | LOCK_FDC(drive, 1); | ||
3514 | |||
3515 | /* do the actual eject. Fails on | ||
3516 | * non-Sparc architectures */ | ||
3517 | ret = fd_eject(UNIT(drive)); | ||
3518 | |||
3519 | USETF(FD_DISK_CHANGED); | ||
3520 | USETF(FD_VERIFY); | ||
3521 | process_fd_request(); | ||
3522 | return ret; | 3467 | return ret; |
3523 | case FDCLRPRM: | 3468 | } |
3524 | LOCK_FDC(drive, 1); | ||
3525 | current_type[drive] = NULL; | ||
3526 | floppy_sizes[drive] = MAX_DISK_SIZE << 1; | ||
3527 | UDRS->keep_data = 0; | ||
3528 | return invalidate_drive(bdev); | ||
3529 | case FDSETPRM: | ||
3530 | case FDDEFPRM: | ||
3531 | return set_geometry(cmd, &inparam.g, | ||
3532 | drive, type, bdev); | ||
3533 | case FDGETPRM: | ||
3534 | ECALL(get_floppy_geometry(drive, type, | ||
3535 | (struct floppy_struct **) | ||
3536 | &outparam)); | ||
3537 | break; | ||
3538 | |||
3539 | case FDMSGON: | ||
3540 | UDP->flags |= FTD_MSG; | ||
3541 | return 0; | ||
3542 | case FDMSGOFF: | ||
3543 | UDP->flags &= ~FTD_MSG; | ||
3544 | return 0; | ||
3545 | |||
3546 | case FDFMTBEG: | ||
3547 | LOCK_FDC(drive, 1); | ||
3548 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3549 | ret = UDRS->flags; | ||
3550 | process_fd_request(); | ||
3551 | if (ret & FD_VERIFY) | ||
3552 | return -ENODEV; | ||
3553 | if (!(ret & FD_DISK_WRITABLE)) | ||
3554 | return -EROFS; | ||
3555 | return 0; | ||
3556 | case FDFMTTRK: | ||
3557 | if (UDRS->fd_ref != 1) | ||
3558 | return -EBUSY; | ||
3559 | return do_format(drive, &inparam.f); | ||
3560 | case FDFMTEND: | ||
3561 | case FDFLUSH: | ||
3562 | LOCK_FDC(drive, 1); | ||
3563 | return invalidate_drive(bdev); | ||
3564 | |||
3565 | case FDSETEMSGTRESH: | ||
3566 | UDP->max_errors.reporting = | ||
3567 | (unsigned short)(param & 0x0f); | ||
3568 | return 0; | ||
3569 | OUT(FDGETMAXERRS, &UDP->max_errors); | ||
3570 | IN(FDSETMAXERRS, &UDP->max_errors, max_errors); | ||
3571 | |||
3572 | case FDGETDRVTYP: | ||
3573 | outparam = drive_name(type, drive); | ||
3574 | SUPBOUND(size, strlen(outparam) + 1); | ||
3575 | break; | ||
3576 | |||
3577 | IN(FDSETDRVPRM, UDP, dp); | ||
3578 | OUT(FDGETDRVPRM, UDP); | ||
3579 | |||
3580 | case FDPOLLDRVSTAT: | ||
3581 | LOCK_FDC(drive, 1); | ||
3582 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3583 | process_fd_request(); | ||
3584 | /* fall through */ | ||
3585 | OUT(FDGETDRVSTAT, UDRS); | ||
3586 | |||
3587 | case FDRESET: | ||
3588 | return user_reset_fdc(drive, (int)param, 1); | ||
3589 | |||
3590 | OUT(FDGETFDCSTAT, UFDCS); | ||
3591 | 3469 | ||
3592 | case FDWERRORCLR: | 3470 | switch (cmd) { |
3593 | CLEARSTRUCT(UDRWE); | 3471 | case FDEJECT: |
3594 | return 0; | 3472 | if (UDRS->fd_ref != 1) |
3595 | OUT(FDWERRORGET, UDRWE); | 3473 | /* somebody else has this drive open */ |
3596 | 3474 | return -EBUSY; | |
3597 | case FDRAWCMD: | 3475 | if (lock_fdc(drive, true)) |
3598 | if (type) | 3476 | return -EINTR; |
3599 | return -EINVAL; | ||
3600 | LOCK_FDC(drive, 1); | ||
3601 | set_floppy(drive); | ||
3602 | CALL(i = raw_cmd_ioctl(cmd, (void __user *)param)); | ||
3603 | process_fd_request(); | ||
3604 | return i; | ||
3605 | 3477 | ||
3606 | case FDTWADDLE: | 3478 | /* do the actual eject. Fails on |
3607 | LOCK_FDC(drive, 1); | 3479 | * non-Sparc architectures */ |
3608 | twaddle(); | 3480 | ret = fd_eject(UNIT(drive)); |
3609 | process_fd_request(); | ||
3610 | return 0; | ||
3611 | 3481 | ||
3612 | default: | 3482 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
3483 | set_bit(FD_VERIFY_BIT, &UDRS->flags); | ||
3484 | process_fd_request(); | ||
3485 | return ret; | ||
3486 | case FDCLRPRM: | ||
3487 | if (lock_fdc(drive, true)) | ||
3488 | return -EINTR; | ||
3489 | current_type[drive] = NULL; | ||
3490 | floppy_sizes[drive] = MAX_DISK_SIZE << 1; | ||
3491 | UDRS->keep_data = 0; | ||
3492 | return invalidate_drive(bdev); | ||
3493 | case FDSETPRM: | ||
3494 | case FDDEFPRM: | ||
3495 | return set_geometry(cmd, &inparam.g, drive, type, bdev); | ||
3496 | case FDGETPRM: | ||
3497 | ret = get_floppy_geometry(drive, type, | ||
3498 | (struct floppy_struct **)&outparam); | ||
3499 | if (ret) | ||
3500 | return ret; | ||
3501 | break; | ||
3502 | case FDMSGON: | ||
3503 | UDP->flags |= FTD_MSG; | ||
3504 | return 0; | ||
3505 | case FDMSGOFF: | ||
3506 | UDP->flags &= ~FTD_MSG; | ||
3507 | return 0; | ||
3508 | case FDFMTBEG: | ||
3509 | if (lock_fdc(drive, true)) | ||
3510 | return -EINTR; | ||
3511 | if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) | ||
3512 | return -EINTR; | ||
3513 | ret = UDRS->flags; | ||
3514 | process_fd_request(); | ||
3515 | if (ret & FD_VERIFY) | ||
3516 | return -ENODEV; | ||
3517 | if (!(ret & FD_DISK_WRITABLE)) | ||
3518 | return -EROFS; | ||
3519 | return 0; | ||
3520 | case FDFMTTRK: | ||
3521 | if (UDRS->fd_ref != 1) | ||
3522 | return -EBUSY; | ||
3523 | return do_format(drive, &inparam.f); | ||
3524 | case FDFMTEND: | ||
3525 | case FDFLUSH: | ||
3526 | if (lock_fdc(drive, true)) | ||
3527 | return -EINTR; | ||
3528 | return invalidate_drive(bdev); | ||
3529 | case FDSETEMSGTRESH: | ||
3530 | UDP->max_errors.reporting = (unsigned short)(param & 0x0f); | ||
3531 | return 0; | ||
3532 | case FDGETMAXERRS: | ||
3533 | outparam = &UDP->max_errors; | ||
3534 | break; | ||
3535 | case FDSETMAXERRS: | ||
3536 | UDP->max_errors = inparam.max_errors; | ||
3537 | break; | ||
3538 | case FDGETDRVTYP: | ||
3539 | outparam = drive_name(type, drive); | ||
3540 | SUPBOUND(size, strlen((const char *)outparam) + 1); | ||
3541 | break; | ||
3542 | case FDSETDRVPRM: | ||
3543 | *UDP = inparam.dp; | ||
3544 | break; | ||
3545 | case FDGETDRVPRM: | ||
3546 | outparam = UDP; | ||
3547 | break; | ||
3548 | case FDPOLLDRVSTAT: | ||
3549 | if (lock_fdc(drive, true)) | ||
3550 | return -EINTR; | ||
3551 | if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) | ||
3552 | return -EINTR; | ||
3553 | process_fd_request(); | ||
3554 | /* fall through */ | ||
3555 | case FDGETDRVSTAT: | ||
3556 | outparam = UDRS; | ||
3557 | break; | ||
3558 | case FDRESET: | ||
3559 | return user_reset_fdc(drive, (int)param, true); | ||
3560 | case FDGETFDCSTAT: | ||
3561 | outparam = UFDCS; | ||
3562 | break; | ||
3563 | case FDWERRORCLR: | ||
3564 | memset(UDRWE, 0, sizeof(*UDRWE)); | ||
3565 | return 0; | ||
3566 | case FDWERRORGET: | ||
3567 | outparam = UDRWE; | ||
3568 | break; | ||
3569 | case FDRAWCMD: | ||
3570 | if (type) | ||
3613 | return -EINVAL; | 3571 | return -EINVAL; |
3614 | } | 3572 | if (lock_fdc(drive, true)) |
3573 | return -EINTR; | ||
3574 | set_floppy(drive); | ||
3575 | i = raw_cmd_ioctl(cmd, (void __user *)param); | ||
3576 | if (i == -EINTR) | ||
3577 | return -EINTR; | ||
3578 | process_fd_request(); | ||
3579 | return i; | ||
3580 | case FDTWADDLE: | ||
3581 | if (lock_fdc(drive, true)) | ||
3582 | return -EINTR; | ||
3583 | twaddle(); | ||
3584 | process_fd_request(); | ||
3585 | return 0; | ||
3586 | default: | ||
3587 | return -EINVAL; | ||
3588 | } | ||
3615 | 3589 | ||
3616 | if (_IOC_DIR(cmd) & _IOC_READ) | 3590 | if (_IOC_DIR(cmd) & _IOC_READ) |
3617 | return fd_copyout((void __user *)param, outparam, size); | 3591 | return fd_copyout((void __user *)param, outparam, size); |
3618 | else | 3592 | |
3619 | return 0; | 3593 | return 0; |
3620 | #undef OUT | ||
3621 | #undef IN | ||
3622 | } | 3594 | } |
3623 | 3595 | ||
3624 | static void __init config_types(void) | 3596 | static void __init config_types(void) |
3625 | { | 3597 | { |
3626 | int first = 1; | 3598 | bool has_drive = false; |
3627 | int drive; | 3599 | int drive; |
3628 | 3600 | ||
3629 | /* read drive info out of physical CMOS */ | 3601 | /* read drive info out of physical CMOS */ |
@@ -3655,17 +3627,22 @@ static void __init config_types(void) | |||
3655 | name = temparea; | 3627 | name = temparea; |
3656 | } | 3628 | } |
3657 | if (name) { | 3629 | if (name) { |
3658 | const char *prepend = ","; | 3630 | const char *prepend; |
3659 | if (first) { | 3631 | if (!has_drive) { |
3660 | prepend = KERN_INFO "Floppy drive(s):"; | 3632 | prepend = ""; |
3661 | first = 0; | 3633 | has_drive = true; |
3634 | pr_info("Floppy drive(s):"); | ||
3635 | } else { | ||
3636 | prepend = ","; | ||
3662 | } | 3637 | } |
3663 | printk("%s fd%d is %s", prepend, drive, name); | 3638 | |
3639 | pr_cont("%s fd%d is %s", prepend, drive, name); | ||
3664 | } | 3640 | } |
3665 | *UDP = *params; | 3641 | *UDP = *params; |
3666 | } | 3642 | } |
3667 | if (!first) | 3643 | |
3668 | printk("\n"); | 3644 | if (has_drive) |
3645 | pr_cont("\n"); | ||
3669 | } | 3646 | } |
3670 | 3647 | ||
3671 | static int floppy_release(struct gendisk *disk, fmode_t mode) | 3648 | static int floppy_release(struct gendisk *disk, fmode_t mode) |
@@ -3705,8 +3682,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3705 | goto out2; | 3682 | goto out2; |
3706 | 3683 | ||
3707 | if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { | 3684 | if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { |
3708 | USETF(FD_DISK_CHANGED); | 3685 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
3709 | USETF(FD_VERIFY); | 3686 | set_bit(FD_VERIFY_BIT, &UDRS->flags); |
3710 | } | 3687 | } |
3711 | 3688 | ||
3712 | if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) | 3689 | if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) |
@@ -3735,9 +3712,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3735 | INFBOUND(try, 16); | 3712 | INFBOUND(try, 16); |
3736 | tmp = (char *)fd_dma_mem_alloc(1024 * try); | 3713 | tmp = (char *)fd_dma_mem_alloc(1024 * try); |
3737 | } | 3714 | } |
3738 | if (!tmp && !floppy_track_buffer) { | 3715 | if (!tmp && !floppy_track_buffer) |
3739 | fallback_on_nodma_alloc(&tmp, 2048 * try); | 3716 | fallback_on_nodma_alloc(&tmp, 2048 * try); |
3740 | } | ||
3741 | if (!tmp && !floppy_track_buffer) { | 3717 | if (!tmp && !floppy_track_buffer) { |
3742 | DPRINT("Unable to allocate DMA memory\n"); | 3718 | DPRINT("Unable to allocate DMA memory\n"); |
3743 | goto out; | 3719 | goto out; |
@@ -3767,11 +3743,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3767 | if (mode & (FMODE_READ|FMODE_WRITE)) { | 3743 | if (mode & (FMODE_READ|FMODE_WRITE)) { |
3768 | UDRS->last_checked = 0; | 3744 | UDRS->last_checked = 0; |
3769 | check_disk_change(bdev); | 3745 | check_disk_change(bdev); |
3770 | if (UTESTF(FD_DISK_CHANGED)) | 3746 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) |
3771 | goto out; | 3747 | goto out; |
3772 | } | 3748 | } |
3773 | res = -EROFS; | 3749 | res = -EROFS; |
3774 | if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE))) | 3750 | if ((mode & FMODE_WRITE) && |
3751 | !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) | ||
3775 | goto out; | 3752 | goto out; |
3776 | } | 3753 | } |
3777 | mutex_unlock(&open_lock); | 3754 | mutex_unlock(&open_lock); |
@@ -3795,17 +3772,18 @@ static int check_floppy_change(struct gendisk *disk) | |||
3795 | { | 3772 | { |
3796 | int drive = (long)disk->private_data; | 3773 | int drive = (long)disk->private_data; |
3797 | 3774 | ||
3798 | if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY)) | 3775 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3776 | test_bit(FD_VERIFY_BIT, &UDRS->flags)) | ||
3799 | return 1; | 3777 | return 1; |
3800 | 3778 | ||
3801 | if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { | 3779 | if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { |
3802 | lock_fdc(drive, 0); | 3780 | lock_fdc(drive, false); |
3803 | poll_drive(0, 0); | 3781 | poll_drive(false, 0); |
3804 | process_fd_request(); | 3782 | process_fd_request(); |
3805 | } | 3783 | } |
3806 | 3784 | ||
3807 | if (UTESTF(FD_DISK_CHANGED) || | 3785 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3808 | UTESTF(FD_VERIFY) || | 3786 | test_bit(FD_VERIFY_BIT, &UDRS->flags) || |
3809 | test_bit(drive, &fake_change) || | 3787 | test_bit(drive, &fake_change) || |
3810 | (!ITYPE(UDRS->fd_device) && !current_type[drive])) | 3788 | (!ITYPE(UDRS->fd_device) && !current_type[drive])) |
3811 | return 1; | 3789 | return 1; |
@@ -3818,8 +3796,7 @@ static int check_floppy_change(struct gendisk *disk) | |||
3818 | * a disk in the drive, and whether that disk is writable. | 3796 | * a disk in the drive, and whether that disk is writable. |
3819 | */ | 3797 | */ |
3820 | 3798 | ||
3821 | static void floppy_rb0_complete(struct bio *bio, | 3799 | static void floppy_rb0_complete(struct bio *bio, int err) |
3822 | int err) | ||
3823 | { | 3800 | { |
3824 | complete((struct completion *)bio->bi_private); | 3801 | complete((struct completion *)bio->bi_private); |
3825 | } | 3802 | } |
@@ -3877,14 +3854,16 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3877 | int cf; | 3854 | int cf; |
3878 | int res = 0; | 3855 | int res = 0; |
3879 | 3856 | ||
3880 | if (UTESTF(FD_DISK_CHANGED) || | 3857 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3881 | UTESTF(FD_VERIFY) || test_bit(drive, &fake_change) || NO_GEOM) { | 3858 | test_bit(FD_VERIFY_BIT, &UDRS->flags) || |
3859 | test_bit(drive, &fake_change) || NO_GEOM) { | ||
3882 | if (usage_count == 0) { | 3860 | if (usage_count == 0) { |
3883 | printk("VFS: revalidate called on non-open device.\n"); | 3861 | pr_info("VFS: revalidate called on non-open device.\n"); |
3884 | return -EFAULT; | 3862 | return -EFAULT; |
3885 | } | 3863 | } |
3886 | lock_fdc(drive, 0); | 3864 | lock_fdc(drive, false); |
3887 | cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY); | 3865 | cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3866 | test_bit(FD_VERIFY_BIT, &UDRS->flags)); | ||
3888 | if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) { | 3867 | if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) { |
3889 | process_fd_request(); /*already done by another thread */ | 3868 | process_fd_request(); /*already done by another thread */ |
3890 | return 0; | 3869 | return 0; |
@@ -3894,7 +3873,7 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3894 | if (buffer_drive == drive) | 3873 | if (buffer_drive == drive) |
3895 | buffer_track = -1; | 3874 | buffer_track = -1; |
3896 | clear_bit(drive, &fake_change); | 3875 | clear_bit(drive, &fake_change); |
3897 | UCLEARF(FD_DISK_CHANGED); | 3876 | clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
3898 | if (cf) | 3877 | if (cf) |
3899 | UDRS->generation++; | 3878 | UDRS->generation++; |
3900 | if (NO_GEOM) { | 3879 | if (NO_GEOM) { |
@@ -3902,7 +3881,7 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3902 | res = __floppy_read_block_0(opened_bdev[drive]); | 3881 | res = __floppy_read_block_0(opened_bdev[drive]); |
3903 | } else { | 3882 | } else { |
3904 | if (cf) | 3883 | if (cf) |
3905 | poll_drive(0, FD_RAW_NEED_DISK); | 3884 | poll_drive(false, FD_RAW_NEED_DISK); |
3906 | process_fd_request(); | 3885 | process_fd_request(); |
3907 | } | 3886 | } |
3908 | } | 3887 | } |
@@ -3934,21 +3913,21 @@ static char __init get_fdc_version(void) | |||
3934 | output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */ | 3913 | output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */ |
3935 | if (FDCS->reset) | 3914 | if (FDCS->reset) |
3936 | return FDC_NONE; | 3915 | return FDC_NONE; |
3937 | if ((r = result()) <= 0x00) | 3916 | r = result(); |
3917 | if (r <= 0x00) | ||
3938 | return FDC_NONE; /* No FDC present ??? */ | 3918 | return FDC_NONE; /* No FDC present ??? */ |
3939 | if ((r == 1) && (reply_buffer[0] == 0x80)) { | 3919 | if ((r == 1) && (reply_buffer[0] == 0x80)) { |
3940 | printk(KERN_INFO "FDC %d is an 8272A\n", fdc); | 3920 | pr_info("FDC %d is an 8272A\n", fdc); |
3941 | return FDC_8272A; /* 8272a/765 don't know DUMPREGS */ | 3921 | return FDC_8272A; /* 8272a/765 don't know DUMPREGS */ |
3942 | } | 3922 | } |
3943 | if (r != 10) { | 3923 | if (r != 10) { |
3944 | printk | 3924 | pr_info("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n", |
3945 | ("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n", | 3925 | fdc, r); |
3946 | fdc, r); | ||
3947 | return FDC_UNKNOWN; | 3926 | return FDC_UNKNOWN; |
3948 | } | 3927 | } |
3949 | 3928 | ||
3950 | if (!fdc_configure()) { | 3929 | if (!fdc_configure()) { |
3951 | printk(KERN_INFO "FDC %d is an 82072\n", fdc); | 3930 | pr_info("FDC %d is an 82072\n", fdc); |
3952 | return FDC_82072; /* 82072 doesn't know CONFIGURE */ | 3931 | return FDC_82072; /* 82072 doesn't know CONFIGURE */ |
3953 | } | 3932 | } |
3954 | 3933 | ||
@@ -3956,52 +3935,50 @@ static char __init get_fdc_version(void) | |||
3956 | if (need_more_output() == MORE_OUTPUT) { | 3935 | if (need_more_output() == MORE_OUTPUT) { |
3957 | output_byte(0); | 3936 | output_byte(0); |
3958 | } else { | 3937 | } else { |
3959 | printk(KERN_INFO "FDC %d is an 82072A\n", fdc); | 3938 | pr_info("FDC %d is an 82072A\n", fdc); |
3960 | return FDC_82072A; /* 82072A as found on Sparcs. */ | 3939 | return FDC_82072A; /* 82072A as found on Sparcs. */ |
3961 | } | 3940 | } |
3962 | 3941 | ||
3963 | output_byte(FD_UNLOCK); | 3942 | output_byte(FD_UNLOCK); |
3964 | r = result(); | 3943 | r = result(); |
3965 | if ((r == 1) && (reply_buffer[0] == 0x80)) { | 3944 | if ((r == 1) && (reply_buffer[0] == 0x80)) { |
3966 | printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc); | 3945 | pr_info("FDC %d is a pre-1991 82077\n", fdc); |
3967 | return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know | 3946 | return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know |
3968 | * LOCK/UNLOCK */ | 3947 | * LOCK/UNLOCK */ |
3969 | } | 3948 | } |
3970 | if ((r != 1) || (reply_buffer[0] != 0x00)) { | 3949 | if ((r != 1) || (reply_buffer[0] != 0x00)) { |
3971 | printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n", | 3950 | pr_info("FDC %d init: UNLOCK: unexpected return of %d bytes.\n", |
3972 | fdc, r); | 3951 | fdc, r); |
3973 | return FDC_UNKNOWN; | 3952 | return FDC_UNKNOWN; |
3974 | } | 3953 | } |
3975 | output_byte(FD_PARTID); | 3954 | output_byte(FD_PARTID); |
3976 | r = result(); | 3955 | r = result(); |
3977 | if (r != 1) { | 3956 | if (r != 1) { |
3978 | printk("FDC %d init: PARTID: unexpected return of %d bytes.\n", | 3957 | pr_info("FDC %d init: PARTID: unexpected return of %d bytes.\n", |
3979 | fdc, r); | 3958 | fdc, r); |
3980 | return FDC_UNKNOWN; | 3959 | return FDC_UNKNOWN; |
3981 | } | 3960 | } |
3982 | if (reply_buffer[0] == 0x80) { | 3961 | if (reply_buffer[0] == 0x80) { |
3983 | printk(KERN_INFO "FDC %d is a post-1991 82077\n", fdc); | 3962 | pr_info("FDC %d is a post-1991 82077\n", fdc); |
3984 | return FDC_82077; /* Revised 82077AA passes all the tests */ | 3963 | return FDC_82077; /* Revised 82077AA passes all the tests */ |
3985 | } | 3964 | } |
3986 | switch (reply_buffer[0] >> 5) { | 3965 | switch (reply_buffer[0] >> 5) { |
3987 | case 0x0: | 3966 | case 0x0: |
3988 | /* Either a 82078-1 or a 82078SL running at 5Volt */ | 3967 | /* Either a 82078-1 or a 82078SL running at 5Volt */ |
3989 | printk(KERN_INFO "FDC %d is an 82078.\n", fdc); | 3968 | pr_info("FDC %d is an 82078.\n", fdc); |
3990 | return FDC_82078; | 3969 | return FDC_82078; |
3991 | case 0x1: | 3970 | case 0x1: |
3992 | printk(KERN_INFO "FDC %d is a 44pin 82078\n", fdc); | 3971 | pr_info("FDC %d is a 44pin 82078\n", fdc); |
3993 | return FDC_82078; | 3972 | return FDC_82078; |
3994 | case 0x2: | 3973 | case 0x2: |
3995 | printk(KERN_INFO "FDC %d is a S82078B\n", fdc); | 3974 | pr_info("FDC %d is a S82078B\n", fdc); |
3996 | return FDC_S82078B; | 3975 | return FDC_S82078B; |
3997 | case 0x3: | 3976 | case 0x3: |
3998 | printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n", | 3977 | pr_info("FDC %d is a National Semiconductor PC87306\n", fdc); |
3999 | fdc); | ||
4000 | return FDC_87306; | 3978 | return FDC_87306; |
4001 | default: | 3979 | default: |
4002 | printk(KERN_INFO | 3980 | pr_info("FDC %d init: 82078 variant with unknown PARTID=%d.\n", |
4003 | "FDC %d init: 82078 variant with unknown PARTID=%d.\n", | 3981 | fdc, reply_buffer[0] >> 5); |
4004 | fdc, reply_buffer[0] >> 5); | ||
4005 | return FDC_82078_UNKN; | 3982 | return FDC_82078_UNKN; |
4006 | } | 3983 | } |
4007 | } /* get_fdc_version */ | 3984 | } /* get_fdc_version */ |
@@ -4113,9 +4090,9 @@ static int __init floppy_setup(char *str) | |||
4113 | else | 4090 | else |
4114 | param = config_params[i].def_param; | 4091 | param = config_params[i].def_param; |
4115 | if (config_params[i].fn) | 4092 | if (config_params[i].fn) |
4116 | config_params[i]. | 4093 | config_params[i].fn(ints, param, |
4117 | fn(ints, param, | 4094 | config_params[i]. |
4118 | config_params[i].param2); | 4095 | param2); |
4119 | if (config_params[i].var) { | 4096 | if (config_params[i].var) { |
4120 | DPRINT("%s=%d\n", str, param); | 4097 | DPRINT("%s=%d\n", str, param); |
4121 | *config_params[i].var = param; | 4098 | *config_params[i].var = param; |
@@ -4129,8 +4106,8 @@ static int __init floppy_setup(char *str) | |||
4129 | 4106 | ||
4130 | DPRINT("allowed options are:"); | 4107 | DPRINT("allowed options are:"); |
4131 | for (i = 0; i < ARRAY_SIZE(config_params); i++) | 4108 | for (i = 0; i < ARRAY_SIZE(config_params); i++) |
4132 | printk(" %s", config_params[i].name); | 4109 | pr_cont(" %s", config_params[i].name); |
4133 | printk("\n"); | 4110 | pr_cont("\n"); |
4134 | } else | 4111 | } else |
4135 | DPRINT("botched floppy option\n"); | 4112 | DPRINT("botched floppy option\n"); |
4136 | DPRINT("Read Documentation/blockdev/floppy.txt\n"); | 4113 | DPRINT("Read Documentation/blockdev/floppy.txt\n"); |
@@ -4148,7 +4125,8 @@ static ssize_t floppy_cmos_show(struct device *dev, | |||
4148 | drive = p->id; | 4125 | drive = p->id; |
4149 | return sprintf(buf, "%X\n", UDP->cmos); | 4126 | return sprintf(buf, "%X\n", UDP->cmos); |
4150 | } | 4127 | } |
4151 | DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL); | 4128 | |
4129 | DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL); | ||
4152 | 4130 | ||
4153 | static void floppy_device_release(struct device *dev) | 4131 | static void floppy_device_release(struct device *dev) |
4154 | { | 4132 | { |
@@ -4160,7 +4138,7 @@ static int floppy_resume(struct device *dev) | |||
4160 | 4138 | ||
4161 | for (fdc = 0; fdc < N_FDC; fdc++) | 4139 | for (fdc = 0; fdc < N_FDC; fdc++) |
4162 | if (FDCS->address != -1) | 4140 | if (FDCS->address != -1) |
4163 | user_reset_fdc(-1, FD_RESET_ALWAYS, 0); | 4141 | user_reset_fdc(-1, FD_RESET_ALWAYS, false); |
4164 | 4142 | ||
4165 | return 0; | 4143 | return 0; |
4166 | } | 4144 | } |
@@ -4172,8 +4150,8 @@ static const struct dev_pm_ops floppy_pm_ops = { | |||
4172 | 4150 | ||
4173 | static struct platform_driver floppy_driver = { | 4151 | static struct platform_driver floppy_driver = { |
4174 | .driver = { | 4152 | .driver = { |
4175 | .name = "floppy", | 4153 | .name = "floppy", |
4176 | .pm = &floppy_pm_ops, | 4154 | .pm = &floppy_pm_ops, |
4177 | }, | 4155 | }, |
4178 | }; | 4156 | }; |
4179 | 4157 | ||
@@ -4245,16 +4223,16 @@ static int __init floppy_init(void) | |||
4245 | else | 4223 | else |
4246 | floppy_sizes[i] = MAX_DISK_SIZE << 1; | 4224 | floppy_sizes[i] = MAX_DISK_SIZE << 1; |
4247 | 4225 | ||
4248 | reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); | 4226 | reschedule_timeout(MAXTIMEOUT, "floppy init"); |
4249 | config_types(); | 4227 | config_types(); |
4250 | 4228 | ||
4251 | for (i = 0; i < N_FDC; i++) { | 4229 | for (i = 0; i < N_FDC; i++) { |
4252 | fdc = i; | 4230 | fdc = i; |
4253 | CLEARSTRUCT(FDCS); | 4231 | memset(FDCS, 0, sizeof(*FDCS)); |
4254 | FDCS->dtr = -1; | 4232 | FDCS->dtr = -1; |
4255 | FDCS->dor = 0x4; | 4233 | FDCS->dor = 0x4; |
4256 | #if defined(__sparc__) || defined(__mc68000__) | 4234 | #if defined(__sparc__) || defined(__mc68000__) |
4257 | /*sparcs/sun3x don't have a DOR reset which we can fall back on to */ | 4235 | /*sparcs/sun3x don't have a DOR reset which we can fall back on to */ |
4258 | #ifdef __mc68000__ | 4236 | #ifdef __mc68000__ |
4259 | if (MACH_IS_SUN3X) | 4237 | if (MACH_IS_SUN3X) |
4260 | #endif | 4238 | #endif |
@@ -4283,11 +4261,11 @@ static int __init floppy_init(void) | |||
4283 | 4261 | ||
4284 | /* initialise drive state */ | 4262 | /* initialise drive state */ |
4285 | for (drive = 0; drive < N_DRIVE; drive++) { | 4263 | for (drive = 0; drive < N_DRIVE; drive++) { |
4286 | CLEARSTRUCT(UDRS); | 4264 | memset(UDRS, 0, sizeof(*UDRS)); |
4287 | CLEARSTRUCT(UDRWE); | 4265 | memset(UDRWE, 0, sizeof(*UDRWE)); |
4288 | USETF(FD_DISK_NEWCHANGE); | 4266 | set_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags); |
4289 | USETF(FD_DISK_CHANGED); | 4267 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
4290 | USETF(FD_VERIFY); | 4268 | set_bit(FD_VERIFY_BIT, &UDRS->flags); |
4291 | UDRS->fd_device = -1; | 4269 | UDRS->fd_device = -1; |
4292 | floppy_track_buffer = NULL; | 4270 | floppy_track_buffer = NULL; |
4293 | max_buffer_sectors = 0; | 4271 | max_buffer_sectors = 0; |
@@ -4307,7 +4285,7 @@ static int __init floppy_init(void) | |||
4307 | if (FDCS->address == -1) | 4285 | if (FDCS->address == -1) |
4308 | continue; | 4286 | continue; |
4309 | FDCS->rawcmd = 2; | 4287 | FDCS->rawcmd = 2; |
4310 | if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) { | 4288 | if (user_reset_fdc(-1, FD_RESET_ALWAYS, false)) { |
4311 | /* free ioports reserved by floppy_grab_irq_and_dma() */ | 4289 | /* free ioports reserved by floppy_grab_irq_and_dma() */ |
4312 | floppy_release_regions(fdc); | 4290 | floppy_release_regions(fdc); |
4313 | FDCS->address = -1; | 4291 | FDCS->address = -1; |
@@ -4330,12 +4308,12 @@ static int __init floppy_init(void) | |||
4330 | * properly, so force a reset for the standard FDC clones, | 4308 | * properly, so force a reset for the standard FDC clones, |
4331 | * to avoid interrupt garbage. | 4309 | * to avoid interrupt garbage. |
4332 | */ | 4310 | */ |
4333 | user_reset_fdc(-1, FD_RESET_ALWAYS, 0); | 4311 | user_reset_fdc(-1, FD_RESET_ALWAYS, false); |
4334 | } | 4312 | } |
4335 | fdc = 0; | 4313 | fdc = 0; |
4336 | del_timer(&fd_timeout); | 4314 | del_timer(&fd_timeout); |
4337 | current_drive = 0; | 4315 | current_drive = 0; |
4338 | initialising = 0; | 4316 | initialized = true; |
4339 | if (have_no_fdc) { | 4317 | if (have_no_fdc) { |
4340 | DPRINT("no floppy controllers found\n"); | 4318 | DPRINT("no floppy controllers found\n"); |
4341 | err = have_no_fdc; | 4319 | err = have_no_fdc; |
@@ -4356,7 +4334,8 @@ static int __init floppy_init(void) | |||
4356 | if (err) | 4334 | if (err) |
4357 | goto out_flush_work; | 4335 | goto out_flush_work; |
4358 | 4336 | ||
4359 | err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); | 4337 | err = device_create_file(&floppy_device[drive].dev, |
4338 | &dev_attr_cmos); | ||
4360 | if (err) | 4339 | if (err) |
4361 | goto out_unreg_platform_dev; | 4340 | goto out_unreg_platform_dev; |
4362 | 4341 | ||
@@ -4420,8 +4399,10 @@ static int floppy_request_regions(int fdc) | |||
4420 | const struct io_region *p; | 4399 | const struct io_region *p; |
4421 | 4400 | ||
4422 | for (p = io_regions; p < ARRAY_END(io_regions); p++) { | 4401 | for (p = io_regions; p < ARRAY_END(io_regions); p++) { |
4423 | if (!request_region(FDCS->address + p->offset, p->size, "floppy")) { | 4402 | if (!request_region(FDCS->address + p->offset, |
4424 | DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset); | 4403 | p->size, "floppy")) { |
4404 | DPRINT("Floppy io-port 0x%04lx in use\n", | ||
4405 | FDCS->address + p->offset); | ||
4425 | floppy_release_allocated_regions(fdc, p); | 4406 | floppy_release_allocated_regions(fdc, p); |
4426 | return -EBUSY; | 4407 | return -EBUSY; |
4427 | } | 4408 | } |
@@ -4512,11 +4493,9 @@ cleanup: | |||
4512 | static void floppy_release_irq_and_dma(void) | 4493 | static void floppy_release_irq_and_dma(void) |
4513 | { | 4494 | { |
4514 | int old_fdc; | 4495 | int old_fdc; |
4515 | #ifdef FLOPPY_SANITY_CHECK | ||
4516 | #ifndef __sparc__ | 4496 | #ifndef __sparc__ |
4517 | int drive; | 4497 | int drive; |
4518 | #endif | 4498 | #endif |
4519 | #endif | ||
4520 | long tmpsize; | 4499 | long tmpsize; |
4521 | unsigned long tmpaddr; | 4500 | unsigned long tmpaddr; |
4522 | unsigned long flags; | 4501 | unsigned long flags; |
@@ -4547,20 +4526,18 @@ static void floppy_release_irq_and_dma(void) | |||
4547 | buffer_min = buffer_max = -1; | 4526 | buffer_min = buffer_max = -1; |
4548 | fd_dma_mem_free(tmpaddr, tmpsize); | 4527 | fd_dma_mem_free(tmpaddr, tmpsize); |
4549 | } | 4528 | } |
4550 | #ifdef FLOPPY_SANITY_CHECK | ||
4551 | #ifndef __sparc__ | 4529 | #ifndef __sparc__ |
4552 | for (drive = 0; drive < N_FDC * 4; drive++) | 4530 | for (drive = 0; drive < N_FDC * 4; drive++) |
4553 | if (timer_pending(motor_off_timer + drive)) | 4531 | if (timer_pending(motor_off_timer + drive)) |
4554 | printk("motor off timer %d still active\n", drive); | 4532 | pr_info("motor off timer %d still active\n", drive); |
4555 | #endif | 4533 | #endif |
4556 | 4534 | ||
4557 | if (timer_pending(&fd_timeout)) | 4535 | if (timer_pending(&fd_timeout)) |
4558 | printk("floppy timer still active:%s\n", timeout_message); | 4536 | pr_info("floppy timer still active:%s\n", timeout_message); |
4559 | if (timer_pending(&fd_timer)) | 4537 | if (timer_pending(&fd_timer)) |
4560 | printk("auxiliary floppy timer still active\n"); | 4538 | pr_info("auxiliary floppy timer still active\n"); |
4561 | if (work_pending(&floppy_work)) | 4539 | if (work_pending(&floppy_work)) |
4562 | printk("work still pending\n"); | 4540 | pr_info("work still pending\n"); |
4563 | #endif | ||
4564 | old_fdc = fdc; | 4541 | old_fdc = fdc; |
4565 | for (fdc = 0; fdc < N_FDC; fdc++) | 4542 | for (fdc = 0; fdc < N_FDC; fdc++) |
4566 | if (FDCS->address != -1) | 4543 | if (FDCS->address != -1) |
@@ -4577,7 +4554,9 @@ static void __init parse_floppy_cfg_string(char *cfg) | |||
4577 | char *ptr; | 4554 | char *ptr; |
4578 | 4555 | ||
4579 | while (*cfg) { | 4556 | while (*cfg) { |
4580 | for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ; | 4557 | ptr = cfg; |
4558 | while (*cfg && *cfg != ' ' && *cfg != '\t') | ||
4559 | cfg++; | ||
4581 | if (*cfg) { | 4560 | if (*cfg) { |
4582 | *cfg = '\0'; | 4561 | *cfg = '\0'; |
4583 | cfg++; | 4562 | cfg++; |
@@ -4625,6 +4604,7 @@ static void __exit floppy_module_exit(void) | |||
4625 | /* eject disk, if any */ | 4604 | /* eject disk, if any */ |
4626 | fd_eject(0); | 4605 | fd_eject(0); |
4627 | } | 4606 | } |
4607 | |||
4628 | module_exit(floppy_module_exit); | 4608 | module_exit(floppy_module_exit); |
4629 | 4609 | ||
4630 | module_param(floppy, charp, 0); | 4610 | module_param(floppy, charp, 0); |
@@ -4636,9 +4616,10 @@ MODULE_LICENSE("GPL"); | |||
4636 | 4616 | ||
4637 | /* This doesn't actually get used other than for module information */ | 4617 | /* This doesn't actually get used other than for module information */ |
4638 | static const struct pnp_device_id floppy_pnpids[] = { | 4618 | static const struct pnp_device_id floppy_pnpids[] = { |
4639 | { "PNP0700", 0 }, | 4619 | {"PNP0700", 0}, |
4640 | { } | 4620 | {} |
4641 | }; | 4621 | }; |
4622 | |||
4642 | MODULE_DEVICE_TABLE(pnp, floppy_pnpids); | 4623 | MODULE_DEVICE_TABLE(pnp, floppy_pnpids); |
4643 | 4624 | ||
4644 | #else | 4625 | #else |