Import 2.1.118
[davej-history.git] / drivers / block / swim3.c
blobeb2b38e953cfc370742b69ad3408e0e73ddaba2b
1 /*
2 * Driver for the SWIM3 (Super Woz Integrated Machine 3)
3 * floppy controller found on Power Macintoshes.
5 * Copyright (C) 1996 Paul Mackerras.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
13 #include <linux/stddef.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/timer.h>
17 #include <linux/delay.h>
18 #include <linux/fd.h>
19 #include <linux/ioctl.h>
20 #include <asm/io.h>
21 #include <asm/dbdma.h>
22 #include <asm/prom.h>
23 #include <asm/uaccess.h>
24 #include <asm/mediabay.h>
26 #define MAJOR_NR FLOPPY_MAJOR
27 #include <linux/blk.h>
29 static int floppy_blocksizes[2] = {512};
30 static int floppy_sizes[2] = {2880};
32 enum swim_state {
33 idle,
34 locating,
35 seeking,
36 settling,
37 do_transfer,
38 jogging,
39 available,
40 revalidating,
41 ejecting
44 #define REG(x) unsigned char x; char x ## _pad[15];
47 * The names for these registers mostly represent speculation on my part.
48 * It will be interesting to see how close they are to the names Apple uses.
50 struct swim3 {
51 REG(data);
52 REG(usecs); /* counts down at 1MHz */
53 REG(error);
54 REG(mode);
55 REG(select); /* controls CA0, CA1, CA2 and LSTRB signals */
56 REG(reg5);
57 REG(control); /* writing bits clears them */
58 REG(status); /* writing bits sets them in control */
59 REG(intr);
60 REG(nseek); /* # tracks to seek */
61 REG(ctrack); /* current track number */
62 REG(csect); /* current sector number */
63 REG(ssize); /* sector size code?? */
64 REG(sector); /* sector # to read or write */
65 REG(nsect); /* # sectors to read or write */
66 REG(intr_enable);
69 #define control_bic control
70 #define control_bis status
72 /* Bits in select register */
73 #define CA_MASK 7
74 #define LSTRB 8
76 /* Bits in control register */
77 #define DO_SEEK 0x80
78 #define SELECT 0x20
79 #define WRITE_SECTORS 0x10
80 #define SCAN_TRACK 0x08
81 #define DRIVE_ENABLE 0x02
82 #define INTR_ENABLE 0x01
84 /* Bits in status register */
85 #define DATA 0x08
87 /* Bits in intr and intr_enable registers */
88 #define ERROR 0x20
89 #define DATA_CHANGED 0x10
90 #define TRANSFER_DONE 0x08
91 #define SEEN_SECTOR 0x04
92 #define SEEK_DONE 0x02
94 /* Select values for swim3_action */
95 #define SEEK_POSITIVE 0
96 #define SEEK_NEGATIVE 4
97 #define STEP 1
98 #define MOTOR_ON 2
99 #define MOTOR_OFF 6
100 #define EJECT 7
102 /* Select values for swim3_select and swim3_readbit */
103 #define STEP_DIR 0
104 #define STEPPING 1
105 #define MOTOR_ON 2
106 #define RELAX 3
107 #define READ_DATA_0 4
108 #define SINGLE_SIDED 6
109 #define DRIVE_PRESENT 7
110 #define DISK_IN 8
111 #define WRITE_PROT 9
112 #define TRACK_ZERO 10
113 #define TACHO 11
114 #define READ_DATA_1 12
115 #define SEEK_COMPLETE 14
117 struct floppy_state {
118 enum swim_state state;
119 volatile struct swim3 *swim3; /* hardware registers */
120 struct dbdma_regs *dma; /* DMA controller registers */
121 int swim3_intr; /* interrupt number for SWIM3 */
122 int dma_intr; /* interrupt number for DMA channel */
123 int cur_cyl; /* cylinder head is on, or -1 */
124 int cur_sector; /* last sector we saw go past */
125 int req_cyl; /* the cylinder for the current r/w request */
126 int head; /* head number ditto */
127 int req_sector; /* sector number ditto */
128 int scount; /* # sectors we're transferring at present */
129 int retries;
130 int secpercyl; /* disk geometry information */
131 int secpertrack;
132 int total_secs;
133 int write_prot; /* 1 if write-protected, 0 if not, -1 dunno */
134 struct dbdma_cmd *dma_cmd;
135 int ref_count;
136 int expect_cyl;
137 struct timer_list timeout;
138 int timeout_pending;
139 int ejected;
140 struct wait_queue *wait;
141 int wanted;
142 int in_media_bay;
143 char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)];
146 static struct floppy_state floppy_states[1];
148 static unsigned short write_preamble[] = {
149 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, 0x4e4e, /* gap field */
150 0, 0, 0, 0, 0, 0, /* sync field */
151 0x99a1, 0x99a1, 0x99a1, 0x99fb, /* data address mark */
152 0x990f /* init CRC generator */
155 static unsigned short write_postamble[] = {
156 0x9904, /* insert CRC */
157 0x4e4e, 0x4e4e,
158 0x9908, /* stop writing */
159 0, 0, 0, 0, 0, 0
162 static void swim3_select(struct floppy_state *fs, int sel);
163 static void swim3_action(struct floppy_state *fs, int action);
164 static int swim3_readbit(struct floppy_state *fs, int bit);
165 static void do_fd_request(void);
166 static void start_request(struct floppy_state *fs);
167 static void set_timeout(struct floppy_state *fs, int nticks,
168 void (*proc)(unsigned long));
169 static void scan_track(struct floppy_state *fs);
170 static void seek_track(struct floppy_state *fs, int n);
171 static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count);
172 static void setup_transfer(struct floppy_state *fs);
173 static void act(struct floppy_state *fs);
174 static void scan_timeout(unsigned long data);
175 static void seek_timeout(unsigned long data);
176 static void xfer_timeout(unsigned long data);
177 static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
178 static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);
179 static int grab_drive(struct floppy_state *fs, enum swim_state state,
180 int interruptible);
181 static void release_drive(struct floppy_state *fs);
182 static int fd_eject(struct floppy_state *fs);
183 static int floppy_ioctl(struct inode *inode, struct file *filp,
184 unsigned int cmd, unsigned long param);
185 static int floppy_open(struct inode *inode, struct file *filp);
186 static int floppy_release(struct inode *inode, struct file *filp);
187 static ssize_t floppy_read(struct file *filp, char *buf,
188 size_t count, loff_t *ppos);
189 static ssize_t floppy_write(struct file *filp, const char *buf,
190 size_t count, loff_t *ppos);
191 static int floppy_check_change(kdev_t dev);
192 static int floppy_revalidate(kdev_t dev);
193 int swim3_init(void);
195 #define IOCTL_MODE_BIT 8
196 #define OPEN_WRITE_BIT 16
198 static void swim3_select(struct floppy_state *fs, int sel)
200 volatile struct swim3 *sw = fs->swim3;
202 out_8(&sw->select, RELAX);
203 if (sel & 8)
204 out_8(&sw->control_bis, SELECT);
205 else
206 out_8(&sw->control_bic, SELECT);
207 out_8(&sw->select, sel & CA_MASK);
210 static void swim3_action(struct floppy_state *fs, int action)
212 volatile struct swim3 *sw = fs->swim3;
214 swim3_select(fs, action);
215 udelay(1);
216 sw->select |= LSTRB; eieio();
217 udelay(2);
218 sw->select &= ~LSTRB; eieio();
219 udelay(1);
220 out_8(&sw->select, RELAX);
223 static int swim3_readbit(struct floppy_state *fs, int bit)
225 volatile struct swim3 *sw = fs->swim3;
226 int stat;
228 swim3_select(fs, bit);
229 udelay(1);
230 stat = in_8(&sw->status);
231 out_8(&sw->select, RELAX);
232 return (stat & DATA) == 0;
235 static void do_fd_request(void)
237 start_request(&floppy_states[0]);
238 sti();
241 static void start_request(struct floppy_state *fs)
243 int drive;
244 unsigned long x;
246 if (fs->state == idle && fs->wanted) {
247 fs->state = available;
248 wake_up(&fs->wait);
249 return;
251 while (CURRENT && fs->state == idle) {
252 if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
253 panic(DEVICE_NAME ": request list destroyed");
254 if (CURRENT->bh && !buffer_locked(CURRENT->bh))
255 panic(DEVICE_NAME ": block not locked");
256 #if 0
257 printk("do_fd_req: dev=%x cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
258 kdev_t_to_nr(CURRENT->rq_dev), CURRENT->cmd,
259 CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer);
260 printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n",
261 CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors);
262 #endif
264 drive = MINOR(CURRENT->rq_dev);
265 if (drive != 0) {
266 end_request(0);
267 continue;
269 if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
270 end_request(0);
271 continue;
273 if (CURRENT->current_nr_sectors == 0) {
274 end_request(1);
275 continue;
277 if (fs->ejected) {
278 end_request(0);
279 continue;
282 if (CURRENT->cmd == WRITE) {
283 if (fs->write_prot < 0)
284 fs->write_prot = swim3_readbit(fs, WRITE_PROT);
285 if (fs->write_prot) {
286 end_request(0);
287 continue;
291 fs->req_cyl = CURRENT->sector / fs->secpercyl;
292 x = CURRENT->sector % fs->secpercyl;
293 fs->head = x / fs->secpertrack;
294 fs->req_sector = x % fs->secpertrack + 1;
295 fs->state = do_transfer;
296 fs->retries = 0;
298 act(fs);
302 static void set_timeout(struct floppy_state *fs, int nticks,
303 void (*proc)(unsigned long))
305 unsigned long flags;
307 save_flags(flags); cli();
308 if (fs->timeout_pending)
309 del_timer(&fs->timeout);
310 fs->timeout.expires = jiffies + nticks;
311 fs->timeout.function = proc;
312 fs->timeout.data = (unsigned long) fs;
313 add_timer(&fs->timeout);
314 fs->timeout_pending = 1;
315 restore_flags(flags);
318 static inline void scan_track(struct floppy_state *fs)
320 volatile struct swim3 *sw = fs->swim3;
321 int xx;
323 swim3_select(fs, READ_DATA_0);
324 xx = sw->intr; /* clear SEEN_SECTOR bit */
325 out_8(&sw->control_bis, SCAN_TRACK);
326 /* enable intr when track found */
327 out_8(&sw->intr_enable, ERROR | SEEN_SECTOR);
328 set_timeout(fs, HZ, scan_timeout); /* enable timeout */
331 static inline void seek_track(struct floppy_state *fs, int n)
333 volatile struct swim3 *sw = fs->swim3;
335 if (n >= 0) {
336 swim3_action(fs, SEEK_POSITIVE);
337 sw->nseek = n;
338 } else {
339 swim3_action(fs, SEEK_NEGATIVE);
340 sw->nseek = -n;
342 fs->expect_cyl = (fs->cur_cyl > 0)? fs->cur_cyl + n: -1;
343 swim3_select(fs, STEP);
344 out_8(&sw->control_bis, DO_SEEK);
345 /* enable intr when seek finished */
346 out_8(&sw->intr_enable, ERROR | SEEK_DONE);
347 set_timeout(fs, HZ/2, seek_timeout); /* enable timeout */
350 static inline void init_dma(struct dbdma_cmd *cp, int cmd,
351 void *buf, int count)
353 st_le16(&cp->req_count, count);
354 st_le16(&cp->command, cmd);
355 st_le32(&cp->phy_addr, virt_to_bus(buf));
356 cp->xfer_status = 0;
359 static inline void setup_transfer(struct floppy_state *fs)
361 int n;
362 volatile struct swim3 *sw = fs->swim3;
363 struct dbdma_cmd *cp = fs->dma_cmd;
364 struct dbdma_regs *dr = fs->dma;
366 if (CURRENT->current_nr_sectors <= 0) {
367 printk(KERN_ERR "swim3: transfer 0 sectors?\n");
368 return;
370 if (CURRENT->cmd == WRITE)
371 n = 1;
372 else {
373 n = fs->secpertrack - fs->req_sector + 1;
374 if (n > CURRENT->current_nr_sectors)
375 n = CURRENT->current_nr_sectors;
377 fs->scount = n;
378 swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0);
379 out_8(&sw->sector, fs->req_sector);
380 out_8(&sw->nsect, n);
381 out_8(&sw->ssize, 0);
382 st_le32(&dr->cmdptr, virt_to_bus(cp));
383 if (CURRENT->cmd == WRITE) {
384 /* Set up 3 dma commands: write preamble, data, postamble */
385 init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble));
386 ++cp;
387 init_dma(cp, OUTPUT_MORE, CURRENT->buffer, 512);
388 ++cp;
389 init_dma(cp, OUTPUT_MORE, write_postamble, sizeof(write_postamble));
390 } else {
391 init_dma(cp, INPUT_MORE, CURRENT->buffer, n * 512);
393 ++cp;
394 out_le16(&cp->command, DBDMA_STOP);
395 out_le32(&dr->control, (RUN << 16) | RUN);
396 out_8(&sw->control_bis,
397 (CURRENT->cmd == WRITE? WRITE_SECTORS: 0) | SCAN_TRACK);
398 /* enable intr when transfer complete */
399 out_8(&sw->intr_enable, ERROR | TRANSFER_DONE);
400 set_timeout(fs, 2*HZ, xfer_timeout); /* enable timeout */
403 static void act(struct floppy_state *fs)
405 volatile struct swim3 *sw = fs->swim3;
407 for (;;) {
408 switch (fs->state) {
409 case idle:
410 return; /* XXX shouldn't get here */
412 case locating:
413 if (swim3_readbit(fs, TRACK_ZERO)) {
414 fs->cur_cyl = 0;
415 if (fs->req_cyl == 0)
416 fs->state = do_transfer;
417 else
418 fs->state = seeking;
419 break;
421 scan_track(fs);
422 return;
424 case seeking:
425 if (fs->cur_cyl < 0) {
426 fs->expect_cyl = -1;
427 fs->state = locating;
428 break;
430 if (fs->req_cyl == fs->cur_cyl) {
431 printk("whoops, seeking 0\n");
432 fs->state = do_transfer;
433 break;
435 seek_track(fs, fs->req_cyl - fs->cur_cyl);
436 return;
438 case settling:
439 /* wait for SEEK_COMPLETE to become true */
440 swim3_select(fs, SEEK_COMPLETE);
441 udelay(1);
442 out_8(&sw->intr_enable, ERROR | DATA_CHANGED);
443 in_8(&sw->intr); /* clear DATA_CHANGED */
444 if (in_8(&sw->status) & DATA) {
445 /* seek_complete is not yet true */
446 set_timeout(fs, HZ/2, seek_timeout);
447 return;
449 out_8(&sw->intr_enable, 0);
450 in_8(&sw->intr);
451 fs->state = locating;
452 break;
454 case do_transfer:
455 if (fs->cur_cyl != fs->req_cyl) {
456 if (fs->retries > 5) {
457 end_request(0);
458 fs->state = idle;
459 return;
461 fs->state = seeking;
462 break;
464 setup_transfer(fs);
465 return;
467 case jogging:
468 seek_track(fs, -5);
469 return;
471 default:
472 printk(KERN_ERR"swim3: unknown state %d\n", fs->state);
473 return;
478 static void scan_timeout(unsigned long data)
480 struct floppy_state *fs = (struct floppy_state *) data;
481 volatile struct swim3 *sw = fs->swim3;
483 fs->timeout_pending = 0;
484 out_8(&sw->control_bic, SCAN_TRACK);
485 out_8(&sw->select, RELAX);
486 out_8(&sw->intr_enable, 0);
487 fs->cur_cyl = -1;
488 if (fs->retries > 5) {
489 end_request(0);
490 fs->state = idle;
491 start_request(fs);
492 } else {
493 fs->state = jogging;
494 act(fs);
498 static void seek_timeout(unsigned long data)
500 struct floppy_state *fs = (struct floppy_state *) data;
501 volatile struct swim3 *sw = fs->swim3;
503 fs->timeout_pending = 0;
504 if (fs->state == settling) {
505 printk(KERN_ERR "swim3: MSI sel=%x ctrl=%x stat=%x intr=%x ie=%x\n",
506 sw->select, sw->control, sw->status, sw->intr, sw->intr_enable);
508 out_8(&sw->control_bic, DO_SEEK);
509 out_8(&sw->select, RELAX);
510 out_8(&sw->intr_enable, 0);
511 if (fs->state == settling && swim3_readbit(fs, SEEK_COMPLETE)) {
512 /* printk(KERN_DEBUG "swim3: missed settling interrupt\n"); */
513 fs->state = locating;
514 act(fs);
515 return;
517 printk(KERN_ERR "swim3: seek timeout\n");
518 end_request(0);
519 fs->state = idle;
520 start_request(fs);
523 static void xfer_timeout(unsigned long data)
525 struct floppy_state *fs = (struct floppy_state *) data;
526 volatile struct swim3 *sw = fs->swim3;
527 struct dbdma_regs *dr = fs->dma;
528 struct dbdma_cmd *cp = fs->dma_cmd;
529 unsigned long s;
531 fs->timeout_pending = 0;
532 st_le32(&dr->control, RUN << 16);
533 out_8(&sw->intr_enable, 0);
534 out_8(&sw->control_bic, WRITE_SECTORS | SCAN_TRACK);
535 out_8(&sw->select, RELAX);
536 if (CURRENT->cmd == WRITE)
537 ++cp;
538 if (ld_le16(&cp->xfer_status) != 0)
539 s = fs->scount - ((ld_le16(&cp->res_count) + 511) >> 9);
540 else
541 s = 0;
542 CURRENT->sector += s;
543 CURRENT->current_nr_sectors -= s;
544 printk(KERN_ERR "swim3: timeout %sing sector %ld\n",
545 (CURRENT->cmd==WRITE? "writ": "read"), CURRENT->sector);
546 end_request(0);
547 fs->state = idle;
548 start_request(fs);
551 static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
553 struct floppy_state *fs = (struct floppy_state *) dev_id;
554 volatile struct swim3 *sw = fs->swim3;
555 int intr, err, n;
556 int stat, resid;
557 struct dbdma_regs *dr;
558 struct dbdma_cmd *cp;
560 err = in_8(&sw->error);
561 intr = in_8(&sw->intr);
562 #if 0
563 printk(KERN_DEBUG "swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err);
564 #endif
565 if ((intr & ERROR) && fs->state != do_transfer)
566 printk(KERN_ERR "swim3_interrupt, state=%d, cmd=%x, intr=%x, err=%x\n",
567 fs->state, CURRENT->cmd, intr, err);
568 switch (fs->state) {
569 case locating:
570 if (intr & SEEN_SECTOR) {
571 out_8(&sw->control_bic, SCAN_TRACK);
572 out_8(&sw->select, RELAX);
573 out_8(&sw->intr_enable, 0);
574 del_timer(&fs->timeout);
575 fs->timeout_pending = 0;
576 if (sw->ctrack == 0xff) {
577 printk(KERN_ERR "swim3: seen sector but cyl=ff?\n");
578 fs->cur_cyl = -1;
579 if (fs->retries > 5) {
580 end_request(0);
581 fs->state = idle;
582 start_request(fs);
583 } else {
584 fs->state = jogging;
585 act(fs);
587 break;
589 fs->cur_cyl = sw->ctrack;
590 fs->cur_sector = sw->csect;
591 if (fs->expect_cyl != -1 && fs->expect_cyl != fs->cur_cyl)
592 printk(KERN_ERR "swim3: expected cyl %d, got %d\n",
593 fs->expect_cyl, fs->cur_cyl);
594 fs->state = do_transfer;
595 act(fs);
597 break;
598 case seeking:
599 case jogging:
600 if (sw->nseek == 0) {
601 out_8(&sw->control_bic, DO_SEEK);
602 out_8(&sw->select, RELAX);
603 out_8(&sw->intr_enable, 0);
604 del_timer(&fs->timeout);
605 fs->timeout_pending = 0;
606 if (fs->state == seeking)
607 ++fs->retries;
608 fs->state = settling;
609 act(fs);
611 break;
612 case settling:
613 out_8(&sw->intr_enable, 0);
614 del_timer(&fs->timeout);
615 fs->timeout_pending = 0;
616 act(fs);
617 break;
618 case do_transfer:
619 if ((intr & (ERROR | TRANSFER_DONE)) == 0)
620 break;
621 dr = fs->dma;
622 cp = fs->dma_cmd;
623 st_le32(&dr->control, RUN << 16);
624 out_8(&sw->intr_enable, 0);
625 out_8(&sw->control_bic, WRITE_SECTORS | SCAN_TRACK);
626 out_8(&sw->select, RELAX);
627 del_timer(&fs->timeout);
628 fs->timeout_pending = 0;
629 if (CURRENT->cmd == WRITE)
630 ++cp;
631 stat = ld_le16(&cp->xfer_status);
632 resid = ld_le16(&cp->res_count);
633 if (intr & ERROR) {
634 n = fs->scount - 1 - resid / 512;
635 if (n > 0) {
636 CURRENT->sector += n;
637 CURRENT->current_nr_sectors -= n;
638 CURRENT->buffer += n * 512;
639 fs->req_sector += n;
641 if (fs->retries < 5) {
642 ++fs->retries;
643 act(fs);
644 } else {
645 printk("swim3: error %sing block %ld (err=%x)\n",
646 CURRENT->cmd == WRITE? "writ": "read",
647 CURRENT->sector, err);
648 end_request(0);
649 fs->state = idle;
651 } else {
652 if ((stat & ACTIVE) == 0 || resid != 0) {
653 /* musta been an error */
654 printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid);
655 printk(KERN_ERR " state=%d, cmd=%x, intr=%x, err=%x\n",
656 fs->state, CURRENT->cmd, intr, err);
657 end_request(0);
658 fs->state = idle;
659 start_request(fs);
660 break;
662 CURRENT->sector += fs->scount;
663 CURRENT->current_nr_sectors -= fs->scount;
664 CURRENT->buffer += fs->scount * 512;
665 if (CURRENT->current_nr_sectors <= 0) {
666 end_request(1);
667 fs->state = idle;
668 } else {
669 fs->req_sector += fs->scount;
670 if (fs->req_sector > fs->secpertrack) {
671 fs->req_sector -= fs->secpertrack;
672 if (++fs->head > 1) {
673 fs->head = 0;
674 ++fs->req_cyl;
677 act(fs);
680 if (fs->state == idle)
681 start_request(fs);
682 break;
683 default:
684 printk(KERN_ERR "swim3: don't know what to do in state %d\n", fs->state);
688 static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
692 static int grab_drive(struct floppy_state *fs, enum swim_state state,
693 int interruptible)
695 unsigned long flags;
697 save_flags(flags);
698 cli();
699 if (fs->state != idle) {
700 ++fs->wanted;
701 while (fs->state != available) {
702 if (interruptible && signal_pending(current)) {
703 --fs->wanted;
704 restore_flags(flags);
705 return -EINTR;
707 interruptible_sleep_on(&fs->wait);
709 --fs->wanted;
711 fs->state = state;
712 restore_flags(flags);
713 return 0;
716 static void release_drive(struct floppy_state *fs)
718 unsigned long flags;
720 save_flags(flags);
721 cli();
722 fs->state = idle;
723 start_request(fs);
724 restore_flags(flags);
727 static int fd_eject(struct floppy_state *fs)
729 int err, n;
731 err = grab_drive(fs, ejecting, 1);
732 if (err)
733 return err;
734 swim3_action(fs, EJECT);
735 for (n = 2*HZ; n > 0; --n) {
736 if (swim3_readbit(fs, RELAX))
737 break;
738 if (signal_pending(current)) {
739 err = -EINTR;
740 break;
742 current->state = TASK_INTERRUPTIBLE;
743 current->timeout = jiffies + 1;
744 schedule();
746 fs->ejected = 1;
747 release_drive(fs);
748 return err;
751 static struct floppy_struct floppy_type =
752 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */
754 static int floppy_ioctl(struct inode *inode, struct file *filp,
755 unsigned int cmd, unsigned long param)
757 struct floppy_state *fs;
758 int err;
760 if (((cmd & 0x40) && !(filp && (filp->f_mode & IOCTL_MODE_BIT))) ||
761 ((cmd & 0x80) && !suser()))
762 return -EPERM;
764 fs = &floppy_states[0];
765 switch (cmd) {
766 case FDEJECT:
767 if (fs->ref_count != 1)
768 return -EBUSY;
769 err = fd_eject(fs);
770 return err;
771 case FDGETPRM:
772 err = copy_to_user((void *) param, (void *) &floppy_type,
773 sizeof(struct floppy_struct));
774 return err;
776 return -ENOIOCTLCMD;
779 static int floppy_open(struct inode *inode, struct file *filp)
781 struct floppy_state *fs;
782 volatile struct swim3 *sw;
783 int n, err;
785 if (MINOR(inode->i_rdev) != 0)
786 return -ENODEV;
787 fs = &floppy_states[0];
788 sw = fs->swim3;
789 err = 0;
790 if (fs->ref_count == 0) {
791 if (fs->in_media_bay && !check_media_bay(MB_FD))
792 return -ENXIO;
793 out_8(&sw->mode, 0x95);
794 out_8(&sw->control_bic, 0xff);
795 out_8(&sw->reg5, 0x28);
796 udelay(1);
797 out_8(&sw->intr_enable, 0);
798 out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
799 swim3_action(fs, MOTOR_ON);
800 fs->write_prot = -1;
801 fs->cur_cyl = -1;
802 for (n = HZ; n > 0; --n) {
803 if (swim3_readbit(fs, SEEK_COMPLETE))
804 break;
805 if (signal_pending(current)) {
806 err = -EINTR;
807 break;
809 current->state = TASK_INTERRUPTIBLE;
810 current->timeout = jiffies + 1;
811 schedule();
813 if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
814 || swim3_readbit(fs, DISK_IN) == 0))
815 err = -ENXIO;
816 swim3_action(fs, 9);
818 } else if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
819 return -EBUSY;
821 if (err == 0 && filp && (filp->f_flags & O_NDELAY) == 0
822 && (filp->f_mode & 3)) {
823 check_disk_change(inode->i_rdev);
824 if (fs->ejected)
825 err = -ENXIO;
828 if (err == 0 && filp && (filp->f_flags & (O_WRONLY | O_RDWR))) {
829 if (fs->write_prot < 0)
830 fs->write_prot = swim3_readbit(fs, WRITE_PROT);
831 if (fs->write_prot)
832 err = -EROFS;
835 if (err) {
836 if (fs->ref_count == 0) {
837 swim3_action(fs, MOTOR_OFF);
838 out_8(&sw->control_bic, DRIVE_ENABLE | INTR_ENABLE);
840 return err;
843 if (filp->f_flags & O_EXCL)
844 fs->ref_count = -1;
845 else
846 ++fs->ref_count;
848 /* Allow ioctls if we have write-permissions even if read-only open */
849 if ((filp->f_mode & 2) || (permission(inode, 2) == 0))
850 filp->f_mode |= IOCTL_MODE_BIT;
851 if (filp->f_mode & 2)
852 filp->f_mode |= OPEN_WRITE_BIT;
854 return 0;
857 static int floppy_release(struct inode *inode, struct file *filp)
859 struct floppy_state *fs;
860 volatile struct swim3 *sw;
862 if (MINOR(inode->i_rdev) != 0)
863 return -ENXIO;
865 * If filp is NULL, we're being called from blkdev_release
866 * or after a failed mount attempt. In the former case the
867 * device has already been sync'ed, and in the latter no
868 * sync is required. Otherwise, sync if filp is writable.
870 if (filp && (filp->f_mode & (2 | OPEN_WRITE_BIT)))
871 block_fsync (filp, filp->f_dentry);
873 fs = &floppy_states[0];
874 sw = fs->swim3;
875 if (fs->ref_count > 0 && --fs->ref_count == 0) {
876 swim3_action(fs, MOTOR_OFF);
877 out_8(&sw->control_bic, 0xff);
879 return 0;
882 static int floppy_check_change(kdev_t dev)
884 struct floppy_state *fs;
886 if (MAJOR(dev) != MAJOR_NR || MINOR(dev) != 0)
887 return 0;
888 fs = &floppy_states[0];
889 return fs->ejected;
892 static int floppy_revalidate(kdev_t dev)
894 struct floppy_state *fs;
895 volatile struct swim3 *sw;
896 int ret, n;
898 if (MAJOR(dev) != MAJOR_NR || MINOR(dev) != 0)
899 return 0;
900 fs = &floppy_states[0];
901 sw = fs->swim3;
902 grab_drive(fs, revalidating, 0);
903 out_8(&sw->intr_enable, 0);
904 out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
905 swim3_action(fs, MOTOR_ON);
906 fs->write_prot = -1;
907 fs->cur_cyl = -1;
908 for (n = HZ; n > 0; --n) {
909 if (swim3_readbit(fs, SEEK_COMPLETE))
910 break;
911 if (signal_pending(current))
912 break;
913 current->state = TASK_INTERRUPTIBLE;
914 current->timeout = jiffies + 1;
915 schedule();
917 ret = swim3_readbit(fs, SEEK_COMPLETE) == 0
918 || swim3_readbit(fs, DISK_IN) == 0;
919 if (ret)
920 swim3_action(fs, MOTOR_OFF);
921 else {
922 fs->ejected = 0;
923 swim3_action(fs, 9);
926 release_drive(fs);
927 return ret;
930 static ssize_t floppy_read(struct file *filp, char *buf,
931 size_t count, loff_t *ppos)
933 struct inode *inode = filp->f_dentry->d_inode;
934 struct floppy_state *fs;
936 if (MINOR(inode->i_rdev) != 0)
937 return -ENODEV;
938 fs = &floppy_states[0];
939 if (fs->ejected)
940 return -ENXIO;
941 return block_read(filp, buf, count, ppos);
944 static ssize_t floppy_write(struct file * filp, const char * buf,
945 size_t count, loff_t *ppos)
947 struct inode * inode = filp->f_dentry->d_inode;
948 struct floppy_state *fs;
950 if (MINOR(inode->i_rdev) != 0)
951 return -ENODEV;
952 fs = &floppy_states[0];
953 if (fs->ejected)
954 return -ENXIO;
955 return block_write(filp, buf, count, ppos);
958 static void floppy_off(unsigned int nr)
962 static struct file_operations floppy_fops = {
963 NULL, /* lseek */
964 floppy_read, /* read */
965 floppy_write, /* write */
966 NULL, /* readdir */
967 NULL, /* poll */
968 floppy_ioctl, /* ioctl */
969 NULL, /* mmap */
970 floppy_open, /* open */
971 NULL, /* flush */
972 floppy_release, /* release *
973 block_fsync, /* fsync */
974 NULL, /* fasync */
975 floppy_check_change, /* check_media_change */
976 floppy_revalidate, /* revalidate */
979 int swim3_init(void)
981 struct device_node *swims;
982 struct floppy_state *fs = &floppy_states[0];
983 int is_3400 = 0;
985 if (find_devices("media-bay") != NULL) {
986 /* assume this is a PB3400 */
987 swims = find_devices("floppy");
988 is_3400 = 1;
989 } else {
990 swims = find_devices("swim3");
993 if (swims == NULL)
994 return 0;
996 if (swims->next != NULL)
997 printk(KERN_ERR "Warning: only using first SWIM3 floppy controller\n");
998 if (swims->n_addrs != 2 || swims->n_intrs != 2) {
999 printk(KERN_ERR "swim3: expecting 2 addrs and 2 intrs! (%d, %d)\n",
1000 swims->n_addrs, swims->n_intrs);
1001 return -EINVAL;
1004 if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
1005 printk(KERN_ERR "Unable to get major %d for floppy\n",
1006 MAJOR_NR);
1007 return -EBUSY;
1009 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1010 blksize_size[MAJOR_NR] = floppy_blocksizes;
1011 blk_size[MAJOR_NR] = floppy_sizes;
1013 memset(fs, 0, sizeof(*fs));
1014 fs->state = idle;
1015 fs->swim3 = (volatile struct swim3 *) swims->addrs[0].address;
1016 fs->dma = (struct dbdma_regs *) swims->addrs[1].address;
1017 fs->swim3_intr = swims->intrs[0].line;
1018 fs->dma_intr = swims->intrs[1].line;
1019 fs->cur_cyl = -1;
1020 fs->cur_sector = -1;
1021 fs->secpercyl = 36;
1022 fs->secpertrack = 18;
1023 fs->total_secs = 2880;
1024 fs->in_media_bay = is_3400;
1026 fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
1027 memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd));
1028 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP);
1030 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
1031 printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr);
1032 return -EBUSY;
1034 if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) {
1035 printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA",
1036 fs->dma_intr);
1037 return -EBUSY;
1040 init_timer(&fs->timeout);
1042 do_floppy = NULL;
1044 printk(KERN_INFO "fd0: SWIM3 floppy controller\n");
1046 return 0;