@@ -116,6 +116,9 @@ static DEFINE_IDA(sd_index_ida);
116116 * object after last put) */
117117static DEFINE_MUTEX (sd_ref_mutex );
118118
119+ struct kmem_cache * sd_cdb_cache ;
120+ mempool_t * sd_cdb_pool ;
121+
119122static const char * sd_cache_types [] = {
120123 "write through" , "none" , "write back" ,
121124 "write back, no read (daft)"
@@ -413,6 +416,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
413416 sector_t threshold ;
414417 unsigned int this_count = blk_rq_sectors (rq );
415418 int ret , host_dif ;
419+ unsigned char protect ;
416420
417421 if (rq -> cmd_type == REQ_TYPE_BLOCK_PC ) {
418422 ret = scsi_setup_blk_pc_cmnd (sdp , rq );
@@ -545,13 +549,49 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
545549 /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */
546550 host_dif = scsi_host_dif_capable (sdp -> host , sdkp -> protection_type );
547551 if (host_dif )
548- SCpnt -> cmnd [ 1 ] = 1 << 5 ;
552+ protect = 1 << 5 ;
549553 else
550- SCpnt -> cmnd [1 ] = 0 ;
554+ protect = 0 ;
555+
556+ if (host_dif == SD_DIF_TYPE2_PROTECTION ) {
557+ SCpnt -> cmnd = mempool_alloc (sd_cdb_pool , GFP_ATOMIC );
558+
559+ if (unlikely (SCpnt -> cmnd == NULL )) {
560+ ret = BLKPREP_DEFER ;
561+ goto out ;
562+ }
551563
552- if (block > 0xffffffff ) {
564+ SCpnt -> cmd_len = SD_EXT_CDB_SIZE ;
565+ memset (SCpnt -> cmnd , 0 , SCpnt -> cmd_len );
566+ SCpnt -> cmnd [0 ] = VARIABLE_LENGTH_CMD ;
567+ SCpnt -> cmnd [7 ] = 0x18 ;
568+ SCpnt -> cmnd [9 ] = (rq_data_dir (rq ) == READ ) ? READ_32 : WRITE_32 ;
569+ SCpnt -> cmnd [10 ] = protect | (blk_fua_rq (rq ) ? 0x8 : 0 );
570+
571+ /* LBA */
572+ SCpnt -> cmnd [12 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 56 ) & 0xff : 0 ;
573+ SCpnt -> cmnd [13 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 48 ) & 0xff : 0 ;
574+ SCpnt -> cmnd [14 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 40 ) & 0xff : 0 ;
575+ SCpnt -> cmnd [15 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 32 ) & 0xff : 0 ;
576+ SCpnt -> cmnd [16 ] = (unsigned char ) (block >> 24 ) & 0xff ;
577+ SCpnt -> cmnd [17 ] = (unsigned char ) (block >> 16 ) & 0xff ;
578+ SCpnt -> cmnd [18 ] = (unsigned char ) (block >> 8 ) & 0xff ;
579+ SCpnt -> cmnd [19 ] = (unsigned char ) block & 0xff ;
580+
581+ /* Expected Indirect LBA */
582+ SCpnt -> cmnd [20 ] = (unsigned char ) (block >> 24 ) & 0xff ;
583+ SCpnt -> cmnd [21 ] = (unsigned char ) (block >> 16 ) & 0xff ;
584+ SCpnt -> cmnd [22 ] = (unsigned char ) (block >> 8 ) & 0xff ;
585+ SCpnt -> cmnd [23 ] = (unsigned char ) block & 0xff ;
586+
587+ /* Transfer length */
588+ SCpnt -> cmnd [28 ] = (unsigned char ) (this_count >> 24 ) & 0xff ;
589+ SCpnt -> cmnd [29 ] = (unsigned char ) (this_count >> 16 ) & 0xff ;
590+ SCpnt -> cmnd [30 ] = (unsigned char ) (this_count >> 8 ) & 0xff ;
591+ SCpnt -> cmnd [31 ] = (unsigned char ) this_count & 0xff ;
592+ } else if (block > 0xffffffff ) {
553593 SCpnt -> cmnd [0 ] += READ_16 - READ_6 ;
554- SCpnt -> cmnd [1 ] |= blk_fua_rq (rq ) ? 0x8 : 0 ;
594+ SCpnt -> cmnd [1 ] = protect | ( blk_fua_rq (rq ) ? 0x8 : 0 ) ;
555595 SCpnt -> cmnd [2 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 56 ) & 0xff : 0 ;
556596 SCpnt -> cmnd [3 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 48 ) & 0xff : 0 ;
557597 SCpnt -> cmnd [4 ] = sizeof (block ) > 4 ? (unsigned char ) (block >> 40 ) & 0xff : 0 ;
@@ -572,7 +612,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
572612 this_count = 0xffff ;
573613
574614 SCpnt -> cmnd [0 ] += READ_10 - READ_6 ;
575- SCpnt -> cmnd [1 ] |= blk_fua_rq (rq ) ? 0x8 : 0 ;
615+ SCpnt -> cmnd [1 ] = protect | ( blk_fua_rq (rq ) ? 0x8 : 0 ) ;
576616 SCpnt -> cmnd [2 ] = (unsigned char ) (block >> 24 ) & 0xff ;
577617 SCpnt -> cmnd [3 ] = (unsigned char ) (block >> 16 ) & 0xff ;
578618 SCpnt -> cmnd [4 ] = (unsigned char ) (block >> 8 ) & 0xff ;
@@ -1047,6 +1087,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
10471087 int result = SCpnt -> result ;
10481088 unsigned int good_bytes = result ? 0 : scsi_bufflen (SCpnt );
10491089 struct scsi_sense_hdr sshdr ;
1090+ struct scsi_disk * sdkp = scsi_disk (SCpnt -> request -> rq_disk );
10501091 int sense_valid = 0 ;
10511092 int sense_deferred = 0 ;
10521093
@@ -1108,6 +1149,10 @@ static int sd_done(struct scsi_cmnd *SCpnt)
11081149 if (rq_data_dir (SCpnt -> request ) == READ && scsi_prot_sg_count (SCpnt ))
11091150 sd_dif_complete (SCpnt , good_bytes );
11101151
1152+ if (scsi_host_dif_capable (sdkp -> device -> host , sdkp -> protection_type )
1153+ == SD_DIF_TYPE2_PROTECTION && SCpnt -> cmnd != SCpnt -> request -> cmd )
1154+ mempool_free (SCpnt -> cmnd , sd_cdb_pool );
1155+
11111156 return good_bytes ;
11121157}
11131158
@@ -1271,12 +1316,7 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
12711316
12721317 sdkp -> protection_type = type ;
12731318
1274- switch (type ) {
1275- case SD_DIF_TYPE1_PROTECTION :
1276- case SD_DIF_TYPE3_PROTECTION :
1277- break ;
1278-
1279- default :
1319+ if (type > SD_DIF_TYPE3_PROTECTION ) {
12801320 sd_printk (KERN_ERR , sdkp , "formatted with unsupported " \
12811321 "protection type %u. Disabling disk!\n" , type );
12821322 sdkp -> capacity = 0 ;
@@ -2323,8 +2363,24 @@ static int __init init_sd(void)
23232363 if (err )
23242364 goto err_out_class ;
23252365
2366+ sd_cdb_cache = kmem_cache_create ("sd_ext_cdb" , SD_EXT_CDB_SIZE ,
2367+ 0 , 0 , NULL );
2368+ if (!sd_cdb_cache ) {
2369+ printk (KERN_ERR "sd: can't init extended cdb cache\n" );
2370+ goto err_out_class ;
2371+ }
2372+
2373+ sd_cdb_pool = mempool_create_slab_pool (SD_MEMPOOL_SIZE , sd_cdb_cache );
2374+ if (!sd_cdb_pool ) {
2375+ printk (KERN_ERR "sd: can't init extended cdb pool\n" );
2376+ goto err_out_cache ;
2377+ }
2378+
23262379 return 0 ;
23272380
2381+ err_out_cache :
2382+ kmem_cache_destroy (sd_cdb_cache );
2383+
23282384err_out_class :
23292385 class_unregister (& sd_disk_class );
23302386err_out :
@@ -2344,6 +2400,9 @@ static void __exit exit_sd(void)
23442400
23452401 SCSI_LOG_HLQUEUE (3 , printk ("exit_sd: exiting sd driver\n" ));
23462402
2403+ mempool_destroy (sd_cdb_pool );
2404+ kmem_cache_destroy (sd_cdb_cache );
2405+
23472406 scsi_unregister_driver (& sd_template .gendrv );
23482407 class_unregister (& sd_disk_class );
23492408
0 commit comments