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 ro : 1;
|
||||||
unsigned int prevent_medium_removal : 1;
|
unsigned int prevent_medium_removal : 1;
|
||||||
unsigned int registered : 1;
|
unsigned int registered : 1;
|
||||||
|
unsigned int info_valid : 1;
|
||||||
|
|
||||||
u32 sense_data;
|
u32 sense_data;
|
||||||
u32 sense_data_info;
|
u32 sense_data_info;
|
||||||
|
@ -1656,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg)
|
||||||
curlun->sense_data =
|
curlun->sense_data =
|
||||||
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||||
curlun->sense_data_info = file_offset >> 9;
|
curlun->sense_data_info = file_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
bh->inreq->length = 0;
|
bh->inreq->length = 0;
|
||||||
bh->state = BUF_STATE_FULL;
|
bh->state = BUF_STATE_FULL;
|
||||||
break;
|
break;
|
||||||
|
@ -1691,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg)
|
||||||
if (nread < amount) {
|
if (nread < amount) {
|
||||||
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||||
curlun->sense_data_info = file_offset >> 9;
|
curlun->sense_data_info = file_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1785,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg)
|
||||||
curlun->sense_data =
|
curlun->sense_data =
|
||||||
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||||
curlun->sense_data_info = usb_offset >> 9;
|
curlun->sense_data_info = usb_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
amount -= (amount & 511);
|
amount -= (amount & 511);
|
||||||
|
@ -1827,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg)
|
||||||
if (bh->outreq->status != 0) {
|
if (bh->outreq->status != 0) {
|
||||||
curlun->sense_data = SS_COMMUNICATION_FAILURE;
|
curlun->sense_data = SS_COMMUNICATION_FAILURE;
|
||||||
curlun->sense_data_info = file_offset >> 9;
|
curlun->sense_data_info = file_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1868,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg)
|
||||||
if (nwritten < amount) {
|
if (nwritten < amount) {
|
||||||
curlun->sense_data = SS_WRITE_ERROR;
|
curlun->sense_data = SS_WRITE_ERROR;
|
||||||
curlun->sense_data_info = file_offset >> 9;
|
curlun->sense_data_info = file_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2010,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg)
|
||||||
curlun->sense_data =
|
curlun->sense_data =
|
||||||
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||||
curlun->sense_data_info = file_offset >> 9;
|
curlun->sense_data_info = file_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2036,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg)
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||||
curlun->sense_data_info = file_offset >> 9;
|
curlun->sense_data_info = file_offset >> 9;
|
||||||
|
curlun->info_valid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
file_offset += nread;
|
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;
|
struct lun *curlun = fsg->curlun;
|
||||||
u8 *buf = (u8 *) bh->buf;
|
u8 *buf = (u8 *) bh->buf;
|
||||||
u32 sd, sdinfo;
|
u32 sd, sdinfo;
|
||||||
|
int valid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From the SCSI-2 spec., section 7.9 (Unit attention condition):
|
* 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;
|
fsg->bad_lun_okay = 1;
|
||||||
sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
|
sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
|
||||||
sdinfo = 0;
|
sdinfo = 0;
|
||||||
|
valid = 0;
|
||||||
} else {
|
} else {
|
||||||
sd = curlun->sense_data;
|
sd = curlun->sense_data;
|
||||||
sdinfo = curlun->sense_data_info;
|
sdinfo = curlun->sense_data_info;
|
||||||
|
valid = curlun->info_valid << 7;
|
||||||
curlun->sense_data = SS_NO_SENSE;
|
curlun->sense_data = SS_NO_SENSE;
|
||||||
curlun->sense_data_info = 0;
|
curlun->sense_data_info = 0;
|
||||||
|
curlun->info_valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(buf, 0, 18);
|
memset(buf, 0, 18);
|
||||||
buf[0] = 0x80 | 0x70; // Valid, current error
|
buf[0] = valid | 0x70; // Valid, current error
|
||||||
buf[2] = SK(sd);
|
buf[2] = SK(sd);
|
||||||
put_be32(&buf[3], sdinfo); // Sense information
|
put_be32(&buf[3], sdinfo); // Sense information
|
||||||
buf[7] = 18 - 8; // Additional sense length
|
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) {
|
if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
|
||||||
curlun->sense_data = SS_NO_SENSE;
|
curlun->sense_data = SS_NO_SENSE;
|
||||||
curlun->sense_data_info = 0;
|
curlun->sense_data_info = 0;
|
||||||
|
curlun->info_valid = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fsg->curlun = curlun = NULL;
|
fsg->curlun = curlun = NULL;
|
||||||
|
@ -3332,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg)
|
||||||
curlun->sense_data = curlun->unit_attention_data =
|
curlun->sense_data = curlun->unit_attention_data =
|
||||||
SS_NO_SENSE;
|
SS_NO_SENSE;
|
||||||
curlun->sense_data_info = 0;
|
curlun->sense_data_info = 0;
|
||||||
|
curlun->info_valid = 0;
|
||||||
}
|
}
|
||||||
fsg->state = FSG_STATE_IDLE;
|
fsg->state = FSG_STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue