X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fscsi%2Fsd.c;h=7e22aa7b8b8a9072f806497bbfed7377fa09e86f;hb=d4c9b736080056ae3ba81dcf2ac418193c57dbb1;hp=a7b53be633676399e3a08b6a6113a2b95da7cc6e;hpb=be3bfbba8f7f6c8f32e8444ef895433701a3f801;p=linux-2.6-omap-h63xx.git diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a7b53be6336..7e22aa7b8b8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -384,7 +384,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) sector_t block = rq->sector; sector_t threshold; unsigned int this_count = rq->nr_sectors; - int ret; + int ret, host_dif; if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { ret = scsi_setup_blk_pc_cmnd(sdp, rq); @@ -515,7 +515,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) rq->nr_sectors)); /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ - if (scsi_host_dif_capable(sdp->host, sdkp->protection_type)) + host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); + if (host_dif) SCpnt->cmnd[1] = 1 << 5; else SCpnt->cmnd[1] = 0; @@ -573,8 +574,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->sdb.length = this_count * sdp->sector_size; /* If DIF or DIX is enabled, tell HBA how to handle request */ - if (sdkp->protection_type || scsi_prot_sg_count(SCpnt)) - sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt)); + if (host_dif || scsi_prot_sg_count(SCpnt)) + sd_dif_op(SCpnt, host_dif, scsi_prot_sg_count(SCpnt), + sdkp->protection_type); /* * We shouldn't disconnect in the middle of a sector, so with a dumb @@ -1052,7 +1054,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) good_bytes = sd_completed_bytes(SCpnt); break; case RECOVERED_ERROR: - case NO_SENSE: /* Inform the user, but make sure that it's not treated * as a hard error. */ @@ -1061,6 +1062,15 @@ static int sd_done(struct scsi_cmnd *SCpnt) memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); good_bytes = scsi_bufflen(SCpnt); break; + case NO_SENSE: + /* This indicates a false check condition, so ignore it. An + * unknown amount of data was transferred so treat it as an + * error. + */ + scsi_print_sense("sd", SCpnt); + SCpnt->result = 0; + memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + break; case ABORTED_COMMAND: if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ scsi_print_result(SCpnt); @@ -1074,15 +1084,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) scsi_print_sense("sd", SCpnt); good_bytes = sd_completed_bytes(SCpnt); } - if (!scsi_device_protection(SCpnt->device) && - SCpnt->device->use_10_for_rw && - (SCpnt->cmnd[0] == READ_10 || - SCpnt->cmnd[0] == WRITE_10)) - SCpnt->device->use_10_for_rw = 0; - if (SCpnt->device->use_10_for_ms && - (SCpnt->cmnd[0] == MODE_SENSE_10 || - SCpnt->cmnd[0] == MODE_SELECT_10)) - SCpnt->device->use_10_for_ms = 0; break; default: break; @@ -1252,14 +1253,12 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) else type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ + sdkp->protection_type = type; + switch (type) { case SD_DIF_TYPE0_PROTECTION: - sdkp->protection_type = 0; - break; - case SD_DIF_TYPE1_PROTECTION: case SD_DIF_TYPE3_PROTECTION: - sdkp->protection_type = type; break; case SD_DIF_TYPE2_PROTECTION: @@ -1277,7 +1276,6 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) return; disable: - sdkp->protection_type = 0; sdkp->capacity = 0; }