@@ -58,6 +58,8 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
5858#define CDL_T2A_SUB_MPAGE 0x07
5959#define CDL_T2B_SUB_MPAGE 0x08
6060#define CDL_T2_SUB_MPAGE_LEN 232
61+ #define ATA_FEATURE_SUB_MPAGE 0xf2
62+ #define ATA_FEATURE_SUB_MPAGE_LEN 16
6163
6264static const u8 def_rw_recovery_mpage [RW_RECOVERY_MPAGE_LEN ] = {
6365 RW_RECOVERY_MPAGE ,
@@ -2286,6 +2288,31 @@ static unsigned int ata_msense_control_spgt2(struct ata_device *dev, u8 *buf,
22862288 return CDL_T2_SUB_MPAGE_LEN ;
22872289}
22882290
2291+ /*
2292+ * Simulate MODE SENSE control mode page, sub-page f2h
2293+ * (ATA feature control mode page).
2294+ */
2295+ static unsigned int ata_msense_control_ata_feature (struct ata_device * dev ,
2296+ u8 * buf )
2297+ {
2298+ /* PS=0, SPF=1 */
2299+ buf [0 ] = CONTROL_MPAGE | (1 << 6 );
2300+ buf [1 ] = ATA_FEATURE_SUB_MPAGE ;
2301+
2302+ /*
2303+ * The first four bytes of ATA Feature Control mode page are a header.
2304+ * The PAGE LENGTH field is the size of the page excluding the header.
2305+ */
2306+ put_unaligned_be16 (ATA_FEATURE_SUB_MPAGE_LEN - 4 , & buf [2 ]);
2307+
2308+ if (dev -> flags & ATA_DFLAG_CDL )
2309+ buf [4 ] = 0x02 ; /* Support T2A and T2B pages */
2310+ else
2311+ buf [4 ] = 0 ;
2312+
2313+ return ATA_FEATURE_SUB_MPAGE_LEN ;
2314+ }
2315+
22892316/**
22902317 * ata_msense_control - Simulate MODE SENSE control mode page
22912318 * @dev: ATA device of interest
@@ -2309,10 +2336,13 @@ static unsigned int ata_msense_control(struct ata_device *dev, u8 *buf,
23092336 case CDL_T2A_SUB_MPAGE :
23102337 case CDL_T2B_SUB_MPAGE :
23112338 return ata_msense_control_spgt2 (dev , buf , spg );
2339+ case ATA_FEATURE_SUB_MPAGE :
2340+ return ata_msense_control_ata_feature (dev , buf );
23122341 case ALL_SUB_MPAGES :
23132342 n = ata_msense_control_spg0 (dev , buf , changeable );
23142343 n += ata_msense_control_spgt2 (dev , buf + n , CDL_T2A_SUB_MPAGE );
23152344 n += ata_msense_control_spgt2 (dev , buf + n , CDL_T2A_SUB_MPAGE );
2345+ n += ata_msense_control_ata_feature (dev , buf + n );
23162346 return n ;
23172347 default :
23182348 return 0 ;
@@ -2391,7 +2421,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
23912421 spg = scsicmd [3 ];
23922422
23932423 /*
2394- * Supported subpages: all subpages and sub-pages 07h and 08h of
2424+ * Supported subpages: all subpages and sub-pages 07h, 08h and f2h of
23952425 * the control page.
23962426 */
23972427 if (spg ) {
@@ -2400,6 +2430,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
24002430 break ;
24012431 case CDL_T2A_SUB_MPAGE :
24022432 case CDL_T2B_SUB_MPAGE :
2433+ case ATA_FEATURE_SUB_MPAGE :
24032434 if (dev -> flags & ATA_DFLAG_CDL && pg == CONTROL_MPAGE )
24042435 break ;
24052436 fallthrough ;
@@ -3708,20 +3739,11 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
37083739 return 0 ;
37093740}
37103741
3711- /**
3712- * ata_mselect_control - Simulate MODE SELECT for control page
3713- * @qc: Storage for translated ATA taskfile
3714- * @buf: input buffer
3715- * @len: number of valid bytes in the input buffer
3716- * @fp: out parameter for the failed field on error
3717- *
3718- * Prepare a taskfile to modify caching information for the device.
3719- *
3720- * LOCKING:
3721- * None.
3742+ /*
3743+ * Simulate MODE SELECT control mode page, sub-page 0.
37223744 */
3723- static int ata_mselect_control (struct ata_queued_cmd * qc ,
3724- const u8 * buf , int len , u16 * fp )
3745+ static int ata_mselect_control_spg0 (struct ata_queued_cmd * qc ,
3746+ const u8 * buf , int len , u16 * fp )
37253747{
37263748 struct ata_device * dev = qc -> dev ;
37273749 u8 mpage [CONTROL_MPAGE_LEN ];
@@ -3759,6 +3781,83 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
37593781 return 0 ;
37603782}
37613783
3784+ /*
3785+ * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode
3786+ * page) into a SET FEATURES command.
3787+ */
3788+ static unsigned int ata_mselect_control_ata_feature (struct ata_queued_cmd * qc ,
3789+ const u8 * buf , int len ,
3790+ u16 * fp )
3791+ {
3792+ struct ata_device * dev = qc -> dev ;
3793+ struct ata_taskfile * tf = & qc -> tf ;
3794+ u8 cdl_action ;
3795+
3796+ /*
3797+ * The first four bytes of ATA Feature Control mode page are a header,
3798+ * so offsets in mpage are off by 4 compared to buf. Same for len.
3799+ */
3800+ if (len != ATA_FEATURE_SUB_MPAGE_LEN - 4 ) {
3801+ * fp = min (len , ATA_FEATURE_SUB_MPAGE_LEN - 4 );
3802+ return - EINVAL ;
3803+ }
3804+
3805+ /* Check cdl_ctrl */
3806+ switch (buf [0 ] & 0x03 ) {
3807+ case 0 :
3808+ /* Disable CDL */
3809+ cdl_action = 0 ;
3810+ dev -> flags &= ~ATA_DFLAG_CDL_ENABLED ;
3811+ break ;
3812+ case 0x02 :
3813+ /* Enable CDL T2A/T2B: NCQ priority must be disabled */
3814+ if (dev -> flags & ATA_DFLAG_NCQ_PRIO_ENABLED ) {
3815+ ata_dev_err (dev ,
3816+ "NCQ priority must be disabled to enable CDL\n" );
3817+ return - EINVAL ;
3818+ }
3819+ cdl_action = 1 ;
3820+ dev -> flags |= ATA_DFLAG_CDL_ENABLED ;
3821+ break ;
3822+ default :
3823+ * fp = 0 ;
3824+ return - EINVAL ;
3825+ }
3826+
3827+ tf -> flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR ;
3828+ tf -> protocol = ATA_PROT_NODATA ;
3829+ tf -> command = ATA_CMD_SET_FEATURES ;
3830+ tf -> feature = SETFEATURES_CDL ;
3831+ tf -> nsect = cdl_action ;
3832+
3833+ return 1 ;
3834+ }
3835+
3836+ /**
3837+ * ata_mselect_control - Simulate MODE SELECT for control page
3838+ * @qc: Storage for translated ATA taskfile
3839+ * @buf: input buffer
3840+ * @len: number of valid bytes in the input buffer
3841+ * @fp: out parameter for the failed field on error
3842+ *
3843+ * Prepare a taskfile to modify caching information for the device.
3844+ *
3845+ * LOCKING:
3846+ * None.
3847+ */
3848+ static int ata_mselect_control (struct ata_queued_cmd * qc , u8 spg ,
3849+ const u8 * buf , int len , u16 * fp )
3850+ {
3851+ switch (spg ) {
3852+ case 0 :
3853+ return ata_mselect_control_spg0 (qc , buf , len , fp );
3854+ case ATA_FEATURE_SUB_MPAGE :
3855+ return ata_mselect_control_ata_feature (qc , buf , len , fp );
3856+ default :
3857+ return - EINVAL ;
3858+ }
3859+ }
3860+
37623861/**
37633862 * ata_scsi_mode_select_xlat - Simulate MODE SELECT 6, 10 commands
37643863 * @qc: Storage for translated ATA taskfile
@@ -3776,7 +3875,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
37763875 const u8 * cdb = scmd -> cmnd ;
37773876 u8 pg , spg ;
37783877 unsigned six_byte , pg_len , hdr_len , bd_len ;
3779- int len ;
3878+ int len , ret ;
37803879 u16 fp = (u16 )- 1 ;
37813880 u8 bp = 0xff ;
37823881 u8 buffer [64 ];
@@ -3861,13 +3960,29 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
38613960 }
38623961
38633962 /*
3864- * No mode subpages supported (yet) but asking for _all_
3865- * subpages may be valid
3963+ * Supported subpages: all subpages and ATA feature sub-page f2h of
3964+ * the control page.
38663965 */
3867- if (spg && (spg != ALL_SUB_MPAGES )) {
3868- fp = (p [0 ] & 0x40 ) ? 1 : 0 ;
3869- fp += hdr_len + bd_len ;
3870- goto invalid_param ;
3966+ if (spg ) {
3967+ switch (spg ) {
3968+ case ALL_SUB_MPAGES :
3969+ /* All subpages is not supported for the control page */
3970+ if (pg == CONTROL_MPAGE ) {
3971+ fp = (p [0 ] & 0x40 ) ? 1 : 0 ;
3972+ fp += hdr_len + bd_len ;
3973+ goto invalid_param ;
3974+ }
3975+ break ;
3976+ case ATA_FEATURE_SUB_MPAGE :
3977+ if (qc -> dev -> flags & ATA_DFLAG_CDL &&
3978+ pg == CONTROL_MPAGE )
3979+ break ;
3980+ fallthrough ;
3981+ default :
3982+ fp = (p [0 ] & 0x40 ) ? 1 : 0 ;
3983+ fp += hdr_len + bd_len ;
3984+ goto invalid_param ;
3985+ }
38713986 }
38723987 if (pg_len > len )
38733988 goto invalid_param_len ;
@@ -3880,14 +3995,16 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
38803995 }
38813996 break ;
38823997 case CONTROL_MPAGE :
3883- if (ata_mselect_control (qc , p , pg_len , & fp ) < 0 ) {
3998+ ret = ata_mselect_control (qc , spg , p , pg_len , & fp );
3999+ if (ret < 0 ) {
38844000 fp += hdr_len + bd_len ;
38854001 goto invalid_param ;
3886- } else {
3887- goto skip ; /* No ATA command to send */
38884002 }
4003+ if (!ret )
4004+ goto skip ; /* No ATA command to send */
38894005 break ;
3890- default : /* invalid page code */
4006+ default :
4007+ /* Invalid page code */
38914008 fp = bd_len + hdr_len ;
38924009 goto invalid_param ;
38934010 }
0 commit comments