forked from Minki/linux
USB: g_file_storage: Set sense info Valid bit only when needed
Strictly speaking, the Valid bit in SCSI sense data is supposed to be set only when the Information field contains a valid number. This patch (as793) turns off the Valid bit when the Information field hasn't been set. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
e0318ebff4
commit
6174d0fd35
@ -567,6 +567,7 @@ struct lun {
|
||||
unsigned int ro : 1;
|
||||
unsigned int prevent_medium_removal : 1;
|
||||
unsigned int registered : 1;
|
||||
unsigned int info_valid : 1;
|
||||
|
||||
u32 sense_data;
|
||||
u32 sense_data_info;
|
||||
@ -1656,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg)
|
||||
curlun->sense_data =
|
||||
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
curlun->sense_data_info = file_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
bh->inreq->length = 0;
|
||||
bh->state = BUF_STATE_FULL;
|
||||
break;
|
||||
@ -1691,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg)
|
||||
if (nread < amount) {
|
||||
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||
curlun->sense_data_info = file_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1785,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg)
|
||||
curlun->sense_data =
|
||||
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
curlun->sense_data_info = usb_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
continue;
|
||||
}
|
||||
amount -= (amount & 511);
|
||||
@ -1827,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg)
|
||||
if (bh->outreq->status != 0) {
|
||||
curlun->sense_data = SS_COMMUNICATION_FAILURE;
|
||||
curlun->sense_data_info = file_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1868,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg)
|
||||
if (nwritten < amount) {
|
||||
curlun->sense_data = SS_WRITE_ERROR;
|
||||
curlun->sense_data_info = file_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2010,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg)
|
||||
curlun->sense_data =
|
||||
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
curlun->sense_data_info = file_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2036,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg)
|
||||
if (nread == 0) {
|
||||
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||
curlun->sense_data_info = file_offset >> 9;
|
||||
curlun->info_valid = 1;
|
||||
break;
|
||||
}
|
||||
file_offset += nread;
|
||||
@ -2079,6 +2087,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
||||
struct lun *curlun = fsg->curlun;
|
||||
u8 *buf = (u8 *) bh->buf;
|
||||
u32 sd, sdinfo;
|
||||
int valid;
|
||||
|
||||
/*
|
||||
* From the SCSI-2 spec., section 7.9 (Unit attention condition):
|
||||
@ -2106,15 +2115,18 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
||||
fsg->bad_lun_okay = 1;
|
||||
sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
|
||||
sdinfo = 0;
|
||||
valid = 0;
|
||||
} else {
|
||||
sd = curlun->sense_data;
|
||||
sdinfo = curlun->sense_data_info;
|
||||
valid = curlun->info_valid << 7;
|
||||
curlun->sense_data = SS_NO_SENSE;
|
||||
curlun->sense_data_info = 0;
|
||||
curlun->info_valid = 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, 18);
|
||||
buf[0] = 0x80 | 0x70; // Valid, current error
|
||||
buf[0] = valid | 0x70; // Valid, current error
|
||||
buf[2] = SK(sd);
|
||||
put_be32(&buf[3], sdinfo); // Sense information
|
||||
buf[7] = 18 - 8; // Additional sense length
|
||||
@ -2703,6 +2715,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
|
||||
if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
|
||||
curlun->sense_data = SS_NO_SENSE;
|
||||
curlun->sense_data_info = 0;
|
||||
curlun->info_valid = 0;
|
||||
}
|
||||
} else {
|
||||
fsg->curlun = curlun = NULL;
|
||||
@ -3332,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg)
|
||||
curlun->sense_data = curlun->unit_attention_data =
|
||||
SS_NO_SENSE;
|
||||
curlun->sense_data_info = 0;
|
||||
curlun->info_valid = 0;
|
||||
}
|
||||
fsg->state = FSG_STATE_IDLE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user