@ -328,6 +328,27 @@ static void storvsc_bus_scan(struct work_struct *work)
kfree ( wrk ) ;
}
static void storvsc_remove_lun ( struct work_struct * work )
{
struct storvsc_scan_work * wrk ;
struct scsi_device * sdev ;
wrk = container_of ( work , struct storvsc_scan_work , work ) ;
if ( ! scsi_host_get ( wrk - > host ) )
goto done ;
sdev = scsi_device_lookup ( wrk - > host , 0 , 0 , wrk - > lun ) ;
if ( sdev ) {
scsi_remove_device ( sdev ) ;
scsi_device_put ( sdev ) ;
}
scsi_host_put ( wrk - > host ) ;
done :
kfree ( wrk ) ;
}
static inline struct storvsc_device * get_out_stor_device (
struct hv_device * device )
{
@ -1112,6 +1133,7 @@ static void storvsc_command_completion(struct hv_storvsc_request *request)
void ( * scsi_done_fn ) ( struct scsi_cmnd * ) ;
struct scsi_sense_hdr sense_hdr ;
struct vmscsi_request * vm_srb ;
struct storvsc_scan_work * wrk ;
vm_srb = & request - > vstor_packet . vm_srb ;
if ( cmd_request - > bounce_sgl_count ) {
@ -1134,6 +1156,29 @@ static void storvsc_command_completion(struct hv_storvsc_request *request)
else
scmnd - > result = vm_srb - > scsi_status ;
/*
* If the LUN is invalid ; remove the device .
*/
if ( vm_srb - > srb_status = = 0x20 ) {
struct storvsc_device * stor_dev ;
struct hv_device * dev = host_dev - > dev ;
struct Scsi_Host * host ;
stor_dev = get_in_stor_device ( dev ) ;
host = stor_dev - > host ;
wrk = kmalloc ( sizeof ( struct storvsc_scan_work ) ,
GFP_ATOMIC ) ;
if ( ! wrk ) {
scmnd - > result = DID_TARGET_FAILURE < < 16 ;
} else {
wrk - > host = host ;
wrk - > lun = vm_srb - > lun ;
INIT_WORK ( & wrk - > work , storvsc_remove_lun ) ;
schedule_work ( & wrk - > work ) ;
}
}
if ( scmnd - > result ) {
if ( scsi_normalize_sense ( scmnd - > sense_buffer ,
SCSI_SENSE_BUFFERSIZE , & sense_hdr ) )