Source
12
12
* as published by the Free Software Foundation; either version
13
13
* 2 of the License, or (at your option) any later version.
14
14
*
15
15
* 2004-08-21 (lv) - Initial implementation
16
16
* 2008-10-30 (lv) - Port to 2.6
17
17
*/
18
18
19
19
#include <linux/module.h>
20
20
#include <linux/fd.h>
21
21
#include <linux/slab.h>
22
-
#include <linux/blkdev.h>
22
+
#include <linux/blk-mq.h>
23
23
#include <linux/mutex.h>
24
24
#include <linux/hdreg.h>
25
25
#include <linux/kernel.h>
26
26
#include <linux/delay.h>
27
27
#include <linux/platform_device.h>
28
28
29
29
#include <asm/mac_via.h>
30
30
31
31
#define CARDNAME "swim"
32
32
183
183
int total_secs;
184
184
int secpercyl;
185
185
int secpertrack;
186
186
187
187
/* in-use information */
188
188
189
189
int track;
190
190
int ref_count;
191
191
192
192
struct gendisk *disk;
193
+
struct blk_mq_tag_set tag_set;
193
194
194
195
/* parent controller */
195
196
196
197
struct swim_priv *swd;
197
198
};
198
199
199
200
enum motor_action {
200
201
OFF,
201
202
ON,
202
203
};
204
205
enum head {
205
206
LOWER_HEAD = 0,
206
207
UPPER_HEAD = 1,
207
208
};
208
209
209
210
#define FD_MAX_UNIT 2
210
211
211
212
struct swim_priv {
212
213
struct swim __iomem *base;
213
214
spinlock_t lock;
214
-
int fdc_queue;
215
215
int floppy_count;
216
216
struct floppy_state unit[FD_MAX_UNIT];
217
217
};
218
218
219
219
extern int swim_read_sector_header(struct swim __iomem *base,
220
220
struct sector_header *header);
221
221
extern int swim_read_sector_data(struct swim __iomem *base,
222
222
unsigned char *data);
223
223
224
224
static DEFINE_MUTEX(swim_mutex);
518
518
if (try-- == 0)
519
519
return BLK_STS_IOERR;
520
520
} while (ret != 512);
521
521
522
522
buffer += ret;
523
523
}
524
524
525
525
return 0;
526
526
}
527
527
528
-
static struct request *swim_next_request(struct swim_priv *swd)
528
+
static blk_status_t swim_queue_rq(struct blk_mq_hw_ctx *hctx,
529
+
const struct blk_mq_queue_data *bd)
529
530
{
530
-
struct request_queue *q;
531
-
struct request *rq;
532
-
int old_pos = swd->fdc_queue;
531
+
struct floppy_state *fs = hctx->queue->queuedata;
532
+
struct swim_priv *swd = fs->swd;
533
+
struct request *req = bd->rq;
534
+
blk_status_t err;
533
535
534
-
do {
535
-
q = swd->unit[swd->fdc_queue].disk->queue;
536
-
if (++swd->fdc_queue == swd->floppy_count)
537
-
swd->fdc_queue = 0;
538
-
if (q) {
539
-
rq = blk_fetch_request(q);
540
-
if (rq)
541
-
return rq;
542
-
}
543
-
} while (swd->fdc_queue != old_pos);
536
+
if (!spin_trylock_irq(&swd->lock))
537
+
return BLK_STS_DEV_RESOURCE;
544
538
545
-
return NULL;
546
-
}
539
+
blk_mq_start_request(req);
547
540
548
-
static void do_fd_request(struct request_queue *q)
549
-
{
550
-
struct swim_priv *swd = q->queuedata;
551
-
struct request *req;
552
-
struct floppy_state *fs;
541
+
if (!fs->disk_in || rq_data_dir(req) == WRITE) {
542
+
err = BLK_STS_IOERR;
543
+
goto out;
544
+
}
553
545
554
-
req = swim_next_request(swd);
555
-
while (req) {
556
-
blk_status_t err = BLK_STS_IOERR;
546
+
do {
547
+
err = floppy_read_sectors(fs, blk_rq_pos(req),
548
+
blk_rq_cur_sectors(req),
549
+
bio_data(req->bio));
550
+
} while (blk_update_request(req, err, blk_rq_cur_bytes(req)));
551
+
__blk_mq_end_request(req, err);
557
552
558
-
fs = req->rq_disk->private_data;
559
-
if (blk_rq_pos(req) >= fs->total_secs)
560
-
goto done;
561
-
if (!fs->disk_in)
562
-
goto done;
563
-
if (rq_data_dir(req) == WRITE && fs->write_protected)
564
-
goto done;
553
+
err = BLK_STS_OK;
554
+
out:
555
+
spin_unlock_irq(&swd->lock);
556
+
return err;
565
557
566
-
switch (rq_data_dir(req)) {
567
-
case WRITE:
568
-
/* NOT IMPLEMENTED */
569
-
break;
570
-
case READ:
571
-
err = floppy_read_sectors(fs, blk_rq_pos(req),
572
-
blk_rq_cur_sectors(req),
573
-
bio_data(req->bio));
574
-
break;
575
-
}
576
-
done:
577
-
if (!__blk_end_request_cur(req, err))
578
-
req = swim_next_request(swd);
579
-
}
580
558
}
581
559
582
560
static struct floppy_struct floppy_type[4] = {
583
561
{ 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing */
584
562
{ 720, 9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
585
563
{ 1440, 9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 720KB 3.5" */
586
564
{ 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL }, /* 1.44MB 3.5" */
587
565
};
588
566
589
567
static int get_floppy_geometry(struct floppy_state *fs, int type,
816
794
fs->head_number = 2;
817
795
818
796
fs->ref_count = 0;
819
797
fs->ejected = 1;
820
798
821
799
swd->floppy_count++;
822
800
823
801
return 0;
824
802
}
825
803
804
+
static const struct blk_mq_ops swim_mq_ops = {
805
+
.queue_rq = swim_queue_rq,
806
+
};
807
+
826
808
static int swim_floppy_init(struct swim_priv *swd)
827
809
{
828
810
int err;
829
811
int drive;
830
812
struct swim __iomem *base = swd->base;
831
813
832
814
/* scan floppy drives */
833
815
834
816
swim_drive(base, INTERNAL_DRIVE);
835
817
if (swim_readbit(base, DRIVE_PRESENT) &&
845
827
err = register_blkdev(FLOPPY_MAJOR, "fd");
846
828
if (err) {
847
829
printk(KERN_ERR "Unable to get major %d for SWIM floppy\n",
848
830
FLOPPY_MAJOR);
849
831
return -EBUSY;
850
832
}
851
833
852
834
spin_lock_init(&swd->lock);
853
835
854
836
for (drive = 0; drive < swd->floppy_count; drive++) {
837
+
struct request_queue *q;
838
+
855
839
swd->unit[drive].disk = alloc_disk(1);
856
840
if (swd->unit[drive].disk == NULL) {
857
841
err = -ENOMEM;
858
842
goto exit_put_disks;
859
843
}
860
-
swd->unit[drive].disk->queue = blk_init_queue(do_fd_request,
861
-
&swd->lock);
862
-
if (!swd->unit[drive].disk->queue) {
863
-
err = -ENOMEM;
844
+
845
+
q = blk_mq_init_sq_queue(&swd->unit[drive].tag_set, &swim_mq_ops,
846
+
2, BLK_MQ_F_SHOULD_MERGE);
847
+
if (IS_ERR(q)) {
848
+
err = PTR_ERR(q);
864
849
goto exit_put_disks;
865
850
}
851
+
852
+
swd->unit[drive].disk->queue = q;
866
853
blk_queue_bounce_limit(swd->unit[drive].disk->queue,
867
854
BLK_BOUNCE_HIGH);
868
-
swd->unit[drive].disk->queue->queuedata = swd;
855
+
swd->unit[drive].disk->queue->queuedata = &swd->unit[drive];
869
856
swd->unit[drive].swd = swd;
870
857
}
871
858
872
859
for (drive = 0; drive < swd->floppy_count; drive++) {
873
860
swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
874
861
swd->unit[drive].disk->major = FLOPPY_MAJOR;
875
862
swd->unit[drive].disk->first_minor = drive;
876
863
sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
877
864
swd->unit[drive].disk->fops = &floppy_fops;
878
865
swd->unit[drive].disk->private_data = &swd->unit[drive];
888
875
exit_put_disks:
889
876
unregister_blkdev(FLOPPY_MAJOR, "fd");
890
877
do {
891
878
struct gendisk *disk = swd->unit[drive].disk;
892
879
893
880
if (disk) {
894
881
if (disk->queue) {
895
882
blk_cleanup_queue(disk->queue);
896
883
disk->queue = NULL;
897
884
}
885
+
blk_mq_free_tag_set(&swd->unit[drive].tag_set);
898
886
put_disk(disk);
899
887
}
900
888
} while (drive--);
901
889
return err;
902
890
}
903
891
904
892
static int swim_probe(struct platform_device *dev)
905
893
{
906
894
struct resource *res;
907
895
struct swim __iomem *swim_base;
963
951
{
964
952
struct swim_priv *swd = platform_get_drvdata(dev);
965
953
int drive;
966
954
struct resource *res;
967
955
968
956
blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
969
957
970
958
for (drive = 0; drive < swd->floppy_count; drive++) {
971
959
del_gendisk(swd->unit[drive].disk);
972
960
blk_cleanup_queue(swd->unit[drive].disk->queue);
961
+
blk_mq_free_tag_set(&swd->unit[drive].tag_set);
973
962
put_disk(swd->unit[drive].disk);
974
963
}
975
964
976
965
unregister_blkdev(FLOPPY_MAJOR, "fd");
977
966
978
967
/* eject floppies */
979
968
980
969
for (drive = 0; drive < swd->floppy_count; drive++)
981
970
floppy_eject(&swd->unit[drive]);
982
971