]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/block/swim.c
Merge branch 'for-jens' of git://git.drbd.org/linux-2.6-drbd into for-2.6.37/drivers
[mv-sheeva.git] / drivers / block / swim.c
1 /*
2  * Driver for SWIM (Sander Woz Integrated Machine) floppy controller
3  *
4  * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
5  *
6  * based on Alastair Bridgewater SWIM analysis, 2001
7  * based on SWIM3 driver (c) Paul Mackerras, 1996
8  * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version
13  * 2 of the License, or (at your option) any later version.
14  *
15  * 2004-08-21 (lv) - Initial implementation
16  * 2008-10-30 (lv) - Port to 2.6
17  */
18
19 #include <linux/module.h>
20 #include <linux/fd.h>
21 #include <linux/slab.h>
22 #include <linux/blkdev.h>
23 #include <linux/mutex.h>
24 #include <linux/hdreg.h>
25 #include <linux/kernel.h>
26 #include <linux/delay.h>
27 #include <linux/platform_device.h>
28
29 #include <asm/macintosh.h>
30 #include <asm/mac_via.h>
31
32 #define CARDNAME "swim"
33
34 struct sector_header {
35         unsigned char side;
36         unsigned char track;
37         unsigned char sector;
38         unsigned char size;
39         unsigned char crc0;
40         unsigned char crc1;
41 } __attribute__((packed));
42
43 #define DRIVER_VERSION "Version 0.2 (2008-10-30)"
44
45 #define REG(x)  unsigned char x, x ## _pad[0x200 - 1];
46
47 struct swim {
48         REG(write_data)
49         REG(write_mark)
50         REG(write_CRC)
51         REG(write_parameter)
52         REG(write_phase)
53         REG(write_setup)
54         REG(write_mode0)
55         REG(write_mode1)
56
57         REG(read_data)
58         REG(read_mark)
59         REG(read_error)
60         REG(read_parameter)
61         REG(read_phase)
62         REG(read_setup)
63         REG(read_status)
64         REG(read_handshake)
65 } __attribute__((packed));
66
67 #define swim_write(base, reg, v)        out_8(&(base)->write_##reg, (v))
68 #define swim_read(base, reg)            in_8(&(base)->read_##reg)
69
70 /* IWM registers */
71
72 struct iwm {
73         REG(ph0L)
74         REG(ph0H)
75         REG(ph1L)
76         REG(ph1H)
77         REG(ph2L)
78         REG(ph2H)
79         REG(ph3L)
80         REG(ph3H)
81         REG(mtrOff)
82         REG(mtrOn)
83         REG(intDrive)
84         REG(extDrive)
85         REG(q6L)
86         REG(q6H)
87         REG(q7L)
88         REG(q7H)
89 } __attribute__((packed));
90
91 #define iwm_write(base, reg, v)         out_8(&(base)->reg, (v))
92 #define iwm_read(base, reg)             in_8(&(base)->reg)
93
94 /* bits in phase register */
95
96 #define SEEK_POSITIVE   0x070
97 #define SEEK_NEGATIVE   0x074
98 #define STEP            0x071
99 #define MOTOR_ON        0x072
100 #define MOTOR_OFF       0x076
101 #define INDEX           0x073
102 #define EJECT           0x077
103 #define SETMFM          0x171
104 #define SETGCR          0x175
105
106 #define RELAX           0x033
107 #define LSTRB           0x008
108
109 #define CA_MASK         0x077
110
111 /* Select values for swim_select and swim_readbit */
112
113 #define READ_DATA_0     0x074
114 #define TWOMEG_DRIVE    0x075
115 #define SINGLE_SIDED    0x076
116 #define DRIVE_PRESENT   0x077
117 #define DISK_IN         0x170
118 #define WRITE_PROT      0x171
119 #define TRACK_ZERO      0x172
120 #define TACHO           0x173
121 #define READ_DATA_1     0x174
122 #define MFM_MODE        0x175
123 #define SEEK_COMPLETE   0x176
124 #define ONEMEG_MEDIA    0x177
125
126 /* Bits in handshake register */
127
128 #define MARK_BYTE       0x01
129 #define CRC_ZERO        0x02
130 #define RDDATA          0x04
131 #define SENSE           0x08
132 #define MOTEN           0x10
133 #define ERROR           0x20
134 #define DAT2BYTE        0x40
135 #define DAT1BYTE        0x80
136
137 /* bits in setup register */
138
139 #define S_INV_WDATA     0x01
140 #define S_3_5_SELECT    0x02
141 #define S_GCR           0x04
142 #define S_FCLK_DIV2     0x08
143 #define S_ERROR_CORR    0x10
144 #define S_IBM_DRIVE     0x20
145 #define S_GCR_WRITE     0x40
146 #define S_TIMEOUT       0x80
147
148 /* bits in mode register */
149
150 #define CLFIFO          0x01
151 #define ENBL1           0x02
152 #define ENBL2           0x04
153 #define ACTION          0x08
154 #define WRITE_MODE      0x10
155 #define HEDSEL          0x20
156 #define MOTON           0x80
157
158 /*----------------------------------------------------------------------------*/
159
160 enum drive_location {
161         INTERNAL_DRIVE = 0x02,
162         EXTERNAL_DRIVE = 0x04,
163 };
164
165 enum media_type {
166         DD_MEDIA,
167         HD_MEDIA,
168 };
169
170 struct floppy_state {
171
172         /* physical properties */
173
174         enum drive_location location;   /* internal or external drive */
175         int              head_number;   /* single- or double-sided drive */
176
177         /* media */
178
179         int              disk_in;
180         int              ejected;
181         enum media_type  type;
182         int              write_protected;
183
184         int              total_secs;
185         int              secpercyl;
186         int              secpertrack;
187
188         /* in-use information */
189
190         int             track;
191         int             ref_count;
192
193         struct gendisk *disk;
194
195         /* parent controller */
196
197         struct swim_priv *swd;
198 };
199
200 enum motor_action {
201         OFF,
202         ON,
203 };
204
205 enum head {
206         LOWER_HEAD = 0,
207         UPPER_HEAD = 1,
208 };
209
210 #define FD_MAX_UNIT     2
211
212 struct swim_priv {
213         struct swim __iomem *base;
214         spinlock_t lock;
215         struct request_queue *queue;
216         int floppy_count;
217         struct floppy_state unit[FD_MAX_UNIT];
218 };
219
220 extern int swim_read_sector_header(struct swim __iomem *base,
221                                    struct sector_header *header);
222 extern int swim_read_sector_data(struct swim __iomem *base,
223                                  unsigned char *data);
224
225 static DEFINE_MUTEX(swim_mutex);
226 static inline void set_swim_mode(struct swim __iomem *base, int enable)
227 {
228         struct iwm __iomem *iwm_base;
229         unsigned long flags;
230
231         if (!enable) {
232                 swim_write(base, mode0, 0xf8);
233                 return;
234         }
235
236         iwm_base = (struct iwm __iomem *)base;
237         local_irq_save(flags);
238
239         iwm_read(iwm_base, q7L);
240         iwm_read(iwm_base, mtrOff);
241         iwm_read(iwm_base, q6H);
242
243         iwm_write(iwm_base, q7H, 0x57);
244         iwm_write(iwm_base, q7H, 0x17);
245         iwm_write(iwm_base, q7H, 0x57);
246         iwm_write(iwm_base, q7H, 0x57);
247
248         local_irq_restore(flags);
249 }
250
251 static inline int get_swim_mode(struct swim __iomem *base)
252 {
253         unsigned long flags;
254
255         local_irq_save(flags);
256
257         swim_write(base, phase, 0xf5);
258         if (swim_read(base, phase) != 0xf5)
259                 goto is_iwm;
260         swim_write(base, phase, 0xf6);
261         if (swim_read(base, phase) != 0xf6)
262                 goto is_iwm;
263         swim_write(base, phase, 0xf7);
264         if (swim_read(base, phase) != 0xf7)
265                 goto is_iwm;
266         local_irq_restore(flags);
267         return 1;
268 is_iwm:
269         local_irq_restore(flags);
270         return 0;
271 }
272
273 static inline void swim_select(struct swim __iomem *base, int sel)
274 {
275         swim_write(base, phase, RELAX);
276
277         via1_set_head(sel & 0x100);
278
279         swim_write(base, phase, sel & CA_MASK);
280 }
281
282 static inline void swim_action(struct swim __iomem *base, int action)
283 {
284         unsigned long flags;
285
286         local_irq_save(flags);
287
288         swim_select(base, action);
289         udelay(1);
290         swim_write(base, phase, (LSTRB<<4) | LSTRB);
291         udelay(1);
292         swim_write(base, phase, (LSTRB<<4) | ((~LSTRB) & 0x0F));
293         udelay(1);
294
295         local_irq_restore(flags);
296 }
297
298 static inline int swim_readbit(struct swim __iomem *base, int bit)
299 {
300         int stat;
301
302         swim_select(base, bit);
303
304         udelay(10);
305
306         stat = swim_read(base, handshake);
307
308         return (stat & SENSE) == 0;
309 }
310
311 static inline void swim_drive(struct swim __iomem *base,
312                               enum drive_location location)
313 {
314         if (location == INTERNAL_DRIVE) {
315                 swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */
316                 swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */
317         } else if (location == EXTERNAL_DRIVE) {
318                 swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */
319                 swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */
320         }
321 }
322
323 static inline void swim_motor(struct swim __iomem *base,
324                               enum motor_action action)
325 {
326         if (action == ON) {
327                 int i;
328
329                 swim_action(base, MOTOR_ON);
330
331                 for (i = 0; i < 2*HZ; i++) {
332                         swim_select(base, RELAX);
333                         if (swim_readbit(base, MOTOR_ON))
334                                 break;
335                         current->state = TASK_INTERRUPTIBLE;
336                         schedule_timeout(1);
337                 }
338         } else if (action == OFF) {
339                 swim_action(base, MOTOR_OFF);
340                 swim_select(base, RELAX);
341         }
342 }
343
344 static inline void swim_eject(struct swim __iomem *base)
345 {
346         int i;
347
348         swim_action(base, EJECT);
349
350         for (i = 0; i < 2*HZ; i++) {
351                 swim_select(base, RELAX);
352                 if (!swim_readbit(base, DISK_IN))
353                         break;
354                 current->state = TASK_INTERRUPTIBLE;
355                 schedule_timeout(1);
356         }
357         swim_select(base, RELAX);
358 }
359
360 static inline void swim_head(struct swim __iomem *base, enum head head)
361 {
362         /* wait drive is ready */
363
364         if (head == UPPER_HEAD)
365                 swim_select(base, READ_DATA_1);
366         else if (head == LOWER_HEAD)
367                 swim_select(base, READ_DATA_0);
368 }
369
370 static inline int swim_step(struct swim __iomem *base)
371 {
372         int wait;
373
374         swim_action(base, STEP);
375
376         for (wait = 0; wait < HZ; wait++) {
377
378                 current->state = TASK_INTERRUPTIBLE;
379                 schedule_timeout(1);
380
381                 swim_select(base, RELAX);
382                 if (!swim_readbit(base, STEP))
383                         return 0;
384         }
385         return -1;
386 }
387
388 static inline int swim_track00(struct swim __iomem *base)
389 {
390         int try;
391
392         swim_action(base, SEEK_NEGATIVE);
393
394         for (try = 0; try < 100; try++) {
395
396                 swim_select(base, RELAX);
397                 if (swim_readbit(base, TRACK_ZERO))
398                         break;
399
400                 if (swim_step(base))
401                         return -1;
402         }
403
404         if (swim_readbit(base, TRACK_ZERO))
405                 return 0;
406
407         return -1;
408 }
409
410 static inline int swim_seek(struct swim __iomem *base, int step)
411 {
412         if (step == 0)
413                 return 0;
414
415         if (step < 0) {
416                 swim_action(base, SEEK_NEGATIVE);
417                 step = -step;
418         } else
419                 swim_action(base, SEEK_POSITIVE);
420
421         for ( ; step > 0; step--) {
422                 if (swim_step(base))
423                         return -1;
424         }
425
426         return 0;
427 }
428
429 static inline int swim_track(struct floppy_state *fs,  int track)
430 {
431         struct swim __iomem *base = fs->swd->base;
432         int ret;
433
434         ret = swim_seek(base, track - fs->track);
435
436         if (ret == 0)
437                 fs->track = track;
438         else {
439                 swim_track00(base);
440                 fs->track = 0;
441         }
442
443         return ret;
444 }
445
446 static int floppy_eject(struct floppy_state *fs)
447 {
448         struct swim __iomem *base = fs->swd->base;
449
450         swim_drive(base, fs->location);
451         swim_motor(base, OFF);
452         swim_eject(base);
453
454         fs->disk_in = 0;
455         fs->ejected = 1;
456
457         return 0;
458 }
459
460 static inline int swim_read_sector(struct floppy_state *fs,
461                                    int side, int track,
462                                    int sector, unsigned char *buffer)
463 {
464         struct swim __iomem *base = fs->swd->base;
465         unsigned long flags;
466         struct sector_header header;
467         int ret = -1;
468         short i;
469
470         swim_track(fs, track);
471
472         swim_write(base, mode1, MOTON);
473         swim_head(base, side);
474         swim_write(base, mode0, side);
475
476         local_irq_save(flags);
477         for (i = 0; i < 36; i++) {
478                 ret = swim_read_sector_header(base, &header);
479                 if (!ret && (header.sector == sector)) {
480                         /* found */
481
482                         ret = swim_read_sector_data(base, buffer);
483                         break;
484                 }
485         }
486         local_irq_restore(flags);
487
488         swim_write(base, mode0, MOTON);
489
490         if ((header.side != side)  || (header.track != track) ||
491              (header.sector != sector))
492                 return 0;
493
494         return ret;
495 }
496
497 static int floppy_read_sectors(struct floppy_state *fs,
498                                int req_sector, int sectors_nb,
499                                unsigned char *buffer)
500 {
501         struct swim __iomem *base = fs->swd->base;
502         int ret;
503         int side, track, sector;
504         int i, try;
505
506
507         swim_drive(base, fs->location);
508         for (i = req_sector; i < req_sector + sectors_nb; i++) {
509                 int x;
510                 track = i / fs->secpercyl;
511                 x = i % fs->secpercyl;
512                 side = x / fs->secpertrack;
513                 sector = x % fs->secpertrack + 1;
514
515                 try = 5;
516                 do {
517                         ret = swim_read_sector(fs, side, track, sector,
518                                                 buffer);
519                         if (try-- == 0)
520                                 return -EIO;
521                 } while (ret != 512);
522
523                 buffer += ret;
524         }
525
526         return 0;
527 }
528
529 static void redo_fd_request(struct request_queue *q)
530 {
531         struct request *req;
532         struct floppy_state *fs;
533
534         req = blk_fetch_request(q);
535         while (req) {
536                 int err = -EIO;
537
538                 fs = req->rq_disk->private_data;
539                 if (blk_rq_pos(req) >= fs->total_secs)
540                         goto done;
541                 if (!fs->disk_in)
542                         goto done;
543                 if (rq_data_dir(req) == WRITE && fs->write_protected)
544                         goto done;
545
546                 switch (rq_data_dir(req)) {
547                 case WRITE:
548                         /* NOT IMPLEMENTED */
549                         break;
550                 case READ:
551                         err = floppy_read_sectors(fs, blk_rq_pos(req),
552                                                   blk_rq_cur_sectors(req),
553                                                   req->buffer);
554                         break;
555                 }
556         done:
557                 if (!__blk_end_request_cur(req, err))
558                         req = blk_fetch_request(q);
559         }
560 }
561
562 static void do_fd_request(struct request_queue *q)
563 {
564         redo_fd_request(q);
565 }
566
567 static struct floppy_struct floppy_type[4] = {
568         {    0,  0, 0,  0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing   */
569         {  720,  9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
570         { 1440,  9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 720KB 3.5"   */
571         { 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL }, /* 1.44MB 3.5"  */
572 };
573
574 static int get_floppy_geometry(struct floppy_state *fs, int type,
575                                struct floppy_struct **g)
576 {
577         if (type >= ARRAY_SIZE(floppy_type))
578                 return -EINVAL;
579
580         if (type)
581                 *g = &floppy_type[type];
582         else if (fs->type == HD_MEDIA) /* High-Density media */
583                 *g = &floppy_type[3];
584         else if (fs->head_number == 2) /* double-sided */
585                 *g = &floppy_type[2];
586         else
587                 *g = &floppy_type[1];
588
589         return 0;
590 }
591
592 static void setup_medium(struct floppy_state *fs)
593 {
594         struct swim __iomem *base = fs->swd->base;
595
596         if (swim_readbit(base, DISK_IN)) {
597                 struct floppy_struct *g;
598                 fs->disk_in = 1;
599                 fs->write_protected = swim_readbit(base, WRITE_PROT);
600                 fs->type = swim_readbit(base, ONEMEG_MEDIA);
601
602                 if (swim_track00(base))
603                         printk(KERN_ERR
604                                 "SWIM: cannot move floppy head to track 0\n");
605
606                 swim_track00(base);
607
608                 get_floppy_geometry(fs, 0, &g);
609                 fs->total_secs = g->size;
610                 fs->secpercyl = g->head * g->sect;
611                 fs->secpertrack = g->sect;
612                 fs->track = 0;
613         } else {
614                 fs->disk_in = 0;
615         }
616 }
617
618 static int floppy_open(struct block_device *bdev, fmode_t mode)
619 {
620         struct floppy_state *fs = bdev->bd_disk->private_data;
621         struct swim __iomem *base = fs->swd->base;
622         int err;
623
624         if (fs->ref_count == -1 || (fs->ref_count && mode & FMODE_EXCL))
625                 return -EBUSY;
626
627         if (mode & FMODE_EXCL)
628                 fs->ref_count = -1;
629         else
630                 fs->ref_count++;
631
632         swim_write(base, setup, S_IBM_DRIVE  | S_FCLK_DIV2);
633         udelay(10);
634         swim_drive(base, INTERNAL_DRIVE);
635         swim_motor(base, ON);
636         swim_action(base, SETMFM);
637         if (fs->ejected)
638                 setup_medium(fs);
639         if (!fs->disk_in) {
640                 err = -ENXIO;
641                 goto out;
642         }
643
644         if (mode & FMODE_NDELAY)
645                 return 0;
646
647         if (mode & (FMODE_READ|FMODE_WRITE)) {
648                 check_disk_change(bdev);
649                 if ((mode & FMODE_WRITE) && fs->write_protected) {
650                         err = -EROFS;
651                         goto out;
652                 }
653         }
654         return 0;
655 out:
656         if (fs->ref_count < 0)
657                 fs->ref_count = 0;
658         else if (fs->ref_count > 0)
659                 --fs->ref_count;
660
661         if (fs->ref_count == 0)
662                 swim_motor(base, OFF);
663         return err;
664 }
665
666 static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
667 {
668         int ret;
669
670         mutex_lock(&swim_mutex);
671         ret = floppy_open(bdev, mode);
672         mutex_unlock(&swim_mutex);
673
674         return ret;
675 }
676
677 static int floppy_release(struct gendisk *disk, fmode_t mode)
678 {
679         struct floppy_state *fs = disk->private_data;
680         struct swim __iomem *base = fs->swd->base;
681
682         mutex_lock(&swim_mutex);
683         if (fs->ref_count < 0)
684                 fs->ref_count = 0;
685         else if (fs->ref_count > 0)
686                 --fs->ref_count;
687
688         if (fs->ref_count == 0)
689                 swim_motor(base, OFF);
690         mutex_unlock(&swim_mutex);
691
692         return 0;
693 }
694
695 static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
696                         unsigned int cmd, unsigned long param)
697 {
698         struct floppy_state *fs = bdev->bd_disk->private_data;
699         int err;
700
701         if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
702                         return -EPERM;
703
704         switch (cmd) {
705         case FDEJECT:
706                 if (fs->ref_count != 1)
707                         return -EBUSY;
708                 mutex_lock(&swim_mutex);
709                 err = floppy_eject(fs);
710                 mutex_unlock(&swim_mutex);
711                 return err;
712
713         case FDGETPRM:
714                 if (copy_to_user((void __user *) param, (void *) &floppy_type,
715                                  sizeof(struct floppy_struct)))
716                         return -EFAULT;
717                 break;
718
719         default:
720                 printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n",
721                        cmd);
722                 return -ENOSYS;
723         }
724         return 0;
725 }
726
727 static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
728 {
729         struct floppy_state *fs = bdev->bd_disk->private_data;
730         struct floppy_struct *g;
731         int ret;
732
733         ret = get_floppy_geometry(fs, 0, &g);
734         if (ret)
735                 return ret;
736
737         geo->heads = g->head;
738         geo->sectors = g->sect;
739         geo->cylinders = g->track;
740
741         return 0;
742 }
743
744 static int floppy_check_change(struct gendisk *disk)
745 {
746         struct floppy_state *fs = disk->private_data;
747
748         return fs->ejected;
749 }
750
751 static int floppy_revalidate(struct gendisk *disk)
752 {
753         struct floppy_state *fs = disk->private_data;
754         struct swim __iomem *base = fs->swd->base;
755
756         swim_drive(base, fs->location);
757
758         if (fs->ejected)
759                 setup_medium(fs);
760
761         if (!fs->disk_in)
762                 swim_motor(base, OFF);
763         else
764                 fs->ejected = 0;
765
766         return !fs->disk_in;
767 }
768
769 static const struct block_device_operations floppy_fops = {
770         .owner           = THIS_MODULE,
771         .open            = floppy_unlocked_open,
772         .release         = floppy_release,
773         .ioctl           = floppy_ioctl,
774         .getgeo          = floppy_getgeo,
775         .media_changed   = floppy_check_change,
776         .revalidate_disk = floppy_revalidate,
777 };
778
779 static struct kobject *floppy_find(dev_t dev, int *part, void *data)
780 {
781         struct swim_priv *swd = data;
782         int drive = (*part & 3);
783
784         if (drive > swd->floppy_count)
785                 return NULL;
786
787         *part = 0;
788         return get_disk(swd->unit[drive].disk);
789 }
790
791 static int __devinit swim_add_floppy(struct swim_priv *swd,
792                                      enum drive_location location)
793 {
794         struct floppy_state *fs = &swd->unit[swd->floppy_count];
795         struct swim __iomem *base = swd->base;
796
797         fs->location = location;
798
799         swim_drive(base, location);
800
801         swim_motor(base, OFF);
802
803         if (swim_readbit(base, SINGLE_SIDED))
804                 fs->head_number = 1;
805         else
806                 fs->head_number = 2;
807         fs->ref_count = 0;
808         fs->ejected = 1;
809
810         swd->floppy_count++;
811
812         return 0;
813 }
814
815 static int __devinit swim_floppy_init(struct swim_priv *swd)
816 {
817         int err;
818         int drive;
819         struct swim __iomem *base = swd->base;
820
821         /* scan floppy drives */
822
823         swim_drive(base, INTERNAL_DRIVE);
824         if (swim_readbit(base, DRIVE_PRESENT))
825                 swim_add_floppy(swd, INTERNAL_DRIVE);
826         swim_drive(base, EXTERNAL_DRIVE);
827         if (swim_readbit(base, DRIVE_PRESENT))
828                 swim_add_floppy(swd, EXTERNAL_DRIVE);
829
830         /* register floppy drives */
831
832         err = register_blkdev(FLOPPY_MAJOR, "fd");
833         if (err) {
834                 printk(KERN_ERR "Unable to get major %d for SWIM floppy\n",
835                        FLOPPY_MAJOR);
836                 return -EBUSY;
837         }
838
839         for (drive = 0; drive < swd->floppy_count; drive++) {
840                 swd->unit[drive].disk = alloc_disk(1);
841                 if (swd->unit[drive].disk == NULL) {
842                         err = -ENOMEM;
843                         goto exit_put_disks;
844                 }
845                 swd->unit[drive].swd = swd;
846         }
847
848         swd->queue = blk_init_queue(do_fd_request, &swd->lock);
849         if (!swd->queue) {
850                 err = -ENOMEM;
851                 goto exit_put_disks;
852         }
853
854         for (drive = 0; drive < swd->floppy_count; drive++) {
855                 swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
856                 swd->unit[drive].disk->major = FLOPPY_MAJOR;
857                 swd->unit[drive].disk->first_minor = drive;
858                 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
859                 swd->unit[drive].disk->fops = &floppy_fops;
860                 swd->unit[drive].disk->private_data = &swd->unit[drive];
861                 swd->unit[drive].disk->queue = swd->queue;
862                 set_capacity(swd->unit[drive].disk, 2880);
863                 add_disk(swd->unit[drive].disk);
864         }
865
866         blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
867                             floppy_find, NULL, swd);
868
869         return 0;
870
871 exit_put_disks:
872         unregister_blkdev(FLOPPY_MAJOR, "fd");
873         while (drive--)
874                 put_disk(swd->unit[drive].disk);
875         return err;
876 }
877
878 static int __devinit swim_probe(struct platform_device *dev)
879 {
880         struct resource *res;
881         struct swim __iomem *swim_base;
882         struct swim_priv *swd;
883         int ret;
884
885         res = platform_get_resource(dev, IORESOURCE_MEM, 0);
886         if (!res) {
887                 ret = -ENODEV;
888                 goto out;
889         }
890
891         if (!request_mem_region(res->start, resource_size(res), CARDNAME)) {
892                 ret = -EBUSY;
893                 goto out;
894         }
895
896         swim_base = ioremap(res->start, resource_size(res));
897         if (!swim_base) {
898                 return -ENOMEM;
899                 goto out_release_io;
900         }
901
902         /* probe device */
903
904         set_swim_mode(swim_base, 1);
905         if (!get_swim_mode(swim_base)) {
906                 printk(KERN_INFO "SWIM device not found !\n");
907                 ret = -ENODEV;
908                 goto out_iounmap;
909         }
910
911         /* set platform driver data */
912
913         swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
914         if (!swd) {
915                 ret = -ENOMEM;
916                 goto out_iounmap;
917         }
918         platform_set_drvdata(dev, swd);
919
920         swd->base = swim_base;
921
922         ret = swim_floppy_init(swd);
923         if (ret)
924                 goto out_kfree;
925
926         return 0;
927
928 out_kfree:
929         platform_set_drvdata(dev, NULL);
930         kfree(swd);
931 out_iounmap:
932         iounmap(swim_base);
933 out_release_io:
934         release_mem_region(res->start, resource_size(res));
935 out:
936         return ret;
937 }
938
939 static int __devexit swim_remove(struct platform_device *dev)
940 {
941         struct swim_priv *swd = platform_get_drvdata(dev);
942         int drive;
943         struct resource *res;
944
945         blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
946
947         for (drive = 0; drive < swd->floppy_count; drive++) {
948                 del_gendisk(swd->unit[drive].disk);
949                 put_disk(swd->unit[drive].disk);
950         }
951
952         unregister_blkdev(FLOPPY_MAJOR, "fd");
953
954         blk_cleanup_queue(swd->queue);
955
956         /* eject floppies */
957
958         for (drive = 0; drive < swd->floppy_count; drive++)
959                 floppy_eject(&swd->unit[drive]);
960
961         iounmap(swd->base);
962
963         res = platform_get_resource(dev, IORESOURCE_MEM, 0);
964         if (res)
965                 release_mem_region(res->start, resource_size(res));
966
967         platform_set_drvdata(dev, NULL);
968         kfree(swd);
969
970         return 0;
971 }
972
973 static struct platform_driver swim_driver = {
974         .probe  = swim_probe,
975         .remove = __devexit_p(swim_remove),
976         .driver   = {
977                 .name   = CARDNAME,
978                 .owner  = THIS_MODULE,
979         },
980 };
981
982 static int __init swim_init(void)
983 {
984         printk(KERN_INFO "SWIM floppy driver %s\n", DRIVER_VERSION);
985
986         return platform_driver_register(&swim_driver);
987 }
988 module_init(swim_init);
989
990 static void __exit swim_exit(void)
991 {
992         platform_driver_unregister(&swim_driver);
993 }
994 module_exit(swim_exit);
995
996 MODULE_DESCRIPTION("Driver for SWIM floppy controller");
997 MODULE_LICENSE("GPL");
998 MODULE_AUTHOR("Laurent Vivier <laurent@lvivier.info>");
999 MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);