.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * drivers/block/ataflop.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
66 | 67 | #include <linux/fd.h> |
---|
67 | 68 | #include <linux/delay.h> |
---|
68 | 69 | #include <linux/init.h> |
---|
69 | | -#include <linux/blkdev.h> |
---|
| 70 | +#include <linux/blk-mq.h> |
---|
70 | 71 | #include <linux/mutex.h> |
---|
71 | 72 | #include <linux/completion.h> |
---|
72 | 73 | #include <linux/wait.h> |
---|
73 | 74 | |
---|
74 | | -#include <asm/atafd.h> |
---|
75 | | -#include <asm/atafdreg.h> |
---|
76 | 75 | #include <asm/atariints.h> |
---|
77 | 76 | #include <asm/atari_stdma.h> |
---|
78 | 77 | #include <asm/atari_stram.h> |
---|
.. | .. |
---|
83 | 82 | |
---|
84 | 83 | static DEFINE_MUTEX(ataflop_mutex); |
---|
85 | 84 | static struct request *fd_request; |
---|
86 | | -static int fdc_queue; |
---|
| 85 | + |
---|
| 86 | +/* |
---|
| 87 | + * WD1772 stuff |
---|
| 88 | + */ |
---|
| 89 | + |
---|
| 90 | +/* register codes */ |
---|
| 91 | + |
---|
| 92 | +#define FDCSELREG_STP (0x80) /* command/status register */ |
---|
| 93 | +#define FDCSELREG_TRA (0x82) /* track register */ |
---|
| 94 | +#define FDCSELREG_SEC (0x84) /* sector register */ |
---|
| 95 | +#define FDCSELREG_DTA (0x86) /* data register */ |
---|
| 96 | + |
---|
| 97 | +/* register names for FDC_READ/WRITE macros */ |
---|
| 98 | + |
---|
| 99 | +#define FDCREG_CMD 0 |
---|
| 100 | +#define FDCREG_STATUS 0 |
---|
| 101 | +#define FDCREG_TRACK 2 |
---|
| 102 | +#define FDCREG_SECTOR 4 |
---|
| 103 | +#define FDCREG_DATA 6 |
---|
| 104 | + |
---|
| 105 | +/* command opcodes */ |
---|
| 106 | + |
---|
| 107 | +#define FDCCMD_RESTORE (0x00) /* - */ |
---|
| 108 | +#define FDCCMD_SEEK (0x10) /* | */ |
---|
| 109 | +#define FDCCMD_STEP (0x20) /* | TYP 1 Commands */ |
---|
| 110 | +#define FDCCMD_STIN (0x40) /* | */ |
---|
| 111 | +#define FDCCMD_STOT (0x60) /* - */ |
---|
| 112 | +#define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */ |
---|
| 113 | +#define FDCCMD_WRSEC (0xa0) /* - " */ |
---|
| 114 | +#define FDCCMD_RDADR (0xc0) /* - */ |
---|
| 115 | +#define FDCCMD_RDTRA (0xe0) /* | TYP 3 Commands */ |
---|
| 116 | +#define FDCCMD_WRTRA (0xf0) /* - */ |
---|
| 117 | +#define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */ |
---|
| 118 | + |
---|
| 119 | +/* command modifier bits */ |
---|
| 120 | + |
---|
| 121 | +#define FDCCMDADD_SR6 (0x00) /* step rate settings */ |
---|
| 122 | +#define FDCCMDADD_SR12 (0x01) |
---|
| 123 | +#define FDCCMDADD_SR2 (0x02) |
---|
| 124 | +#define FDCCMDADD_SR3 (0x03) |
---|
| 125 | +#define FDCCMDADD_V (0x04) /* verify */ |
---|
| 126 | +#define FDCCMDADD_H (0x08) /* wait for spin-up */ |
---|
| 127 | +#define FDCCMDADD_U (0x10) /* update track register */ |
---|
| 128 | +#define FDCCMDADD_M (0x10) /* multiple sector access */ |
---|
| 129 | +#define FDCCMDADD_E (0x04) /* head settling flag */ |
---|
| 130 | +#define FDCCMDADD_P (0x02) /* precompensation off */ |
---|
| 131 | +#define FDCCMDADD_A0 (0x01) /* DAM flag */ |
---|
| 132 | + |
---|
| 133 | +/* status register bits */ |
---|
| 134 | + |
---|
| 135 | +#define FDCSTAT_MOTORON (0x80) /* motor on */ |
---|
| 136 | +#define FDCSTAT_WPROT (0x40) /* write protected (FDCCMD_WR*) */ |
---|
| 137 | +#define FDCSTAT_SPINUP (0x20) /* motor speed stable (Type I) */ |
---|
| 138 | +#define FDCSTAT_DELDAM (0x20) /* sector has deleted DAM (Type II+III) */ |
---|
| 139 | +#define FDCSTAT_RECNF (0x10) /* record not found */ |
---|
| 140 | +#define FDCSTAT_CRC (0x08) /* CRC error */ |
---|
| 141 | +#define FDCSTAT_TR00 (0x04) /* Track 00 flag (Type I) */ |
---|
| 142 | +#define FDCSTAT_LOST (0x04) /* Lost Data (Type II+III) */ |
---|
| 143 | +#define FDCSTAT_IDX (0x02) /* Index status (Type I) */ |
---|
| 144 | +#define FDCSTAT_DRQ (0x02) /* DRQ status (Type II+III) */ |
---|
| 145 | +#define FDCSTAT_BUSY (0x01) /* FDC is busy */ |
---|
| 146 | + |
---|
| 147 | + |
---|
| 148 | +/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */ |
---|
| 149 | +#define DSKSIDE (0x01) |
---|
| 150 | + |
---|
| 151 | +#define DSKDRVNONE (0x06) |
---|
| 152 | +#define DSKDRV0 (0x02) |
---|
| 153 | +#define DSKDRV1 (0x04) |
---|
| 154 | + |
---|
| 155 | +/* step rates */ |
---|
| 156 | +#define FDCSTEP_6 0x00 |
---|
| 157 | +#define FDCSTEP_12 0x01 |
---|
| 158 | +#define FDCSTEP_2 0x02 |
---|
| 159 | +#define FDCSTEP_3 0x03 |
---|
| 160 | + |
---|
| 161 | +struct atari_format_descr { |
---|
| 162 | + int track; /* to be formatted */ |
---|
| 163 | + int head; /* "" "" */ |
---|
| 164 | + int sect_offset; /* offset of first sector */ |
---|
| 165 | +}; |
---|
87 | 166 | |
---|
88 | 167 | /* Disk types: DD, HD, ED */ |
---|
89 | 168 | static struct atari_disk_type { |
---|
.. | .. |
---|
221 | 300 | struct gendisk *disk; |
---|
222 | 301 | int ref; |
---|
223 | 302 | int type; |
---|
| 303 | + struct blk_mq_tag_set tag_set; |
---|
224 | 304 | } unit[FD_MAX_UNITS]; |
---|
225 | 305 | |
---|
226 | 306 | #define UD unit[drive] |
---|
.. | .. |
---|
300 | 380 | static int UserSteprate[FD_MAX_UNITS] = { -1, -1 }; |
---|
301 | 381 | module_param_array(UserSteprate, int, NULL, 0); |
---|
302 | 382 | |
---|
303 | | -/* Synchronization of FDC access. */ |
---|
304 | | -static volatile int fdc_busy = 0; |
---|
305 | | -static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); |
---|
306 | 383 | static DECLARE_COMPLETION(format_wait); |
---|
307 | 384 | |
---|
308 | 385 | static unsigned long changed_floppies = 0xff, fake_change = 0; |
---|
.. | .. |
---|
362 | 439 | static void finish_fdc( void ); |
---|
363 | 440 | static void finish_fdc_done( int dummy ); |
---|
364 | 441 | static void setup_req_params( int drive ); |
---|
365 | | -static void redo_fd_request( void); |
---|
366 | 442 | static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int |
---|
367 | 443 | cmd, unsigned long param); |
---|
368 | 444 | static void fd_probe( int drive ); |
---|
.. | .. |
---|
380 | 456 | |
---|
381 | 457 | static void fd_end_request_cur(blk_status_t err) |
---|
382 | 458 | { |
---|
383 | | - if (!__blk_end_request_cur(fd_request, err)) |
---|
| 459 | + if (!blk_update_request(fd_request, err, |
---|
| 460 | + blk_rq_cur_bytes(fd_request))) { |
---|
| 461 | + __blk_mq_end_request(fd_request, err); |
---|
384 | 462 | fd_request = NULL; |
---|
| 463 | + } |
---|
385 | 464 | } |
---|
386 | 465 | |
---|
387 | 466 | static inline void start_motor_off_timer(void) |
---|
.. | .. |
---|
627 | 706 | if (SelectedDrive != -1) |
---|
628 | 707 | SUD.track = -1; |
---|
629 | 708 | } |
---|
630 | | - redo_fd_request(); |
---|
631 | 709 | } |
---|
632 | 710 | |
---|
633 | 711 | |
---|
.. | .. |
---|
645 | 723 | |
---|
646 | 724 | static int do_format(int drive, int type, struct atari_format_descr *desc) |
---|
647 | 725 | { |
---|
| 726 | + struct request_queue *q = unit[drive].disk->queue; |
---|
648 | 727 | unsigned char *p; |
---|
649 | 728 | int sect, nsect; |
---|
650 | 729 | unsigned long flags; |
---|
| 730 | + int ret; |
---|
651 | 731 | |
---|
652 | | - DPRINT(("do_format( dr=%d tr=%d he=%d offs=%d )\n", |
---|
653 | | - drive, desc->track, desc->head, desc->sect_offset )); |
---|
| 732 | + blk_mq_freeze_queue(q); |
---|
| 733 | + blk_mq_quiesce_queue(q); |
---|
654 | 734 | |
---|
655 | | - wait_event(fdc_wait, cmpxchg(&fdc_busy, 0, 1) == 0); |
---|
656 | 735 | local_irq_save(flags); |
---|
657 | 736 | stdma_lock(floppy_irq, NULL); |
---|
658 | 737 | atari_turnon_irq( IRQ_MFP_FDC ); /* should be already, just to be sure */ |
---|
.. | .. |
---|
661 | 740 | if (type) { |
---|
662 | 741 | if (--type >= NUM_DISK_MINORS || |
---|
663 | 742 | minor2disktype[type].drive_types > DriveType) { |
---|
664 | | - redo_fd_request(); |
---|
665 | | - return -EINVAL; |
---|
| 743 | + ret = -EINVAL; |
---|
| 744 | + goto out; |
---|
666 | 745 | } |
---|
667 | 746 | type = minor2disktype[type].index; |
---|
668 | 747 | UDT = &atari_disk_type[type]; |
---|
669 | 748 | } |
---|
670 | 749 | |
---|
671 | 750 | if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { |
---|
672 | | - redo_fd_request(); |
---|
673 | | - return -EINVAL; |
---|
| 751 | + ret = -EINVAL; |
---|
| 752 | + goto out; |
---|
674 | 753 | } |
---|
675 | 754 | |
---|
676 | 755 | nsect = UDT->spt; |
---|
.. | .. |
---|
709 | 788 | |
---|
710 | 789 | wait_for_completion(&format_wait); |
---|
711 | 790 | |
---|
712 | | - redo_fd_request(); |
---|
713 | | - return( FormatError ? -EIO : 0 ); |
---|
| 791 | + ret = FormatError ? -EIO : 0; |
---|
| 792 | +out: |
---|
| 793 | + blk_mq_unquiesce_queue(q); |
---|
| 794 | + blk_mq_unfreeze_queue(q); |
---|
| 795 | + return ret; |
---|
714 | 796 | } |
---|
715 | 797 | |
---|
716 | 798 | |
---|
.. | .. |
---|
740 | 822 | else { |
---|
741 | 823 | /* all sectors finished */ |
---|
742 | 824 | fd_end_request_cur(BLK_STS_OK); |
---|
743 | | - redo_fd_request(); |
---|
744 | 825 | return; |
---|
745 | 826 | } |
---|
746 | 827 | } |
---|
.. | .. |
---|
776 | 857 | } |
---|
777 | 858 | |
---|
778 | 859 | if (ATARIHW_PRESENT(FDCSPEED)) |
---|
779 | | - dma_wd.fdc_speed = 0; /* always seek with 8 Mhz */; |
---|
| 860 | + dma_wd.fdc_speed = 0; /* always seek with 8 Mhz */ |
---|
780 | 861 | DPRINT(("fd_calibrate\n")); |
---|
781 | 862 | SET_IRQ_HANDLER( fd_calibrate_done ); |
---|
782 | 863 | /* we can't verify, since the speed may be incorrect */ |
---|
.. | .. |
---|
1145 | 1226 | else { |
---|
1146 | 1227 | /* all sectors finished */ |
---|
1147 | 1228 | fd_end_request_cur(BLK_STS_OK); |
---|
1148 | | - redo_fd_request(); |
---|
1149 | 1229 | } |
---|
1150 | 1230 | return; |
---|
1151 | 1231 | |
---|
.. | .. |
---|
1303 | 1383 | |
---|
1304 | 1384 | local_irq_save(flags); |
---|
1305 | 1385 | stdma_release(); |
---|
1306 | | - fdc_busy = 0; |
---|
1307 | | - wake_up( &fdc_wait ); |
---|
1308 | 1386 | local_irq_restore(flags); |
---|
1309 | 1387 | |
---|
1310 | 1388 | DPRINT(("finish_fdc() finished\n")); |
---|
.. | .. |
---|
1394 | 1472 | ReqTrack, ReqSector, (unsigned long)ReqData )); |
---|
1395 | 1473 | } |
---|
1396 | 1474 | |
---|
1397 | | -/* |
---|
1398 | | - * Round-robin between our available drives, doing one request from each |
---|
1399 | | - */ |
---|
1400 | | -static struct request *set_next_request(void) |
---|
| 1475 | +static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx) |
---|
1401 | 1476 | { |
---|
1402 | | - struct request_queue *q; |
---|
1403 | | - int old_pos = fdc_queue; |
---|
1404 | | - struct request *rq = NULL; |
---|
1405 | | - |
---|
1406 | | - do { |
---|
1407 | | - q = unit[fdc_queue].disk->queue; |
---|
1408 | | - if (++fdc_queue == FD_MAX_UNITS) |
---|
1409 | | - fdc_queue = 0; |
---|
1410 | | - if (q) { |
---|
1411 | | - rq = blk_fetch_request(q); |
---|
1412 | | - if (rq) { |
---|
1413 | | - rq->error_count = 0; |
---|
1414 | | - break; |
---|
1415 | | - } |
---|
1416 | | - } |
---|
1417 | | - } while (fdc_queue != old_pos); |
---|
1418 | | - |
---|
1419 | | - return rq; |
---|
| 1477 | + spin_lock_irq(&ataflop_lock); |
---|
| 1478 | + atari_disable_irq(IRQ_MFP_FDC); |
---|
| 1479 | + finish_fdc(); |
---|
| 1480 | + atari_enable_irq(IRQ_MFP_FDC); |
---|
| 1481 | + spin_unlock_irq(&ataflop_lock); |
---|
1420 | 1482 | } |
---|
1421 | 1483 | |
---|
1422 | | - |
---|
1423 | | -static void redo_fd_request(void) |
---|
| 1484 | +static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, |
---|
| 1485 | + const struct blk_mq_queue_data *bd) |
---|
1424 | 1486 | { |
---|
1425 | | - int drive, type; |
---|
1426 | | - struct atari_floppy_struct *floppy; |
---|
| 1487 | + struct atari_floppy_struct *floppy = bd->rq->rq_disk->private_data; |
---|
| 1488 | + int drive = floppy - unit; |
---|
| 1489 | + int type = floppy->type; |
---|
1427 | 1490 | |
---|
1428 | | - DPRINT(("redo_fd_request: fd_request=%p dev=%s fd_request->sector=%ld\n", |
---|
1429 | | - fd_request, fd_request ? fd_request->rq_disk->disk_name : "", |
---|
1430 | | - fd_request ? blk_rq_pos(fd_request) : 0 )); |
---|
| 1491 | + spin_lock_irq(&ataflop_lock); |
---|
| 1492 | + if (fd_request) { |
---|
| 1493 | + spin_unlock_irq(&ataflop_lock); |
---|
| 1494 | + return BLK_STS_DEV_RESOURCE; |
---|
| 1495 | + } |
---|
| 1496 | + if (!stdma_try_lock(floppy_irq, NULL)) { |
---|
| 1497 | + spin_unlock_irq(&ataflop_lock); |
---|
| 1498 | + return BLK_STS_RESOURCE; |
---|
| 1499 | + } |
---|
| 1500 | + fd_request = bd->rq; |
---|
| 1501 | + blk_mq_start_request(fd_request); |
---|
| 1502 | + |
---|
| 1503 | + atari_disable_irq( IRQ_MFP_FDC ); |
---|
1431 | 1504 | |
---|
1432 | 1505 | IsFormatting = 0; |
---|
1433 | 1506 | |
---|
1434 | | -repeat: |
---|
1435 | | - if (!fd_request) { |
---|
1436 | | - fd_request = set_next_request(); |
---|
1437 | | - if (!fd_request) |
---|
1438 | | - goto the_end; |
---|
1439 | | - } |
---|
1440 | | - |
---|
1441 | | - floppy = fd_request->rq_disk->private_data; |
---|
1442 | | - drive = floppy - unit; |
---|
1443 | | - type = floppy->type; |
---|
1444 | | - |
---|
1445 | 1507 | if (!UD.connected) { |
---|
1446 | 1508 | /* drive not connected */ |
---|
1447 | 1509 | printk(KERN_ERR "Unknown Device: fd%d\n", drive ); |
---|
1448 | 1510 | fd_end_request_cur(BLK_STS_IOERR); |
---|
1449 | | - goto repeat; |
---|
| 1511 | + goto out; |
---|
1450 | 1512 | } |
---|
1451 | 1513 | |
---|
1452 | 1514 | if (type == 0) { |
---|
.. | .. |
---|
1462 | 1524 | if (--type >= NUM_DISK_MINORS) { |
---|
1463 | 1525 | printk(KERN_WARNING "fd%d: invalid disk format", drive ); |
---|
1464 | 1526 | fd_end_request_cur(BLK_STS_IOERR); |
---|
1465 | | - goto repeat; |
---|
| 1527 | + goto out; |
---|
1466 | 1528 | } |
---|
1467 | 1529 | if (minor2disktype[type].drive_types > DriveType) { |
---|
1468 | 1530 | printk(KERN_WARNING "fd%d: unsupported disk format", drive ); |
---|
1469 | 1531 | fd_end_request_cur(BLK_STS_IOERR); |
---|
1470 | | - goto repeat; |
---|
| 1532 | + goto out; |
---|
1471 | 1533 | } |
---|
1472 | 1534 | type = minor2disktype[type].index; |
---|
1473 | 1535 | UDT = &atari_disk_type[type]; |
---|
1474 | 1536 | set_capacity(floppy->disk, UDT->blocks); |
---|
1475 | 1537 | UD.autoprobe = 0; |
---|
1476 | | - } |
---|
1477 | | - |
---|
1478 | | - if (blk_rq_pos(fd_request) + 1 > UDT->blocks) { |
---|
1479 | | - fd_end_request_cur(BLK_STS_IOERR); |
---|
1480 | | - goto repeat; |
---|
1481 | 1538 | } |
---|
1482 | 1539 | |
---|
1483 | 1540 | /* stop deselect timer */ |
---|
.. | .. |
---|
1490 | 1547 | setup_req_params( drive ); |
---|
1491 | 1548 | do_fd_action( drive ); |
---|
1492 | 1549 | |
---|
1493 | | - return; |
---|
1494 | | - |
---|
1495 | | - the_end: |
---|
1496 | | - finish_fdc(); |
---|
1497 | | -} |
---|
1498 | | - |
---|
1499 | | - |
---|
1500 | | -void do_fd_request(struct request_queue * q) |
---|
1501 | | -{ |
---|
1502 | | - DPRINT(("do_fd_request for pid %d\n",current->pid)); |
---|
1503 | | - wait_event(fdc_wait, cmpxchg(&fdc_busy, 0, 1) == 0); |
---|
1504 | | - stdma_lock(floppy_irq, NULL); |
---|
1505 | | - |
---|
1506 | | - atari_disable_irq( IRQ_MFP_FDC ); |
---|
1507 | | - redo_fd_request(); |
---|
| 1550 | + if (bd->last) |
---|
| 1551 | + finish_fdc(); |
---|
1508 | 1552 | atari_enable_irq( IRQ_MFP_FDC ); |
---|
| 1553 | + |
---|
| 1554 | +out: |
---|
| 1555 | + spin_unlock_irq(&ataflop_lock); |
---|
| 1556 | + return BLK_STS_OK; |
---|
1509 | 1557 | } |
---|
1510 | 1558 | |
---|
1511 | 1559 | static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, |
---|
.. | .. |
---|
1583 | 1631 | /* what if type > 0 here? Overwrite specified entry ? */ |
---|
1584 | 1632 | if (type) { |
---|
1585 | 1633 | /* refuse to re-set a predefined type for now */ |
---|
1586 | | - redo_fd_request(); |
---|
1587 | 1634 | return -EINVAL; |
---|
1588 | 1635 | } |
---|
1589 | 1636 | |
---|
.. | .. |
---|
1651 | 1698 | |
---|
1652 | 1699 | /* sanity check */ |
---|
1653 | 1700 | if (setprm.track != dtp->blocks/dtp->spt/2 || |
---|
1654 | | - setprm.head != 2) { |
---|
1655 | | - redo_fd_request(); |
---|
| 1701 | + setprm.head != 2) |
---|
1656 | 1702 | return -EINVAL; |
---|
1657 | | - } |
---|
1658 | 1703 | |
---|
1659 | 1704 | UDT = dtp; |
---|
1660 | 1705 | set_capacity(floppy->disk, UDT->blocks); |
---|
.. | .. |
---|
1681 | 1726 | /* MSch: invalidate default_params */ |
---|
1682 | 1727 | default_params[drive].blocks = 0; |
---|
1683 | 1728 | set_capacity(floppy->disk, MAX_DISK_SIZE * 2); |
---|
| 1729 | + fallthrough; |
---|
1684 | 1730 | case FDFMTEND: |
---|
1685 | 1731 | case FDFLUSH: |
---|
1686 | 1732 | /* invalidate the buffer track to force a reread */ |
---|
1687 | 1733 | BufferDrive = -1; |
---|
1688 | 1734 | set_bit(drive, &fake_change); |
---|
1689 | | - check_disk_change(bdev); |
---|
| 1735 | + if (bdev_check_media_change(bdev)) |
---|
| 1736 | + floppy_revalidate(bdev->bd_disk); |
---|
1690 | 1737 | return 0; |
---|
1691 | 1738 | default: |
---|
1692 | 1739 | return -EINVAL; |
---|
.. | .. |
---|
1863 | 1910 | return 0; |
---|
1864 | 1911 | |
---|
1865 | 1912 | if (mode & (FMODE_READ|FMODE_WRITE)) { |
---|
1866 | | - check_disk_change(bdev); |
---|
| 1913 | + if (bdev_check_media_change(bdev)) |
---|
| 1914 | + floppy_revalidate(bdev->bd_disk); |
---|
1867 | 1915 | if (mode & FMODE_WRITE) { |
---|
1868 | 1916 | if (p->wpstat) { |
---|
1869 | 1917 | if (p->ref < 0) |
---|
.. | .. |
---|
1907 | 1955 | .release = floppy_release, |
---|
1908 | 1956 | .ioctl = fd_ioctl, |
---|
1909 | 1957 | .check_events = floppy_check_events, |
---|
1910 | | - .revalidate_disk= floppy_revalidate, |
---|
| 1958 | +}; |
---|
| 1959 | + |
---|
| 1960 | +static const struct blk_mq_ops ataflop_mq_ops = { |
---|
| 1961 | + .queue_rq = ataflop_queue_rq, |
---|
| 1962 | + .commit_rqs = ataflop_commit_rqs, |
---|
1911 | 1963 | }; |
---|
1912 | 1964 | |
---|
1913 | 1965 | static struct kobject *floppy_find(dev_t dev, int *part, void *data) |
---|
.. | .. |
---|
1923 | 1975 | static int __init atari_floppy_init (void) |
---|
1924 | 1976 | { |
---|
1925 | 1977 | int i; |
---|
| 1978 | + int ret; |
---|
1926 | 1979 | |
---|
1927 | 1980 | if (!MACH_IS_ATARI) |
---|
1928 | 1981 | /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ |
---|
.. | .. |
---|
1933 | 1986 | |
---|
1934 | 1987 | for (i = 0; i < FD_MAX_UNITS; i++) { |
---|
1935 | 1988 | unit[i].disk = alloc_disk(1); |
---|
1936 | | - if (!unit[i].disk) |
---|
1937 | | - goto Enomem; |
---|
| 1989 | + if (!unit[i].disk) { |
---|
| 1990 | + ret = -ENOMEM; |
---|
| 1991 | + goto err; |
---|
| 1992 | + } |
---|
1938 | 1993 | |
---|
1939 | | - unit[i].disk->queue = blk_init_queue(do_fd_request, |
---|
1940 | | - &ataflop_lock); |
---|
1941 | | - if (!unit[i].disk->queue) |
---|
1942 | | - goto Enomem; |
---|
| 1994 | + unit[i].disk->queue = blk_mq_init_sq_queue(&unit[i].tag_set, |
---|
| 1995 | + &ataflop_mq_ops, 2, |
---|
| 1996 | + BLK_MQ_F_SHOULD_MERGE); |
---|
| 1997 | + if (IS_ERR(unit[i].disk->queue)) { |
---|
| 1998 | + put_disk(unit[i].disk); |
---|
| 1999 | + ret = PTR_ERR(unit[i].disk->queue); |
---|
| 2000 | + unit[i].disk->queue = NULL; |
---|
| 2001 | + goto err; |
---|
| 2002 | + } |
---|
1943 | 2003 | } |
---|
1944 | 2004 | |
---|
1945 | 2005 | if (UseTrackbuffer < 0) |
---|
.. | .. |
---|
1956 | 2016 | DMABuffer = atari_stram_alloc(BUFFER_SIZE+512, "ataflop"); |
---|
1957 | 2017 | if (!DMABuffer) { |
---|
1958 | 2018 | printk(KERN_ERR "atari_floppy_init: cannot get dma buffer\n"); |
---|
1959 | | - goto Enomem; |
---|
| 2019 | + ret = -ENOMEM; |
---|
| 2020 | + goto err; |
---|
1960 | 2021 | } |
---|
1961 | 2022 | TrackBuffer = DMABuffer + 512; |
---|
1962 | 2023 | PhysDMABuffer = atari_stram_to_phys(DMABuffer); |
---|
.. | .. |
---|
1970 | 2031 | unit[i].disk->first_minor = i; |
---|
1971 | 2032 | sprintf(unit[i].disk->disk_name, "fd%d", i); |
---|
1972 | 2033 | unit[i].disk->fops = &floppy_fops; |
---|
| 2034 | + unit[i].disk->events = DISK_EVENT_MEDIA_CHANGE; |
---|
1973 | 2035 | unit[i].disk->private_data = &unit[i]; |
---|
1974 | 2036 | set_capacity(unit[i].disk, MAX_DISK_SIZE * 2); |
---|
1975 | 2037 | add_disk(unit[i].disk); |
---|
.. | .. |
---|
1984 | 2046 | config_types(); |
---|
1985 | 2047 | |
---|
1986 | 2048 | return 0; |
---|
1987 | | -Enomem: |
---|
1988 | | - do { |
---|
| 2049 | + |
---|
| 2050 | +err: |
---|
| 2051 | + while (--i >= 0) { |
---|
1989 | 2052 | struct gendisk *disk = unit[i].disk; |
---|
1990 | 2053 | |
---|
1991 | | - if (disk) { |
---|
1992 | | - if (disk->queue) { |
---|
1993 | | - blk_cleanup_queue(disk->queue); |
---|
1994 | | - disk->queue = NULL; |
---|
1995 | | - } |
---|
1996 | | - put_disk(unit[i].disk); |
---|
1997 | | - } |
---|
1998 | | - } while (i--); |
---|
| 2054 | + blk_cleanup_queue(disk->queue); |
---|
| 2055 | + blk_mq_free_tag_set(&unit[i].tag_set); |
---|
| 2056 | + put_disk(unit[i].disk); |
---|
| 2057 | + } |
---|
1999 | 2058 | |
---|
2000 | 2059 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
---|
2001 | | - return -ENOMEM; |
---|
| 2060 | + return ret; |
---|
2002 | 2061 | } |
---|
2003 | 2062 | |
---|
2004 | 2063 | #ifndef MODULE |
---|
.. | .. |
---|
2045 | 2104 | int i; |
---|
2046 | 2105 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
---|
2047 | 2106 | for (i = 0; i < FD_MAX_UNITS; i++) { |
---|
2048 | | - struct request_queue *q = unit[i].disk->queue; |
---|
2049 | | - |
---|
2050 | 2107 | del_gendisk(unit[i].disk); |
---|
| 2108 | + blk_cleanup_queue(unit[i].disk->queue); |
---|
| 2109 | + blk_mq_free_tag_set(&unit[i].tag_set); |
---|
2051 | 2110 | put_disk(unit[i].disk); |
---|
2052 | | - blk_cleanup_queue(q); |
---|
2053 | 2111 | } |
---|
2054 | 2112 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
---|
2055 | 2113 | |
---|