@ -48,6 +48,7 @@
# include <linux/delay.h>
# include <linux/mutex.h>
# include <linux/string_helpers.h>
# include <linux/async.h>
# include <asm/uaccess.h>
# include <scsi/scsi.h>
@ -1802,6 +1803,71 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
return 0 ;
}
/*
* The asynchronous part of sd_probe
*/
static void sd_probe_async ( void * data , async_cookie_t cookie )
{
struct scsi_disk * sdkp = data ;
struct scsi_device * sdp ;
struct gendisk * gd ;
u32 index ;
struct device * dev ;
sdp = sdkp - > device ;
gd = sdkp - > disk ;
index = sdkp - > index ;
dev = & sdp - > sdev_gendev ;
if ( ! sdp - > request_queue - > rq_timeout ) {
if ( sdp - > type ! = TYPE_MOD )
blk_queue_rq_timeout ( sdp - > request_queue , SD_TIMEOUT ) ;
else
blk_queue_rq_timeout ( sdp - > request_queue ,
SD_MOD_TIMEOUT ) ;
}
device_initialize ( & sdkp - > dev ) ;
sdkp - > dev . parent = & sdp - > sdev_gendev ;
sdkp - > dev . class = & sd_disk_class ;
strncpy ( sdkp - > dev . bus_id , sdp - > sdev_gendev . bus_id , BUS_ID_SIZE ) ;
if ( device_add ( & sdkp - > dev ) )
goto out_free_index ;
get_device ( & sdp - > sdev_gendev ) ;
if ( index < SD_MAX_DISKS ) {
gd - > major = sd_major ( ( index & 0xf0 ) > > 4 ) ;
gd - > first_minor = ( ( index & 0xf ) < < 4 ) | ( index & 0xfff00 ) ;
gd - > minors = SD_MINORS ;
}
gd - > fops = & sd_fops ;
gd - > private_data = & sdkp - > driver ;
gd - > queue = sdkp - > device - > request_queue ;
sd_revalidate_disk ( gd ) ;
blk_queue_prep_rq ( sdp - > request_queue , sd_prep_fn ) ;
gd - > driverfs_dev = & sdp - > sdev_gendev ;
gd - > flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS ;
if ( sdp - > removable )
gd - > flags | = GENHD_FL_REMOVABLE ;
dev_set_drvdata ( dev , sdkp ) ;
add_disk ( gd ) ;
sd_dif_config_host ( sdkp ) ;
sd_printk ( KERN_NOTICE , sdkp , " Attached SCSI %sdisk \n " ,
sdp - > removable ? " removable " : " " ) ;
return ;
out_free_index :
ida_remove ( & sd_index_ida , index ) ;
}
/**
* sd_probe - called during driver initialization and whenever a
* new scsi device is attached to the system . It is called once
@ -1865,48 +1931,7 @@ static int sd_probe(struct device *dev)
sdkp - > openers = 0 ;
sdkp - > previous_state = 1 ;
if ( ! sdp - > request_queue - > rq_timeout ) {
if ( sdp - > type ! = TYPE_MOD )
blk_queue_rq_timeout ( sdp - > request_queue , SD_TIMEOUT ) ;
else
blk_queue_rq_timeout ( sdp - > request_queue ,
SD_MOD_TIMEOUT ) ;
}
device_initialize ( & sdkp - > dev ) ;
sdkp - > dev . parent = & sdp - > sdev_gendev ;
sdkp - > dev . class = & sd_disk_class ;
strncpy ( sdkp - > dev . bus_id , sdp - > sdev_gendev . bus_id , BUS_ID_SIZE ) ;
if ( device_add ( & sdkp - > dev ) )
goto out_free_index ;
get_device ( & sdp - > sdev_gendev ) ;
if ( index < SD_MAX_DISKS ) {
gd - > major = sd_major ( ( index & 0xf0 ) > > 4 ) ;
gd - > first_minor = ( ( index & 0xf ) < < 4 ) | ( index & 0xfff00 ) ;
gd - > minors = SD_MINORS ;
}
gd - > fops = & sd_fops ;
gd - > private_data = & sdkp - > driver ;
gd - > queue = sdkp - > device - > request_queue ;
sd_revalidate_disk ( gd ) ;
blk_queue_prep_rq ( sdp - > request_queue , sd_prep_fn ) ;
gd - > driverfs_dev = & sdp - > sdev_gendev ;
gd - > flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS ;
if ( sdp - > removable )
gd - > flags | = GENHD_FL_REMOVABLE ;
dev_set_drvdata ( dev , sdkp ) ;
add_disk ( gd ) ;
sd_dif_config_host ( sdkp ) ;
sd_printk ( KERN_NOTICE , sdkp , " Attached SCSI %sdisk \n " ,
sdp - > removable ? " removable " : " " ) ;
async_schedule ( sd_probe_async , sdkp ) ;
return 0 ;