[SCSI] Support devices with protection information

Implement support for DMA of protection information for devices that
are data integrity capable.

 - Add support for mapping an extra scatter-gather list containing
   the protection information.

 - Allocate protection scsi_data_buffer if host is DIX (integrity DMA)
   capable.

 - Accessor function for checking whether a device has protection
   enabled.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
Martin K. Petersen
2008-07-17 17:08:48 -04:00
committed by James Bottomley
parent db007fc5e2
commit 7027ad72a6
5 changed files with 84 additions and 3 deletions

View File

@ -65,7 +65,7 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
};
#undef SP
static struct kmem_cache *scsi_sdb_cache;
struct kmem_cache *scsi_sdb_cache;
static void scsi_run_queue(struct request_queue *q);
@ -787,6 +787,9 @@ void scsi_release_buffers(struct scsi_cmnd *cmd)
kmem_cache_free(scsi_sdb_cache, bidi_sdb);
cmd->request->next_rq->special = NULL;
}
if (scsi_prot_sg_count(cmd))
scsi_free_sgtable(cmd->prot_sdb);
}
EXPORT_SYMBOL(scsi_release_buffers);
@ -1072,6 +1075,26 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
goto err_exit;
}
if (blk_integrity_rq(cmd->request)) {
struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
int ivecs, count;
BUG_ON(prot_sdb == NULL);
ivecs = blk_rq_count_integrity_sg(cmd->request);
if (scsi_alloc_sgtable(prot_sdb, ivecs, gfp_mask)) {
error = BLKPREP_DEFER;
goto err_exit;
}
count = blk_rq_map_integrity_sg(cmd->request,
prot_sdb->table.sgl);
BUG_ON(unlikely(count > ivecs));
cmd->prot_sdb = prot_sdb;
cmd->prot_sdb->table.nents = count;
}
return BLKPREP_OK ;
err_exit: