scsi: use sdev as argument for sense code printing
[pandora-kernel.git] / drivers / scsi / sd.c
index 0cb5c9f..3ae7540 100644 (file)
@@ -610,29 +610,44 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
        mutex_unlock(&sd_ref_mutex);
 }
 
-static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif)
-{
-       unsigned int prot_op = SCSI_PROT_NORMAL;
-       unsigned int dix = scsi_prot_sg_count(scmd);
-
-       if (scmd->sc_data_direction == DMA_FROM_DEVICE) {
-               if (dif && dix)
-                       prot_op = SCSI_PROT_READ_PASS;
-               else if (dif && !dix)
-                       prot_op = SCSI_PROT_READ_STRIP;
-               else if (!dif && dix)
-                       prot_op = SCSI_PROT_READ_INSERT;
-       } else {
-               if (dif && dix)
-                       prot_op = SCSI_PROT_WRITE_PASS;
-               else if (dif && !dix)
-                       prot_op = SCSI_PROT_WRITE_INSERT;
-               else if (!dif && dix)
-                       prot_op = SCSI_PROT_WRITE_STRIP;
+
+
+static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
+                                          unsigned int dix, unsigned int dif)
+{
+       struct bio *bio = scmd->request->bio;
+       unsigned int prot_op = sd_prot_op(rq_data_dir(scmd->request), dix, dif);
+       unsigned int protect = 0;
+
+       if (dix) {                              /* DIX Type 0, 1, 2, 3 */
+               if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM))
+                       scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
+
+               if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
+                       scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
+       }
+
+       if (dif != SD_DIF_TYPE3_PROTECTION) {   /* DIX/DIF Type 0, 1, 2 */
+               scmd->prot_flags |= SCSI_PROT_REF_INCREMENT;
+
+               if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
+                       scmd->prot_flags |= SCSI_PROT_REF_CHECK;
+       }
+
+       if (dif) {                              /* DIX/DIF Type 1, 2, 3 */
+               scmd->prot_flags |= SCSI_PROT_TRANSFER_PI;
+
+               if (bio_integrity_flagged(bio, BIP_DISK_NOCHECK))
+                       protect = 3 << 5;       /* Disable target PI checking */
+               else
+                       protect = 1 << 5;       /* Enable target PI checking */
        }
 
        scsi_set_prot_op(scmd, prot_op);
        scsi_set_prot_type(scmd, dif);
+       scmd->prot_flags &= sd_prot_flag_mask(prot_op);
+
+       return protect;
 }
 
 static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
@@ -893,7 +908,8 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
        sector_t block = blk_rq_pos(rq);
        sector_t threshold;
        unsigned int this_count = blk_rq_sectors(rq);
-       int ret, host_dif;
+       unsigned int dif, dix;
+       int ret;
        unsigned char protect;
 
        ret = scsi_init_io(SCpnt, GFP_ATOMIC);
@@ -995,7 +1011,7 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
                SCpnt->cmnd[0] = WRITE_6;
 
                if (blk_integrity_rq(rq))
-                       sd_dif_prepare(rq, block, sdp->sector_size);
+                       sd_dif_prepare(SCpnt);
 
        } else if (rq_data_dir(rq) == READ) {
                SCpnt->cmnd[0] = READ_6;
@@ -1010,14 +1026,15 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
                                        "writing" : "reading", this_count,
                                        blk_rq_sectors(rq)));
 
-       /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */
-       host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
-       if (host_dif)
-               protect = 1 << 5;
+       dix = scsi_prot_sg_count(SCpnt);
+       dif = scsi_host_dif_capable(SCpnt->device->host, sdkp->protection_type);
+
+       if (dif || dix)
+               protect = sd_setup_protect_cmnd(SCpnt, dix, dif);
        else
                protect = 0;
 
-       if (host_dif == SD_DIF_TYPE2_PROTECTION) {
+       if (protect && sdkp->protection_type == SD_DIF_TYPE2_PROTECTION) {
                SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC);
 
                if (unlikely(SCpnt->cmnd == NULL)) {
@@ -1102,10 +1119,6 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
        }
        SCpnt->sdb.length = this_count * sdp->sector_size;
 
-       /* If DIF or DIX is enabled, tell HBA how to handle request */
-       if (host_dif || scsi_prot_sg_count(SCpnt))
-               sd_prot_op(SCpnt, host_dif);
-
        /*
         * We shouldn't disconnect in the middle of a sector, so with a dumb
         * host adapter, it's safe to assume that we can at least transfer
@@ -1730,7 +1743,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                 * 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;
@@ -2664,8 +2676,10 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 
        rot = get_unaligned_be16(&buffer[4]);
 
-       if (rot == 1)
+       if (rot == 1) {
                queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue);
+               queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, sdkp->disk->queue);
+       }
 
  out:
        kfree(buffer);
@@ -3322,10 +3336,11 @@ module_exit(exit_sd);
 static void sd_print_sense_hdr(struct scsi_disk *sdkp,
                               struct scsi_sense_hdr *sshdr)
 {
-       sd_printk(KERN_INFO, sdkp, " ");
-       scsi_show_sense_hdr(sshdr);
-       sd_printk(KERN_INFO, sdkp, " ");
-       scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
+       scsi_show_sense_hdr(sdkp->device,
+                           sdkp->disk ? sdkp->disk->disk_name : NULL, sshdr);
+       scsi_show_extd_sense(sdkp->device,
+                            sdkp->disk ? sdkp->disk->disk_name : NULL,
+                            sshdr->asc, sshdr->ascq);
 }
 
 static void sd_print_result(struct scsi_disk *sdkp, int result)