aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/amiflop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/amiflop.c')
-rw-r--r--drivers/block/amiflop.c60
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
115module_param(fd_def_df0, ulong, 0); 115module_param(fd_def_df0, ulong, 0);
116MODULE_LICENSE("GPL"); 116MODULE_LICENSE("GPL");
117 117
118static 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 */
165static int writepending; 163static int writepending;
166static int writefromint; 164static int writefromint;
167static char *raw_buf; 165static char *raw_buf;
166static int fdc_queue;
168 167
169static DEFINE_SPINLOCK(amiflop_lock); 168static 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 */
1340static 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
1338static void redo_fd_request(void) 1373static 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
1348next_req: 1383next_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
1794out_probe: 1830out_probe:
1795 blk_cleanup_queue(floppy_queue);
1796out_queue:
1797 free_irq(IRQ_AMIGA_CIAA_TB, NULL); 1831 free_irq(IRQ_AMIGA_CIAA_TB, NULL);
1798out_irq2: 1832out_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