diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 144c72f0737a1e..78c29040426639 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1568,6 +1568,7 @@ static void scsi_complete(struct request *rq) static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; + struct scsi_device *sdev = cmd->device; int rtn = 0; atomic_inc(&cmd->device->iorequest_cnt); @@ -1616,6 +1617,17 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) goto done; } + /* + * Before we queue this command, check attribute use_192_bytes_for_3f. + * Because transmits data with a length of 0xff bytes via ioctl may + * cause some hard drives to hang and become unusable. + */ + if (cmd->cmnd[0] == MODE_SENSE && sdev->use_192_bytes_for_3f && + cmd->cmnd[2] == 0x3f && cmd->cmnd[4] != 192) { + cmd->result = DID_ABORT << 16; + goto done; + } + if (unlikely(host->shost_state == SHOST_DEL)) { cmd->result = (DID_NO_CONNECT << 16); goto done;