diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2010-09-24 14:35:44 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-09-24 14:35:44 -0400 |
commit | 786029ff810ff4a2fd52c0462713985a415417ab (patch) | |
tree | 9779d53ecc99b88513be0177bfdbecb92dc6edb9 /drivers/block/amiflop.c | |
parent | 488211844e0c3fad6ffa98a6f3c4f2139074e79a (diff) |
amiga floppy: Stop sharing request queue across multiple gendisks
o Use one request queue per gendisk instead of sharing request queue
o Don't have hardware. No compile testing or run time testing done. Completely
untested.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block/amiflop.c')
-rw-r--r-- | drivers/block/amiflop.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 76f114f0bba3..ead8b7792c52 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c | |||
@@ -114,8 +114,6 @@ static unsigned long int fd_def_df0 = FD_DD_3; /* default for df0 if it does | |||
114 | module_param(fd_def_df0, ulong, 0); | 114 | module_param(fd_def_df0, ulong, 0); |
115 | MODULE_LICENSE("GPL"); | 115 | MODULE_LICENSE("GPL"); |
116 | 116 | ||
117 | static struct request_queue *floppy_queue; | ||
118 | |||
119 | /* | 117 | /* |
120 | * Macros | 118 | * Macros |
121 | */ | 119 | */ |
@@ -164,6 +162,7 @@ static volatile int selected = -1; /* currently selected drive */ | |||
164 | static int writepending; | 162 | static int writepending; |
165 | static int writefromint; | 163 | static int writefromint; |
166 | static char *raw_buf; | 164 | static char *raw_buf; |
165 | static int fdc_queue; | ||
167 | 166 | ||
168 | static DEFINE_SPINLOCK(amiflop_lock); | 167 | static DEFINE_SPINLOCK(amiflop_lock); |
169 | 168 | ||
@@ -1334,6 +1333,42 @@ static int get_track(int drive, int track) | |||
1334 | return -1; | 1333 | return -1; |
1335 | } | 1334 | } |
1336 | 1335 | ||
1336 | /* | ||
1337 | * Round-robin between our available drives, doing one request from each | ||
1338 | */ | ||
1339 | static struct request *set_next_request(void) | ||
1340 | { | ||
1341 | struct request_queue *q; | ||
1342 | int cnt = FD_MAX_UNITS; | ||
1343 | struct request *rq; | ||
1344 | |||
1345 | /* Find next queue we can dispatch from */ | ||
1346 | fdc_queue = fdc_queue + 1; | ||
1347 | if (fdc_queue == FD_MAX_UNITS) | ||
1348 | fdc_queue = 0; | ||
1349 | |||
1350 | for(cnt = FD_MAX_UNITS; cnt > 0, cnt--) { | ||
1351 | |||
1352 | if (unit[fdc_queue].type->code == FD_NODRIVE) { | ||
1353 | if (++fdc_queue == FD_MAX_UNITS) | ||
1354 | fdc_queue = 0; | ||
1355 | cotinue; | ||
1356 | } | ||
1357 | |||
1358 | q = unit[fdc_queue].gendisk->queue; | ||
1359 | if (q) { | ||
1360 | rq = blk_fetch_request(q); | ||
1361 | if (rq) | ||
1362 | break; | ||
1363 | } | ||
1364 | |||
1365 | if (++fdc_queue == FD_MAX_UNITS) | ||
1366 | fdc_queue = 0; | ||
1367 | } | ||
1368 | |||
1369 | return rq; | ||
1370 | } | ||
1371 | |||
1337 | static void redo_fd_request(void) | 1372 | static void redo_fd_request(void) |
1338 | { | 1373 | { |
1339 | struct request *rq; | 1374 | struct request *rq; |
@@ -1345,7 +1380,7 @@ static void redo_fd_request(void) | |||
1345 | int err; | 1380 | int err; |
1346 | 1381 | ||
1347 | next_req: | 1382 | next_req: |
1348 | rq = blk_fetch_request(floppy_queue); | 1383 | rq = set_next_request(); |
1349 | if (!rq) { | 1384 | if (!rq) { |
1350 | /* Nothing left to do */ | 1385 | /* Nothing left to do */ |
1351 | return; | 1386 | return; |
@@ -1682,6 +1717,13 @@ static int __init fd_probe_drives(void) | |||
1682 | continue; | 1717 | continue; |
1683 | } | 1718 | } |
1684 | unit[drive].gendisk = disk; | 1719 | unit[drive].gendisk = disk; |
1720 | |||
1721 | disk->queue = blk_init_queue(do_fd_request, &amiflop_lock); | ||
1722 | if (!disk->queue) { | ||
1723 | unit[drive].type->code = FD_NODRIVE; | ||
1724 | continue; | ||
1725 | } | ||
1726 | |||
1685 | drives++; | 1727 | drives++; |
1686 | if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) { | 1728 | if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) { |
1687 | printk("no mem for "); | 1729 | printk("no mem for "); |
@@ -1695,7 +1737,6 @@ static int __init fd_probe_drives(void) | |||
1695 | disk->fops = &floppy_fops; | 1737 | disk->fops = &floppy_fops; |
1696 | sprintf(disk->disk_name, "fd%d", drive); | 1738 | sprintf(disk->disk_name, "fd%d", drive); |
1697 | disk->private_data = &unit[drive]; | 1739 | disk->private_data = &unit[drive]; |
1698 | disk->queue = floppy_queue; | ||
1699 | set_capacity(disk, 880*2); | 1740 | set_capacity(disk, 880*2); |
1700 | add_disk(disk); | 1741 | add_disk(disk); |
1701 | } | 1742 | } |
@@ -1743,11 +1784,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev) | |||
1743 | goto out_irq2; | 1784 | goto out_irq2; |
1744 | } | 1785 | } |
1745 | 1786 | ||
1746 | ret = -ENOMEM; | ||
1747 | floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock); | ||
1748 | if (!floppy_queue) | ||
1749 | goto out_queue; | ||
1750 | |||
1751 | ret = -ENODEV; | 1787 | ret = -ENODEV; |
1752 | if (fd_probe_drives() < 1) /* No usable drives */ | 1788 | if (fd_probe_drives() < 1) /* No usable drives */ |
1753 | goto out_probe; | 1789 | goto out_probe; |
@@ -1791,7 +1827,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev) | |||
1791 | return 0; | 1827 | return 0; |
1792 | 1828 | ||
1793 | out_probe: | 1829 | out_probe: |
1794 | blk_cleanup_queue(floppy_queue); | ||
1795 | out_queue: | 1830 | out_queue: |
1796 | free_irq(IRQ_AMIGA_CIAA_TB, NULL); | 1831 | free_irq(IRQ_AMIGA_CIAA_TB, NULL); |
1797 | out_irq2: | 1832 | out_irq2: |
@@ -1810,9 +1845,12 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev) | |||
1810 | 1845 | ||
1811 | for( i = 0; i < FD_MAX_UNITS; i++) { | 1846 | for( i = 0; i < FD_MAX_UNITS; i++) { |
1812 | if (unit[i].type->code != FD_NODRIVE) { | 1847 | if (unit[i].type->code != FD_NODRIVE) { |
1848 | struct request_queue *q = unit[i].gendisk->queue; | ||
1813 | del_gendisk(unit[i].gendisk); | 1849 | del_gendisk(unit[i].gendisk); |
1814 | put_disk(unit[i].gendisk); | 1850 | put_disk(unit[i].gendisk); |
1815 | kfree(unit[i].trackbuf); | 1851 | kfree(unit[i].trackbuf); |
1852 | if (q) | ||
1853 | blk_cleanup_queue(q); | ||
1816 | } | 1854 | } |
1817 | } | 1855 | } |
1818 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); | 1856 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
@@ -1820,7 +1858,6 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev) | |||
1820 | free_irq(IRQ_AMIGA_DSKBLK, NULL); | 1858 | free_irq(IRQ_AMIGA_DSKBLK, NULL); |
1821 | custom.dmacon = DMAF_DISK; /* disable DMA */ | 1859 | custom.dmacon = DMAF_DISK; /* disable DMA */ |
1822 | amiga_chip_free(raw_buf); | 1860 | amiga_chip_free(raw_buf); |
1823 | blk_cleanup_queue(floppy_queue); | ||
1824 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | 1861 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
1825 | } | 1862 | } |
1826 | #endif | 1863 | #endif |