diff options
Diffstat (limited to 'drivers/block/amiflop.c')
-rw-r--r-- | drivers/block/amiflop.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 4b852c962266..a1725e6488d3 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c | |||
@@ -115,8 +115,6 @@ static unsigned long int fd_def_df0 = FD_DD_3; /* default for df0 if it does | |||
115 | module_param(fd_def_df0, ulong, 0); | 115 | module_param(fd_def_df0, ulong, 0); |
116 | MODULE_LICENSE("GPL"); | 116 | MODULE_LICENSE("GPL"); |
117 | 117 | ||
118 | static struct request_queue *floppy_queue; | ||
119 | |||
120 | /* | 118 | /* |
121 | * Macros | 119 | * Macros |
122 | */ | 120 | */ |
@@ -165,6 +163,7 @@ static volatile int selected = -1; /* currently selected drive */ | |||
165 | static int writepending; | 163 | static int writepending; |
166 | static int writefromint; | 164 | static int writefromint; |
167 | static char *raw_buf; | 165 | static char *raw_buf; |
166 | static int fdc_queue; | ||
168 | 167 | ||
169 | static DEFINE_SPINLOCK(amiflop_lock); | 168 | static DEFINE_SPINLOCK(amiflop_lock); |
170 | 169 | ||
@@ -1335,6 +1334,42 @@ static int get_track(int drive, int track) | |||
1335 | return -1; | 1334 | return -1; |
1336 | } | 1335 | } |
1337 | 1336 | ||
1337 | /* | ||
1338 | * Round-robin between our available drives, doing one request from each | ||
1339 | */ | ||
1340 | static struct request *set_next_request(void) | ||
1341 | { | ||
1342 | struct request_queue *q; | ||
1343 | int cnt = FD_MAX_UNITS; | ||
1344 | struct request *rq; | ||
1345 | |||
1346 | /* Find next queue we can dispatch from */ | ||
1347 | fdc_queue = fdc_queue + 1; | ||
1348 | if (fdc_queue == FD_MAX_UNITS) | ||
1349 | fdc_queue = 0; | ||
1350 | |||
1351 | for(cnt = FD_MAX_UNITS; cnt > 0; cnt--) { | ||
1352 | |||
1353 | if (unit[fdc_queue].type->code == FD_NODRIVE) { | ||
1354 | if (++fdc_queue == FD_MAX_UNITS) | ||
1355 | fdc_queue = 0; | ||
1356 | continue; | ||
1357 | } | ||
1358 | |||
1359 | q = unit[fdc_queue].gendisk->queue; | ||
1360 | if (q) { | ||
1361 | rq = blk_fetch_request(q); | ||
1362 | if (rq) | ||
1363 | break; | ||
1364 | } | ||
1365 | |||
1366 | if (++fdc_queue == FD_MAX_UNITS) | ||
1367 | fdc_queue = 0; | ||
1368 | } | ||
1369 | |||
1370 | return rq; | ||
1371 | } | ||
1372 | |||
1338 | static void redo_fd_request(void) | 1373 | static void redo_fd_request(void) |
1339 | { | 1374 | { |
1340 | struct request *rq; | 1375 | struct request *rq; |
@@ -1346,7 +1381,7 @@ static void redo_fd_request(void) | |||
1346 | int err; | 1381 | int err; |
1347 | 1382 | ||
1348 | next_req: | 1383 | next_req: |
1349 | rq = blk_fetch_request(floppy_queue); | 1384 | rq = set_next_request(); |
1350 | if (!rq) { | 1385 | if (!rq) { |
1351 | /* Nothing left to do */ | 1386 | /* Nothing left to do */ |
1352 | return; | 1387 | return; |
@@ -1683,6 +1718,13 @@ static int __init fd_probe_drives(void) | |||
1683 | continue; | 1718 | continue; |
1684 | } | 1719 | } |
1685 | unit[drive].gendisk = disk; | 1720 | unit[drive].gendisk = disk; |
1721 | |||
1722 | disk->queue = blk_init_queue(do_fd_request, &amiflop_lock); | ||
1723 | if (!disk->queue) { | ||
1724 | unit[drive].type->code = FD_NODRIVE; | ||
1725 | continue; | ||
1726 | } | ||
1727 | |||
1686 | drives++; | 1728 | drives++; |
1687 | if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) { | 1729 | if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) { |
1688 | printk("no mem for "); | 1730 | printk("no mem for "); |
@@ -1696,7 +1738,6 @@ static int __init fd_probe_drives(void) | |||
1696 | disk->fops = &floppy_fops; | 1738 | disk->fops = &floppy_fops; |
1697 | sprintf(disk->disk_name, "fd%d", drive); | 1739 | sprintf(disk->disk_name, "fd%d", drive); |
1698 | disk->private_data = &unit[drive]; | 1740 | disk->private_data = &unit[drive]; |
1699 | disk->queue = floppy_queue; | ||
1700 | set_capacity(disk, 880*2); | 1741 | set_capacity(disk, 880*2); |
1701 | add_disk(disk); | 1742 | add_disk(disk); |
1702 | } | 1743 | } |
@@ -1744,11 +1785,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev) | |||
1744 | goto out_irq2; | 1785 | goto out_irq2; |
1745 | } | 1786 | } |
1746 | 1787 | ||
1747 | ret = -ENOMEM; | ||
1748 | floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock); | ||
1749 | if (!floppy_queue) | ||
1750 | goto out_queue; | ||
1751 | |||
1752 | ret = -ENODEV; | 1788 | ret = -ENODEV; |
1753 | if (fd_probe_drives() < 1) /* No usable drives */ | 1789 | if (fd_probe_drives() < 1) /* No usable drives */ |
1754 | goto out_probe; | 1790 | goto out_probe; |
@@ -1792,8 +1828,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev) | |||
1792 | return 0; | 1828 | return 0; |
1793 | 1829 | ||
1794 | out_probe: | 1830 | out_probe: |
1795 | blk_cleanup_queue(floppy_queue); | ||
1796 | out_queue: | ||
1797 | free_irq(IRQ_AMIGA_CIAA_TB, NULL); | 1831 | free_irq(IRQ_AMIGA_CIAA_TB, NULL); |
1798 | out_irq2: | 1832 | out_irq2: |
1799 | free_irq(IRQ_AMIGA_DSKBLK, NULL); | 1833 | free_irq(IRQ_AMIGA_DSKBLK, NULL); |
@@ -1811,9 +1845,12 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev) | |||
1811 | 1845 | ||
1812 | for( i = 0; i < FD_MAX_UNITS; i++) { | 1846 | for( i = 0; i < FD_MAX_UNITS; i++) { |
1813 | if (unit[i].type->code != FD_NODRIVE) { | 1847 | if (unit[i].type->code != FD_NODRIVE) { |
1848 | struct request_queue *q = unit[i].gendisk->queue; | ||
1814 | del_gendisk(unit[i].gendisk); | 1849 | del_gendisk(unit[i].gendisk); |
1815 | put_disk(unit[i].gendisk); | 1850 | put_disk(unit[i].gendisk); |
1816 | kfree(unit[i].trackbuf); | 1851 | kfree(unit[i].trackbuf); |
1852 | if (q) | ||
1853 | blk_cleanup_queue(q); | ||
1817 | } | 1854 | } |
1818 | } | 1855 | } |
1819 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); | 1856 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
@@ -1821,7 +1858,6 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev) | |||
1821 | free_irq(IRQ_AMIGA_DSKBLK, NULL); | 1858 | free_irq(IRQ_AMIGA_DSKBLK, NULL); |
1822 | custom.dmacon = DMAF_DISK; /* disable DMA */ | 1859 | custom.dmacon = DMAF_DISK; /* disable DMA */ |
1823 | amiga_chip_free(raw_buf); | 1860 | amiga_chip_free(raw_buf); |
1824 | blk_cleanup_queue(floppy_queue); | ||
1825 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 1861 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
1826 | } | 1862 | } |
1827 | #endif | 1863 | #endif |