@@ -297,7 +297,7 @@ static struct atari_floppy_struct {
297297 unsigned int wpstat ; /* current state of WP signal (for
298298 disk change detection) */
299299 int flags ; /* flags */
300- struct gendisk * disk ;
300+ struct gendisk * disk [ NUM_DISK_MINORS ] ;
301301 int ref ;
302302 int type ;
303303 struct blk_mq_tag_set tag_set ;
@@ -723,12 +723,16 @@ static void fd_error( void )
723723
724724static int do_format (int drive , int type , struct atari_format_descr * desc )
725725{
726- struct request_queue * q = unit [ drive ]. disk -> queue ;
726+ struct request_queue * q ;
727727 unsigned char * p ;
728728 int sect , nsect ;
729729 unsigned long flags ;
730730 int ret ;
731731
732+ if (type )
733+ type -- ;
734+
735+ q = unit [drive ].disk [type ]-> queue ;
732736 blk_mq_freeze_queue (q );
733737 blk_mq_quiesce_queue (q );
734738
@@ -738,7 +742,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
738742 local_irq_restore (flags );
739743
740744 if (type ) {
741- if (-- type >= NUM_DISK_MINORS ||
745+ if (type >= NUM_DISK_MINORS ||
742746 minor2disktype [type ].drive_types > DriveType ) {
743747 ret = - EINVAL ;
744748 goto out ;
@@ -1154,7 +1158,7 @@ static void fd_rwsec_done1(int status)
11541158 if (SUDT [-1 ].blocks > ReqBlock ) {
11551159 /* try another disk type */
11561160 SUDT -- ;
1157- set_capacity (unit [SelectedDrive ].disk ,
1161+ set_capacity (unit [SelectedDrive ].disk [ 0 ] ,
11581162 SUDT -> blocks );
11591163 } else
11601164 Probing = 0 ;
@@ -1169,7 +1173,7 @@ static void fd_rwsec_done1(int status)
11691173/* record not found, but not probing. Maybe stretch wrong ? Restart probing */
11701174 if (SUD .autoprobe ) {
11711175 SUDT = atari_disk_type + StartDiskType [DriveType ];
1172- set_capacity (unit [SelectedDrive ].disk ,
1176+ set_capacity (unit [SelectedDrive ].disk [ 0 ] ,
11731177 SUDT -> blocks );
11741178 Probing = 1 ;
11751179 }
@@ -1515,7 +1519,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
15151519 if (!UDT ) {
15161520 Probing = 1 ;
15171521 UDT = atari_disk_type + StartDiskType [DriveType ];
1518- set_capacity (floppy -> disk , UDT -> blocks );
1522+ set_capacity (bd -> rq -> rq_disk , UDT -> blocks );
15191523 UD .autoprobe = 1 ;
15201524 }
15211525 }
@@ -1533,7 +1537,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
15331537 }
15341538 type = minor2disktype [type ].index ;
15351539 UDT = & atari_disk_type [type ];
1536- set_capacity (floppy -> disk , UDT -> blocks );
1540+ set_capacity (bd -> rq -> rq_disk , UDT -> blocks );
15371541 UD .autoprobe = 0 ;
15381542 }
15391543
@@ -1658,7 +1662,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
16581662 printk (KERN_INFO "floppy%d: setting %s %p!\n" ,
16591663 drive , dtp -> name , dtp );
16601664 UDT = dtp ;
1661- set_capacity (floppy -> disk , UDT -> blocks );
1665+ set_capacity (disk , UDT -> blocks );
16621666
16631667 if (cmd == FDDEFPRM ) {
16641668 /* save settings as permanent default type */
@@ -1702,7 +1706,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
17021706 return - EINVAL ;
17031707
17041708 UDT = dtp ;
1705- set_capacity (floppy -> disk , UDT -> blocks );
1709+ set_capacity (disk , UDT -> blocks );
17061710
17071711 return 0 ;
17081712 case FDMSGON :
@@ -1725,7 +1729,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
17251729 UDT = NULL ;
17261730 /* MSch: invalidate default_params */
17271731 default_params [drive ].blocks = 0 ;
1728- set_capacity (floppy -> disk , MAX_DISK_SIZE * 2 );
1732+ set_capacity (disk , MAX_DISK_SIZE * 2 );
17291733 fallthrough ;
17301734 case FDFMTEND :
17311735 case FDFLUSH :
@@ -1962,14 +1966,50 @@ static const struct blk_mq_ops ataflop_mq_ops = {
19621966 .commit_rqs = ataflop_commit_rqs ,
19631967};
19641968
1965- static struct kobject * floppy_find ( dev_t dev , int * part , void * data )
1969+ static int ataflop_alloc_disk ( unsigned int drive , unsigned int type )
19661970{
1967- int drive = * part & 3 ;
1968- int type = * part >> 2 ;
1971+ struct gendisk * disk ;
1972+ int ret ;
1973+
1974+ disk = alloc_disk (1 );
1975+ if (!disk )
1976+ return - ENOMEM ;
1977+
1978+ disk -> queue = blk_mq_init_queue (& unit [drive ].tag_set );
1979+ if (IS_ERR (disk -> queue )) {
1980+ ret = PTR_ERR (disk -> queue );
1981+ disk -> queue = NULL ;
1982+ put_disk (disk );
1983+ return ret ;
1984+ }
1985+
1986+ disk -> major = FLOPPY_MAJOR ;
1987+ disk -> first_minor = drive + (type << 2 );
1988+ sprintf (disk -> disk_name , "fd%d" , drive );
1989+ disk -> fops = & floppy_fops ;
1990+ disk -> events = DISK_EVENT_MEDIA_CHANGE ;
1991+ disk -> private_data = & unit [drive ];
1992+ set_capacity (disk , MAX_DISK_SIZE * 2 );
1993+
1994+ unit [drive ].disk [type ] = disk ;
1995+ return 0 ;
1996+ }
1997+
1998+ static DEFINE_MUTEX (ataflop_probe_lock );
1999+
2000+ static void ataflop_probe (dev_t dev )
2001+ {
2002+ int drive = MINOR (dev ) & 3 ;
2003+ int type = MINOR (dev ) >> 2 ;
2004+
19692005 if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS )
1970- return NULL ;
1971- * part = 0 ;
1972- return get_disk_and_module (unit [drive ].disk );
2006+ return ;
2007+ mutex_lock (& ataflop_probe_lock );
2008+ if (!unit [drive ].disk [type ]) {
2009+ if (ataflop_alloc_disk (drive , type ) == 0 )
2010+ add_disk (unit [drive ].disk [type ]);
2011+ }
2012+ mutex_unlock (& ataflop_probe_lock );
19732013}
19742014
19752015static int __init atari_floppy_init (void )
@@ -1981,23 +2021,26 @@ static int __init atari_floppy_init (void)
19812021 /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
19822022 return - ENODEV ;
19832023
1984- if (register_blkdev (FLOPPY_MAJOR ,"fd" ))
1985- return - EBUSY ;
2024+ mutex_lock (& ataflop_probe_lock );
2025+ ret = __register_blkdev (FLOPPY_MAJOR , "fd" , ataflop_probe );
2026+ if (ret )
2027+ goto out_unlock ;
19862028
19872029 for (i = 0 ; i < FD_MAX_UNITS ; i ++ ) {
1988- unit [i ].disk = alloc_disk (1 );
1989- if (!unit [i ].disk ) {
1990- ret = - ENOMEM ;
2030+ memset (& unit [i ].tag_set , 0 , sizeof (unit [i ].tag_set ));
2031+ unit [i ].tag_set .ops = & ataflop_mq_ops ;
2032+ unit [i ].tag_set .nr_hw_queues = 1 ;
2033+ unit [i ].tag_set .nr_maps = 1 ;
2034+ unit [i ].tag_set .queue_depth = 2 ;
2035+ unit [i ].tag_set .numa_node = NUMA_NO_NODE ;
2036+ unit [i ].tag_set .flags = BLK_MQ_F_SHOULD_MERGE ;
2037+ ret = blk_mq_alloc_tag_set (& unit [i ].tag_set );
2038+ if (ret )
19912039 goto err ;
1992- }
19932040
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 ;
2041+ ret = ataflop_alloc_disk (i , 0 );
2042+ if (ret ) {
2043+ blk_mq_free_tag_set (& unit [i ].tag_set );
20012044 goto err ;
20022045 }
20032046 }
@@ -2027,19 +2070,9 @@ static int __init atari_floppy_init (void)
20272070 for (i = 0 ; i < FD_MAX_UNITS ; i ++ ) {
20282071 unit [i ].track = -1 ;
20292072 unit [i ].flags = 0 ;
2030- unit [i ].disk -> major = FLOPPY_MAJOR ;
2031- unit [i ].disk -> first_minor = i ;
2032- sprintf (unit [i ].disk -> disk_name , "fd%d" , i );
2033- unit [i ].disk -> fops = & floppy_fops ;
2034- unit [i ].disk -> events = DISK_EVENT_MEDIA_CHANGE ;
2035- unit [i ].disk -> private_data = & unit [i ];
2036- set_capacity (unit [i ].disk , MAX_DISK_SIZE * 2 );
2037- add_disk (unit [i ].disk );
2073+ add_disk (unit [i ].disk [0 ]);
20382074 }
20392075
2040- blk_register_region (MKDEV (FLOPPY_MAJOR , 0 ), 256 , THIS_MODULE ,
2041- floppy_find , NULL , NULL );
2042-
20432076 printk (KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n" ,
20442077 DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E' ,
20452078 UseTrackbuffer ? "" : "no " );
@@ -2049,14 +2082,14 @@ static int __init atari_floppy_init (void)
20492082
20502083err :
20512084 while (-- i >= 0 ) {
2052- struct gendisk * disk = unit [i ].disk ;
2053-
2054- blk_cleanup_queue (disk -> queue );
2085+ blk_cleanup_queue (unit [i ].disk [0 ]-> queue );
2086+ put_disk (unit [i ].disk [0 ]);
20552087 blk_mq_free_tag_set (& unit [i ].tag_set );
2056- put_disk (unit [i ].disk );
20572088 }
20582089
20592090 unregister_blkdev (FLOPPY_MAJOR , "fd" );
2091+ out_unlock :
2092+ mutex_unlock (& ataflop_probe_lock );
20602093 return ret ;
20612094}
20622095
@@ -2101,13 +2134,17 @@ __setup("floppy=", atari_floppy_setup);
21012134
21022135static void __exit atari_floppy_exit (void )
21032136{
2104- int i ;
2105- blk_unregister_region ( MKDEV ( FLOPPY_MAJOR , 0 ), 256 );
2137+ int i , type ;
2138+
21062139 for (i = 0 ; i < FD_MAX_UNITS ; i ++ ) {
2107- del_gendisk (unit [i ].disk );
2108- blk_cleanup_queue (unit [i ].disk -> queue );
2140+ for (type = 0 ; type < NUM_DISK_MINORS ; type ++ ) {
2141+ if (!unit [i ].disk [type ])
2142+ continue ;
2143+ del_gendisk (unit [i ].disk [type ]);
2144+ blk_cleanup_queue (unit [i ].disk [type ]-> queue );
2145+ put_disk (unit [i ].disk [type ]);
2146+ }
21092147 blk_mq_free_tag_set (& unit [i ].tag_set );
2110- put_disk (unit [i ].disk );
21112148 }
21122149 unregister_blkdev (FLOPPY_MAJOR , "fd" );
21132150
0 commit comments